1/* 2 * Copyright (c) 2009-2012 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#define CP_V4_RESERVEDBYTES 20 /* Number of reserved bytes in EA still present */ 49 50/* lock events from AppleKeyStore */ 51#define CP_LOCKED_STATE 0 /* Device is locked */ 52#define CP_UNLOCKED_STATE 1 /* Device is unlocked */ 53 54#define CP_MAX_STATE 1 /* uint8_t ; maximum # of states is 255 */ 55 56#define CP_LOCKED_KEYCHAIN 0 57#define CP_UNLOCKED_KEYCHAIN 1 58 59/* For struct cprotect: cp_flags */ 60#define CP_NEEDS_KEYS 0x01 /* File needs persistent keys */ 61#define CP_KEY_FLUSHED 0x02 /* File's unwrapped key has been purged from memory */ 62#define CP_NO_XATTR 0x04 /* Key info has not been saved as EA to the FS */ 63#define CP_OFF_IV_ENABLED 0x08 /* Only go down relative IV route if this flag is set */ 64#define CP_RELOCATION_INFLIGHT 0x10 /* File with offset IVs is in the process of being relocated. */ 65#define CP_SEP_WRAPPEDKEY 0x20 /* Wrapped key delivered from keybag */ 66 67/* Content Protection VNOP Operation flags */ 68#define CP_READ_ACCESS 0x1 69#define CP_WRITE_ACCESS 0x2 70 71/* 72 * Check for this version when deciding to enable features 73 * For iOS 4, CP_CURRENT_MAJOR_VERS = 2.0 74 * For iOS 5, CP_CURRENT_MAJOR_VERS = 4.0 75 */ 76#define CONTENT_PROTECTION_XATTR_NAME "com.apple.system.cprotect" 77#define CP_NEW_MAJOR_VERS 4 78#define CP_PREV_MAJOR_VERS 2 79#define CP_MINOR_VERS 0 80 81typedef struct cprotect *cprotect_t; 82typedef struct cp_wrap_func *cp_wrap_func_t; 83typedef struct cp_global_state *cp_global_state_t; 84typedef struct cp_xattr *cp_xattr_t; 85 86typedef struct cnode * cnode_ptr_t; 87//forward declare the struct. 88struct hfsmount; 89 90/* Structures passed between HFS and AKS kext */ 91typedef struct { 92 void *key; 93 unsigned key_len; 94 void *iv_key; 95 unsigned iv_key_len; 96 uint32_t flags; 97} cp_raw_key_s, *cp_raw_key_t; 98 99typedef struct { 100 void *key; 101 unsigned key_len; 102 uint32_t dp_class; 103} cp_wrapped_key_s, *cp_wrapped_key_t; 104 105typedef struct { 106 ino64_t inode; 107 uint32_t volume; 108 pid_t pid; 109 uid_t uid; 110} cp_cred_s, *cp_cred_t; 111 112/* The wrappers are invoked on the AKS kext */ 113typedef int unwrapper_t(cp_cred_t access, const cp_wrapped_key_t wrapped_key_in, cp_raw_key_t key_out); 114typedef 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); 115typedef 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); 116typedef int invalidater_t(cp_cred_t access); /* invalidates keys */ 117 118 119/* Flags for Interaction between AKS / Kernel */ 120#define CP_RAW_KEY_WRAPPEDKEY 0x00000001 121 122 123/* 124 * Runtime-only structure containing the content protection status 125 * for the given file. This is contained within the cnode 126 * This is passed down to IOStorageFamily via the bufattr struct 127 * 128 ****************************************************** 129 * Some Key calculation information for offset based IV 130 ****************************************************** 131 * Kf = original 256 bit per file key 132 * Kiv = SHA1(Kf), use full Kf, but truncate Kiv to 128 bits 133 * Kiv can be cached in the cprotect, so it only has to be calculated once for the file init 134 * 135 * IVb = Encrypt(Kiv, offset) 136 * 137 */ 138struct cprotect { 139 uint32_t cp_flags; 140 uint32_t cp_pclass; 141 aes_encrypt_ctx cp_cache_iv_ctx; 142 uint32_t cp_cache_key_len; 143 uint8_t cp_cache_key[CP_MAX_KEYSIZE]; 144 uint32_t cp_persistent_key_len; 145 void* cp_backing_cnode; 146 uint8_t cp_persistent_key[]; 147}; 148 149struct cp_wrap_func { 150 new_key_t *new_key; 151 unwrapper_t *unwrapper; 152 rewrapper_t *rewrapper; 153 invalidater_t *invalidater; 154}; 155 156struct cp_global_state { 157 uint8_t wrap_functions_set; 158 uint8_t lock_state; 159 u_int16_t reserved; 160}; 161 162/* 163 * On-disk structure written as the per-file EA payload 164 * All on-disk multi-byte fields for the CP XATTR must be stored 165 * little-endian on-disk. This means they must be endian swapped to 166 * L.E on getxattr() and converted to LE on setxattr(). 167 * 168 * This structure is a fixed length and is tightly packed. 169 * 56 bytes total. 170 */ 171struct cp_xattr_v2 { 172 u_int16_t xattr_major_version; 173 u_int16_t xattr_minor_version; 174 u_int32_t flags; 175 u_int32_t persistent_class; 176 u_int32_t key_size; 177 uint8_t persistent_key[CP_V2_WRAPPEDKEYSIZE]; 178} __attribute__((aligned(2), packed)); 179 180 181/* 182 * V4 Content Protection EA On-Disk Layout. 183 * 184 * This structure must be tightly packed, but the *size can vary* 185 * depending on the length of the key. At MOST, the key length will be 186 * CP_MAX_WRAPPEDKEYSIZE, but the length is defined by the key_size field. 187 * 188 * Either way, the packing must be applied to ensure that the key data is 189 * retrievable in the right location relative to the start of the struct. 190 * 191 * Fully packed, this structure can range from : 192 * MIN: 36 bytes (no key -- used with directories) 193 * MAX: 164 bytes (with 128 byte key) 194 * 195 * During runtime we always allocate with the full 128 byte key, but only 196 * use as much of the key buffer as needed. It must be tightly packed, though. 197 */ 198 199struct cp_xattr_v4 { 200 u_int16_t xattr_major_version; 201 u_int16_t xattr_minor_version; 202 u_int32_t flags; 203 u_int32_t persistent_class; 204 u_int32_t key_size; 205 /* CP V4 Reserved Bytes == 20 */ 206 u_int8_t reserved[CP_V4_RESERVEDBYTES]; 207 /* All above fields are fixed regardless of key length (36 bytes) */ 208 /* Max Wrapped Size == 128 */ 209 uint8_t persistent_key[CP_MAX_WRAPPEDKEYSIZE]; 210} __attribute__((aligned(2), packed)); 211 212 213/* 214 * The Root Directory's EA (fileid 1) is special; it defines information about 215 * what capabilities the filesystem is using. 216 * 217 * The data is still stored little endian. 218 * 219 * Note that this structure is tightly packed: 28 bytes total. 220 */ 221 struct cp_root_xattr { 222 u_int16_t major_version; 223 u_int16_t minor_version; 224 u_int64_t flags; 225 u_int8_t reserved[16]; 226} __attribute__((aligned(2), packed)); 227 228 229/* 230 * Functions to check the status of a CP and to query 231 * the containing filesystem to see if it is supported. 232 */ 233int cp_vnode_getclass(vnode_t, int *); 234int cp_vnode_setclass(vnode_t, uint32_t); 235int cp_vnode_transcode(vnode_t); 236 237int cp_key_store_action(int); 238int cp_register_wraps(cp_wrap_func_t); 239 240int cp_entry_init(cnode_ptr_t, struct mount *); 241int cp_entry_gentempkeys(struct cprotect **entry_ptr, struct hfsmount *hfsmp); 242int cp_needs_tempkeys (struct hfsmount *hfsmp, int* needs); 243void cp_entry_destroy(struct cprotect *entry_ptr); 244void cp_replace_entry (struct cnode *cp, struct cprotect *newentry); 245cnode_ptr_t cp_get_protected_cnode(vnode_t); 246int cp_handle_vnop(vnode_t, int, int); 247int cp_fs_protected (mount_t); 248int cp_getrootxattr (struct hfsmount *hfsmp, struct cp_root_xattr *outxattr); 249int cp_setrootxattr (struct hfsmount *hfsmp, struct cp_root_xattr *newxattr); 250int cp_setxattr(struct cnode *cp, struct cprotect *entry, struct hfsmount *hfsmp, uint32_t fileid, int options); 251int cp_generate_keys (struct hfsmount *hfsmp, struct cnode *cp, int targetclass, struct cprotect **newentry); 252int cp_setup_newentry (struct hfsmount *hfsmp, struct cnode *dcp, int32_t suppliedclass, 253 mode_t cmode, struct cprotect **tmpentry); 254int cp_handle_relocate (cnode_ptr_t cp, struct hfsmount *hfsmp); 255int cp_handle_open(struct vnode *vp, int mode); 256int cp_get_root_major_vers (struct vnode *vp, uint32_t *level); 257int cp_get_default_level (struct vnode *vp, uint32_t *level); 258int cp_is_valid_class (int isdir, int32_t protectionclass); 259 260#endif /* KERNEL_PRIVATE */ 261 262#ifdef __cplusplus 263}; 264#endif 265 266#endif /* !_SYS_CPROTECT_H_ */ 267