00001
00002
00003
00004
00005
00006
00007
00008 #include <botan/ecb.h>
00009
00010 namespace Botan {
00011
00012
00013
00014
00015 ECB_Encryption::ECB_Encryption(BlockCipher* ciph,
00016 BlockCipherModePaddingMethod* pad) :
00017 Buffered_Filter(ciph->parallel_bytes(), 0)
00018 {
00019 cipher = ciph;
00020 padder = pad;
00021
00022 temp.resize(buffered_block_size());
00023 }
00024
00025
00026
00027
00028 ECB_Encryption::ECB_Encryption(BlockCipher* ciph,
00029 BlockCipherModePaddingMethod* pad,
00030 const SymmetricKey& key) :
00031 Buffered_Filter(ciph->parallel_bytes(), 0)
00032 {
00033 cipher = ciph;
00034 padder = pad;
00035
00036 temp.resize(buffered_block_size());
00037
00038 cipher->set_key(key);
00039 }
00040
00041
00042
00043
00044 ECB_Encryption::~ECB_Encryption()
00045 {
00046 delete cipher;
00047 delete padder;
00048 }
00049
00050
00051
00052
00053 std::string ECB_Encryption::name() const
00054 {
00055 return (cipher->name() + "/ECB/" + padder->name());
00056 }
00057
00058
00059
00060
00061 void ECB_Encryption::write(const byte input[], u32bit length)
00062 {
00063 Buffered_Filter::write(input, length);
00064 }
00065
00066
00067
00068
00069 void ECB_Encryption::end_msg()
00070 {
00071 u32bit last_block = current_position() % cipher->BLOCK_SIZE;
00072
00073 SecureVector<byte> padding(cipher->BLOCK_SIZE);
00074 padder->pad(padding, padding.size(), last_block);
00075
00076 u32bit pad_bytes = padder->pad_bytes(cipher->BLOCK_SIZE, last_block);
00077
00078 if(pad_bytes)
00079 Buffered_Filter::write(padding, pad_bytes);
00080 Buffered_Filter::end_msg();
00081 }
00082
00083 void ECB_Encryption::buffered_block(const byte input[], u32bit input_length)
00084 {
00085 const u32bit blocks_in_temp = temp.size() / cipher->BLOCK_SIZE;
00086 u32bit blocks = input_length / cipher->BLOCK_SIZE;
00087
00088 while(blocks)
00089 {
00090 u32bit to_proc = std::min<u32bit>(blocks, blocks_in_temp);
00091
00092 cipher->encrypt_n(input, &temp[0], to_proc);
00093
00094 send(temp, to_proc * cipher->BLOCK_SIZE);
00095
00096 input += to_proc * cipher->BLOCK_SIZE;
00097 blocks -= to_proc;
00098 }
00099 }
00100
00101 void ECB_Encryption::buffered_final(const byte input[], u32bit input_length)
00102 {
00103 if(input_length % cipher->BLOCK_SIZE == 0)
00104 buffered_block(input, input_length);
00105 else if(input_length != 0)
00106 throw Encoding_Error(name() + ": Did not pad to full blocksize");
00107 }
00108
00109
00110
00111
00112 ECB_Decryption::ECB_Decryption(BlockCipher* ciph,
00113 BlockCipherModePaddingMethod* pad) :
00114 Buffered_Filter(ciph->parallel_bytes(), 1)
00115 {
00116 cipher = ciph;
00117 padder = pad;
00118
00119 temp.resize(buffered_block_size());
00120 }
00121
00122
00123
00124
00125 ECB_Decryption::ECB_Decryption(BlockCipher* ciph,
00126 BlockCipherModePaddingMethod* pad,
00127 const SymmetricKey& key) :
00128 Buffered_Filter(ciph->parallel_bytes(), 1)
00129 {
00130 cipher = ciph;
00131 padder = pad;
00132
00133 temp.resize(buffered_block_size());
00134
00135 cipher->set_key(key);
00136 }
00137
00138
00139
00140
00141 ECB_Decryption::~ECB_Decryption()
00142 {
00143 delete cipher;
00144 delete padder;
00145 }
00146
00147
00148
00149
00150 std::string ECB_Decryption::name() const
00151 {
00152 return (cipher->name() + "/ECB/" + padder->name());
00153 }
00154
00155
00156
00157
00158 void ECB_Decryption::write(const byte input[], u32bit length)
00159 {
00160 Buffered_Filter::write(input, length);
00161 }
00162
00163
00164
00165
00166 void ECB_Decryption::end_msg()
00167 {
00168 Buffered_Filter::end_msg();
00169 }
00170
00171
00172
00173
00174 void ECB_Decryption::buffered_block(const byte input[], u32bit length)
00175 {
00176 const u32bit blocks_in_temp = temp.size() / cipher->BLOCK_SIZE;
00177 u32bit blocks = length / cipher->BLOCK_SIZE;
00178
00179 while(blocks)
00180 {
00181 u32bit to_proc = std::min<u32bit>(blocks, blocks_in_temp);
00182
00183 cipher->decrypt_n(input, &temp[0], to_proc);
00184
00185 send(temp, to_proc * cipher->BLOCK_SIZE);
00186
00187 input += to_proc * cipher->BLOCK_SIZE;
00188 blocks -= to_proc;
00189 }
00190 }
00191
00192
00193
00194
00195 void ECB_Decryption::buffered_final(const byte input[], u32bit length)
00196 {
00197 if(length == 0 || length % cipher->BLOCK_SIZE != 0)
00198 throw Decoding_Error(name() + ": Ciphertext not multiple of block size");
00199
00200 size_t extra_blocks = (length - 1) / cipher->BLOCK_SIZE;
00201
00202 buffered_block(input, extra_blocks * cipher->BLOCK_SIZE);
00203
00204 input += extra_blocks * cipher->BLOCK_SIZE;
00205
00206 cipher->decrypt(input, temp);
00207 send(temp, padder->unpad(temp, cipher->BLOCK_SIZE));
00208 }
00209
00210 }