]> git.saurik.com Git - apple/xnu.git/blobdiff - bsd/sys/cprotect.h
xnu-2422.1.72.tar.gz
[apple/xnu.git] / bsd / sys / cprotect.h
index eb0a134fdff7fca6d8ec54373325449543adf2eb..9a7c36d773df126032bea5cc9ac5b71cbe8bbccc 100644 (file)
@@ -1,8 +1,8 @@
 /*
- * Copyright (c) 2009 Apple Inc. All rights reserved.
+ * Copyright (c) 2009-2012 Apple Inc. All rights reserved.
  *
  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
- * 
+ *
  * This file contains Original Code and/or Modifications of Original Code
  * as defined in and that are subject to the Apple Public Source License
  * Version 2.0 (the 'License'). You may not use this file except in
  * unlawful or unlicensed copies of an Apple operating system, or to
  * circumvent, violate, or enable the circumvention or violation of, any
  * terms of an Apple operating system software license agreement.
- * 
+ *
  * Please obtain a copy of the License at
  * http://www.opensource.apple.com/apsl/ and read it before using this file.
- * 
+ *
  * The Original Code and all software distributed under the License are
  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
@@ -22,7 +22,7 @@
  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
  * Please see the License for the specific language governing rights and
  * limitations under the License.
- * 
+ *
  * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
  */
 
@@ -40,38 +40,43 @@ extern "C" {
 #include <sys/kernel_types.h>
 #include <crypto/aes.h>
 
-#define CP_IV_KEYSIZE 20                       /* 16x8 = 128, but SHA1 pushes 20 bytes so keep space for that */
-#define CP_MAX_KEYSIZE 32              /* 8x4 = 32, 32x8 = 256 */
-#define CP_MAX_WRAPPEDKEYSIZE  128     /* The size of the largest allowed key */
+#define CP_IV_KEYSIZE             20   /* 16x8 = 128, but SHA1 pushes 20 bytes so keep space for that */
+#define CP_MAX_KEYSIZE            32   /* 8x4 = 32, 32x8 = 256 */
+#define CP_MAX_WRAPPEDKEYSIZE     128  /* The size of the largest allowed key */
 #define CP_INITIAL_WRAPPEDKEYSIZE 40
-#define CP_V2_WRAPPEDKEYSIZE 40                /* Size of the wrapped key in a v2 EA */
+#define CP_V2_WRAPPEDKEYSIZE      40   /* Size of the wrapped key in a v2 EA */
+#define CP_V4_RESERVEDBYTES       20   /* Number of reserved bytes in EA still present */
 
 /* lock events from AppleKeyStore */
-#define CP_LOCKED_STATE 0              /* Device is locked */
-#define CP_UNLOCKED_STATE 1            /* Device is unlocked */
+#define CP_LOCKED_STATE           0    /* Device is locked */
+#define CP_UNLOCKED_STATE         1    /* Device is unlocked */
 
-#define CP_LOCKED_KEYCHAIN 0   
-#define CP_UNLOCKED_KEYCHAIN 1
+#define CP_MAX_STATE                     1     /* uint8_t ; maximum # of states is 255 */
 
-/* For struct cprotect: cp_flags */
-#define CP_NEEDS_KEYS          0x1             /* File needs persistent keys */
-#define CP_KEY_FLUSHED         0x2             /* File's unwrapped key has been purged from memory */
-#define CP_NO_XATTR                    0x4             /* Key info has not been saved as EA to the FS */
-#define CP_OFF_IV_ENABLED      0x8             /* Only go down relative IV route if this flag is set */
+#define CP_LOCKED_KEYCHAIN        0
+#define CP_UNLOCKED_KEYCHAIN      1
 
-#define CP_RELOCATION_INFLIGHT 0x10    /* File with offset IVs is in the process of being relocated. */
+/* For struct cprotect: cp_flags */
+#define CP_NEEDS_KEYS             0x01 /* File needs persistent keys */
+#define CP_KEY_FLUSHED            0x02 /* File's unwrapped key has been purged from memory */
+#define CP_NO_XATTR               0x04 /* Key info has not been saved as EA to the FS */
+#define CP_OFF_IV_ENABLED         0x08 /* Only go down relative IV route if this flag is set */
+#define CP_RELOCATION_INFLIGHT    0x10 /* File with offset IVs is in the process of being relocated. */
+#define CP_SEP_WRAPPEDKEY                0x20  /* Wrapped key delivered from keybag */
 
 /* Content Protection VNOP Operation flags */
-#define CP_READ_ACCESS         0x1
-#define CP_WRITE_ACCESS 0x2
+#define CP_READ_ACCESS            0x1
+#define CP_WRITE_ACCESS           0x2
 
-/* 
+/*
  * Check for this version when deciding to enable features
+ * For iOS 4, CP_CURRENT_MAJOR_VERS = 2.0
+ * For iOS 5, CP_CURRENT_MAJOR_VERS = 4.0
  */
 #define CONTENT_PROTECTION_XATTR_NAME  "com.apple.system.cprotect"
-#define CP_NEW_MAJOR_VERS 4
-#define CP_PREV_MAJOR_VERS 2
-#define CP_MINOR_VERS 0
+#define CP_NEW_MAJOR_VERS         4
+#define CP_PREV_MAJOR_VERS        2
+#define CP_MINOR_VERS             0
 
 typedef struct cprotect *cprotect_t;
 typedef struct cp_wrap_func *cp_wrap_func_t;
@@ -82,13 +87,42 @@ typedef struct cnode * cnode_ptr_t;
 //forward declare the struct.
 struct hfsmount;
 
-/* The wrappers are invoked by the AKS kext */
-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);
-typedef        int unwrapper_t(uint32_t properties, void *wrapped_data, size_t wrapped_data_length, void *key_bytes, size_t *key_length);
+/* Structures passed between HFS and AKS kext */
+typedef struct {
+       void     *key;
+       unsigned key_len;
+       void     *iv_key;
+       unsigned iv_key_len;
+       uint32_t flags;
+} cp_raw_key_s, *cp_raw_key_t;
+
+typedef struct {
+       void     *key;
+       unsigned key_len;
+       uint32_t dp_class;
+} cp_wrapped_key_s, *cp_wrapped_key_t;
+
+typedef struct {
+       ino64_t  inode;
+       uint32_t volume;
+       pid_t    pid;
+       uid_t    uid;
+} cp_cred_s, *cp_cred_t;
 
-/* 
- * Runtime-only structure containing the content protection status 
- * for the given file.  This is contained within the cnode 
+/* The wrappers are invoked on the AKS kext */
+typedef int unwrapper_t(cp_cred_t access, const cp_wrapped_key_t wrapped_key_in, cp_raw_key_t key_out);
+typedef 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);
+typedef 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);
+typedef int invalidater_t(cp_cred_t access); /* invalidates keys */
+
+
+/* Flags for Interaction between AKS / Kernel */
+#define CP_RAW_KEY_WRAPPEDKEY 0x00000001
+
+
+/*
+ * Runtime-only structure containing the content protection status
+ * for the given file.  This is contained within the cnode
  * This is passed down to IOStorageFamily via the bufattr struct
  *
  ******************************************************
@@ -108,12 +142,15 @@ struct cprotect {
        uint32_t        cp_cache_key_len;
        uint8_t         cp_cache_key[CP_MAX_KEYSIZE];
        uint32_t        cp_persistent_key_len;
+       void*           cp_backing_cnode;
        uint8_t         cp_persistent_key[];
 };
 
 struct cp_wrap_func {
-       wrapper_t       *wrapper;
-       unwrapper_t     *unwrapper;
+       new_key_t       *new_key;
+       unwrapper_t     *unwrapper;
+       rewrapper_t     *rewrapper;
+       invalidater_t   *invalidater;
 };
 
 struct cp_global_state {
@@ -123,10 +160,13 @@ struct cp_global_state {
 };
 
 /*
- * On-disk structure written as the per-file EA payload 
+ * On-disk structure written as the per-file EA payload
  * All on-disk multi-byte fields for the CP XATTR must be stored
  * little-endian on-disk.  This means they must be endian swapped to
- * L.E on getxattr() and converted to LE on setxattr().        
+ * L.E on getxattr() and converted to LE on setxattr().
+ *
+ * This structure is a fixed length and is tightly packed.
+ * 56 bytes total.
  */
 struct cp_xattr_v2 {
        u_int16_t xattr_major_version;
@@ -135,7 +175,26 @@ struct cp_xattr_v2 {
        u_int32_t persistent_class;
        u_int32_t key_size;
        uint8_t   persistent_key[CP_V2_WRAPPEDKEYSIZE];
-};
+} __attribute__((aligned(2), packed));
+
+
+/*
+ * V4 Content Protection EA On-Disk Layout.
+ *
+ * This structure must be tightly packed, but the *size can vary*
+ * depending on the length of the key.  At MOST, the key length will be
+ * CP_MAX_WRAPPEDKEYSIZE, but the length is defined by the key_size field.
+ *
+ * Either way, the packing must be applied to ensure that the key data is
+ * retrievable in the right location relative to the start of the struct.
+ *
+ * Fully packed, this structure can range from :
+ *             MIN: 36 bytes (no key -- used with directories)
+ *             MAX: 164 bytes (with 128 byte key)
+ *
+ * During runtime we always allocate with the full 128 byte key, but only
+ * use as much of the key buffer as needed. It must be tightly packed, though.
+ */
 
 struct cp_xattr_v4 {
        u_int16_t xattr_major_version;
@@ -143,28 +202,32 @@ struct cp_xattr_v4 {
        u_int32_t flags;
        u_int32_t persistent_class;
        u_int32_t key_size;
-       u_int32_t reserved1;
-       u_int32_t reserved2;
-       u_int32_t reserved3;
-       u_int32_t reserved4;
-       u_int32_t reserved5;
+       /* CP V4 Reserved Bytes == 20 */
+       u_int8_t reserved[CP_V4_RESERVEDBYTES];
+       /* All above fields are fixed regardless of key length (36 bytes) */
+       /* Max Wrapped Size == 128 */
        uint8_t   persistent_key[CP_MAX_WRAPPEDKEYSIZE];
-};
+} __attribute__((aligned(2), packed));
 
-/* Same is true for the root EA, all fields must be written little endian. */
-struct cp_root_xattr {
-       u_int16_t major_version;
-       u_int16_t minor_version;
-       u_int64_t flags;
-       u_int32_t reserved1;
-       u_int32_t reserved2;
-       u_int32_t reserved3;
-       u_int32_t reserved4;
-};
+
+/*
+ * The Root Directory's EA (fileid 1) is special; it defines information about
+ * what capabilities the filesystem is using.
+ *
+ * The data is still stored little endian.
+ *
+ * Note that this structure is tightly packed: 28 bytes total.
+ */
+ struct cp_root_xattr {
+       u_int16_t major_version;
+       u_int16_t minor_version;
+       u_int64_t flags;
+       u_int8_t reserved[16];
+} __attribute__((aligned(2), packed));
 
 
-/* 
- * Functions to check the status of a CP and to query 
+/*
+ * Functions to check the status of a CP and to query
  * the containing filesystem to see if it is supported.
  */
 int cp_vnode_getclass(vnode_t, int *);
@@ -175,25 +238,24 @@ int cp_key_store_action(int);
 int cp_register_wraps(cp_wrap_func_t);
 
 int cp_entry_init(cnode_ptr_t, struct mount *);
-int cp_entry_create_keys(struct cprotect **entry_ptr, struct cnode *dcp, struct hfsmount *hfsmp, 
-               uint32_t input_class, uint32_t fileid, mode_t cmode);
 int cp_entry_gentempkeys(struct cprotect **entry_ptr, struct hfsmount *hfsmp);
-void cp_entry_destroy(struct cprotect **entry_ptr);
-
+int cp_needs_tempkeys (struct hfsmount *hfsmp, int* needs);
+void cp_entry_destroy(struct cprotect *entry_ptr);
+void cp_replace_entry (struct cnode *cp, struct cprotect *newentry);
 cnode_ptr_t cp_get_protected_cnode(vnode_t);
 int cp_handle_vnop(vnode_t, int, int);
 int cp_fs_protected (mount_t);
 int cp_getrootxattr (struct hfsmount *hfsmp, struct cp_root_xattr *outxattr);
 int cp_setrootxattr (struct hfsmount *hfsmp, struct cp_root_xattr *newxattr);
 int cp_setxattr(struct cnode *cp, struct cprotect *entry, struct hfsmount *hfsmp, uint32_t fileid, int options);
-int cp_update_mkb (struct cprotect *entry, uint32_t fileid);
+int cp_generate_keys (struct hfsmount *hfsmp, struct cnode *cp, int targetclass, struct cprotect **newentry);
+int cp_setup_newentry (struct hfsmount *hfsmp, struct cnode *dcp, int32_t suppliedclass, 
+               mode_t cmode, struct cprotect **tmpentry);
 int cp_handle_relocate (cnode_ptr_t cp, struct hfsmount *hfsmp);
 int cp_handle_open(struct vnode *vp, int mode);
 int cp_get_root_major_vers (struct vnode *vp, uint32_t *level);
-
-#if 0
-int cp_isdevice_locked (void);
-#endif
+int cp_get_default_level (struct vnode *vp, uint32_t *level);
+int cp_is_valid_class (int isdir, int32_t protectionclass);
 
 #endif /* KERNEL_PRIVATE */