monotone

monotone Mtn Source Tree

Root/botan/cbc.cpp

1/*************************************************
2* CBC Mode Source File *
3* (C) 1999-2006 The Botan Project *
4*************************************************/
5
6#include <botan/cbc.h>
7#include <botan/lookup.h>
8#include <botan/bit_ops.h>
9#include <algorithm>
10
11namespace Botan {
12
13/*************************************************
14* CBC Encryption Constructor *
15*************************************************/
16CBC_Encryption::CBC_Encryption(const std::string& cipher_name,
17 const std::string& padding_name) :
18 BlockCipherMode(cipher_name, "CBC", block_size_of(cipher_name)),
19 padder(get_bc_pad(padding_name))
20 {
21 if(!padder->valid_blocksize(BLOCK_SIZE))
22 throw Invalid_Block_Size(name(), padder->name());
23 }
24
25/*************************************************
26* CBC Encryption Constructor *
27*************************************************/
28CBC_Encryption::CBC_Encryption(const std::string& cipher_name,
29 const std::string& padding_name,
30 const SymmetricKey& key,
31 const InitializationVector& iv) :
32 BlockCipherMode(cipher_name, "CBC", block_size_of(cipher_name)),
33 padder(get_bc_pad(padding_name))
34 {
35 if(!padder->valid_blocksize(BLOCK_SIZE))
36 throw Invalid_Block_Size(name(), padder->name());
37 set_key(key);
38 set_iv(iv);
39 }
40
41/*************************************************
42* Encrypt in CBC mode *
43*************************************************/
44void CBC_Encryption::write(const byte input[], u32bit length)
45 {
46 while(length)
47 {
48 u32bit xored = std::min(BLOCK_SIZE - position, length);
49 xor_buf(state + position, input, xored);
50 input += xored;
51 length -= xored;
52 position += xored;
53 if(position == BLOCK_SIZE)
54 {
55 cipher->encrypt(state);
56 send(state, BLOCK_SIZE);
57 position = 0;
58 }
59 }
60 }
61
62/*************************************************
63* Finish encrypting in CBC mode *
64*************************************************/
65void CBC_Encryption::end_msg()
66 {
67 SecureVector<byte> padding(BLOCK_SIZE);
68 padder->pad(padding, padding.size(), position);
69 write(padding, padder->pad_bytes(BLOCK_SIZE, position));
70 if(position != 0)
71 throw Exception(name() + ": Did not pad to full blocksize");
72 }
73
74/*************************************************
75* Return a CBC mode name *
76*************************************************/
77std::string CBC_Encryption::name() const
78 {
79 return (cipher->name() + "/" + mode_name + "/" + padder->name());
80 }
81
82/*************************************************
83* CBC Decryption Constructor *
84*************************************************/
85CBC_Decryption::CBC_Decryption(const std::string& cipher_name,
86 const std::string& padding_name) :
87 BlockCipherMode(cipher_name, "CBC", block_size_of(cipher_name)),
88 padder(get_bc_pad(padding_name))
89 {
90 if(!padder->valid_blocksize(BLOCK_SIZE))
91 throw Invalid_Block_Size(name(), padder->name());
92 temp.create(BLOCK_SIZE);
93 }
94
95/*************************************************
96* CBC Decryption Constructor *
97*************************************************/
98CBC_Decryption::CBC_Decryption(const std::string& cipher_name,
99 const std::string& padding_name,
100 const SymmetricKey& key,
101 const InitializationVector& iv) :
102 BlockCipherMode(cipher_name, "CBC", block_size_of(cipher_name)),
103 padder(get_bc_pad(padding_name))
104 {
105 if(!padder->valid_blocksize(BLOCK_SIZE))
106 throw Invalid_Block_Size(name(), padder->name());
107 temp.create(BLOCK_SIZE);
108 set_key(key);
109 set_iv(iv);
110 }
111
112/*************************************************
113* Decrypt in CBC mode *
114*************************************************/
115void CBC_Decryption::write(const byte input[], u32bit length)
116 {
117 while(length)
118 {
119 if(position == BLOCK_SIZE)
120 {
121 cipher->decrypt(buffer, temp);
122 xor_buf(temp, state, BLOCK_SIZE);
123 send(temp, BLOCK_SIZE);
124 state = buffer;
125 position = 0;
126 }
127 u32bit added = std::min(BLOCK_SIZE - position, length);
128 buffer.copy(position, input, added);
129 input += added;
130 length -= added;
131 position += added;
132 }
133 }
134
135/*************************************************
136* Finish decrypting in CBC mode *
137*************************************************/
138void CBC_Decryption::end_msg()
139 {
140 if(position != BLOCK_SIZE)
141 throw Decoding_Error(name());
142 cipher->decrypt(buffer, temp);
143 xor_buf(temp, state, BLOCK_SIZE);
144 send(temp, padder->unpad(temp, BLOCK_SIZE));
145 state = buffer;
146 position = 0;
147 }
148
149/*************************************************
150* Return a CBC mode name *
151*************************************************/
152std::string CBC_Decryption::name() const
153 {
154 return (cipher->name() + "/" + mode_name + "/" + padder->name());
155 }
156
157}

Archive Download this file

Branches

Tags

Quick Links:     www.monotone.ca    -     Downloads    -     Documentation    -     Wiki    -     Code Forge    -     Build Status