X-Git-Url: https://git.saurik.com/apple/security.git/blobdiff_plain/80e2389990082500d76eb566d4946be3e786c3ef..d8f41ccd20de16f8ebe2ccc84d47bf1cb2b26bbb:/libsecurity_apple_csp/lib/BlockCryptor.cpp diff --git a/libsecurity_apple_csp/lib/BlockCryptor.cpp b/libsecurity_apple_csp/lib/BlockCryptor.cpp deleted file mode 100644 index 23ab8203..00000000 --- a/libsecurity_apple_csp/lib/BlockCryptor.cpp +++ /dev/null @@ -1,636 +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. - */ - - -/* - * BlockCryptor.cpp - common context for block-oriented encryption algorithms - * - * Created March 5 2001 by dmitch - */ - -#include "BlockCryptor.h" -#include "BinaryKey.h" -#include "AppleCSPSession.h" -#include -#include -#include -#include -#include - -#define BlockCryptDebug(args...) secdebug("blockCrypt", ## args) -#define bprintf(args...) secdebug("blockCryptBuf", ## args) -#define ioprintf(args...) secdebug("blockCryptIo", ## args) - -BlockCryptor::~BlockCryptor() -{ - if(mInBuf) { - memset(mInBuf, 0, mInBlockSize); - session().free(mInBuf); - mInBuf = NULL; - } - if(mChainBuf) { - memset(mChainBuf, 0, mInBlockSize); - session().free(mChainBuf); - mChainBuf = NULL; - } - mInBufSize = 0; -} - -/* - * Reusable setup functions called from subclass's init. - * This is the general purpose one.... - */ -void BlockCryptor::setup( - size_t blockSizeIn, // block size of input - size_t blockSizeOut, // block size of output - bool pkcsPad, // this class performs PKCS{5,7} padding - bool needsFinal, // needs final update with valid data - BC_Mode mode, // ECB, CBC - const CssmData *iv) // init vector, required for CBC - //Ê must be at least blockSizeIn bytes -{ - if(pkcsPad && needsFinal) { - BlockCryptDebug("BlockCryptor::setup pkcsPad && needsFinal"); - CssmError::throwMe(CSSMERR_CSP_INTERNAL_ERROR); - } - mPkcsPadding = pkcsPad; - mMode = mode; - mNeedFinalData = needsFinal; - - /* set up inBuf, all configurations */ - if(mInBuf != NULL) { - /* only reuse if same size */ - if(mInBlockSize != blockSizeIn) { - session().free(mInBuf); - mInBuf = NULL; - } - } - if(mInBuf == NULL) { - mInBuf = (uint8 *)session().malloc(blockSizeIn); - } - - /* set up chain buf, decrypt/CBC only; skip if algorithm does its own chaining */ - if((mMode == BCM_CBC) && !encoding() && !mCbcCapable) { - if(mChainBuf != NULL) { - /* only reuse if same size */ - if(mInBlockSize != blockSizeIn) { - session().free(mChainBuf); - mChainBuf = NULL; - } - } - if(mChainBuf == NULL) { - mChainBuf = (uint8 *)session().malloc(blockSizeIn); - } - } - - /* IV iff CBC mode, and ensure IV is big enough */ - switch(mMode) { - case BCM_ECB: - if(iv != NULL) { - CssmError::throwMe(CSSMERR_CSP_INVALID_ATTR_INIT_VECTOR); - } - break; - case BCM_CBC: - if(iv == NULL) { - CssmError::throwMe(CSSMERR_CSP_MISSING_ATTR_INIT_VECTOR); - } - if(blockSizeIn != blockSizeOut) { - /* no can do, must be same block sizes */ - CssmError::throwMe(CSSMERR_CSP_INVALID_ATTR_MODE); - } - if(iv->Length < blockSizeIn) { - /* not enough IV */ - CssmError::throwMe(CSSMERR_CSP_INVALID_ATTR_INIT_VECTOR); - } - /* save IV as appropriate */ - if(!mCbcCapable) { - if(encoding()) { - memmove(mInBuf, iv->Data, blockSizeIn); - } - else { - assert(mChainBuf != NULL); - memmove(mChainBuf, iv->Data, blockSizeIn); - } - } - break; - } - - mInBlockSize = blockSizeIn; - mInBufSize = 0; - mOutBlockSize = blockSizeOut; - mOpStarted = false; -} - -/* - * This one is used by simple, well-behaved algorithms which don't do their own - * padding and which rely on us to do everything but one-block-at-a-time - * encrypt and decrypt. - */ -void BlockCryptor::setup( - size_t blockSize, // block size of input and output - const Context &context) -{ - bool padEnable = false; - bool chainEnable = false; - bool ivEnable = false; - CssmData *iv = NULL; - - /* - * Validate context - * IV optional per mode - * pad optional per mode - * Currently we ignore extraneous attributes (e.g., it's OK to pass in - * an IV if the mode doesn't specify it), mainly for simplifying test routines. - */ - CSSM_ENCRYPT_MODE cssmMode = context.getInt(CSSM_ATTRIBUTE_MODE); - - switch (cssmMode) { - /* no mode attr --> 0 == CSSM_ALGMODE_NONE, not currently supported */ - case CSSM_ALGMODE_CBCPadIV8: - padEnable = true; - ivEnable = true; - chainEnable = true; - break; - - case CSSM_ALGMODE_CBC_IV8: - ivEnable = true; - chainEnable = true; - break; - - case CSSM_ALGMODE_ECB: - break; - - case CSSM_ALGMODE_ECBPad: - padEnable = true; - break; - - default: - errorLog1("DESContext::init: illegal mode (%d)\n", (int)cssmMode); - CssmError::throwMe(CSSMERR_CSP_INVALID_ATTR_MODE); - } - - if(padEnable) { - /* validate padding type */ - uint32 padding = context.getInt(CSSM_ATTRIBUTE_PADDING); // 0 ==> PADDING_NONE - if(blockSize == 8) { - switch(padding) { - /* backwards compatibility - used to be PKCS1, should be PKCS5 or 7 */ - case CSSM_PADDING_PKCS7: - case CSSM_PADDING_PKCS5: - case CSSM_PADDING_PKCS1: //Êthis goes away soon - /* OK */ - break; - default: - CssmError::throwMe(CSSMERR_CSP_INVALID_ATTR_PADDING); - } - } - else { - switch(padding) { - case CSSM_PADDING_PKCS5: // this goes away soon - case CSSM_PADDING_PKCS7: - /* OK */ - break; - default: - CssmError::throwMe(CSSMERR_CSP_INVALID_ATTR_PADDING); - } - } - } - if(ivEnable) { - /* make sure there's an IV in the context of sufficient length */ - iv = context.get(CSSM_ATTRIBUTE_INIT_VECTOR); - if(iv == NULL) { - CssmError::throwMe(CSSMERR_CSP_MISSING_ATTR_INIT_VECTOR); - } - if(iv->Length < blockSize) { - CssmError::throwMe(CSSMERR_CSP_INVALID_ATTR_INIT_VECTOR); - } - } - setup(blockSize, - blockSize, - padEnable, - false, // needsFinal - chainEnable ? BCM_CBC : BCM_ECB, - iv); -} - -/* - * Update always leaves some data in mInBuf if: - * mNeedsFinalData is true, or - * decrypting and mPkcsPadding true. - * Also, we always process all of the input (except on error). - */ -void BlockCryptor::update( - void *inp, - size_t &inSize, // in/out - void *outp, - size_t &outSize) // in/out -{ - uint8 *uInp = (UInt8 *)inp; - uint8 *uOutp = (UInt8 *)outp; - size_t uInSize = inSize; // input bytes to go - size_t uOutSize = 0; // ouput bytes generated - size_t uOutLeft = outSize; // bytes remaining in outp - size_t toMove; - size_t actMoved; - unsigned i; - bool needLeftOver = mNeedFinalData || (!encoding() && mPkcsPadding); - bool doCbc = (mMode == BCM_CBC) && !mCbcCapable; - - assert(mInBuf != NULL); - mOpStarted = true; - - if(mInBufSize) { - /* attempt to fill mInBuf from inp */ - toMove = mInBlockSize - mInBufSize; - if(toMove > uInSize) { - toMove = uInSize; - } - if(encoding() && doCbc) { - /* xor into last cipherblock or IV */ - for(i=0; i mInBuf */ - if(leftOver) { - if(encoding() && doCbc) { - /* xor into last cipherblock or IV */ - for(i=0; i mOutBlockSize) { - BlockCryptDebug("BlockCryptor::final malformed ciphertext (1)"); - CssmError::throwMe(CSSM_ERRCODE_INVALID_DATA); - } - uint8 *padPtr = ptext + mOutBlockSize - padSize; - for(unsigned i=0; i= 1); - inSize = (wholeBlocks * mInBlockSize) - mInBufSize; - if(inSize == 0) { - /* i.e., we're holding a whole buffer */ - inSize++; - } - } - bprintf("--- BlockCryptor::inputSize inSize 0x%lx outSize 0x%lx mInBufSize 0x%lx", - inSize, outSize, mInBufSize); - return inSize; -} - -size_t BlockCryptor::outputSize( - bool final, - size_t inSize /*= 0*/) // output for given input size -{ - size_t rawBytes = inSize + mInBufSize; - // huh?Êdon't round this up! - //size_t rawBlocks = (rawBytes + mInBlockSize - 1) / mInBlockSize; - size_t rawBlocks = rawBytes / mInBlockSize; - - /* - * encrypting: always get one additional block on final() if we're padding - * or (we presume) the subclass is padding. Note that we - * truncated when calculating rawBlocks; to finish out on the - * final block, we (or our subclass) will either have to pad - * out the current partial block, or cook up a full pad block if - * mInBufSize is currently zero. Subclasses which pad some other - * way need to override this method. - * - * decrypting: outsize always <= insize - */ - if(encoding() && final && (mPkcsPadding || mNeedFinalData)) { - rawBlocks++; - } - - /* FIXME - optimize for needFinalData? (can squeak by with smaller outSize) */ - size_t rtn = rawBlocks * mOutBlockSize; - bprintf("--- BlockCryptor::outputSize inSize 0x%lx outSize 0x%lx final %d " - "inBufSize 0x%lx", inSize, rtn, final, mInBufSize); - return rtn; -} - - -