]>
Commit | Line | Data |
---|---|---|
d1ecb069 A |
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 | |
33 | extern "C" { | |
34 | #endif | |
35 | ||
36 | #if KERNEL_PRIVATE | |
37 | ||
38 | #include <sys/cdefs.h> | |
6d2010ae | 39 | #include <sys/content_protection.h> |
d1ecb069 | 40 | #include <sys/kernel_types.h> |
316670eb | 41 | #include <crypto/aes.h> |
d1ecb069 | 42 | |
316670eb A |
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 */ | |
d1ecb069 | 48 | |
6d2010ae A |
49 | /* lock events from AppleKeyStore */ |
50 | #define CP_LOCKED_STATE 0 /* Device is locked */ | |
51 | #define CP_UNLOCKED_STATE 1 /* Device is unlocked */ | |
d1ecb069 | 52 | |
6d2010ae A |
53 | #define CP_LOCKED_KEYCHAIN 0 |
54 | #define CP_UNLOCKED_KEYCHAIN 1 | |
d1ecb069 | 55 | |
6d2010ae A |
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 */ | |
316670eb A |
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. */ | |
d1ecb069 | 63 | |
6d2010ae A |
64 | /* Content Protection VNOP Operation flags */ |
65 | #define CP_READ_ACCESS 0x1 | |
66 | #define CP_WRITE_ACCESS 0x2 | |
d1ecb069 | 67 | |
99c3a104 A |
68 | /* |
69 | * Check for this version when deciding to enable features | |
70 | */ | |
6d2010ae | 71 | #define CONTENT_PROTECTION_XATTR_NAME "com.apple.system.cprotect" |
316670eb A |
72 | #define CP_NEW_MAJOR_VERS 4 |
73 | #define CP_PREV_MAJOR_VERS 2 | |
74 | #define CP_MINOR_VERS 0 | |
d1ecb069 A |
75 | |
76 | typedef struct cprotect *cprotect_t; | |
77 | typedef struct cp_wrap_func *cp_wrap_func_t; | |
78 | typedef struct cp_global_state *cp_global_state_t; | |
79 | typedef struct cp_xattr *cp_xattr_t; | |
80 | ||
6d2010ae A |
81 | typedef struct cnode * cnode_ptr_t; |
82 | //forward declare the struct. | |
83 | struct hfsmount; | |
d1ecb069 | 84 | |
6d2010ae | 85 | /* The wrappers are invoked by the AKS kext */ |
316670eb | 86 | typedef int wrapper_t(uint32_t properties, uint64_t file_id, void *key_bytes, size_t key_length, void *wrapped_data, size_t *wrapped_length); |
6d2010ae | 87 | typedef int unwrapper_t(uint32_t properties, void *wrapped_data, size_t wrapped_data_length, void *key_bytes, size_t *key_length); |
d1ecb069 | 88 | |
6d2010ae A |
89 | /* |
90 | * Runtime-only structure containing the content protection status | |
91 | * for the given file. This is contained within the cnode | |
316670eb A |
92 | * This is passed down to IOStorageFamily via the bufattr struct |
93 | * | |
94 | ****************************************************** | |
95 | * Some Key calculation information for offset based IV | |
96 | ****************************************************** | |
97 | * Kf = original 256 bit per file key | |
98 | * Kiv = SHA1(Kf), use full Kf, but truncate Kiv to 128 bits | |
99 | * Kiv can be cached in the cprotect, so it only has to be calculated once for the file init | |
100 | * | |
101 | * IVb = Encrypt(Kiv, offset) | |
102 | * | |
6d2010ae | 103 | */ |
d1ecb069 | 104 | struct cprotect { |
6d2010ae A |
105 | uint32_t cp_flags; |
106 | uint32_t cp_pclass; | |
316670eb A |
107 | aes_encrypt_ctx cp_cache_iv_ctx; |
108 | uint32_t cp_cache_key_len; | |
109 | uint8_t cp_cache_key[CP_MAX_KEYSIZE]; | |
110 | uint32_t cp_persistent_key_len; | |
111 | uint8_t cp_persistent_key[]; | |
d1ecb069 A |
112 | }; |
113 | ||
114 | struct cp_wrap_func { | |
6d2010ae A |
115 | wrapper_t *wrapper; |
116 | unwrapper_t *unwrapper; | |
d1ecb069 A |
117 | }; |
118 | ||
119 | struct cp_global_state { | |
6d2010ae | 120 | uint8_t wrap_functions_set; |
316670eb A |
121 | uint8_t lock_state; |
122 | u_int16_t reserved; | |
d1ecb069 A |
123 | }; |
124 | ||
6d2010ae A |
125 | /* |
126 | * On-disk structure written as the per-file EA payload | |
127 | * All on-disk multi-byte fields for the CP XATTR must be stored | |
128 | * little-endian on-disk. This means they must be endian swapped to | |
129 | * L.E on getxattr() and converted to LE on setxattr(). | |
130 | */ | |
316670eb A |
131 | struct cp_xattr_v2 { |
132 | u_int16_t xattr_major_version; | |
133 | u_int16_t xattr_minor_version; | |
134 | u_int32_t flags; | |
135 | u_int32_t persistent_class; | |
136 | u_int32_t key_size; | |
137 | uint8_t persistent_key[CP_V2_WRAPPEDKEYSIZE]; | |
138 | }; | |
139 | ||
140 | struct cp_xattr_v4 { | |
141 | u_int16_t xattr_major_version; | |
142 | u_int16_t xattr_minor_version; | |
143 | u_int32_t flags; | |
144 | u_int32_t persistent_class; | |
145 | u_int32_t key_size; | |
146 | u_int32_t reserved1; | |
147 | u_int32_t reserved2; | |
148 | u_int32_t reserved3; | |
149 | u_int32_t reserved4; | |
150 | u_int32_t reserved5; | |
151 | uint8_t persistent_key[CP_MAX_WRAPPEDKEYSIZE]; | |
d1ecb069 A |
152 | }; |
153 | ||
6d2010ae A |
154 | /* Same is true for the root EA, all fields must be written little endian. */ |
155 | struct cp_root_xattr { | |
156 | u_int16_t major_version; | |
157 | u_int16_t minor_version; | |
158 | u_int64_t flags; | |
159 | u_int32_t reserved1; | |
160 | u_int32_t reserved2; | |
161 | u_int32_t reserved3; | |
162 | u_int32_t reserved4; | |
163 | }; | |
164 | ||
165 | ||
166 | /* | |
167 | * Functions to check the status of a CP and to query | |
168 | * the containing filesystem to see if it is supported. | |
169 | */ | |
170 | int cp_vnode_getclass(vnode_t, int *); | |
171 | int cp_vnode_setclass(vnode_t, uint32_t); | |
316670eb | 172 | int cp_vnode_transcode(vnode_t); |
6d2010ae | 173 | |
d1ecb069 A |
174 | int cp_key_store_action(int); |
175 | int cp_register_wraps(cp_wrap_func_t); | |
6d2010ae A |
176 | |
177 | int cp_entry_init(cnode_ptr_t, struct mount *); | |
316670eb A |
178 | int cp_entry_create_keys(struct cprotect **entry_ptr, struct cnode *dcp, struct hfsmount *hfsmp, |
179 | uint32_t input_class, uint32_t fileid, mode_t cmode); | |
180 | int cp_entry_gentempkeys(struct cprotect **entry_ptr, struct hfsmount *hfsmp); | |
181 | void cp_entry_destroy(struct cprotect **entry_ptr); | |
6d2010ae A |
182 | |
183 | cnode_ptr_t cp_get_protected_cnode(vnode_t); | |
316670eb | 184 | int cp_handle_vnop(vnode_t, int, int); |
6d2010ae A |
185 | int cp_fs_protected (mount_t); |
186 | int cp_getrootxattr (struct hfsmount *hfsmp, struct cp_root_xattr *outxattr); | |
187 | int cp_setrootxattr (struct hfsmount *hfsmp, struct cp_root_xattr *newxattr); | |
316670eb A |
188 | int cp_setxattr(struct cnode *cp, struct cprotect *entry, struct hfsmount *hfsmp, uint32_t fileid, int options); |
189 | int cp_update_mkb (struct cprotect *entry, uint32_t fileid); | |
190 | int cp_handle_relocate (cnode_ptr_t cp, struct hfsmount *hfsmp); | |
191 | int cp_handle_open(struct vnode *vp, int mode); | |
192 | int cp_get_root_major_vers (struct vnode *vp, uint32_t *level); | |
193 | ||
194 | #if 0 | |
195 | int cp_isdevice_locked (void); | |
196 | #endif | |
d1ecb069 A |
197 | |
198 | #endif /* KERNEL_PRIVATE */ | |
199 | ||
200 | #ifdef __cplusplus | |
201 | }; | |
202 | #endif | |
203 | ||
204 | #endif /* !_SYS_CPROTECT_H_ */ |