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