monotone

monotone Mtn Source Tree

Root/botan/cbc.cpp

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

Archive Download this file

Branches

Tags

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