X-Git-Url: https://git.saurik.com/apple/security.git/blobdiff_plain/e3d460c9de4426da6c630c3ae3f46173a99f82d8..b3971512e61ecab68b17ca7ffe6c8c600310a026:/securityd/src/dbcrypto.cpp diff --git a/securityd/src/dbcrypto.cpp b/securityd/src/dbcrypto.cpp index b009f003..4fed2f52 100644 --- a/securityd/src/dbcrypto.cpp +++ b/securityd/src/dbcrypto.cpp @@ -26,6 +26,8 @@ // dbcrypto - cryptographic core for database and key blob cryptography // #include "dbcrypto.h" +#include "SecRandom.h" +#include #include #include "server.h" // just for Server::csp() #include @@ -43,9 +45,14 @@ using LowLevelMemoryUtilities::fieldOffsetOf; // The CryptoCore constructor doesn't do anything interesting. // It just initializes us to "empty". // -DatabaseCryptoCore::DatabaseCryptoCore() : mBlobVersion(CommonBlob::version_MacOS_10_0), mHaveMaster(false), mIsValid(false) +DatabaseCryptoCore::DatabaseCryptoCore(uint32 requestedVersion) : mBlobVersion(CommonBlob::version_MacOS_10_0), mHaveMaster(false), mIsValid(false) { - mBlobVersion = CommonBlob::getCurrentVersion(); + // If there's a specific version our callers want, give them that. Otherwise, ask CommonBlob what to do. + if(requestedVersion == CommonBlob::version_none) { + mBlobVersion = CommonBlob::getCurrentVersion(); + } else { + mBlobVersion = requestedVersion; + } } DatabaseCryptoCore::~DatabaseCryptoCore() @@ -67,6 +74,31 @@ void DatabaseCryptoCore::invalidate() mIsValid = false; } +// +// Copy everything from another databasecryptocore +// +void DatabaseCryptoCore::initializeFrom(DatabaseCryptoCore& core, uint32 requestedVersion) { + if(core.hasMaster()) { + mMasterKey = core.mMasterKey; + memcpy(mSalt, core.mSalt, sizeof(mSalt)); + mHaveMaster = core.mHaveMaster; + } else { + mHaveMaster = false; + } + + if(core.isValid()) { + importSecrets(core); + } else { + mIsValid = false; + } + + // As the last thing we do, check if we should be changing the version of this blob. + if(requestedVersion == CommonBlob::version_none) { + mBlobVersion = core.mBlobVersion; + } else { + mBlobVersion = requestedVersion; + } +} // // Generate new secrets for this crypto core. @@ -109,8 +141,10 @@ void DatabaseCryptoCore::setup(const DbBlob *blob, const CssmData &passphrase, b mBlobVersion = blob->version(); } memcpy(mSalt, blob->salt, sizeof(mSalt)); - } else - Server::active().random(mSalt); + } else { + MacOSError::check(SecRandomCopyBytes(kSecRandomDefault, sizeof(mSalt), mSalt)); + } + mMasterKey = deriveDbMasterKey(passphrase); mHaveMaster = true; } @@ -136,8 +170,9 @@ void DatabaseCryptoCore::setup(const DbBlob *blob, CssmClient::Key master, bool mBlobVersion = blob->version(); } memcpy(mSalt, blob->salt, sizeof(mSalt)); - } else - Server::active().random(mSalt); + } else { + MacOSError::check(SecRandomCopyBytes(kSecRandomDefault, sizeof(mSalt), mSalt)); + } mMasterKey = master; mHaveMaster = true; } @@ -163,9 +198,12 @@ bool DatabaseCryptoCore::get_encryption_key(CssmOwnedData &data) // bool DatabaseCryptoCore::validatePassphrase(const CssmData &passphrase) { - assert(hasMaster()); CssmClient::Key master = deriveDbMasterKey(passphrase); - + return validateKey(master); +} + +bool DatabaseCryptoCore::validateKey(const CssmClient::Key& master) { + assert(hasMaster()); // to compare master with mMaster, see if they encrypt alike StringData probe ("Now is the time for all good processes to come to the aid of their kernel."); @@ -174,7 +212,8 @@ bool DatabaseCryptoCore::validatePassphrase(const CssmData &passphrase) cryptor.mode(CSSM_ALGMODE_CBCPadIV8); cryptor.padding(CSSM_PADDING_PKCS1); uint8 iv[8]; // leave uninitialized; pseudo-random is cool - cryptor.initVector(CssmData::wrap(iv)); + CssmData ivData = CssmData::wrap(iv); + cryptor.initVector(ivData); cryptor.key(master); CssmAutoData cipher1(Server::csp().allocator()); @@ -198,7 +237,7 @@ DbBlob *DatabaseCryptoCore::encodeCore(const DbBlob &blobTemplate, // make a new IV uint8 iv[8]; - Server::active().random(iv); + MacOSError::check(SecRandomCopyBytes(kSecRandomDefault, sizeof(iv), iv)); // build the encrypted section blob CssmData &encryptionBits = *mEncryptionKey; @@ -228,9 +267,9 @@ DbBlob *DatabaseCryptoCore::encodeCore(const DbBlob &blobTemplate, memcpy(blob->salt, mSalt, sizeof(blob->salt)); memcpy(blob->iv, iv, sizeof(iv)); memcpy(blob->publicAclBlob(), publicAcl, publicAcl.length()); - blob->startCryptoBlob = sizeof(DbBlob) + publicAcl.length(); + blob->startCryptoBlob = sizeof(DbBlob) + int_cast(publicAcl.length()); memcpy(blob->cryptoBlob(), cryptoBlob, cryptoBlob.length()); - blob->totalLength = blob->startCryptoBlob + cryptoBlob.length(); + blob->totalLength = blob->startCryptoBlob + int_cast(cryptoBlob.length()); // sign the blob CssmData signChunk[] = { @@ -300,7 +339,7 @@ void DatabaseCryptoCore::decodeCore(const DbBlob *blob, void **privateAclBlob) // all checks out; start extracting fields if (privateAclBlob) { // extract private ACL blob as a separately allocated area - uint32 blobLength = decryptedBlob.length() - sizeof(DbBlob::PrivateBlob); + uint32 blobLength = (uint32) decryptedBlob.length() - sizeof(DbBlob::PrivateBlob); *privateAclBlob = Allocator::standard().malloc(blobLength); memcpy(*privateAclBlob, privateBlob->privateAclBlob(), blobLength); } @@ -356,7 +395,7 @@ KeyBlob *DatabaseCryptoCore::encodeKeyCore(const CssmKey &inKey, assert(isValid()); // need our database secrets // create new IV - Server::active().random(iv); + MacOSError::check(SecRandomCopyBytes(kSecRandomDefault, sizeof(iv), iv)); // use a CMS wrap to encrypt the key WrapKey wrap(Server::csp(), CSSM_ALGID_3DES_3KEY_EDE); @@ -390,9 +429,9 @@ KeyBlob *DatabaseCryptoCore::encodeKeyCore(const CssmKey &inKey, blob->wrappedHeader.wrapAlgorithm = wrappedKey.wrapAlgorithm(); blob->wrappedHeader.wrapMode = wrappedKey.wrapMode(); memcpy(blob->publicAclBlob(), publicAcl, publicAcl.length()); - blob->startCryptoBlob = sizeof(KeyBlob) + publicAcl.length(); + blob->startCryptoBlob = sizeof(KeyBlob) + int_cast(publicAcl.length()); memcpy(blob->cryptoBlob(), wrappedKey.data(), wrappedKey.length()); - blob->totalLength = blob->startCryptoBlob + wrappedKey.length(); + blob->totalLength = blob->startCryptoBlob + int_cast(wrappedKey.length()); if(inTheClear) { /* indicate that this is cleartext for decoding */