1/*
2 * Copyright (c) 2000-2014 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#include <sys/cprotect.h>
29#include <sys/mman.h>
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 <sys/proc.h>
40#include <sys/kauth.h>
41
42#include "hfs.h"
43#include "hfs_cnode.h"
44#include "hfs_fsctl.h"
45
46#if CONFIG_PROTECT
47/*
48 * The wrap function pointers and the variable to indicate if they
49 * are initialized are system-wide, and hence are defined globally.
50 */
51static struct cp_wrap_func g_cp_wrap_func = {};
52static int are_wraps_initialized = false;
53
54extern int (**hfs_vnodeop_p) (void *);
55
56/*
57 * CP private functions
58 */
59static int cp_root_major_vers(mount_t mp);
60static int cp_getxattr(cnode_t *, struct hfsmount *hfsmp, struct cprotect **);
61static struct cprotect *cp_entry_alloc(size_t);
62static void cp_entry_dealloc(struct cprotect *entry);
63static int cp_restore_keys(struct cprotect *, struct hfsmount *hfsmp, struct cnode *);
64static int cp_lock_vfs_callback(mount_t, void *);
65static int cp_lock_vnode_callback(vnode_t, void *);
66static int cp_vnode_is_eligible (vnode_t);
67static int cp_check_access (cnode_t *cp, struct hfsmount *hfsmp, int vnop);
68static int cp_new(int newclass, struct hfsmount *hfsmp, struct cnode *cp, mode_t cmode,
69		uint32_t flags, struct cprotect **output_entry);
70static int cp_rewrap(struct cnode *cp, struct hfsmount *hfsmp, int newclass);
71static int cp_unwrap(struct hfsmount *, struct cprotect *, struct cnode *);
72static int cp_setup_aes_ctx(struct cprotect *entry);
73static void cp_init_access(cp_cred_t access, struct cnode *cp);
74
75static inline int cp_get_crypto_generation (uint32_t protclass) {
76	if (protclass & CP_CRYPTO_G1) {
77		return 1;
78	}
79	else return 0;
80}
81
82
83#if DEVELOPMENT || DEBUG
84#define CP_ASSERT(x)		\
85	if ((x) == 0) {			\
86		panic("Content Protection: failed assertion in %s", __FUNCTION__); 	\
87	}
88#else
89#define CP_ASSERT(x)
90#endif
91
92int
93cp_key_store_action(int action)
94{
95
96	if (action < 0 || action > CP_MAX_STATE) {
97		return -1;
98	}
99
100	/*
101	 * The lock state is kept locally to each data protected filesystem to
102	 * avoid using globals.  Pass along the lock request to each filesystem
103	 * we iterate through.
104	 */
105
106	/*
107	 * Upcast the value in 'action' to be a pointer-width unsigned integer.
108	 * This avoids issues relating to pointer-width.
109	 */
110	unsigned long action_arg = (unsigned long) action;
111	return vfs_iterate(0, cp_lock_vfs_callback, (void*)action_arg);
112}
113
114
115int
116cp_register_wraps(cp_wrap_func_t key_store_func)
117{
118	g_cp_wrap_func.new_key = key_store_func->new_key;
119	g_cp_wrap_func.unwrapper = key_store_func->unwrapper;
120	g_cp_wrap_func.rewrapper = key_store_func->rewrapper;
121	/* do not use invalidater until rdar://12170050 goes in ! */
122	g_cp_wrap_func.invalidater = key_store_func->invalidater;
123	g_cp_wrap_func.backup_key = key_store_func->backup_key;
124
125	/* Mark the functions as initialized in the function pointer container */
126	are_wraps_initialized = true;
127
128	return 0;
129}
130
131/*
132 * Allocate and initialize a cprotect blob for a new cnode.
133 * Called from hfs_getnewvnode: cnode is locked exclusive.
134 *
135 * Read xattr data off the cnode. Then, if conditions permit,
136 * unwrap the file key and cache it in the cprotect blob.
137 */
138int
139cp_entry_init(struct cnode *cp, struct mount *mp)
140{
141	struct cprotect *entry = NULL;
142	int error = 0;
143	struct hfsmount *hfsmp = VFSTOHFS(mp);
144
145	/*
146	 * The cnode should be locked at this point, regardless of whether or not
147	 * we are creating a new item in the namespace or vending a vnode on behalf
148	 * of lookup.  The only time we tell getnewvnode to skip the lock is when
149	 * constructing a resource fork vnode. But a resource fork vnode must come
150	 * after the regular data fork cnode has already been constructed.
151	 */
152	if (!cp_fs_protected (mp)) {
153		cp->c_cpentry = NULL;
154		return 0;
155	}
156
157	if (!S_ISREG(cp->c_mode) && !S_ISDIR(cp->c_mode)) {
158		cp->c_cpentry = NULL;
159		return 0;
160	}
161
162	if (are_wraps_initialized == false)  {
163		printf("hfs: cp_update_entry: wrap functions not yet set\n");
164		return ENXIO;
165	}
166
167	if (hfsmp->hfs_running_cp_major_vers == 0) {
168		panic ("hfs cp: no running mount point version! ");
169	}
170
171	CP_ASSERT (cp->c_cpentry == NULL);
172
173	error = cp_getxattr(cp, hfsmp, &entry);
174	if (error == 0) {
175		/*
176		 * Success; attribute was found, though it may not have keys.
177		 * If the entry is not returned without keys, we will delay generating
178		 * keys until the first I/O.
179		 */
180		if (S_ISREG(cp->c_mode)) {
181			if (entry->cp_flags & CP_NEEDS_KEYS) {
182				entry->cp_flags &= ~CP_KEY_FLUSHED;
183			}
184			else {
185				entry->cp_flags |= CP_KEY_FLUSHED;
186			}
187		}
188	}
189	else if (error == ENOATTR) {
190		/*
191		 * Normally, we should always have a CP EA for a file or directory that
192		 * we are initializing here. However, there are some extenuating circumstances,
193		 * such as the root directory immediately following a newfs_hfs.
194		 *
195		 * As a result, we leave code here to deal with an ENOATTR which will always
196		 * default to a 'D/NONE' key, though we don't expect to use it much.
197		 */
198		int target_class = PROTECTION_CLASS_D;
199
200		if (S_ISDIR(cp->c_mode)) {
201			target_class = PROTECTION_CLASS_DIR_NONE;
202		}
203		/* allow keybag to override our class preferences */
204		uint32_t keyflags = CP_KEYWRAP_DIFFCLASS;
205		error = cp_new (target_class, hfsmp, cp, cp->c_mode, keyflags, &entry);
206		if (error == 0) {
207			error = cp_setxattr (cp, entry, hfsmp, cp->c_fileid, XATTR_CREATE);
208		}
209	}
210
211	/*
212	 * Bail out if:
213	 * a) error was not ENOATTR (we got something bad from the getxattr call)
214	 * b) we encountered an error setting the xattr above.
215	 * c) we failed to generate a new cprotect data structure.
216	 */
217	if (error) {
218		goto out;
219	}
220
221	cp->c_cpentry = entry;
222
223out:
224	if (error == 0) {
225		entry->cp_backing_cnode = cp;
226	}
227	else {
228		if (entry) {
229			cp_entry_destroy(entry);
230		}
231		cp->c_cpentry = NULL;
232	}
233
234	return error;
235}
236
237/*
238 * cp_setup_newentry
239 *
240 * Generate a keyless cprotect structure for use with the new AppleKeyStore kext.
241 * Since the kext is now responsible for vending us both wrapped/unwrapped keys
242 * we need to create a keyless xattr upon file / directory creation. When we have the inode value
243 * and the file/directory is established, then we can ask it to generate keys.  Note that
244 * this introduces a potential race;  If the device is locked and the wrapping
245 * keys are purged between the time we call this function and the time we ask it to generate
246 * keys for us, we could have to fail the open(2) call and back out the entry.
247 */
248
249int cp_setup_newentry (struct hfsmount *hfsmp, struct cnode *dcp, int32_t suppliedclass,
250		mode_t cmode, struct cprotect **tmpentry)
251{
252	int isdir = 0;
253	struct cprotect *entry = NULL;
254	uint32_t target_class = hfsmp->default_cp_class;
255	suppliedclass = CP_CLASS(suppliedclass);
256
257	if (hfsmp->hfs_running_cp_major_vers == 0) {
258		panic ("CP: major vers not set in mount!");
259	}
260
261	if (S_ISDIR (cmode))  {
262		isdir = 1;
263	}
264
265	/* Decide the target class.  Input argument takes priority. */
266	if (cp_is_valid_class (isdir, suppliedclass)) {
267		/* caller supplies -1 if it was not specified so we will default to the mount point value */
268		target_class = suppliedclass;
269		/*
270		 * One exception, F is never valid for a directory
271		 * because its children may inherit and userland will be
272		 * unable to read/write to the files.
273		 */
274		if (isdir) {
275			if (target_class == PROTECTION_CLASS_F) {
276				*tmpentry = NULL;
277				return EINVAL;
278			}
279		}
280	}
281	else {
282		/*
283		 * If no valid class was supplied, behave differently depending on whether or not
284		 * the item being created is a file or directory.
285		 *
286		 * for FILE:
287		 * 		If parent directory has a non-zero class, use that.
288		 * 		If parent directory has a zero class (not set), then attempt to
289		 *		apply the mount point default.
290		 *
291		 * for DIRECTORY:
292		 *		Directories always inherit from the parent; if the parent
293		 * 		has a NONE class set, then we can continue to use that.
294		 */
295		if ((dcp) && (dcp->c_cpentry)) {
296			uint32_t parentclass = CP_CLASS(dcp->c_cpentry->cp_pclass);
297			/* If the parent class is not valid, default to the mount point value */
298			if (cp_is_valid_class(1, parentclass)) {
299				if (isdir) {
300					target_class = parentclass;
301				}
302				else if (parentclass != PROTECTION_CLASS_DIR_NONE) {
303					/* files can inherit so long as it's not NONE */
304					target_class = parentclass;
305				}
306			}
307			/* Otherwise, we already defaulted to the mount point's default */
308		}
309	}
310
311	/* Generate the cprotect to vend out */
312	entry = cp_entry_alloc (0);
313	if (entry == NULL) {
314		*tmpentry = NULL;
315		return ENOMEM;
316	}
317
318	/*
319	 * We don't have keys yet, so fill in what we can.  At this point
320	 * this blob has no keys and it has no backing xattr.  We just know the
321	 * target class.
322	 */
323	entry->cp_flags = (CP_NEEDS_KEYS | CP_NO_XATTR);
324	/* Note this is only the effective class */
325	entry->cp_pclass = target_class;
326	*tmpentry = entry;
327
328	return 0;
329}
330
331
332/*
333 * cp_needs_tempkeys
334 *
335 * Relay to caller whether or not the filesystem should generate temporary keys
336 * during resize operations.
337 */
338
339int cp_needs_tempkeys (struct hfsmount *hfsmp, int *needs)
340{
341
342	if (hfsmp->hfs_running_cp_major_vers < CP_PREV_MAJOR_VERS ||
343			hfsmp->hfs_running_cp_major_vers > CP_NEW_MAJOR_VERS)  {
344		return -1;
345	}
346
347	/* CP_NEW_MAJOR_VERS implies CP_OFF_IV_ENABLED */
348	if (hfsmp->hfs_running_cp_major_vers < CP_NEW_MAJOR_VERS) {
349		*needs = 0;
350	}
351	else {
352		*needs = 1;
353	}
354
355	return 0;
356}
357
358
359/*
360 * Set up an initial key/class pair for a disassociated cprotect entry.
361 * This function is used to generate transient keys that will never be
362 * written to disk.  We use class F for this since it provides the exact
363 * semantics that are needed here.  Because we never attach this blob to
364 * a cnode directly, we take a pointer to the cprotect struct.
365 *
366 * This function is primarily used in the HFS FS truncation codepath
367 * where we may rely on AES symmetry to relocate encrypted data from
368 * one spot in the disk to another.
369 */
370int cp_entry_gentempkeys(struct cprotect **entry_ptr, struct hfsmount *hfsmp)
371{
372
373	struct cprotect *entry = NULL;
374
375	if (hfsmp->hfs_running_cp_major_vers < CP_NEW_MAJOR_VERS) {
376		return EPERM;
377	}
378
379	/*
380	 * This should only be  used for files and won't be written out.
381	 * We don't need a persistent key.
382	 */
383	entry = cp_entry_alloc (0);
384	if (entry == NULL) {
385		*entry_ptr = NULL;
386		return ENOMEM;
387	}
388	/* This is generated in-kernel so we leave it at the max key*/
389	entry->cp_cache_key_len = CP_MAX_KEYSIZE;
390
391	/* This pclass is only the effective class */
392	entry->cp_pclass = PROTECTION_CLASS_F;
393	entry->cp_persistent_key_len = 0;
394
395	/* Generate the class F key */
396	read_random (&entry->cp_cache_key[0], entry->cp_cache_key_len);
397
398	/* Generate the IV key */
399	cp_setup_aes_ctx(entry);
400	entry->cp_flags |= CP_OFF_IV_ENABLED;
401
402	*entry_ptr = entry;
403	return 0;
404
405}
406
407/*
408 * Tear down and clear a cprotect blob for a closing file.
409 * Called at hfs_reclaim_cnode: cnode is locked exclusive.
410 */
411void
412cp_entry_destroy(struct cprotect *entry_ptr)
413{
414	if (entry_ptr == NULL) {
415		/* nothing to clean up */
416		return;
417	}
418	cp_entry_dealloc(entry_ptr);
419}
420
421
422int
423cp_fs_protected (mount_t mnt)
424{
425	return (vfs_flags(mnt) & MNT_CPROTECT);
426}
427
428
429/*
430 * Return a pointer to underlying cnode if there is one for this vnode.
431 * Done without taking cnode lock, inspecting only vnode state.
432 */
433struct cnode *
434cp_get_protected_cnode(struct vnode *vp)
435{
436	if (!cp_vnode_is_eligible(vp)) {
437		return NULL;
438	}
439
440	if (!cp_fs_protected(VTOVFS(vp))) {
441		/* mount point doesn't support it */
442		return NULL;
443	}
444
445	return (struct cnode*) vp->v_data;
446}
447
448
449/*
450 * Sets *class to persistent class associated with vnode,
451 * or returns error.
452 */
453int
454cp_vnode_getclass(struct vnode *vp, int *class)
455{
456	struct cprotect *entry;
457	int error = 0;
458	struct cnode *cp;
459	int took_truncate_lock = 0;
460	struct hfsmount *hfsmp = NULL;
461
462	/* Is this an interesting vp? */
463	if (!cp_vnode_is_eligible (vp)) {
464		return EBADF;
465	}
466
467	/* Is the mount point formatted for content protection? */
468	if (!cp_fs_protected(VTOVFS(vp))) {
469		return ENOTSUP;
470	}
471
472	cp = VTOC(vp);
473	hfsmp = VTOHFS(vp);
474
475	/*
476	 * Take the truncate lock up-front in shared mode because we may need
477	 * to manipulate the CP blob. Pend lock events until we're done here.
478	 */
479	hfs_lock_truncate (cp, HFS_SHARED_LOCK, HFS_LOCK_DEFAULT);
480	took_truncate_lock = 1;
481
482	/*
483	 * We take only the shared cnode lock up-front.  If it turns out that
484	 * we need to manipulate the CP blob to write a key out, drop the
485	 * shared cnode lock and acquire an exclusive lock.
486	 */
487	error = hfs_lock(cp, HFS_SHARED_LOCK, HFS_LOCK_DEFAULT);
488	if (error) {
489		hfs_unlock_truncate(cp, HFS_LOCK_DEFAULT);
490		return error;
491	}
492
493	/* pull the class from the live entry */
494	entry = cp->c_cpentry;
495
496	if (entry == NULL) {
497		panic("Content Protection: uninitialized cnode %p", cp);
498	}
499
500	/* Note that we may not have keys yet, but we know the target class. */
501
502	if (error == 0) {
503		*class = CP_CLASS(entry->cp_pclass);
504	}
505
506	if (took_truncate_lock) {
507		hfs_unlock_truncate(cp, HFS_LOCK_DEFAULT);
508	}
509
510	hfs_unlock(cp);
511	return error;
512}
513
514
515/*
516 * Sets persistent class for this file or directory.
517 * If vnode cannot be protected (system file, non-regular file, non-hfs), EBADF.
518 * If the new class can't be accessed now, EPERM.
519 * Otherwise, record class and re-wrap key if the mount point is content-protected.
520 */
521int
522cp_vnode_setclass(struct vnode *vp, uint32_t newclass)
523{
524	struct cnode *cp;
525	struct cprotect *entry = 0;
526	int error = 0;
527	int took_truncate_lock = 0;
528	struct hfsmount *hfsmp = NULL;
529	int isdir = 0;
530
531	if (vnode_isdir (vp)) {
532		isdir = 1;
533	}
534
535	/* Ensure we only use the effective class here */
536	newclass = CP_CLASS(newclass);
537
538	if (!cp_is_valid_class(isdir, newclass)) {
539		printf("hfs: CP: cp_setclass called with invalid class %d\n", newclass);
540		return EINVAL;
541	}
542
543	/* Is this an interesting vp? */
544	if (!cp_vnode_is_eligible(vp)) {
545		return EBADF;
546	}
547
548	/* Is the mount point formatted for content protection? */
549	if (!cp_fs_protected(VTOVFS(vp))) {
550		return ENOTSUP;
551	}
552
553	hfsmp = VTOHFS(vp);
554	if (hfsmp->hfs_flags & HFS_READ_ONLY) {
555		return EROFS;
556	}
557
558	/*
559	 * Take the cnode truncate lock exclusive because we want to manipulate the
560	 * CP blob. The lock-event handling code is doing the same.  This also forces
561	 * all pending IOs to drain before we can re-write the persistent and cache keys.
562	 */
563	cp = VTOC(vp);
564	hfs_lock_truncate (cp, HFS_EXCLUSIVE_LOCK, HFS_LOCK_DEFAULT);
565	took_truncate_lock = 1;
566
567	/*
568	 * The truncate lock is not sufficient to guarantee the CP blob
569	 * isn't being used.  We must wait for existing writes to finish.
570	 */
571	vnode_waitforwrites(vp, 0, 0, 0, "cp_vnode_setclass");
572
573	if (hfs_lock(cp, HFS_EXCLUSIVE_LOCK, HFS_LOCK_DEFAULT)) {
574		return EINVAL;
575	}
576
577	entry = cp->c_cpentry;
578	if (entry == NULL) {
579		error = EINVAL;
580		goto out;
581	}
582
583	/*
584	 * re-wrap per-file key with new class.
585	 * Generate an entirely new key if switching to F.
586	 */
587	if (vnode_isreg(vp)) {
588		/*
589		 * The vnode is a file.  Before proceeding with the re-wrap, we need
590		 * to unwrap the keys before proceeding.  This is to ensure that
591		 * the destination class's properties still work appropriately for the
592		 * target class (since B allows I/O but an unwrap prior to the next unlock
593		 * will not be allowed).
594		 */
595		if (entry->cp_flags & CP_KEY_FLUSHED) {
596			error = cp_restore_keys (entry, hfsmp, cp);
597			if (error) {
598				goto out;
599			}
600		}
601		if (newclass == PROTECTION_CLASS_F) {
602			/* Verify that file is blockless if switching to class F */
603			if (cp->c_datafork->ff_size > 0) {
604				error = EINVAL;
605				goto out;
606			}
607
608			/* newclass is only the effective class */
609			entry->cp_pclass = newclass;
610
611			/* Class F files are not wrapped, so they continue to use MAX_KEYSIZE */
612			entry->cp_cache_key_len = CP_MAX_KEYSIZE;
613			read_random (&entry->cp_cache_key[0], entry->cp_cache_key_len);
614			if (hfsmp->hfs_running_cp_major_vers == CP_NEW_MAJOR_VERS) {
615				cp_setup_aes_ctx (entry);
616				entry->cp_flags |= CP_OFF_IV_ENABLED;
617			}
618			bzero(entry->cp_persistent_key, entry->cp_persistent_key_len);
619			entry->cp_persistent_key_len = 0;
620		} else {
621			/* Deny the setclass if file is to be moved from F to something else */
622			if (entry->cp_pclass == PROTECTION_CLASS_F) {
623				error = EPERM;
624				goto out;
625			}
626			/* We cannot call cp_rewrap unless the keys were already in existence. */
627			if (entry->cp_flags & CP_NEEDS_KEYS) {
628				struct cprotect *newentry = NULL;
629				/*
630				 * We want to fail if we can't wrap to the target class. By not setting
631				 * CP_KEYWRAP_DIFFCLASS, we tell keygeneration that if it can't wrap
632				 * to 'newclass' then error out.
633				 */
634				uint32_t flags = 0;
635				error = cp_generate_keys (hfsmp, cp, newclass, flags,  &newentry);
636				if (error == 0) {
637					cp_replace_entry (cp, newentry);
638				}
639				/* Bypass the setxattr code below since generate_keys does it for us */
640				goto out;
641			}
642			else {
643				error = cp_rewrap(cp, hfsmp, newclass);
644			}
645		}
646		if (error) {
647			/* we didn't have perms to set this class. leave file as-is and error out */
648			goto out;
649		}
650	}
651	else if (vnode_isdir(vp)) {
652		/* For directories, just update the pclass.  newclass is only effective class */
653		entry->cp_pclass = newclass;
654		error = 0;
655	}
656	else {
657		/* anything else, just error out */
658		error = EINVAL;
659		goto out;
660	}
661
662	/*
663	 * We get here if the new class was F, or if we were re-wrapping a cprotect that already
664	 * existed. If the keys were never generated, then they'll skip the setxattr calls.
665	 */
666
667	error = cp_setxattr(cp, cp->c_cpentry, VTOHFS(vp), 0, XATTR_REPLACE);
668	if (error == ENOATTR) {
669		error = cp_setxattr(cp, cp->c_cpentry, VTOHFS(vp), 0, XATTR_CREATE);
670	}
671
672out:
673
674	if (took_truncate_lock) {
675		hfs_unlock_truncate (cp, HFS_LOCK_DEFAULT);
676	}
677	hfs_unlock(cp);
678	return error;
679}
680
681
682int cp_vnode_transcode(vnode_t vp, void *key, unsigned *len)
683{
684	struct cnode *cp;
685	struct cprotect *entry = 0;
686	int error = 0;
687	int took_truncate_lock = 0;
688	struct hfsmount *hfsmp = NULL;
689
690	/* Structures passed between HFS and AKS */
691	cp_cred_s access_in;
692	cp_wrapped_key_s wrapped_key_in, wrapped_key_out;
693
694	/* Is this an interesting vp? */
695	if (!cp_vnode_is_eligible(vp)) {
696		return EBADF;
697	}
698
699	/* Is the mount point formatted for content protection? */
700	if (!cp_fs_protected(VTOVFS(vp))) {
701		return ENOTSUP;
702	}
703
704	cp = VTOC(vp);
705	hfsmp = VTOHFS(vp);
706
707	/*
708	 * Take the cnode truncate lock exclusive because we want to manipulate the
709	 * CP blob. The lock-event handling code is doing the same.  This also forces
710	 * all pending IOs to drain before we can re-write the persistent and cache keys.
711	 */
712	hfs_lock_truncate (cp, HFS_EXCLUSIVE_LOCK, HFS_LOCK_DEFAULT);
713	took_truncate_lock = 1;
714
715	if (hfs_lock(cp, HFS_EXCLUSIVE_LOCK, HFS_LOCK_DEFAULT)) {
716		return EINVAL;
717	}
718
719	entry = cp->c_cpentry;
720	if (entry == NULL) {
721		error = EINVAL;
722		goto out;
723	}
724
725	if ((entry->cp_flags & CP_NEEDS_KEYS)) {
726		/*
727		 * If we are transcoding keys for AKB, then we should have already established
728		 * a set of keys for this vnode. IF we don't have keys yet, then something bad
729		 * happened.
730		 */
731		error = EINVAL;
732		goto out;
733	}
734
735	/* Send the per-file key in wrapped form for re-wrap with the current class information
736	 * Send NULLs in the output parameters of the wrapper() and AKS will do the rest.
737	 * Don't need to process any outputs, so just clear the locks and pass along the error. */
738	if (vnode_isreg(vp)) {
739
740		/* Picked up the following from cp_wrap().
741		 * If needed, more comments available there. */
742
743		if (CP_CLASS(entry->cp_pclass) == PROTECTION_CLASS_F) {
744			error = EINVAL;
745			goto out;
746		}
747
748		cp_init_access(&access_in, cp);
749
750		bzero(&wrapped_key_in, sizeof(wrapped_key_in));
751		bzero(&wrapped_key_out, sizeof(wrapped_key_out));
752		wrapped_key_in.key = entry->cp_persistent_key;
753		wrapped_key_in.key_len = entry->cp_persistent_key_len;
754		/* Use the actual persistent class when talking to AKS */
755		wrapped_key_in.dp_class = entry->cp_pclass;
756		wrapped_key_out.key = key;
757		wrapped_key_out.key_len = *len;
758
759		error = g_cp_wrap_func.backup_key(&access_in,
760						&wrapped_key_in,
761						&wrapped_key_out);
762
763		if(error)
764			error = EPERM;
765		else
766			*len = wrapped_key_out.key_len;
767	}
768
769out:
770	if (took_truncate_lock) {
771		hfs_unlock_truncate (cp, HFS_LOCK_DEFAULT);
772	}
773	hfs_unlock(cp);
774	return error;
775}
776
777
778/*
779 * Check permission for the given operation (read, write) on this node.
780 * Additionally, if the node needs work, do it:
781 * - create a new key for the file if one hasn't been set before
782 * - write out the xattr if it hasn't already been saved
783 * - unwrap the key if needed
784 *
785 * Takes cnode lock, and upgrades to exclusive if modifying cprotect.
786 *
787 * Note that this function does *NOT* take the cnode truncate lock.  This is because
788 * the thread calling us may already have the truncate lock.  It is not necessary
789 * because either we successfully finish this function before the keys are tossed
790 * and the IO will fail, or the keys are tossed and then this function will fail.
791 * Either way, the cnode lock still ultimately guards the keys.  We only rely on the
792 * truncate lock to protect us against tossing the keys as a cluster call is in-flight.
793 */
794int
795cp_handle_vnop(struct vnode *vp, int vnop, int ioflag)
796{
797	struct cprotect *entry;
798	int error = 0;
799	struct hfsmount *hfsmp = NULL;
800	struct cnode *cp = NULL;
801
802	/*
803	 * First, do validation against the vnode before proceeding any further:
804	 * Is this vnode originating from a valid content-protected filesystem ?
805	 */
806	if (cp_vnode_is_eligible(vp) == 0) {
807		/*
808		 * It is either not HFS or not a file/dir.  Just return success. This is a valid
809		 * case if servicing i/o against another filesystem type from VFS
810		 */
811		return 0;
812	}
813
814	if (cp_fs_protected (VTOVFS(vp)) == 0) {
815		/*
816		 * The underlying filesystem does not support content protection.  This is also
817		 * a valid case.  Simply return success.
818		 */
819		return 0;
820	}
821
822	/*
823	 * At this point, we know we have a HFS vnode that backs a file or directory on a
824	 * filesystem that supports content protection
825	 */
826	cp = VTOC(vp);
827
828	if ((error = hfs_lock(cp, HFS_SHARED_LOCK, HFS_LOCK_DEFAULT))) {
829		return error;
830	}
831
832	entry = cp->c_cpentry;
833
834	if (entry == NULL) {
835		/*
836		 * If this cnode is not content protected, simply return success.
837		 * Note that this function is called by all I/O-based call sites
838		 * when CONFIG_PROTECT is enabled during XNU building.
839		 */
840
841		/*
842		 * All files should have cprotect structs.  It's possible to encounter
843		 * a directory from a V2.0 CP system but all files should have protection
844		 * EAs
845		 */
846		if (vnode_isreg(vp)) {
847			error = EPERM;
848		}
849
850		goto out;
851	}
852
853	vp = CTOV(cp, 0);
854	if (vp == NULL) {
855		/* is it a rsrc */
856		vp = CTOV(cp,1);
857		if (vp == NULL) {
858			error = EINVAL;
859			goto out;
860		}
861	}
862	hfsmp = VTOHFS(vp);
863
864	if ((error = cp_check_access(cp, hfsmp, vnop))) {
865		/* check for raw encrypted access before bailing out */
866		if ((vnop == CP_READ_ACCESS) && (ioflag & IO_ENCRYPTED)) {
867			/*
868			 * read access only + asking for the raw encrypted bytes
869			 * is legitimate, so reset the error value to 0
870			 */
871			error = 0;
872		}
873		else {
874			goto out;
875		}
876	}
877
878	if (entry->cp_flags == 0) {
879		/* no more work to do */
880		goto out;
881	}
882
883	/* upgrade to exclusive lock */
884	if (lck_rw_lock_shared_to_exclusive(&cp->c_rwlock) == FALSE) {
885		if ((error = hfs_lock(cp, HFS_EXCLUSIVE_LOCK, HFS_LOCK_DEFAULT))) {
886			return error;
887		}
888	} else {
889		cp->c_lockowner = current_thread();
890	}
891
892	/* generate new keys if none have ever been saved */
893	if ((entry->cp_flags & CP_NEEDS_KEYS)) {
894		struct cprotect *newentry = NULL;
895		/*
896		 * It's ok if this ends up being wrapped in a different class than 'pclass'.
897		 * class modification is OK here.
898		 */
899		uint32_t flags = CP_KEYWRAP_DIFFCLASS;
900
901		error = cp_generate_keys (hfsmp, cp, CP_CLASS(cp->c_cpentry->cp_pclass), flags, &newentry);
902		if (error == 0) {
903			cp_replace_entry (cp, newentry);
904			entry = newentry;
905		}
906		else {
907			goto out;
908		}
909	}
910
911	/* unwrap keys if needed */
912	if (entry->cp_flags & CP_KEY_FLUSHED) {
913		if ((vnop == CP_READ_ACCESS) && (ioflag & IO_ENCRYPTED)) {
914			/* no need to try to restore keys; they are not going to be used */
915			error = 0;
916		}
917		else {
918			error = cp_restore_keys(entry, hfsmp, cp);
919			if (error) {
920				goto out;
921			}
922		}
923	}
924
925	/* write out the xattr if it's new */
926	if (entry->cp_flags & CP_NO_XATTR)
927		error = cp_setxattr(cp, entry, VTOHFS(cp->c_vp), 0, XATTR_CREATE);
928
929out:
930
931	hfs_unlock(cp);
932	return error;
933}
934
935
936int
937cp_handle_open(struct vnode *vp, int mode)
938{
939	struct cnode *cp = NULL ;
940	struct cprotect *entry = NULL;
941	struct hfsmount *hfsmp;
942	int error = 0;
943
944	/* If vnode not eligible, just return success */
945	if (!cp_vnode_is_eligible(vp)) {
946		return 0;
947	}
948
949	/* If mount point not properly set up, then also return success */
950	if (!cp_fs_protected(VTOVFS(vp))) {
951		return 0;
952	}
953
954	/* We know the vnode is in a valid state. Acquire cnode and validate */
955	cp = VTOC(vp);
956	hfsmp = VTOHFS(vp);
957
958	if ((error = hfs_lock(cp, HFS_EXCLUSIVE_LOCK, HFS_LOCK_DEFAULT))) {
959		return error;
960	}
961
962	entry = cp->c_cpentry;
963	if (entry == NULL) {
964		/*
965		 * If the mount is protected and we couldn't get a cprotect for this vnode,
966		 * then it's not valid for opening.
967		 */
968		if (vnode_isreg(vp)) {
969			error = EPERM;
970		}
971		goto out;
972	}
973
974	if (!S_ISREG(cp->c_mode))
975		goto out;
976
977	/*
978	 * Does the cnode have keys yet?  If not, then generate them.
979	 */
980	if (entry->cp_flags & CP_NEEDS_KEYS) {
981		struct cprotect *newentry = NULL;
982		/* Allow the keybag to override our class preferences */
983		uint32_t flags = CP_KEYWRAP_DIFFCLASS;
984		error = cp_generate_keys (hfsmp, cp, CP_CLASS(cp->c_cpentry->cp_pclass), flags, &newentry);
985		if (error == 0) {
986			cp_replace_entry (cp, newentry);
987			entry = newentry;
988		}
989		else {
990			goto out;
991		}
992	}
993
994	/*
995	 * We want to minimize the number of unwraps that we'll have to do since
996	 * the cost can vary, depending on the platform we're running.
997	 */
998	switch (CP_CLASS(entry->cp_pclass)) {
999		case PROTECTION_CLASS_B:
1000			if (mode & O_CREAT) {
1001				/*
1002				 * Class B always allows creation.  Since O_CREAT was passed through
1003				 * we infer that this was a newly created vnode/cnode.  Even though a potential
1004				 * race exists when multiple threads attempt to create/open a particular
1005				 * file, only one can "win" and actually create it.  VFS will unset the
1006				 * O_CREAT bit on the loser.
1007				 *
1008				 * Note that skipping the unwrap check here is not a security issue --
1009				 * we have to unwrap the key permanently upon the first I/O.
1010				 */
1011				break;
1012			}
1013
1014			if ((entry->cp_flags & CP_KEY_FLUSHED) == 0) {
1015				/*
1016				 * For a class B file, attempt the unwrap if we have the key in
1017				 * core already.
1018				 * The device could have just transitioned into the lock state, and
1019				 * this vnode may not yet have been purged from the vnode cache (which would
1020				 * remove the keys).
1021				 */
1022				cp_cred_s access_in;
1023				cp_wrapped_key_s wrapped_key_in;
1024
1025				cp_init_access(&access_in, cp);
1026				bzero(&wrapped_key_in, sizeof(wrapped_key_in));
1027				wrapped_key_in.key = entry->cp_persistent_key;
1028				wrapped_key_in.key_len = entry->cp_persistent_key_len;
1029				/* Use the persistent class when talking to AKS */
1030				wrapped_key_in.dp_class = entry->cp_pclass;
1031				error = g_cp_wrap_func.unwrapper(&access_in, &wrapped_key_in, NULL);
1032				if (error) {
1033					error = EPERM;
1034				}
1035				break;
1036			}
1037			/* otherwise, fall through to attempt the unwrap/restore */
1038		case PROTECTION_CLASS_A:
1039		case PROTECTION_CLASS_C:
1040			/*
1041			 * At this point, we know that we need to attempt an unwrap if needed; we want
1042			 * to makes sure that open(2) fails properly if the device is either just-locked
1043			 * or never made it past first unlock.  Since the keybag serializes access to the
1044			 * unwrapping keys for us and only calls our VFS callback once they've been purged,
1045			 * we will get here in two cases:
1046			 *
1047			 * A) we're in a window before the wrapping keys are purged; this is OK since when they get
1048			 * purged, the vnode will get flushed if needed.
1049			 *
1050			 * B) The keys are already gone.  In this case, the restore_keys call below will fail.
1051			 *
1052			 * Since this function is bypassed entirely if we're opening a raw encrypted file,
1053			 * we can always attempt the restore.
1054			 */
1055			if (entry->cp_flags & CP_KEY_FLUSHED) {
1056				error = cp_restore_keys(entry, hfsmp, cp);
1057			}
1058
1059			if (error) {
1060				error = EPERM;
1061			}
1062
1063			break;
1064
1065		case PROTECTION_CLASS_D:
1066		default:
1067			break;
1068	}
1069
1070out:
1071	hfs_unlock(cp);
1072	return error;
1073}
1074
1075
1076/*
1077 * During hfs resize operations, we have slightly different constraints than during
1078 * normal VNOPS that read/write data to files.  Specifically, we already have the cnode
1079 * locked (so nobody else can modify it), and we are doing the IO with root privileges, since
1080 * we are moving the data behind the user's back.  So, we skip access checks here (for unlock
1081 * vs. lock), and don't worry about non-existing keys.  If the file exists on-disk with valid
1082 * payload, then it must have keys set up already by definition.
1083 */
1084int
1085cp_handle_relocate (struct cnode *cp, struct hfsmount *hfsmp)
1086{
1087	struct cprotect *entry;
1088	int error = -1;
1089
1090	/* cp is already locked */
1091	entry = cp->c_cpentry;
1092	if (!entry)
1093		goto out;
1094
1095	/*
1096	 * Still need to validate whether to permit access to the file or not
1097	 * based on lock status
1098	 */
1099	if ((error = cp_check_access(cp, hfsmp,  CP_READ_ACCESS | CP_WRITE_ACCESS))) {
1100		goto out;
1101	}
1102
1103	if (entry->cp_flags == 0) {
1104		/* no more work to do */
1105		error = 0;
1106		goto out;
1107	}
1108
1109	/* it must have keys since it is an existing file with actual payload */
1110
1111	/* unwrap keys if needed */
1112	if (entry->cp_flags & CP_KEY_FLUSHED) {
1113		error = cp_restore_keys(entry, hfsmp, cp);
1114	}
1115
1116	/*
1117	 * Don't need to write out the EA since if the file has actual extents,
1118	 * it must have an EA
1119	 */
1120out:
1121
1122	/* return the cp still locked */
1123	return error;
1124}
1125
1126/*
1127 * cp_getrootxattr:
1128 * Gets the EA we set on the root folder (fileid 1) to get information about the
1129 * version of Content Protection that was used to write to this filesystem.
1130 * Note that all multi-byte fields are written to disk little endian so they must be
1131 * converted to native endian-ness as needed.
1132 */
1133int
1134cp_getrootxattr(struct hfsmount* hfsmp, struct cp_root_xattr *outxattr)
1135{
1136	uio_t   auio;
1137	char    uio_buf[UIO_SIZEOF(1)];
1138	size_t attrsize = sizeof(struct cp_root_xattr);
1139	int error = 0;
1140	struct vnop_getxattr_args args;
1141
1142	if (!outxattr) {
1143		panic("Content Protection: cp_xattr called with xattr == NULL");
1144	}
1145
1146	auio = uio_createwithbuffer(1, 0, UIO_SYSSPACE, UIO_READ, &uio_buf[0], sizeof(uio_buf));
1147	uio_addiov(auio, CAST_USER_ADDR_T(outxattr), attrsize);
1148
1149	args.a_desc = NULL; // unused
1150	args.a_vp = NULL; //unused since we're writing EA to root folder.
1151	args.a_name = CONTENT_PROTECTION_XATTR_NAME;
1152	args.a_uio = auio;
1153	args.a_size = &attrsize;
1154	args.a_options = XATTR_REPLACE;
1155	args.a_context = NULL; // unused
1156
1157	error = hfs_getxattr_internal(NULL, &args, hfsmp, 1);
1158
1159	/* Now convert the multi-byte fields to native endianness */
1160	outxattr->major_version = OSSwapLittleToHostInt16(outxattr->major_version);
1161	outxattr->minor_version = OSSwapLittleToHostInt16(outxattr->minor_version);
1162	outxattr->flags = OSSwapLittleToHostInt64(outxattr->flags);
1163
1164	if (error != 0) {
1165		goto out;
1166	}
1167
1168out:
1169	uio_free(auio);
1170	return error;
1171}
1172
1173/*
1174 * cp_setrootxattr:
1175 * Sets the EA we set on the root folder (fileid 1) to get information about the
1176 * version of Content Protection that was used to write to this filesystem.
1177 * Note that all multi-byte fields are written to disk little endian so they must be
1178 * converted to little endian as needed.
1179 *
1180 * This will be written to the disk when it detects the EA is not there, or when we need
1181 * to make a modification to the on-disk version that can be done in-place.
1182 */
1183int
1184cp_setrootxattr(struct hfsmount *hfsmp, struct cp_root_xattr *newxattr)
1185{
1186	int error = 0;
1187	struct vnop_setxattr_args args;
1188
1189	args.a_desc = NULL;
1190	args.a_vp = NULL;
1191	args.a_name = CONTENT_PROTECTION_XATTR_NAME;
1192	args.a_uio = NULL; //pass data ptr instead
1193	args.a_options = 0;
1194	args.a_context = NULL; //no context needed, only done from mount.
1195
1196	/* Now convert the multi-byte fields to little endian before writing to disk. */
1197	newxattr->major_version = OSSwapHostToLittleInt16(newxattr->major_version);
1198	newxattr->minor_version = OSSwapHostToLittleInt16(newxattr->minor_version);
1199	newxattr->flags = OSSwapHostToLittleInt64(newxattr->flags);
1200
1201	error = hfs_setxattr_internal(NULL, (caddr_t)newxattr,
1202			sizeof(struct cp_root_xattr), &args, hfsmp, 1);
1203	return error;
1204}
1205
1206
1207/*
1208 * Stores new xattr data on the cnode.
1209 * cnode lock held exclusive (if available).
1210 *
1211 * This function is also invoked during file creation.
1212 */
1213int cp_setxattr(struct cnode *cp, struct cprotect *entry, struct hfsmount *hfsmp, uint32_t fileid, int options)
1214{
1215	int error = 0;
1216	size_t attrsize;
1217	struct vnop_setxattr_args args;
1218	uint32_t target_fileid;
1219	struct cnode *arg_cp = NULL;
1220	uint32_t tempflags = 0;
1221
1222	args.a_desc = NULL;
1223
1224	if (hfsmp->hfs_flags & HFS_READ_ONLY) {
1225		return EROFS;
1226	}
1227
1228	if (cp) {
1229		args.a_vp = cp->c_vp;
1230		target_fileid = 0;
1231		arg_cp = cp;
1232	}
1233	else {
1234		/*
1235		 * When we set the EA in the same txn as the file creation,
1236		 * we do not have a vnode/cnode yet. Use the specified fileid.
1237		 */
1238		args.a_vp = NULL;
1239		target_fileid = fileid;
1240	}
1241	args.a_name = CONTENT_PROTECTION_XATTR_NAME;
1242	args.a_uio = NULL; //pass data ptr instead
1243	args.a_options = options;
1244	args.a_context = vfs_context_current();
1245
1246	/* Note that it's OK to write out an XATTR without keys. */
1247	/* Disable flags that will be invalid as we're writing the EA out at this point. */
1248	tempflags = entry->cp_flags;
1249
1250	/* we're writing the EA; CP_NO_XATTR is invalid */
1251	tempflags &= ~CP_NO_XATTR;
1252
1253	/* CP_SEP_WRAPPEDKEY is informational/runtime only. */
1254	tempflags &= ~CP_SEP_WRAPPEDKEY;
1255
1256	switch(hfsmp->hfs_running_cp_major_vers) {
1257		case CP_NEW_MAJOR_VERS: {
1258			struct cp_xattr_v4 *newxattr = NULL; // 70+ bytes; don't alloc on stack.
1259			MALLOC (newxattr, struct cp_xattr_v4*, sizeof(struct cp_xattr_v4), M_TEMP, M_WAITOK);
1260			if (newxattr == NULL) {
1261				error = ENOMEM;
1262				break;
1263			}
1264			bzero (newxattr, sizeof(struct cp_xattr_v4));
1265
1266			attrsize = sizeof(*newxattr) - CP_MAX_WRAPPEDKEYSIZE + entry->cp_persistent_key_len;
1267
1268			/* Endian swap the multi-byte fields into L.E from host. */
1269			newxattr->xattr_major_version = OSSwapHostToLittleInt16 (hfsmp->hfs_running_cp_major_vers);
1270			newxattr->xattr_minor_version = OSSwapHostToLittleInt16(CP_MINOR_VERS);
1271			newxattr->key_size = OSSwapHostToLittleInt32(entry->cp_persistent_key_len);
1272			newxattr->flags = OSSwapHostToLittleInt32(tempflags);
1273			newxattr->persistent_class = OSSwapHostToLittleInt32(entry->cp_pclass);
1274			bcopy(entry->cp_persistent_key, newxattr->persistent_key, entry->cp_persistent_key_len);
1275
1276			error = hfs_setxattr_internal(arg_cp, (caddr_t)newxattr, attrsize, &args, hfsmp, target_fileid);
1277
1278			FREE(newxattr, M_TEMP);
1279			break;
1280		}
1281		case CP_PREV_MAJOR_VERS: {
1282			struct cp_xattr_v2 *newxattr = NULL;
1283			MALLOC (newxattr, struct cp_xattr_v2*, sizeof(struct cp_xattr_v2), M_TEMP, M_WAITOK);
1284			if (newxattr == NULL) {
1285				error = ENOMEM;
1286				break;
1287			}
1288			bzero (newxattr, sizeof(struct cp_xattr_v2));
1289
1290			attrsize = sizeof(*newxattr);
1291
1292			/* Endian swap the multi-byte fields into L.E from host. */
1293			newxattr->xattr_major_version = OSSwapHostToLittleInt16(hfsmp->hfs_running_cp_major_vers);
1294			newxattr->xattr_minor_version = OSSwapHostToLittleInt16(CP_MINOR_VERS);
1295			newxattr->key_size = OSSwapHostToLittleInt32(entry->cp_persistent_key_len);
1296			newxattr->flags = OSSwapHostToLittleInt32(tempflags);
1297			newxattr->persistent_class = OSSwapHostToLittleInt32(entry->cp_pclass);
1298			bcopy(entry->cp_persistent_key, newxattr->persistent_key, entry->cp_persistent_key_len);
1299
1300			error = hfs_setxattr_internal(arg_cp, (caddr_t)newxattr, attrsize, &args, hfsmp, target_fileid);
1301
1302			FREE (newxattr, M_TEMP);
1303			break;
1304		}
1305		default:
1306			printf("hfs: cp_setxattr: Unknown CP version running \n");
1307			break;
1308	}
1309
1310	if (error == 0 ) {
1311		entry->cp_flags &= ~CP_NO_XATTR;
1312	}
1313
1314	return error;
1315
1316
1317}
1318
1319/*
1320 * Used by an fcntl to query the underlying FS for its content protection version #
1321 */
1322
1323int
1324cp_get_root_major_vers(vnode_t vp, uint32_t *level)
1325{
1326	int err = 0;
1327	struct hfsmount *hfsmp = NULL;
1328	struct mount *mp = NULL;
1329
1330	mp = VTOVFS(vp);
1331
1332	/* check if it supports content protection */
1333	if (cp_fs_protected(mp) == 0) {
1334		return ENOTSUP;
1335	}
1336
1337	hfsmp = VFSTOHFS(mp);
1338	/* figure out the level */
1339
1340	err = cp_root_major_vers(mp);
1341
1342	if (err == 0) {
1343		*level = hfsmp->hfs_running_cp_major_vers;
1344	}
1345	/* in error case, cp_root_major_vers will just return EINVAL. Use that */
1346
1347	return err;
1348}
1349
1350/* Used by fcntl to query default protection level of FS */
1351int cp_get_default_level (struct vnode *vp, uint32_t *level) {
1352	int err = 0;
1353	struct hfsmount *hfsmp = NULL;
1354	struct mount *mp = NULL;
1355
1356	mp = VTOVFS(vp);
1357
1358	/* check if it supports content protection */
1359	if (cp_fs_protected(mp) == 0) {
1360		return ENOTSUP;
1361	}
1362
1363	hfsmp = VFSTOHFS(mp);
1364	/* figure out the default */
1365
1366	*level = hfsmp->default_cp_class;
1367	return err;
1368}
1369
1370/********************
1371 * Private Functions
1372 *******************/
1373
1374static int
1375cp_root_major_vers(mount_t mp)
1376{
1377	int err = 0;
1378	struct cp_root_xattr xattr;
1379	struct hfsmount *hfsmp = NULL;
1380
1381	hfsmp = vfs_fsprivate(mp);
1382	err = cp_getrootxattr (hfsmp, &xattr);
1383
1384	if (err == 0) {
1385		hfsmp->hfs_running_cp_major_vers = xattr.major_version;
1386	}
1387	else {
1388		return EINVAL;
1389	}
1390
1391	return 0;
1392}
1393
1394static int
1395cp_vnode_is_eligible(struct vnode *vp)
1396{
1397	return ((vp->v_op == hfs_vnodeop_p) &&
1398			(!vnode_issystem(vp)) &&
1399			(vnode_isreg(vp) || vnode_isdir(vp)));
1400}
1401
1402
1403
1404int
1405cp_is_valid_class(int isdir, int32_t protectionclass)
1406{
1407	/*
1408	 * The valid protection classes are from 0 -> N
1409	 * We use a signed argument to detect unassigned values from
1410	 * directory entry creation time in HFS.
1411	 */
1412	if (isdir) {
1413		/* Directories are not allowed to have F, but they can have "NONE" */
1414		return ((protectionclass >= PROTECTION_CLASS_DIR_NONE) &&
1415				(protectionclass <= PROTECTION_CLASS_D));
1416	}
1417	else {
1418		return ((protectionclass >= PROTECTION_CLASS_A) &&
1419				(protectionclass <= PROTECTION_CLASS_F));
1420	}
1421}
1422
1423
1424static struct cprotect *
1425cp_entry_alloc(size_t keylen)
1426{
1427	struct cprotect *cp_entry;
1428
1429	if (keylen > CP_MAX_WRAPPEDKEYSIZE)
1430		return (NULL);
1431
1432	MALLOC(cp_entry, struct cprotect *, sizeof(struct cprotect) + keylen,
1433		   M_TEMP, M_WAITOK);
1434	if (cp_entry == NULL)
1435		return (NULL);
1436
1437	bzero(cp_entry, sizeof(*cp_entry) + keylen);
1438	cp_entry->cp_persistent_key_len = keylen;
1439	return (cp_entry);
1440}
1441
1442static void
1443cp_entry_dealloc(struct cprotect *entry)
1444{
1445	uint32_t keylen = entry->cp_persistent_key_len;
1446	bzero(entry, (sizeof(*entry) + keylen));
1447	FREE(entry, M_TEMP);
1448}
1449
1450
1451/*
1452 * Initializes a new cprotect entry with xattr data from the cnode.
1453 * cnode lock held shared
1454 */
1455static int
1456cp_getxattr(struct cnode *cp, struct hfsmount *hfsmp, struct cprotect **outentry)
1457{
1458	int error = 0;
1459	uio_t auio;
1460	size_t attrsize;
1461	char uio_buf[UIO_SIZEOF(1)];
1462	struct vnop_getxattr_args args;
1463	struct cprotect *entry = NULL;
1464
1465	auio = uio_createwithbuffer(1, 0, UIO_SYSSPACE, UIO_READ, &uio_buf[0], sizeof(uio_buf));
1466	args.a_desc = NULL; // unused
1467	args.a_vp = cp->c_vp;
1468	args.a_name = CONTENT_PROTECTION_XATTR_NAME;
1469	args.a_uio = auio;
1470	args.a_options = XATTR_REPLACE;
1471	args.a_context = vfs_context_current(); // unused
1472
1473	switch (hfsmp->hfs_running_cp_major_vers) {
1474		case CP_NEW_MAJOR_VERS: {
1475			struct cp_xattr_v4 *xattr = NULL;
1476			MALLOC (xattr, struct cp_xattr_v4*, sizeof(struct cp_xattr_v4), M_TEMP, M_WAITOK);
1477			if (xattr == NULL) {
1478				error = ENOMEM;
1479				break;
1480			}
1481			bzero(xattr, sizeof (struct cp_xattr_v4));
1482			attrsize = sizeof(*xattr);
1483
1484			uio_addiov(auio, CAST_USER_ADDR_T(xattr), attrsize);
1485			args.a_size = &attrsize;
1486
1487			error = hfs_getxattr_internal(cp, &args, VTOHFS(cp->c_vp), 0);
1488			if (error != 0) {
1489				FREE (xattr, M_TEMP);
1490				goto out;
1491			}
1492
1493			/* Endian swap the multi-byte fields into host endianness from L.E. */
1494			xattr->xattr_major_version = OSSwapLittleToHostInt16(xattr->xattr_major_version);
1495			xattr->xattr_minor_version = OSSwapLittleToHostInt16(xattr->xattr_minor_version);
1496			xattr->key_size = OSSwapLittleToHostInt32(xattr->key_size);
1497			xattr->flags = OSSwapLittleToHostInt32(xattr->flags);
1498			xattr->persistent_class = OSSwapLittleToHostInt32(xattr->persistent_class);
1499
1500			if (xattr->xattr_major_version != hfsmp->hfs_running_cp_major_vers ) {
1501				printf("hfs: cp_getxattr: bad xattr version %d expecting %d\n",
1502					xattr->xattr_major_version, hfsmp->hfs_running_cp_major_vers);
1503				error = EINVAL;
1504				FREE (xattr, M_TEMP);
1505
1506				goto out;
1507			}
1508			/*
1509			 * Prevent a buffer overflow, and validate the key length obtained from the
1510			 * EA. If it's too big, then bail out, because the EA can't be trusted at this
1511			 * point.
1512			 */
1513			if (xattr->key_size > CP_MAX_WRAPPEDKEYSIZE) {
1514				error = EINVAL;
1515				FREE (xattr, M_TEMP);
1516
1517				goto out;
1518			}
1519
1520			/*
1521			 * Class F files have no backing key; their keylength should be 0,
1522			 * though they should have the proper flags set.
1523			 *
1524			 * A request to instantiate a CP for a class F file should result
1525			 * in a bzero'd cp that just says class F, with key_flushed set.
1526			 */
1527
1528			/* set up entry with information from xattr */
1529			entry = cp_entry_alloc(xattr->key_size);
1530			if (!entry) {
1531				FREE (xattr, M_TEMP);
1532
1533				return ENOMEM;
1534			}
1535
1536			entry->cp_pclass = xattr->persistent_class;
1537
1538			/*
1539			 * Suppress invalid flags that should not be set.
1540			 * If we have gotten this far, then CP_NO_XATTR cannot possibly
1541			 * be valid; the EA exists.
1542			 */
1543			xattr->flags &= ~CP_NO_XATTR;
1544
1545			entry->cp_flags = xattr->flags;
1546			if (xattr->xattr_major_version >= CP_NEW_MAJOR_VERS) {
1547				entry->cp_flags |= CP_OFF_IV_ENABLED;
1548			}
1549
1550			if (CP_CLASS(entry->cp_pclass) != PROTECTION_CLASS_F ) {
1551				bcopy(xattr->persistent_key, entry->cp_persistent_key, xattr->key_size);
1552			}
1553
1554			FREE (xattr, M_TEMP);
1555
1556			break;
1557		}
1558		case CP_PREV_MAJOR_VERS: {
1559			struct cp_xattr_v2 *xattr = NULL;
1560			MALLOC (xattr, struct cp_xattr_v2*, sizeof(struct cp_xattr_v2), M_TEMP, M_WAITOK);
1561			if (xattr == NULL) {
1562				error = ENOMEM;
1563				break;
1564			}
1565			bzero (xattr, sizeof (struct cp_xattr_v2));
1566			attrsize = sizeof(*xattr);
1567
1568			uio_addiov(auio, CAST_USER_ADDR_T(xattr), attrsize);
1569			args.a_size = &attrsize;
1570
1571			error = hfs_getxattr_internal(cp, &args, VTOHFS(cp->c_vp), 0);
1572			if (error != 0) {
1573				FREE (xattr, M_TEMP);
1574				goto out;
1575			}
1576
1577			/* Endian swap the multi-byte fields into host endianness from L.E. */
1578			xattr->xattr_major_version = OSSwapLittleToHostInt16(xattr->xattr_major_version);
1579			xattr->xattr_minor_version = OSSwapLittleToHostInt16(xattr->xattr_minor_version);
1580			xattr->key_size = OSSwapLittleToHostInt32(xattr->key_size);
1581			xattr->flags = OSSwapLittleToHostInt32(xattr->flags);
1582			xattr->persistent_class = OSSwapLittleToHostInt32(xattr->persistent_class);
1583
1584			if (xattr->xattr_major_version != hfsmp->hfs_running_cp_major_vers) {
1585				printf("hfs: cp_getxattr: bad xattr version %d expecting %d\n",
1586					xattr->xattr_major_version, hfsmp->hfs_running_cp_major_vers);
1587				error = EINVAL;
1588				FREE (xattr, M_TEMP);
1589				goto out;
1590			}
1591
1592			/*
1593			 * Prevent a buffer overflow, and validate the key length obtained from the
1594			 * EA. If it's too big, then bail out, because the EA can't be trusted at this
1595			 * point.
1596			 */
1597			if (xattr->key_size > CP_V2_WRAPPEDKEYSIZE) {
1598				error = EINVAL;
1599				FREE (xattr, M_TEMP);
1600				goto out;
1601			}
1602			/* set up entry with information from xattr */
1603			entry = cp_entry_alloc(xattr->key_size);
1604			if (!entry) {
1605				FREE (xattr, M_TEMP);
1606				return ENOMEM;
1607			}
1608
1609			entry->cp_pclass = xattr->persistent_class;
1610
1611			/*
1612			 * Suppress invalid flags that should not be set.
1613			 * If we have gotten this far, then CP_NO_XATTR cannot possibly
1614			 * be valid; the EA exists.
1615			 */
1616			xattr->flags &= ~CP_NO_XATTR;
1617
1618			entry->cp_flags = xattr->flags;
1619
1620			if (CP_CLASS(entry->cp_pclass) != PROTECTION_CLASS_F ) {
1621				bcopy(xattr->persistent_key, entry->cp_persistent_key, xattr->key_size);
1622			}
1623
1624			FREE (xattr, M_TEMP);
1625			break;
1626		}
1627	}
1628
1629out:
1630	uio_free(auio);
1631
1632	*outentry = entry;
1633	return error;
1634}
1635
1636/*
1637 * If permitted, restore entry's unwrapped key from the persistent key.
1638 * If not, clear key and set CP_KEY_FLUSHED.
1639 * cnode lock held exclusive
1640 */
1641static int
1642cp_restore_keys(struct cprotect *entry, struct hfsmount *hfsmp, struct cnode *cp)
1643{
1644	int error = 0;
1645
1646 	error = cp_unwrap(hfsmp, entry, cp);
1647	if (error) {
1648		entry->cp_flags |= CP_KEY_FLUSHED;
1649		bzero(entry->cp_cache_key, entry->cp_cache_key_len);
1650		error = EPERM;
1651	}
1652	else {
1653		/* ready for business */
1654		entry->cp_flags &= ~CP_KEY_FLUSHED;
1655
1656	}
1657	return error;
1658}
1659
1660static int
1661cp_lock_vfs_callback(mount_t mp, void *arg)
1662{
1663
1664	/* Use a pointer-width integer field for casting */
1665	unsigned long new_state;
1666	struct hfsmount *hfsmp;
1667
1668	/*
1669	 * When iterating the various mount points that may
1670	 * be present on a content-protected device, we need to skip
1671	 * those that do not have it enabled.
1672	 */
1673	if (!cp_fs_protected(mp)) {
1674		return 0;
1675	}
1676	new_state = (unsigned long) arg;
1677
1678	hfsmp = VFSTOHFS(mp);
1679
1680	hfs_lock_mount(hfsmp);
1681	/* this loses all of the upper bytes of precision; that's OK */
1682	hfsmp->hfs_cp_lock_state = (uint8_t) new_state;
1683	hfs_unlock_mount(hfsmp);
1684
1685	if (new_state == CP_LOCKED_STATE) {
1686		/*
1687		 * We respond only to lock events.  Since cprotect structs
1688		 * decrypt/restore keys lazily, the unlock events don't
1689		 * actually cause anything to happen.
1690		 */
1691		return vnode_iterate(mp, 0, cp_lock_vnode_callback, arg);
1692	}
1693	/* Otherwise just return 0. */
1694	return 0;
1695
1696}
1697
1698
1699/*
1700 * Deny access to protected files if keys have been locked.
1701 */
1702static int
1703cp_check_access(struct cnode *cp, struct hfsmount *hfsmp, int vnop __unused)
1704{
1705	int error = 0;
1706
1707	/*
1708	 * For now it's OK to examine the state variable here without
1709	 * holding the HFS lock.  This is only a short-circuit; if the state
1710	 * transitions (or is in transition) after we examine this field, we'd
1711	 * have to handle that anyway.
1712	 */
1713	if (hfsmp->hfs_cp_lock_state == CP_UNLOCKED_STATE) {
1714		return 0;
1715	}
1716
1717	if (!cp->c_cpentry) {
1718		/* unprotected node */
1719		return 0;
1720	}
1721
1722	if (!S_ISREG(cp->c_mode)) {
1723		return 0;
1724	}
1725
1726	/* Deny all access for class A files */
1727	switch (CP_CLASS(cp->c_cpentry->cp_pclass)) {
1728		case PROTECTION_CLASS_A: {
1729			error = EPERM;
1730			break;
1731		}
1732		default:
1733			error = 0;
1734			break;
1735	}
1736
1737	return error;
1738}
1739
1740/*
1741 * Respond to a lock or unlock event.
1742 * On lock: clear out keys from memory, then flush file contents.
1743 * On unlock: nothing (function not called).
1744 */
1745static int
1746cp_lock_vnode_callback(struct vnode *vp, void *arg)
1747{
1748	cnode_t *cp = NULL;
1749	struct cprotect *entry = NULL;
1750	int error = 0;
1751	int locked = 1;
1752	unsigned long action = 0;
1753	int took_truncate_lock = 0;
1754
1755	error = vnode_getwithref (vp);
1756	if (error) {
1757		return error;
1758	}
1759
1760	cp = VTOC(vp);
1761
1762	/*
1763	 * When cleaning cnodes due to a lock event, we must
1764	 * take the truncate lock AND the cnode lock.  By taking
1765	 * the truncate lock here, we force (nearly) all pending IOs
1766	 * to drain before we can acquire the truncate lock.  All HFS cluster
1767	 * io calls except for swapfile IO need to acquire the truncate lock
1768	 * prior to calling into the cluster layer.
1769	 */
1770	hfs_lock_truncate (cp, HFS_EXCLUSIVE_LOCK, HFS_LOCK_DEFAULT);
1771	took_truncate_lock = 1;
1772
1773	hfs_lock(cp, HFS_EXCLUSIVE_LOCK, HFS_LOCK_ALLOW_NOEXISTS);
1774
1775	entry = cp->c_cpentry;
1776	if (!entry) {
1777		/* unprotected vnode: not a regular file */
1778		goto out;
1779	}
1780
1781	action = (unsigned long) arg;
1782	switch (action) {
1783		case CP_LOCKED_STATE: {
1784			vfs_context_t ctx;
1785			if (CP_CLASS(entry->cp_pclass) != PROTECTION_CLASS_A ||
1786				vnode_isdir(vp)) {
1787				/*
1788				 * There is no change at lock for other classes than A.
1789				 * B is kept in memory for writing, and class F (for VM) does
1790				 * not have a wrapped key, so there is no work needed for
1791				 * wrapping/unwrapping.
1792				 *
1793				 * Note that 'class F' is relevant here because if
1794				 * hfs_vnop_strategy does not take the cnode lock
1795				 * to protect the cp blob across IO operations, we rely
1796				 * implicitly on the truncate lock to be held when doing IO.
1797				 * The only case where the truncate lock is not held is during
1798				 * swapfile IO because HFS just funnels the VNOP_PAGEOUT
1799				 * directly to cluster_pageout.
1800				 */
1801				goto out;
1802			}
1803
1804			/* Before doing anything else, zero-fill sparse ranges as needed */
1805			ctx = vfs_context_current();
1806			(void) hfs_filedone (vp, ctx, 0);
1807
1808			/* first, sync back dirty pages */
1809			hfs_unlock (cp);
1810			ubc_msync (vp, 0, ubc_getsize(vp), NULL, UBC_PUSHALL | UBC_INVALIDATE | UBC_SYNC);
1811			hfs_lock (cp, HFS_EXCLUSIVE_LOCK, HFS_LOCK_ALLOW_NOEXISTS);
1812
1813			/* flush keys:
1814			 * There was a concern here(9206856) about flushing keys before nand layer is done using them.
1815			 * But since we are using ubc_msync with UBC_SYNC, it blocks until all IO is completed.
1816			 * Once IOFS caches or is done with these keys, it calls the completion routine in IOSF.
1817			 * Which in turn calls buf_biodone() and eventually unblocks ubc_msync()
1818			 * Also verified that the cached data in IOFS is overwritten by other data, and there
1819			 * is no key leakage in that layer.
1820			 */
1821
1822			entry->cp_flags |= CP_KEY_FLUSHED;
1823			bzero(&entry->cp_cache_key, entry->cp_cache_key_len);
1824			bzero(&entry->cp_cache_iv_ctx, sizeof(aes_encrypt_ctx));
1825
1826			/* some write may have arrived in the mean time. dump those pages */
1827			hfs_unlock(cp);
1828			locked = 0;
1829
1830			ubc_msync (vp, 0, ubc_getsize(vp), NULL, UBC_INVALIDATE | UBC_SYNC);
1831			break;
1832		}
1833		case CP_UNLOCKED_STATE: {
1834			/* no-op */
1835			break;
1836		}
1837		default:
1838			panic("Content Protection: unknown lock action %lu\n", action);
1839	}
1840
1841out:
1842	if (locked) {
1843		hfs_unlock(cp);
1844	}
1845
1846	if (took_truncate_lock) {
1847		hfs_unlock_truncate (cp, HFS_LOCK_DEFAULT);
1848	}
1849
1850	vnode_put (vp);
1851	return error;
1852}
1853
1854
1855/*
1856 * cp_rewrap:
1857 *
1858 * Generate a new wrapped key based on the existing cache key.
1859 */
1860
1861static int
1862cp_rewrap(struct cnode *cp, struct hfsmount *hfsmp, int newclass)
1863{
1864
1865	struct cprotect *entry = cp->c_cpentry;
1866	uint8_t new_persistent_key[CP_MAX_WRAPPEDKEYSIZE];
1867	size_t keylen = CP_MAX_WRAPPEDKEYSIZE;
1868	int error = 0;
1869	newclass = CP_CLASS(newclass);
1870
1871	/* Structures passed between HFS and AKS */
1872	cp_cred_s access_in;
1873	cp_wrapped_key_s wrapped_key_in;
1874	cp_wrapped_key_s wrapped_key_out;
1875
1876	/*
1877	 * PROTECTION_CLASS_F is in-use by VM swapfile; it represents a transient
1878	 * key that is only good as long as the file is open.  There is no
1879	 * wrapped key, so there isn't anything to wrap.
1880	 */
1881	if (newclass == PROTECTION_CLASS_F) {
1882		return EINVAL;
1883	}
1884
1885	cp_init_access(&access_in, cp);
1886
1887	bzero(&wrapped_key_in, sizeof(wrapped_key_in));
1888	wrapped_key_in.key = entry->cp_persistent_key;
1889	wrapped_key_in.key_len = entry->cp_persistent_key_len;
1890	/* Use the persistent class when talking to AKS */
1891	wrapped_key_in.dp_class = entry->cp_pclass;
1892
1893	bzero(&wrapped_key_out, sizeof(wrapped_key_out));
1894	wrapped_key_out.key = new_persistent_key;
1895	wrapped_key_out.key_len = keylen;
1896
1897	/*
1898	 * inode is passed here to find the backup bag wrapped blob
1899	 * from userspace.  This lookup will occur shortly after creation
1900	 * and only if the file still exists.  Beyond this lookup the
1901	 * inode is not used.  Technically there is a race, we practically
1902	 * don't lose.
1903	 */
1904	error = g_cp_wrap_func.rewrapper(&access_in,
1905			newclass, /* new class */
1906			&wrapped_key_in,
1907			&wrapped_key_out);
1908
1909	keylen = wrapped_key_out.key_len;
1910
1911	if (error == 0) {
1912		struct cprotect *newentry = NULL;
1913		/*
1914		 * Verify that AKS returned to us a wrapped key of the
1915		 * target class requested.
1916		 */
1917		/* Get the effective class here */
1918		int effective = CP_CLASS(wrapped_key_out.dp_class);
1919		if (effective != newclass) {
1920			/*
1921			 * Fail the operation if defaults or some other enforcement
1922			 * dictated that the class be wrapped differently.
1923			 */
1924
1925			/* TODO: Invalidate the key when 12170074 unblocked */
1926			return EPERM;
1927		}
1928
1929		/* v2 EA's don't support the larger class B keys */
1930		if ((keylen != CP_V2_WRAPPEDKEYSIZE) &&
1931				(hfsmp->hfs_running_cp_major_vers == CP_PREV_MAJOR_VERS)) {
1932			return EINVAL;
1933		}
1934
1935		/* Allocate a new cpentry */
1936		newentry = cp_entry_alloc (keylen);
1937		bcopy (entry, newentry, sizeof(struct cprotect));
1938
1939		/* copy the new key into the entry */
1940		bcopy (new_persistent_key, newentry->cp_persistent_key, keylen);
1941		newentry->cp_persistent_key_len = keylen;
1942		newentry->cp_backing_cnode = cp;
1943
1944		/* Actually record/store what AKS reported back, not the effective class stored in newclass */
1945		newentry->cp_pclass = wrapped_key_out.dp_class;
1946
1947		/* Attach the new entry to the cnode */
1948		cp->c_cpentry = newentry;
1949
1950		/* destroy the old entry */
1951		cp_entry_destroy (entry);
1952	}
1953	else {
1954		error = EPERM;
1955	}
1956
1957	return error;
1958}
1959
1960
1961static int
1962cp_unwrap(struct hfsmount *hfsmp, struct cprotect *entry, struct cnode *cp)
1963{
1964	int error = 0;
1965	uint8_t iv_key[CP_IV_KEYSIZE];
1966
1967	/* Structures passed between HFS and AKS */
1968	cp_cred_s access_in;
1969	cp_wrapped_key_s wrapped_key_in;
1970	cp_raw_key_s key_out;
1971
1972	/*
1973	 * PROTECTION_CLASS_F is in-use by VM swapfile; it represents a transient
1974	 * key that is only good as long as the file is open.  There is no
1975	 * wrapped key, so there isn't anything to unwrap.
1976	 */
1977	if (CP_CLASS(entry->cp_pclass) == PROTECTION_CLASS_F) {
1978		return EPERM;
1979	}
1980
1981	cp_init_access(&access_in, cp);
1982
1983	bzero(&wrapped_key_in, sizeof(wrapped_key_in));
1984	wrapped_key_in.key = entry->cp_persistent_key;
1985	wrapped_key_in.key_len = entry->cp_persistent_key_len;
1986	/* Use the persistent class when talking to AKS */
1987	wrapped_key_in.dp_class = entry->cp_pclass;
1988
1989	bzero(&key_out, sizeof(key_out));
1990	key_out.iv_key = iv_key;
1991	key_out.key = entry->cp_cache_key;
1992	/*
1993	 * The unwrapper should validate/set the key length for
1994	 * the IV key length and the cache key length, however we need
1995	 * to supply the correct buffer length so that AKS knows how
1996	 * many bytes it has to work with.
1997	 */
1998	key_out.iv_key_len = CP_IV_KEYSIZE;
1999	key_out.key_len = CP_MAX_CACHEBUFLEN;
2000
2001	error = g_cp_wrap_func.unwrapper(&access_in, &wrapped_key_in, &key_out);
2002	if (!error) {
2003		if (key_out.key_len == 0 || key_out.key_len > CP_MAX_CACHEBUFLEN) {
2004			panic ("cp_unwrap: invalid key length! (%ul)\n", key_out.key_len);
2005		}
2006
2007		if (key_out.iv_key_len == 0 || key_out.iv_key_len > CP_IV_KEYSIZE) {
2008			panic ("cp_unwrap: invalid iv key length! (%ul)\n", key_out.iv_key_len);
2009		}
2010
2011		entry->cp_cache_key_len = key_out.key_len;
2012
2013		/* No need to go here for older EAs */
2014		if (hfsmp->hfs_running_cp_major_vers == CP_NEW_MAJOR_VERS) {
2015			aes_encrypt_key128(iv_key, &entry->cp_cache_iv_ctx);
2016			entry->cp_flags |= CP_OFF_IV_ENABLED;
2017		}
2018
2019		/* Is the key a raw wrapped key? */
2020		if (key_out.flags & CP_RAW_KEY_WRAPPEDKEY) {
2021			/* OR in the right bit for the cprotect */
2022			entry->cp_flags |= CP_SEP_WRAPPEDKEY;
2023		}
2024
2025	} else {
2026		error = EPERM;
2027	}
2028
2029	return error;
2030}
2031
2032/* Setup AES context */
2033static int
2034cp_setup_aes_ctx(struct cprotect *entry)
2035{
2036    SHA1_CTX sha1ctxt;
2037    uint8_t cp_cache_iv_key[CP_IV_KEYSIZE]; /* Kiv */
2038
2039    /* First init the cp_cache_iv_key[] */
2040    SHA1Init(&sha1ctxt);
2041
2042	/*
2043	 * We can only use this when the keys are generated in the AP; As a result
2044	 * we only use the first 32 bytes of key length in the cache key
2045	 */
2046    SHA1Update(&sha1ctxt, &entry->cp_cache_key[0], CP_MAX_KEYSIZE);
2047    SHA1Final(&cp_cache_iv_key[0], &sha1ctxt);
2048
2049    aes_encrypt_key128(&cp_cache_iv_key[0], &entry->cp_cache_iv_ctx);
2050
2051    return 0;
2052}
2053
2054/*
2055 * cp_generate_keys
2056 *
2057 * Take a cnode that has already been initialized and establish persistent and
2058 * cache keys for it at this time. Note that at the time this is called, the
2059 * directory entry has already been created and we are holding the cnode lock
2060 * on 'cp'.
2061 *
2062 */
2063int cp_generate_keys (struct hfsmount *hfsmp, struct cnode *cp, int targetclass,
2064		uint32_t keyflags, struct cprotect **newentry)
2065{
2066
2067	int error = 0;
2068	struct cprotect *newcp = NULL;
2069	*newentry = NULL;
2070
2071	/* Target class must be an effective class only */
2072	targetclass = CP_CLASS(targetclass);
2073
2074	/* Validate that it has a cprotect already */
2075	if (cp->c_cpentry == NULL) {
2076		/* We can't do anything if it shouldn't be protected. */
2077		return 0;
2078	}
2079
2080	/* Asserts for the underlying cprotect */
2081	if (cp->c_cpentry->cp_flags & CP_NO_XATTR) {
2082		/* should already have an xattr by this point. */
2083		error = EINVAL;
2084		goto out;
2085	}
2086
2087	if (S_ISREG(cp->c_mode)) {
2088		if ((cp->c_cpentry->cp_flags & CP_NEEDS_KEYS) == 0){
2089			error = EINVAL;
2090			goto out;
2091		}
2092	}
2093
2094	error = cp_new (targetclass, hfsmp, cp, cp->c_mode, keyflags, &newcp);
2095	if (error) {
2096		/*
2097		 * Key generation failed. This is not necessarily fatal
2098		 * since the device could have transitioned into the lock
2099		 * state before we called this.
2100		 */
2101		error = EPERM;
2102		goto out;
2103	}
2104
2105	/*
2106	 * If we got here, then we have a new cprotect.
2107	 * Attempt to write the new one out.
2108	 */
2109	error = cp_setxattr (cp, newcp, hfsmp, cp->c_fileid, XATTR_REPLACE);
2110
2111	if (error) {
2112		/* Tear down the new cprotect; Tell MKB that it's invalid. Bail out */
2113		/* TODO: rdar://12170074 needs to be fixed before we can tell MKB */
2114		if (newcp) {
2115			cp_entry_destroy(newcp);
2116		}
2117		goto out;
2118	}
2119
2120	/*
2121	 * If we get here then we can assert that:
2122	 * 1) generated wrapped/unwrapped keys.
2123	 * 2) wrote the new keys to disk.
2124	 * 3) cprotect is ready to go.
2125	 */
2126
2127	newcp->cp_flags &= ~CP_NEEDS_KEYS;
2128	*newentry = newcp;
2129
2130out:
2131	return error;
2132
2133}
2134
2135void cp_replace_entry (struct cnode *cp, struct cprotect *newentry)
2136{
2137
2138	if (cp->c_cpentry) {
2139		cp_entry_destroy (cp->c_cpentry);
2140	}
2141	cp->c_cpentry = newentry;
2142	newentry->cp_backing_cnode = cp;
2143
2144	return;
2145}
2146
2147
2148/*
2149 * cp_new
2150 *
2151 * Given a double-pointer to a cprotect, generate keys (either in-kernel or from keystore),
2152 * allocate a cprotect, and vend it back to the caller.
2153 *
2154 * Additionally, decide if keys are even needed -- directories get cprotect data structures
2155 * but they do not have keys.
2156 *
2157 */
2158
2159static int
2160cp_new(int newclass_eff, struct hfsmount *hfsmp, struct cnode *cp, mode_t cmode,
2161		uint32_t keyflags, struct cprotect **output_entry)
2162{
2163	struct cprotect *entry = NULL;
2164	int error = 0;
2165	uint8_t new_key[CP_MAX_CACHEBUFLEN];
2166	size_t new_key_len = CP_MAX_CACHEBUFLEN;  /* AKS tell us the proper key length, how much of this is used */
2167	uint8_t new_persistent_key[CP_MAX_WRAPPEDKEYSIZE];
2168	size_t new_persistent_len = CP_MAX_WRAPPEDKEYSIZE;
2169	uint8_t iv_key[CP_IV_KEYSIZE];
2170	size_t iv_key_len = CP_IV_KEYSIZE;
2171	int iswrapped = 0;
2172
2173	newclass_eff = CP_CLASS(newclass_eff);
2174
2175	/* Structures passed between HFS and AKS */
2176	cp_cred_s access_in;
2177	cp_wrapped_key_s wrapped_key_out;
2178	cp_raw_key_s key_out;
2179
2180	if (*output_entry != NULL) {
2181		panic ("cp_new with non-null entry!");
2182	}
2183
2184	if (are_wraps_initialized == false) {
2185		printf("hfs: cp_new: wrap/gen functions not yet set\n");
2186		return ENXIO;
2187	}
2188
2189	/* Sanity check that it's a file or directory here */
2190	if (!(S_ISREG(cmode)) && !(S_ISDIR(cmode))) {
2191		return EPERM;
2192	}
2193
2194	/*
2195	 * Step 1: Generate Keys if needed.
2196	 *
2197	 * For class F files, the kernel provides the key.
2198	 * PROTECTION_CLASS_F is in-use by VM swapfile; it represents a transient
2199	 * key that is only good as long as the file is open.  There is no
2200	 * wrapped key, so there isn't anything to wrap.
2201	 *
2202	 * For class A->D files, the key store provides the key
2203	 *
2204	 * For Directories, we only give them a class ; no keys.
2205	 */
2206	if (S_ISDIR (cmode)) {
2207		/* Directories */
2208		new_persistent_len = 0;
2209		new_key_len = 0;
2210
2211		error = 0;
2212	}
2213	else {
2214		/* Must be a file */
2215		if (newclass_eff == PROTECTION_CLASS_F) {
2216			/* class F files are not wrapped; they can still use the max key size */
2217			new_key_len = CP_MAX_KEYSIZE;
2218			read_random (&new_key[0], new_key_len);
2219			new_persistent_len = 0;
2220
2221			error = 0;
2222		}
2223		else {
2224			/*
2225			 * The keystore is provided the file ID so that it can associate
2226			 * the wrapped backup blob with this key from userspace. This
2227			 * lookup occurs after successful file creation.  Beyond this, the
2228			 * file ID is not used.  Note that there is a potential race here if
2229			 * the file ID is re-used.
2230			 */
2231			cp_init_access(&access_in, cp);
2232
2233			bzero(&key_out, sizeof(key_out));
2234			key_out.key = new_key;
2235			key_out.iv_key = iv_key;
2236			/*
2237			 * AKS will override our key length fields, but we need to supply
2238			 * the length of the buffer in those length fields so that
2239			 * AKS knows hoa many bytes it has to work with.
2240			 */
2241			key_out.key_len = new_key_len;
2242			key_out.iv_key_len = iv_key_len;
2243
2244			bzero(&wrapped_key_out, sizeof(wrapped_key_out));
2245			wrapped_key_out.key = new_persistent_key;
2246			wrapped_key_out.key_len = new_persistent_len;
2247
2248			error = g_cp_wrap_func.new_key(&access_in,
2249					newclass_eff,
2250					&key_out,
2251					&wrapped_key_out);
2252
2253			if (error) {
2254				/* keybag returned failure */
2255				error = EPERM;
2256				goto cpnew_fail;
2257			}
2258
2259			/* Now sanity-check the output from new_key */
2260			if (key_out.key_len == 0 || key_out.key_len > CP_MAX_CACHEBUFLEN) {
2261				panic ("cp_new: invalid key length! (%ul) \n", key_out.key_len);
2262			}
2263
2264			if (key_out.iv_key_len == 0 || key_out.iv_key_len > CP_IV_KEYSIZE) {
2265				panic ("cp_new: invalid iv key length! (%ul) \n", key_out.iv_key_len);
2266			}
2267
2268			/*
2269			 * AKS is allowed to override our preferences and wrap with a
2270			 * different class key for policy reasons. If we were told that
2271			 * any class other than the one specified is unacceptable then error out
2272			 * if that occurred.  Check that the effective class returned by
2273			 * AKS is the same as our effective new class
2274			 */
2275			if ((int)(CP_CLASS(wrapped_key_out.dp_class)) != newclass_eff) {
2276				if (keyflags & CP_KEYWRAP_DIFFCLASS) {
2277					newclass_eff = CP_CLASS(wrapped_key_out.dp_class);
2278				}
2279				else {
2280					error = EPERM;
2281					/* TODO: When 12170074 fixed, release/invalidate the key! */
2282					goto cpnew_fail;
2283				}
2284			}
2285
2286			new_key_len = key_out.key_len;
2287			iv_key_len = key_out.iv_key_len;
2288			new_persistent_len = wrapped_key_out.key_len;
2289
2290			/* Is the key a SEP wrapped key? */
2291			if (key_out.flags & CP_RAW_KEY_WRAPPEDKEY) {
2292				iswrapped = 1;
2293			}
2294		}
2295	}
2296
2297	/*
2298	 * Step 2: allocate cprotect and initialize it.
2299	 */
2300
2301
2302	/*
2303	 * v2 EA's don't support the larger class B keys
2304	 */
2305	if ((new_persistent_len != CP_V2_WRAPPEDKEYSIZE) &&
2306			(hfsmp->hfs_running_cp_major_vers == CP_PREV_MAJOR_VERS)) {
2307		return EINVAL;
2308	}
2309
2310	entry = cp_entry_alloc (new_persistent_len);
2311	if (entry == NULL) {
2312		return ENOMEM;
2313	}
2314
2315	*output_entry = entry;
2316
2317	/*
2318	 * For directories and class F files, just store the effective new class.
2319	 * AKS does not interact with us in generating keys for F files, and directories
2320	 * don't actually have keys.
2321	 */
2322	if ( S_ISDIR (cmode) || (newclass_eff == PROTECTION_CLASS_F)) {
2323		entry->cp_pclass = newclass_eff;
2324	}
2325	else {
2326		/*
2327		 * otherwise, store what AKS actually returned back to us.
2328		 * wrapped_key_out is only valid if we have round-tripped to AKS
2329		 */
2330		entry->cp_pclass = wrapped_key_out.dp_class;
2331	}
2332
2333	/* Copy the cache key & IV keys into place if needed. */
2334	if (new_key_len > 0) {
2335		bcopy (new_key, entry->cp_cache_key, new_key_len);
2336		entry->cp_cache_key_len = new_key_len;
2337
2338
2339		/* Initialize the IV key */
2340		if (hfsmp->hfs_running_cp_major_vers == CP_NEW_MAJOR_VERS) {
2341			if (newclass_eff == PROTECTION_CLASS_F) {
2342				/* class F needs a full IV initialize */
2343				cp_setup_aes_ctx(entry);
2344			}
2345			else {
2346				/* Key store gave us an iv key. Just need to wrap it.*/
2347				aes_encrypt_key128(iv_key, &entry->cp_cache_iv_ctx);
2348			}
2349			entry->cp_flags |= CP_OFF_IV_ENABLED;
2350		}
2351	}
2352	if (new_persistent_len > 0) {
2353		bcopy(new_persistent_key, entry->cp_persistent_key, new_persistent_len);
2354	}
2355
2356	/* Mark it as a wrapped key if necessary */
2357	if (iswrapped) {
2358		entry->cp_flags |= CP_SEP_WRAPPEDKEY;
2359	}
2360
2361cpnew_fail:
2362	return error;
2363}
2364
2365/* Initialize the cp_cred_t structure passed to AKS */
2366static void cp_init_access(cp_cred_t access, struct cnode *cp)
2367{
2368	vfs_context_t context = vfs_context_current();
2369	kauth_cred_t cred = vfs_context_ucred(context);
2370	proc_t proc = vfs_context_proc(context);
2371
2372	bzero(access, sizeof(*access));
2373
2374	/* Note: HFS uses 32-bit fileID, even though inode is a 64-bit value */
2375	access->inode = cp->c_fileid;
2376	access->pid = proc_pid(proc);
2377	access->uid = kauth_cred_getuid(cred);
2378
2379	return;
2380}
2381
2382#else
2383
2384int cp_key_store_action(int action __unused)
2385{
2386	return ENOTSUP;
2387}
2388
2389
2390int cp_register_wraps(cp_wrap_func_t key_store_func __unused)
2391{
2392	return ENOTSUP;
2393}
2394
2395#endif /* CONFIG_PROTECT */
2396