1/* 2 * Copyright (c) 2000-2006 Apple Computer, Inc. All Rights Reserved. 3 * 4 * @APPLE_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. Please obtain a copy of the License at 10 * http://www.opensource.apple.com/apsl/ and read it before using this 11 * file. 12 * 13 * The Original Code and all software distributed under the License are 14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 18 * Please see the License for the specific language governing rights and 19 * limitations under the License. 20 * 21 * @APPLE_LICENSE_HEADER_END@ 22 */ 23 24 25// 26// ssblob - objects to represent persistent blobs used by SecurityServer 27// 28#ifndef _H_SSBLOB 29#define _H_SSBLOB 30 31#include <securityd_client/ssclient.h> 32#include <Security/cssm.h> 33#include <security_utilities/utilities.h> 34#include <security_cdsa_utilities/cssmacl.h> 35#include <security_utilities/memutils.h> 36#include <security_utilities/endian.h> 37 38 39namespace Security { 40namespace SecurityServer { 41 42using LowLevelMemoryUtilities::increment; 43 44 45// 46// A generic blob. 47// Note that Blob and its subclasses are meant to be Byte Order Corrected. 48// Make sure all non-byte fields are Endian<> qualified. 49// 50class Blob { 51public: 52 typedef Endian<uint32> uint32e; 53 typedef Endian<sint32> sint32e; 54 55protected: 56 template <class T> 57 T *at(off_t offset) { return LowLevelMemoryUtilities::increment<T>(this, offset); } 58 void *at(off_t offset) { return LowLevelMemoryUtilities::increment(this, (ptrdiff_t)offset); } 59 60 template <class T> 61 const T *at(off_t offset) const { return LowLevelMemoryUtilities::increment<T>(this, offset); } 62 const void *at(off_t offset) const { return LowLevelMemoryUtilities::increment(this, (ptrdiff_t)offset); } 63}; 64 65 66// 67// The common features of our blobs 68// 69class CommonBlob : public Blob { 70public: 71 // initial fixed fields for versioning 72 uint32e magic; // magic number 73 uint32e blobVersion; // version code 74 uint32 version() const { return blobVersion; } 75 76 static const uint32 magicNumber = 0xfade0711; 77 78 static const uint32 version_MacOS_10_0 = 0x00000100; // MacOS 10.0.x 79 static const uint32 version_MacOS_10_1 = 0x00000101; // MacOS 10.1.x and on 80 static const uint32 currentVersion = version_MacOS_10_0; 81 82public: 83 void initialize(uint32 version = currentVersion); 84 bool isValid() const; 85 void validate(CSSM_RETURN failureCode) const; 86 87 void *data() { return at(0); } 88 const void *data() const { return at(0); } 89}; 90 91 92// 93// A Database blob 94// 95class DbBlob : public CommonBlob { 96public: 97 struct Signature { 98 uint8 bytes[16]; 99 100 bool operator < (const Signature &sig) const 101 { return memcmp(bytes, sig.bytes, sizeof(bytes)) < 0; } 102 bool operator == (const Signature &sig) const 103 { return memcmp(bytes, sig.bytes, sizeof(bytes)) == 0; } 104 }; 105 106 struct PrivateBlob : public Blob { 107 typedef uint8 EncryptionKey[24]; 108 typedef uint8 SigningKey[20]; 109 110 EncryptionKey encryptionKey; // master encryption key 111 SigningKey signingKey; // master signing key 112 113 // private ACL blob follows, to the end 114 void *privateAclBlob() { return at(sizeof(PrivateBlob)); } 115 }; 116 117public: 118 // position separators between variable-length fields (see below) 119 uint32e startCryptoBlob; // end of public ACL; start of crypto blob 120 uint32e totalLength; // end of crypto blob; end of entire blob 121 122 Signature randomSignature; // randomizing database signature 123 uint32e sequence; // database sequence number 124 DBParameters params; // database settable parameters 125 126 uint8 salt[20]; // derivation salt 127 uint8 iv[8]; // encryption iv 128 129 uint8 blobSignature[20]; // HMAC/SHA1 of entire blob except itself 130 131 // variable length fields: 132 void *publicAclBlob() { return at(sizeof(DbBlob)); } 133 const void *publicAclBlob() const { return at(sizeof(DbBlob)); } 134 size_t publicAclBlobLength() const 135 { return startCryptoBlob - sizeof(DbBlob); } 136 137 void *cryptoBlob() { return at(startCryptoBlob); } 138 const void *cryptoBlob() const { return at(startCryptoBlob); } 139 size_t cryptoBlobLength() const { return totalLength - startCryptoBlob; } 140 141 uint32 length() const { return totalLength; } 142 143 DbBlob *copy(Allocator &alloc = Allocator::standard()) const 144 { 145 DbBlob *blob = alloc.malloc<DbBlob>(length()); 146 memcpy(blob, this, length()); 147 return blob; 148 } 149}; 150 151 152// 153// A key blob 154// 155class KeyBlob : public CommonBlob { 156public: 157 uint32e startCryptoBlob; // end of public ACL; start of crypto blob 158 uint32e totalLength; // end of crypto blob; end of entire blob 159 160 uint8 iv[8]; // encryption iv 161 162 CssmKey::Header header; // key header as-is 163 struct WrappedFields { 164 Endian<CSSM_KEYBLOB_TYPE> blobType; 165 Endian<CSSM_KEYBLOB_FORMAT> blobFormat; 166 Endian<CSSM_ALGORITHMS> wrapAlgorithm; 167 Endian<CSSM_ENCRYPT_MODE> wrapMode; 168 } wrappedHeader; 169 170 uint8 blobSignature[20]; // HMAC/SHA1 of entire blob except itself 171 172 // variable length fields: 173 void *publicAclBlob() { return at(sizeof(KeyBlob)); } 174 size_t publicAclBlobLength() const 175 { return startCryptoBlob - sizeof(KeyBlob); } 176 177 void *cryptoBlob() { return at(startCryptoBlob); } 178 size_t cryptoBlobLength() const { return totalLength - startCryptoBlob; } 179 180 uint32 length() const { return totalLength; } 181 182 // these bits are managed internally by the SecurityServer (and not passed to the CSPs) 183 static const uint32 managedAttributes = 184 CSSM_KEYATTR_ALWAYS_SENSITIVE | 185 CSSM_KEYATTR_NEVER_EXTRACTABLE | 186 CSSM_KEYATTR_PERMANENT | 187 CSSM_KEYATTR_SENSITIVE | 188 CSSM_KEYATTR_EXTRACTABLE; 189 static const uint32 forcedAttributes = 190 CSSM_KEYATTR_EXTRACTABLE; 191 192 /* 193 * Public Key blobs can be stored unencrypted. A unique blobSignature 194 * is used to indicate this state. 195 */ 196 bool isClearText(); 197 void setClearTextSignature(); 198 199public: 200 KeyBlob *copy(Allocator &alloc) const 201 { 202 KeyBlob *blob = alloc.malloc<KeyBlob>(length()); 203 memcpy(blob, this, length()); 204 return blob; 205 } 206}; 207 208 209// 210// An auto-unlock record (database identity plus raw unlock key) 211// 212class UnlockBlob : public CommonBlob { 213public: 214 typedef uint8 MasterKey[24]; 215 MasterKey masterKey; // raw bits (triple-DES) - make your own CssmKey 216 DbBlob::Signature signature; // signature is index 217}; 218 219 220} // end namespace SecurityServer 221} // end namespace Security 222 223 224#endif //_H_SSBLOB 225