1/* 2 * Copyright (c) 2009-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 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#include <sys/kdebug.h> 44 45#define CP_CODE(code) FSDBG_CODE(DBG_CONTENT_PROT, code) 46/* 47 * Class DBG_FSYSTEM == 0x03 48 * Subclass DBG_CONTENT_PROT == 0xCF 49 * These debug codes are of the form 0x03CFzzzz 50 */ 51 52enum { 53 CPDBG_OFFSET_IO = CP_CODE(0), /* 0x03CF0000 */ 54}; 55 56/* normally the debug events are no-ops */ 57#define CP_DEBUG(x,a,b,c,d,e) do {} while (0); 58 59/* dev kernels only! */ 60#if !SECURE_KERNEL 61 62/* KDEBUG events used by content protection subsystem */ 63#if 0 64#undef CP_DEBUG 65#define CP_DEBUG KERNEL_DEBUG_CONSTANT 66#endif 67 68#endif 69 70 71 72#define CP_IV_KEYSIZE 20 /* 16x8 = 128, but SHA1 pushes 20 bytes so keep space for that */ 73#define CP_MAX_KEYSIZE 32 /* 8x4 = 32, 32x8 = 256 */ 74#define CP_MAX_CACHEBUFLEN 64 /* Maximum size of cp cache buffer/array */ 75 76#define CP_MAX_WRAPPEDKEYSIZE 128 /* The size of the largest allowed key */ 77#define CP_INITIAL_WRAPPEDKEYSIZE 40 78#define CP_V2_WRAPPEDKEYSIZE 40 /* Size of the wrapped key in a v2 EA */ 79#define CP_V4_RESERVEDBYTES 20 /* Number of reserved bytes in EA still present */ 80 81/* lock events from AppleKeyStore */ 82#define CP_LOCKED_STATE 0 /* Device is locked */ 83#define CP_UNLOCKED_STATE 1 /* Device is unlocked */ 84 85#define CP_MAX_STATE 1 /* uint8_t ; maximum # of states is 255 */ 86 87#define CP_LOCKED_KEYCHAIN 0 88#define CP_UNLOCKED_KEYCHAIN 1 89 90/* For struct cprotect: cp_flags */ 91#define CP_NEEDS_KEYS 0x01 /* File needs persistent keys */ 92#define CP_KEY_FLUSHED 0x02 /* File's unwrapped key has been purged from memory */ 93#define CP_NO_XATTR 0x04 /* Key info has not been saved as EA to the FS */ 94#define CP_OFF_IV_ENABLED 0x08 /* Only go down relative IV route if this flag is set */ 95#define CP_RELOCATION_INFLIGHT 0x10 /* File with offset IVs is in the process of being relocated. */ 96#define CP_SEP_WRAPPEDKEY 0x20 /* Wrapped key delivered from keybag */ 97 98 99 100/* Content Protection VNOP Operation flags */ 101#define CP_READ_ACCESS 0x1 102#define CP_WRITE_ACCESS 0x2 103 104/* 105 * Check for this version when deciding to enable features 106 * For iOS 4, CP_CURRENT_MAJOR_VERS = 2.0 107 * For iOS 5, CP_CURRENT_MAJOR_VERS = 4.0 108 */ 109#define CONTENT_PROTECTION_XATTR_NAME "com.apple.system.cprotect" 110#define CP_NEW_MAJOR_VERS 4 111#define CP_PREV_MAJOR_VERS 2 112#define CP_MINOR_VERS 0 113 114/* the class occupies the lowest 5 bits, so there are 32 values (0-31) */ 115#define CP_EFFECTIVE_CLASSMASK 0x0000001f 116 117/* macros for quick access/typing to mask out the classmask */ 118#define CP_CLASS(x) ((uint32_t)(CP_EFFECTIVE_CLASSMASK & (x))) 119 120#define CP_CRYPTO_G1 0x00000020 121 122typedef struct cprotect *cprotect_t; 123typedef struct cp_wrap_func *cp_wrap_func_t; 124typedef struct cp_xattr *cp_xattr_t; 125 126typedef struct cnode * cnode_ptr_t; 127//forward declare the struct. 128struct hfsmount; 129 130/* Structures passed between HFS and AKS kext */ 131typedef struct { 132 void *key; 133 unsigned key_len; 134 void *iv_key; 135 unsigned iv_key_len; 136 uint32_t flags; 137} cp_raw_key_s; 138 139typedef cp_raw_key_s* cp_raw_key_t; 140 141typedef struct { 142 void *key; 143 unsigned key_len; 144 uint32_t dp_class; 145} cp_wrapped_key_s; 146 147typedef cp_wrapped_key_s* cp_wrapped_key_t; 148 149typedef struct { 150 ino64_t inode; 151 uint32_t volume; 152 pid_t pid; 153 uid_t uid; 154} cp_cred_s; 155 156typedef cp_cred_s* cp_cred_t; 157 158/* The wrappers are invoked on the AKS kext */ 159typedef int unwrapper_t(cp_cred_t access, const cp_wrapped_key_t wrapped_key_in, cp_raw_key_t key_out); 160typedef int rewrapper_t(cp_cred_t access, uint32_t dp_class, const cp_wrapped_key_t wrapped_key_in, cp_wrapped_key_t wrapped_key_out); 161typedef int new_key_t(cp_cred_t access, uint32_t dp_class, cp_raw_key_t key_out, cp_wrapped_key_t wrapped_key_out); 162typedef int invalidater_t(cp_cred_t access); /* invalidates keys */ 163typedef int backup_key_t(cp_cred_t access, const cp_wrapped_key_t wrapped_key_in, cp_wrapped_key_t wrapped_key_out); 164 165 166/* 167 * Flags for Interaction between AKS / Kernel 168 * These are twiddled via the input/output structs in the above 169 * wrapper/unwrapper functions. 170 */ 171#define CP_RAW_KEY_WRAPPEDKEY 0x00000001 172 173 174/* 175 * Flags for Key Generation Behavior 176 * 177 * These are passed to cp_generate_keys() and cp_new() in the 178 * flags arguments 179 */ 180#define CP_KEYWRAP_DIFFCLASS 0x00000001 /* wrapping with a different class bag is OK */ 181 182 183/* 184 * Runtime-only structure containing the content protection status 185 * for the given file. This is contained within the cnode 186 * This is passed down to IOStorageFamily via the bufattr struct 187 * 188 ****************************************************** 189 * Some Key calculation information for offset based IV 190 ****************************************************** 191 * Kf = original 256 bit per file key 192 * Kiv = SHA1(Kf), use full Kf, but truncate Kiv to 128 bits 193 * Kiv can be cached in the cprotect, so it only has to be calculated once for the file init 194 * 195 * IVb = Encrypt(Kiv, offset) 196 * 197 */ 198struct cprotect { 199 uint32_t cp_flags; 200 uint32_t cp_pclass; /* persistent class stored on-disk */ 201 aes_encrypt_ctx cp_cache_iv_ctx; 202 uint32_t cp_cache_key_len; 203 uint8_t cp_cache_key[CP_MAX_CACHEBUFLEN]; 204 uint32_t cp_persistent_key_len; 205 void* cp_backing_cnode; 206 uint8_t cp_persistent_key[]; 207}; 208 209/* Structure to store pointers for AKS functions */ 210struct cp_wrap_func { 211 new_key_t *new_key; 212 unwrapper_t *unwrapper; 213 rewrapper_t *rewrapper; 214 invalidater_t *invalidater; 215 backup_key_t *backup_key; 216}; 217 218/* 219 * On-disk structure written as the per-file EA payload 220 * All on-disk multi-byte fields for the CP XATTR must be stored 221 * little-endian on-disk. This means they must be endian swapped to 222 * L.E on getxattr() and converted to LE on setxattr(). 223 * 224 * This structure is a fixed length and is tightly packed. 225 * 56 bytes total. 226 */ 227struct cp_xattr_v2 { 228 u_int16_t xattr_major_version; 229 u_int16_t xattr_minor_version; 230 u_int32_t flags; 231 u_int32_t persistent_class; 232 u_int32_t key_size; 233 uint8_t persistent_key[CP_V2_WRAPPEDKEYSIZE]; 234} __attribute__((aligned(2), packed)); 235 236 237/* 238 * V4 Content Protection EA On-Disk Layout. 239 * 240 * This structure must be tightly packed, but the *size can vary* 241 * depending on the length of the key. At MOST, the key length will be 242 * CP_MAX_WRAPPEDKEYSIZE, but the length is defined by the key_size field. 243 * 244 * Either way, the packing must be applied to ensure that the key data is 245 * retrievable in the right location relative to the start of the struct. 246 * 247 * Fully packed, this structure can range from : 248 * MIN: 36 bytes (no key -- used with directories) 249 * MAX: 164 bytes (with 128 byte key) 250 * 251 * During runtime we always allocate with the full 128 byte key, but only 252 * use as much of the key buffer as needed. It must be tightly packed, though. 253 */ 254 255struct cp_xattr_v4 { 256 u_int16_t xattr_major_version; 257 u_int16_t xattr_minor_version; 258 u_int32_t flags; 259 u_int32_t persistent_class; 260 u_int32_t key_size; 261 /* CP V4 Reserved Bytes == 20 */ 262 u_int8_t reserved[CP_V4_RESERVEDBYTES]; 263 /* All above fields are fixed regardless of key length (36 bytes) */ 264 /* Max Wrapped Size == 128 */ 265 uint8_t persistent_key[CP_MAX_WRAPPEDKEYSIZE]; 266} __attribute__((aligned(2), packed)); 267 268 269/* 270 * The Root Directory's EA (fileid 1) is special; it defines information about 271 * what capabilities the filesystem is using. 272 * 273 * The data is still stored little endian. 274 * 275 * Note that this structure is tightly packed: 28 bytes total. 276 */ 277 struct cp_root_xattr { 278 u_int16_t major_version; 279 u_int16_t minor_version; 280 u_int64_t flags; 281 u_int8_t reserved[16]; 282} __attribute__((aligned(2), packed)); 283 284 285/* 286 * Functions to check the status of a CP and to query 287 * the containing filesystem to see if it is supported. 288 */ 289int cp_vnode_getclass(vnode_t, int *); 290int cp_vnode_setclass(vnode_t, uint32_t); 291int cp_vnode_transcode(vnode_t vp, void *key, unsigned *len); 292 293int cp_key_store_action(int); 294int cp_register_wraps(cp_wrap_func_t); 295 296int cp_entry_init(cnode_ptr_t, struct mount *); 297int cp_entry_gentempkeys(struct cprotect **entry_ptr, struct hfsmount *hfsmp); 298int cp_needs_tempkeys (struct hfsmount *hfsmp, int* needs); 299void cp_entry_destroy(struct cprotect *entry_ptr); 300void cp_replace_entry (struct cnode *cp, struct cprotect *newentry); 301cnode_ptr_t cp_get_protected_cnode(vnode_t); 302int cp_handle_vnop(vnode_t, int, int); 303int cp_fs_protected (mount_t); 304int cp_getrootxattr (struct hfsmount *hfsmp, struct cp_root_xattr *outxattr); 305int cp_setrootxattr (struct hfsmount *hfsmp, struct cp_root_xattr *newxattr); 306int cp_setxattr(struct cnode *cp, struct cprotect *entry, struct hfsmount *hfsmp, uint32_t fileid, int options); 307int cp_generate_keys (struct hfsmount *hfsmp, struct cnode *cp, int targetclass, 308 uint32_t flags, struct cprotect **newentry); 309int cp_setup_newentry (struct hfsmount *hfsmp, struct cnode *dcp, int32_t suppliedclass, 310 mode_t cmode, struct cprotect **tmpentry); 311int cp_handle_relocate (cnode_ptr_t cp, struct hfsmount *hfsmp); 312int cp_handle_open(struct vnode *vp, int mode); 313int cp_get_root_major_vers (struct vnode *vp, uint32_t *level); 314int cp_get_default_level (struct vnode *vp, uint32_t *level); 315int cp_is_valid_class (int isdir, int32_t protectionclass); 316int cp_set_trimmed(struct hfsmount *hfsmp); 317int cp_set_rewrapped(struct hfsmount *hfsmp); 318int cp_flop_generation (struct hfsmount *hfsmp); 319 320 321#endif /* KERNEL_PRIVATE */ 322 323#ifdef __cplusplus 324}; 325#endif 326 327#endif /* !_SYS_CPROTECT_H_ */ 328