1/*
2 * Copyright (c) 2009 Apple Inc. All rights reserved.
3 *
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. The rights granted to you under the License
10 * may not be used to create, or enable the creation or redistribution of,
11 * unlawful or unlicensed copies of an Apple operating system, or to
12 * circumvent, violate, or enable the circumvention or violation of, any
13 * terms of an Apple operating system software license agreement.
14 *
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
17 *
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
24 * limitations under the License.
25 *
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27 */
28
29#ifndef _SYS_CPROTECT_H_
30#define	_SYS_CPROTECT_H_
31
32#ifdef __cplusplus
33extern "C" {
34#endif
35
36#if KERNEL_PRIVATE
37
38#include <sys/cdefs.h>
39#include <sys/content_protection.h>
40#include <sys/kernel_types.h>
41#include <crypto/aes.h>
42
43#define CP_IV_KEYSIZE 20			/* 16x8 = 128, but SHA1 pushes 20 bytes so keep space for that */
44#define CP_MAX_KEYSIZE 32		/* 8x4 = 32, 32x8 = 256 */
45#define CP_MAX_WRAPPEDKEYSIZE  128	/* The size of the largest allowed key */
46#define CP_INITIAL_WRAPPEDKEYSIZE 40
47#define CP_V2_WRAPPEDKEYSIZE 40		/* Size of the wrapped key in a v2 EA */
48
49/* lock events from AppleKeyStore */
50#define CP_LOCKED_STATE 0		/* Device is locked */
51#define CP_UNLOCKED_STATE 1		/* Device is unlocked */
52
53#define CP_LOCKED_KEYCHAIN 0
54#define CP_UNLOCKED_KEYCHAIN 1
55
56/* For struct cprotect: cp_flags */
57#define CP_NEEDS_KEYS		0x1		/* File needs persistent keys */
58#define CP_KEY_FLUSHED		0x2		/* File's unwrapped key has been purged from memory */
59#define CP_NO_XATTR			0x4		/* Key info has not been saved as EA to the FS */
60#define CP_OFF_IV_ENABLED  	0x8		/* Only go down relative IV route if this flag is set */
61
62#define CP_RELOCATION_INFLIGHT 0x10	/* File with offset IVs is in the process of being relocated. */
63
64/* Content Protection VNOP Operation flags */
65#define CP_READ_ACCESS 	0x1
66#define CP_WRITE_ACCESS 0x2
67
68#define CONTENT_PROTECTION_XATTR_NAME	"com.apple.system.cprotect"
69#define CP_NEW_MAJOR_VERS 4
70#define CP_PREV_MAJOR_VERS 2
71#define CP_MINOR_VERS 0
72
73typedef struct cprotect *cprotect_t;
74typedef struct cp_wrap_func *cp_wrap_func_t;
75typedef struct cp_global_state *cp_global_state_t;
76typedef struct cp_xattr *cp_xattr_t;
77
78typedef struct cnode * cnode_ptr_t;
79//forward declare the struct.
80struct hfsmount;
81
82/* The wrappers are invoked by the AKS kext */
83typedef int wrapper_t(uint32_t properties, uint64_t file_id, void *key_bytes, size_t key_length, void *wrapped_data, size_t *wrapped_length);
84typedef	int unwrapper_t(uint32_t properties, void *wrapped_data, size_t wrapped_data_length, void *key_bytes, size_t *key_length);
85
86/*
87 * Runtime-only structure containing the content protection status
88 * for the given file.  This is contained within the cnode
89 * This is passed down to IOStorageFamily via the bufattr struct
90 *
91 ******************************************************
92 * Some Key calculation information for offset based IV
93 ******************************************************
94 * Kf  = original 256 bit per file key
95 * Kiv = SHA1(Kf), use full Kf, but truncate Kiv to 128 bits
96 * Kiv can be cached in the cprotect, so it only has to be calculated once for the file init
97 *
98 * IVb = Encrypt(Kiv, offset)
99 *
100 */
101struct cprotect {
102	uint32_t	cp_flags;
103	uint32_t	cp_pclass;
104	aes_encrypt_ctx	cp_cache_iv_ctx;
105	uint32_t	cp_cache_key_len;
106	uint8_t		cp_cache_key[CP_MAX_KEYSIZE];
107	uint32_t	cp_persistent_key_len;
108	uint8_t		cp_persistent_key[];
109};
110
111struct cp_wrap_func {
112	wrapper_t	*wrapper;
113	unwrapper_t	*unwrapper;
114};
115
116struct cp_global_state {
117	uint8_t	wrap_functions_set;
118	uint8_t	lock_state;
119	u_int16_t reserved;
120};
121
122/*
123 * On-disk structure written as the per-file EA payload
124 * All on-disk multi-byte fields for the CP XATTR must be stored
125 * little-endian on-disk.  This means they must be endian swapped to
126 * L.E on getxattr() and converted to LE on setxattr().
127 */
128struct cp_xattr_v2 {
129	u_int16_t xattr_major_version;
130	u_int16_t xattr_minor_version;
131	u_int32_t flags;
132	u_int32_t persistent_class;
133	u_int32_t key_size;
134	uint8_t   persistent_key[CP_V2_WRAPPEDKEYSIZE];
135};
136
137struct cp_xattr_v4 {
138	u_int16_t xattr_major_version;
139	u_int16_t xattr_minor_version;
140	u_int32_t flags;
141	u_int32_t persistent_class;
142	u_int32_t key_size;
143	u_int32_t reserved1;
144	u_int32_t reserved2;
145	u_int32_t reserved3;
146	u_int32_t reserved4;
147	u_int32_t reserved5;
148	uint8_t   persistent_key[CP_MAX_WRAPPEDKEYSIZE];
149};
150
151/* Same is true for the root EA, all fields must be written little endian. */
152struct cp_root_xattr {
153	u_int16_t major_version;
154	u_int16_t minor_version;
155	u_int64_t flags;
156	u_int32_t reserved1;
157	u_int32_t reserved2;
158	u_int32_t reserved3;
159	u_int32_t reserved4;
160};
161
162
163/*
164 * Functions to check the status of a CP and to query
165 * the containing filesystem to see if it is supported.
166 */
167int cp_vnode_getclass(vnode_t, int *);
168int cp_vnode_setclass(vnode_t, uint32_t);
169int cp_vnode_transcode(vnode_t);
170
171int cp_key_store_action(int);
172int cp_register_wraps(cp_wrap_func_t);
173
174int cp_entry_init(cnode_ptr_t, struct mount *);
175int cp_entry_create_keys(struct cprotect **entry_ptr, struct cnode *dcp, struct hfsmount *hfsmp,
176		uint32_t input_class, uint32_t fileid, mode_t cmode);
177int cp_entry_gentempkeys(struct cprotect **entry_ptr, struct hfsmount *hfsmp);
178void cp_entry_destroy(struct cprotect **entry_ptr);
179
180cnode_ptr_t cp_get_protected_cnode(vnode_t);
181int cp_handle_vnop(vnode_t, int, int);
182int cp_fs_protected (mount_t);
183int cp_getrootxattr (struct hfsmount *hfsmp, struct cp_root_xattr *outxattr);
184int cp_setrootxattr (struct hfsmount *hfsmp, struct cp_root_xattr *newxattr);
185int cp_setxattr(struct cnode *cp, struct cprotect *entry, struct hfsmount *hfsmp, uint32_t fileid, int options);
186int cp_update_mkb (struct cprotect *entry, uint32_t fileid);
187int cp_handle_relocate (cnode_ptr_t cp, struct hfsmount *hfsmp);
188int cp_handle_open(struct vnode *vp, int mode);
189int cp_get_root_major_vers (struct vnode *vp, uint32_t *level);
190
191#if 0
192int cp_isdevice_locked (void);
193#endif
194
195#endif	/* KERNEL_PRIVATE */
196
197#ifdef __cplusplus
198};
199#endif
200
201#endif /* !_SYS_CPROTECT_H_ */
202