00001 /* modes.hpp 00002 * 00003 * Copyright (C) 2003 Sawtooth Consulting Ltd. 00004 * 00005 * This file is part of yaSSL. 00006 * 00007 * yaSSL is free software; you can redistribute it and/or modify 00008 * it under the terms of the GNU General Public License as published by 00009 * the Free Software Foundation; either version 2 of the License, or 00010 * (at your option) any later version. 00011 * 00012 * There are special exceptions to the terms and conditions of the GPL as it 00013 * is applied to yaSSL. View the full text of the exception in the file 00014 * FLOSS-EXCEPTIONS in the directory of this software distribution. 00015 * 00016 * yaSSL is distributed in the hope that it will be useful, 00017 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00018 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00019 * GNU General Public License for more details. 00020 * 00021 * You should have received a copy of the GNU General Public License 00022 * along with this program; if not, write to the Free Software 00023 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA 00024 */ 00025 00026 /* modes.hpp provides ECB and CBC modes for block cipher encryption/decryption 00027 */ 00028 00029 00030 #ifndef TAO_CRYPT_MODES_HPP 00031 #define TAO_CRYPT_MODES_HPP 00032 00033 #include "misc.hpp" 00034 00035 namespace TaoCrypt { 00036 00037 00038 enum Mode { ECB, CBC }; 00039 00040 00041 // BlockCipher abstraction 00042 template<CipherDir DIR, class T, Mode MODE> 00043 class BlockCipher { 00044 public: 00045 BlockCipher() : cipher_(DIR, MODE) {} 00046 00047 void Process(byte* c, const byte* p, word32 sz) 00048 { cipher_.Process(c, p, sz); } 00049 void SetKey(const byte* k, word32 sz) 00050 { cipher_.SetKey(k, sz, DIR); } 00051 void SetKey(const byte* k, word32 sz, const byte* iv) 00052 { cipher_.SetKey(k, sz, DIR); cipher_.SetIV(iv); } 00053 private: 00054 T cipher_; 00055 00056 BlockCipher(const BlockCipher&); // hide copy 00057 BlockCipher& operator=(const BlockCipher&); // and assign 00058 }; 00059 00060 00061 // Mode Base for block ciphers, static size 00062 class Mode_BASE : public virtual_base { 00063 public: 00064 enum { MaxBlockSz = 16 }; 00065 00066 explicit Mode_BASE(int sz) 00067 : blockSz_(sz), reg_(reinterpret_cast<byte*>(r_)), 00068 tmp_(reinterpret_cast<byte*>(t_)) 00069 { 00070 assert(sz <= MaxBlockSz); 00071 } 00072 virtual ~Mode_BASE() {} 00073 00074 void SetIV(const byte* iv) { memcpy(reg_, iv, blockSz_); } 00075 protected: 00076 int blockSz_; 00077 byte* reg_; 00078 byte* tmp_; 00079 00080 word32 r_[MaxBlockSz / sizeof(word32)]; // align reg_ on word32 00081 word32 t_[MaxBlockSz / sizeof(word32)]; // align tmp_ on word32 00082 00083 void ECB_Process(byte*, const byte*, word32); 00084 void CBC_Encrypt(byte*, const byte*, word32); 00085 void CBC_Decrypt(byte*, const byte*, word32); 00086 00087 Mode_BASE(const Mode_BASE&); // hide copy 00088 Mode_BASE& operator=(const Mode_BASE&); // and assign 00089 00090 private: 00091 virtual void ProcessAndXorBlock(const byte*, const byte*, byte*) const = 0; 00092 }; 00093 00094 00095 // ECB Process blocks 00096 inline void Mode_BASE::ECB_Process(byte* out, const byte* in, word32 sz) 00097 { 00098 word32 blocks = sz / blockSz_; 00099 00100 while (blocks--) { 00101 ProcessAndXorBlock(in, 0, out); 00102 out += blockSz_; 00103 in += blockSz_; 00104 } 00105 } 00106 00107 00108 // CBC Encrypt 00109 inline void Mode_BASE::CBC_Encrypt(byte* out, const byte* in, word32 sz) 00110 { 00111 word32 blocks = sz / blockSz_; 00112 00113 while (blocks--) { 00114 xorbuf(reg_, in, blockSz_); 00115 ProcessAndXorBlock(reg_, 0, reg_); 00116 memcpy(out, reg_, blockSz_); 00117 out += blockSz_; 00118 in += blockSz_; 00119 } 00120 } 00121 00122 00123 // CBC Decrypt 00124 inline void Mode_BASE::CBC_Decrypt(byte* out, const byte* in, word32 sz) 00125 { 00126 word32 blocks = sz / blockSz_; 00127 byte hold[MaxBlockSz]; 00128 00129 while (blocks--) { 00130 memcpy(tmp_, in, blockSz_); 00131 ProcessAndXorBlock(tmp_, 0, out); 00132 xorbuf(out, reg_, blockSz_); 00133 memcpy(hold, reg_, blockSz_); // swap reg_ and tmp_ 00134 memcpy(reg_, tmp_, blockSz_); 00135 memcpy(tmp_, hold, blockSz_); 00136 out += blockSz_; 00137 in += blockSz_; 00138 } 00139 } 00140 00141 00142 } // namespace 00143 00144 #endif // TAO_CRYPT_MODES_HPP
1.4.7

