]> git.saurik.com Git - apple/security.git/blobdiff - libsecurity_apple_csp/lib/BlockCryptor.h
Security-55163.44.tar.gz
[apple/security.git] / libsecurity_apple_csp / lib / BlockCryptor.h
diff --git a/libsecurity_apple_csp/lib/BlockCryptor.h b/libsecurity_apple_csp/lib/BlockCryptor.h
new file mode 100644 (file)
index 0000000..1f10179
--- /dev/null
@@ -0,0 +1,190 @@
+/*
+ * 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.h - common context for block-oriented encryption algorithms
+ *
+ * Created March 5 2001 by dmitch
+ */
+
+#ifndef        _BLOCK_CRYPTOR_H_
+#define _BLOCK_CRYPTOR_H_
+
+#include "AppleCSPContext.h"
+#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacTypes.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_ */