X-Git-Url: https://git.saurik.com/apple/security.git/blobdiff_plain/80e2389990082500d76eb566d4946be3e786c3ef..d8f41ccd20de16f8ebe2ccc84d47bf1cb2b26bbb:/Security/libsecurity_apple_csp/lib/BlockCryptor.h diff --git a/Security/libsecurity_apple_csp/lib/BlockCryptor.h b/Security/libsecurity_apple_csp/lib/BlockCryptor.h new file mode 100644 index 00000000..4e933186 --- /dev/null +++ b/Security/libsecurity_apple_csp/lib/BlockCryptor.h @@ -0,0 +1,188 @@ +/* + * Copyright (c) 2000-2001,2011,2013-2014 Apple 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.h - common context for block-oriented encryption algorithms + * + */ + +#ifndef _BLOCK_CRYPTOR_H_ +#define _BLOCK_CRYPTOR_H_ + +#include "AppleCSPContext.h" + +/* + * Base class for AppleCSPContexts associated with BlockCryptObjects. + * The main purpose of this class is to abstract out the very common work + * of buffering incoming data (per CSSM-style update, ..., final) and + * doing single-block ops on the underlying encrypt/decrypt algorithm + * objects. Standard PKSC5 padding is handled here. All other chaining, + * padding, IV, et al, logic is handled by subclasses. + */ +class BlockCryptor : public AppleCSPContext +{ +public: + BlockCryptor( + AppleCSPSession &session) : + AppleCSPContext(session), + mOpStarted(false), + mCbcCapable(false), + mMultiBlockCapable(false), + mInBuf(NULL), + mChainBuf(NULL) { } + virtual ~BlockCryptor(); + + /* + * Note standard init(const Context &context, bool encoding) is totally + * subclass-specific. + * + * These are implemented here using the subclass's {en,de}cryptBlock functions. + * Note PKCS5 padding is implemented here if mPkcs5Padding is true. PKCS5 + * padding can only be accomplished if the result of decrypting + * cipherBlockSize() bytes of ciphertext yields exactly plainBlockSize() + * bytes of plaintext. (Sound odd? FEED does not meet that restriction...) + */ + void update( + void *inp, + size_t &inSize, // in/out + void *outp, + size_t &outSize); // in/out + + void final( + CssmData &out); + + /* + * Our implementation of these three query functions are only valid + * for algorithms for which encrypting one block of plaintext always + * yields exactly one block of ciphertext, and vice versa for decrypt. + * The block sizes for plaintext and ciphertext do NOT have to be the same. + * Subclasses (e.g. FEED) which do not meet this criterion will have to override. + */ + virtual size_t inputSize( + size_t outSize); // input for given output size + virtual size_t outputSize( + bool final = false, + size_t inSize = 0); // output for given input size + virtual void minimumProgress( + size_t &in, + size_t &out); // minimum progress chunks + +protected: + typedef enum { + BCM_ECB, // no chaining + BCM_CBC // requires inBlockSize == outBlockSize + } BC_Mode; + + /* accessors (see comments below re: the member variables) */ + bool pkcs5Padding() { return mPkcsPadding; } + bool needFinalData() { return mNeedFinalData; } + void *inBuf() { return mInBuf; } + size_t inBufSize() { return mInBufSize; } + void *chainBuf() { return mChainBuf; } + size_t inBlockSize() { return mInBlockSize; } + size_t outBlockSize() { return mOutBlockSize; } + BC_Mode mode() { return mMode; } + bool opStarted() { return mOpStarted; } + bool cbcCapable() { return mCbcCapable; } + void cbcCapable(bool c) { mCbcCapable = c; } + bool multiBlockCapable() { return mMultiBlockCapable; } + void multiBlockCapable(bool c) { mMultiBlockCapable = c; } + + /* + * Reusable setup functions called from subclass's init. + * This is the general purpose one.... + */ + void setup( + size_t blockSizeIn, // block size of input in bytes + size_t blockSizeOut, // block size of output in bytes + 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 + + /* + * 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 setup( + size_t blockSize, // block size of input and output + const Context &context); + + /*** + *** Routines to be implemented by subclass. + ***/ + + /* + virtual void init(const Context &context, bool encoding = true); + */ + + /* + * encrypt/decrypt exactly one block. Output buffers mallocd by caller. + * On encrypt, it may be acceptable for plainTextLen to be less than + * one plainBlockSize() if: + * -- final is true, and + * -- the subclass permits this. That is generally only true + * when the subclass implements some padding other than our + * standard PKCS5. + * + * The subclass throws CSSMERR_CSP_INPUT_LENGTH_ERROR if the above + * conditions are not met. + */ + virtual void encryptBlock( + const void *plainText, // length implied (one block) + size_t plainTextLen, + void *cipherText, + size_t &cipherTextLen, // in/out, subclass throws on overflow + bool final) = 0; + + /* + * Decrypt one block. Incoming cipherText length is ALWAYS cipherBlockSize(). + */ + virtual void decryptBlock( + const void *cipherText, // length implied (one cipher block) + size_t cipherTextLen, + void *plainText, + size_t &plainTextLen, // in/out, subclass throws on overflow + bool final) = 0; + +private: + bool mOpStarted; // for optional use by subclasses when + // resuing context after encrypt/decrypt + // ops occur + bool mCbcCapable; // when true, algorithm can do its own CBC + bool mMultiBlockCapable; // when true, algorithm can do multi-block ops + + /* these are all init'd via setup(), called from subclass-specific init */ + bool mPkcsPadding; // PKCS{5,7} padding enabled + bool mNeedFinalData; // subclass needs an update(final) with + // valid data; if true we always keep + // some data in mInBuf after an update. + // Mutually exclusive with mPkcsPadding. + uint8 *mInBuf; // for buffering input + size_t mInBufSize; // valid bytes in mInBuf + uint8 *mChainBuf; // for CBC, decrypting only + size_t mInBlockSize; // block size of input in bytes; also + // mallocd size of mInBuf + size_t mOutBlockSize; // block size of output in bytes + BC_Mode mMode; // ECB, CBC + +}; + +#endif /* _BLOCK_CRYPTOR_H_ */