X-Git-Url: https://git.saurik.com/apple/security.git/blobdiff_plain/80e2389990082500d76eb566d4946be3e786c3ef..d8f41ccd20de16f8ebe2ccc84d47bf1cb2b26bbb:/libsecurity_apple_csp/lib/wrapKeyCms.cpp diff --git a/libsecurity_apple_csp/lib/wrapKeyCms.cpp b/libsecurity_apple_csp/lib/wrapKeyCms.cpp deleted file mode 100644 index 75d64867..00000000 --- a/libsecurity_apple_csp/lib/wrapKeyCms.cpp +++ /dev/null @@ -1,468 +0,0 @@ -/* - * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved. - * - * The contents of this file constitute Original Code as defined in and are - * subject to the Apple Public Source License Version 1.2 (the 'License'). - * You may not use this file except in compliance with the License. Please obtain - * a copy of the License at http://www.apple.com/publicsource and read it before - * using this file. - * - * This 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, INCLUDING WITHOUT - * LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 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. - */ - - -// -// wrapKeyCms.cpp - wrap/unwrap key, CMS format -// - -#include "AppleCSPSession.h" -#include "AppleCSPUtils.h" -#include "AppleCSPKeys.h" -#include "cspdebugging.h" - -/* - * - * Here is the algorithm implemented in this module: - * - * Note that DEK is the wrapping key, - * - * 1. PRIVATE_KEY_BYTES is the private data to be wrapped. It consists of the - * following concatenation: - * - * 4-byte length of Descriptive Data, big-endian | - * Descriptive Data | - * rawBlob.Data bytes - * - * 2. Encrypt PRIVATE_KEY_BYTES using DEK (3DES) and IV in CBC mode with - * PKCS1 padding. Call the ciphertext TEMP1 - * - * 3. Let TEMP2 = IV || TEMP1. - * - * 4. Reverse the order of the octets in TEMP2 call the result TEMP3. - * - * 5. Encrypt TEMP3 using DEK with an IV of 0x4adda22c79e82105 in CBC mode - * with PKCS1 padding call the result TEMP4. - * - * TEMP4 is wrappedKey.KeyData. - */ - -/* true: cook up second CCHandle via a new HandleObject - * false - OK to reuse a CCHandle */ -#define USE_SECOND_CCHAND 0 - -/* false : make copy of incoming context before changing IV - * true : resuse OK */ -#define REUSE_CONTEXT 1 - -/* lots'o'printfs in lieu of a debugger which works */ -#define VERBOSE_DEBUG 0 - -static const uint8 magicCmsIv[] = - { 0x4a, 0xdd, 0xa2, 0x2c, 0x79, 0xe8, 0x21, 0x05 }; - -#if VERBOSE_DEBUG -static void dumpBuf( - char *title, - const CSSM_DATA *d, - uint32 maxLen) -{ - unsigned i; - uint32 len; - - if(title) { - printf("%s: ", title); - } - if(d == NULL) { - printf("NO DATA\n"); - return; - } - printf("Total Length: %d\n ", d->Length); - len = maxLen; - if(d->Length < len) { - len = d->Length; - } - for(i=0; iData[i]); - if((i % 16) == 15) { - printf("\n "); - } - } - printf("\n"); -} -#else -#define dumpBuf(t, d, m) -#endif /* VERBOSE_DEBUG */ - - -/* serialize/deserialize uint32, big-endian. */ -static void serializeUint32(uint32 i, uint8 *buf) -{ - *buf++ = (uint8)(i >> 24); - *buf++ = (uint8)(i >> 16); - *buf++ = (uint8)(i >> 8); - *buf = (uint8)i; -} - -static uint32 deserializeUint32(const uint8 *buf) { - uint32 result; - - result = ((uint32)buf[0] << 24) | - ((uint32)buf[1] << 16) | - ((uint32)buf[2] << 8) | - (uint32)buf[3]; - return result; -} - -void AppleCSPSession::WrapKeyCms( - CSSM_CC_HANDLE CCHandle, - const Context &context, - const AccessCredentials &AccessCred, - const CssmKey &UnwrappedKey, - CssmData &rawBlob, - bool allocdRawBlob, // callee has to free rawBlob - const CssmData *DescriptiveData, - CssmKey &WrappedKey, - CSSM_PRIVILEGE Privilege) -{ - uint32 ddLen; - CssmData PRIVATE_KEY_BYTES; - #if !REUSE_CONTEXT - Context secondCtx(context.ContextType, context.AlgorithmType); - secondCtx.copyFrom(context, privAllocator); - #endif /* REUSE_CONTEXT */ - - /* - * 1. PRIVATE_KEY_BYTES is the private data to be wrapped. It consists of the - * following concatenation: - * - * 4-byte length of Descriptive Data, big-endian | - * Descriptive Data | - * rawBlob.Data bytes - */ - dumpBuf("wrap rawBlob", &rawBlob, 24); - dumpBuf("wrap DescriptiveData", DescriptiveData, 24); - - if(DescriptiveData == NULL) { - ddLen = 0; - } - else { - ddLen = (uint32) DescriptiveData->Length; - } - size_t pkbLen = 4 + ddLen + rawBlob.Length; - setUpCssmData(PRIVATE_KEY_BYTES, pkbLen, privAllocator); - uint8 *cp = PRIVATE_KEY_BYTES.Data; - serializeUint32(ddLen, cp); - cp += 4; - if(ddLen != 0) { - memcpy(cp, DescriptiveData->Data, ddLen); - cp += ddLen; - } - memcpy(cp, rawBlob.Data, rawBlob.Length); - dumpBuf("wrap PRIVATE_KEY_BYTES", &PRIVATE_KEY_BYTES, 48); - - /* 2. Encrypt PRIVATE_KEY_BYTES using DEK (3DES) and IV in CBC mode with - * PKCS1 padding. Call the ciphertext TEMP1 - * - * We'll just use the caller's context for this. Maybe we should - * validate mode, padding, IV? - */ - CssmData TEMP1; - CSSM_SIZE bytesEncrypted; - CssmData remData; - EncryptData(CCHandle, - context, - &PRIVATE_KEY_BYTES, // ClearBufs[] - 1, // ClearBufCount - &TEMP1, // CipherBufs[], - 1, // CipherBufCount, - bytesEncrypted, - remData, - Privilege); - - // I'm not 100% sure about this.... - assert(remData.Length == 0); - TEMP1.Length = bytesEncrypted; - dumpBuf("wrap TEMP1", &TEMP1, 48); - - /* - * 3. Let TEMP2 = IV || TEMP1. - */ - CssmData TEMP2; - CssmData &IV = context.get(CSSM_ATTRIBUTE_INIT_VECTOR, - CSSMERR_CSP_MISSING_ATTR_INIT_VECTOR); - setUpCssmData(TEMP2, IV.Length + TEMP1.Length, privAllocator); - memcpy(TEMP2.Data, IV.Data, IV.Length); - memcpy(TEMP2.Data + IV.Length, TEMP1.Data, TEMP1.Length); - dumpBuf("wrap TEMP2", &TEMP2, 56); - - - /* - * 4. Reverse the order of the octets in TEMP2 call the result - * TEMP3. - */ - CssmData TEMP3; - setUpCssmData(TEMP3, TEMP2.Length, privAllocator); - uint8 *cp2 = TEMP2.Data + TEMP2.Length - 1; - cp = TEMP3.Data; - for(uint32 i=0; i - * actually is in the context and not a copy! - */ - #if REUSE_CONTEXT - CssmData &IV2 = context.get(CSSM_ATTRIBUTE_INIT_VECTOR, - CSSMERR_CSP_MISSING_ATTR_INIT_VECTOR); - #else - CssmData &IV2 = secondCtx.get(CSSM_ATTRIBUTE_INIT_VECTOR, - CSSMERR_CSP_MISSING_ATTR_INIT_VECTOR); - #endif /* REUSE_CONTEXT */ - - uint8 *savedIV = IV2.Data; - CSSM_SIZE savedIVLen = IV2.Length; - IV2.Data = (uint8 *)magicCmsIv; - IV2.Length = 8; - CssmData &outBlob = CssmData::overlay(WrappedKey.KeyData); - outBlob.Length = 0; - outBlob.Data = NULL; - try { - EncryptData(CCHandle, - #if REUSE_CONTEXT - context, - #else - secondCtx, - #endif /* REUSE_CONTEXT */ - - &TEMP3, // ClearBufs[] - 1, // ClearBufCount - &outBlob, // CipherBufs[], - 1, // CipherBufCount, - bytesEncrypted, - remData, - Privilege); - } - catch (...) { - IV2.Data = savedIV; - IV2.Length = savedIVLen; - throw; // and leak - } - IV2.Data = savedIV; - IV2.Length = savedIVLen; - - // I'm not 100% sure about this.... - assert(remData.Length == 0); - outBlob.Length = bytesEncrypted; - dumpBuf("wrap outBlob", &outBlob, 64); - - /* outgoing header */ - WrappedKey.KeyHeader.BlobType = CSSM_KEYBLOB_WRAPPED; - // OK to be zero or not present - WrappedKey.KeyHeader.WrapMode = context.getInt(CSSM_ATTRIBUTE_MODE); - WrappedKey.KeyHeader.Format = CSSM_KEYBLOB_WRAPPED_FORMAT_APPLE_CUSTOM; - - /* free resources */ - freeCssmData(PRIVATE_KEY_BYTES, privAllocator); - freeCssmData(TEMP1, normAllocator); // alloc via encrypt - freeCssmData(TEMP2, privAllocator); - freeCssmData(TEMP3, privAllocator); - if(allocdRawBlob) { - /* our caller mallocd this when dereferencing a ref key */ - freeCssmData(rawBlob, privAllocator); - } -} - -/* note we expect an IV present in the context though we don't use it - * FIXME - we should figure out how to add this attribute at this level - */ - -/* safety trap - don't try to malloc anything bigger than this - we get - * sizes from the processed bit stream.... */ -#define MAX_MALLOC_SIZE 0x10000 - -void AppleCSPSession::UnwrapKeyCms( - CSSM_CC_HANDLE CCHandle, - const Context &Context, - const CssmKey &WrappedKey, - const CSSM_RESOURCE_CONTROL_CONTEXT *CredAndAclEntry, - CssmKey &UnwrappedKey, - CssmData &DescriptiveData, - CSSM_PRIVILEGE Privilege, - cspKeyStorage keyStorage) -{ - /* - * In reverse order, the steps from wrap... - * - * 5. Encrypt TEMP3 using DEK with an IV of 0x4adda22c79e82105 in CBC mode - * with PKCS1 padding call the result TEMP4. - * - * TEMP4 is wrappedKey.KeyData. - */ - const CssmData &wrappedBlob = CssmData::overlay(WrappedKey.KeyData); - dumpBuf("unwrap inBlob", &wrappedBlob, 64); - CssmData &IV1 = Context.get(CSSM_ATTRIBUTE_INIT_VECTOR, - CSSMERR_CSP_MISSING_ATTR_INIT_VECTOR); - uint8 *savedIV = IV1.Data; - CSSM_SIZE savedIvLen = IV1.Length; - IV1.Data = (uint8 *)magicCmsIv; - IV1.Length = 8; - CssmData TEMP3; - CSSM_SIZE bytesDecrypted; - CssmData remData; - - try { - DecryptData(CCHandle, - Context, - &wrappedBlob, // CipherBufs[], - 1, // CipherBufCount, - &TEMP3, // ClearBufs[] - 1, // ClearBufCount - bytesDecrypted, - remData, - Privilege); - } - catch(...) { - IV1.Data = savedIV; - IV1.Length = savedIvLen; - throw; - } - IV1.Data = savedIV; - IV1.Length = savedIvLen; - // I'm not 100% sure about this.... - assert(remData.Length == 0); - TEMP3.Length = bytesDecrypted; - dumpBuf("unwrap TEMP3", &TEMP3, 64); - - /* - * 4. Reverse the order of the octets in TEMP2 call the result - * TEMP3. - * - * i.e., TEMP2 := reverse(TEMP3) - */ - CssmData TEMP2; - setUpCssmData(TEMP2, TEMP3.Length, privAllocator); - uint8 *src = TEMP3.Data + TEMP3.Length - 1; - uint8 *dst = TEMP2.Data; - for(uint32 i=0; i MAX_MALLOC_SIZE) { - dprintf0("UnwrapKeyCms: preposterous ddLen in PRIVATE_KEY_BYTES\n"); - CssmError::throwMe(CSSMERR_CSP_INVALID_KEY); - } - setUpCssmData(DescriptiveData, ddLen, normAllocator); - memcpy(DescriptiveData.Data, cp1, ddLen); - cp1 += ddLen; - size_t outBlobLen = PRIVATE_KEY_BYTES.Length - ddLen - 4; - if(ddLen > MAX_MALLOC_SIZE) { - dprintf0("UnwrapKeyCms: preposterous outBlobLen in PRIVATE_KEY_BYTES\n"); - CssmError::throwMe(CSSMERR_CSP_INVALID_KEY); - } - CssmData &outBlob = CssmData::overlay(UnwrappedKey.KeyData); - setUpCssmData(outBlob, outBlobLen, normAllocator); - memcpy(outBlob.Data, cp1, outBlobLen); - - /* set up outgoing header */ - UnwrappedKey.KeyHeader.BlobType = CSSM_KEYBLOB_RAW; - UnwrappedKey.KeyHeader.Format = inferFormat(UnwrappedKey); - - /* - * Cook up a BinaryKey if caller wants a reference key. - */ - if(keyStorage == CKS_Ref) { - BinaryKey *binKey = NULL; - CSPKeyInfoProvider *provider = infoProvider(UnwrappedKey); - /* optional parameter-bearing key */ - CssmKey *paramKey = Context.get(CSSM_ATTRIBUTE_PARAM_KEY); - provider->CssmKeyToBinary(paramKey, UnwrappedKey.KeyHeader.KeyAttr, &binKey); - addRefKey(*binKey, UnwrappedKey); - delete provider; - } - /* free resources */ - freeCssmData(PRIVATE_KEY_BYTES, normAllocator); // alloc via decrypt - freeCssmData(TEMP1, privAllocator); - freeCssmData(IV2, privAllocator); - freeCssmData(TEMP2, privAllocator); - freeCssmData(TEMP3, normAllocator); // via decrypt - -} -