AnCH Framework 0.1
Another C++ Hack Framework
 
Loading...
Searching...
No Matches
cbc.hpp
1/*
2 ANCH Framework: ANother C++ Hack is a C++ framework based on C++11 standard
3 Copyright (C) 2012 Vincent Lachenal
4
5 This file is part of ANCH Framework.
6
7 ANCH Framework is free software: you can redistribute it and/or modify
8 it under the terms of the GNU Lesser General Public License as published by
9 the Free Software Foundation, either version 3 of the License, or
10 (at your option) any later version.
11
12 ANCH Framework is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU Lesser General Public License for more details.
16
17 You should have received a copy of the GNU Lesser General Public License
18 along with ANCH Framework. If not, see <http://www.gnu.org/licenses/>.
19*/
20#pragma once
21
22#include "crypto/cipher/bcModOp.hpp"
23
24namespace anch {
25 namespace crypto {
26
36 template<typename Cipher, typename Padding>
37 class CBC: public BlockCipherModeOfOperation<CBC<Cipher,Padding>,Cipher> {
38
39 // Attributes +
40 private:
42 std::array<uint8_t,Cipher::getBlockSize()> _initVect;
43
45 std::array<uint8_t,Cipher::getBlockSize()> _ctxtVect;
46 // Attributes -
47
48
49 // Constructors +
50 public:
58 CBC(const std::array<uint8_t,Cipher::getBlockSize()>& initVect, unsigned int nbThread = 1);
59 // Constructors -
60
61
62 // Destructor +
66 virtual ~CBC();
67 // Destructor -
68
69
70 // Methods +
71 protected:
83 virtual std::size_t cipherBlock(std::array<uint8_t,Cipher::getBlockSize()>& input,
84 std::streamsize nbRead,
85 std::array<uint8_t,Cipher::getBlockSize()>& output,
86 uint32_t, Cipher& cipher) override;
87
101 virtual std::size_t decipherBlock(std::array<uint8_t,Cipher::getBlockSize()>& input,
102 std::array<uint8_t,Cipher::getBlockSize()>& prevInput,
103 std::streamsize nbRead,
104 bool lastBlock,
105 std::array<uint8_t,Cipher::getBlockSize()>& output,
106 uint32_t, Cipher& cipher) override;
107
113 virtual const std::array<uint8_t,Cipher::getBlockSize()>& reset();
114 // Methods -
115
116 };
117
118 // Constructors +
119 template<typename Cipher, typename Padding>
120 CBC<Cipher,Padding>::CBC(const std::array<uint8_t,Cipher::getBlockSize()>& initVect, unsigned int nbThread):
121 BlockCipherModeOfOperation<CBC<Cipher,Padding>,Cipher>(false, true, nbThread),
122 _initVect(initVect),
123 _ctxtVect() {
124 // Nothing to do
125 }
126 // Constructors -
127
128
129 // Destructor +
130 template<typename Cipher, typename Padding>
132 // Nothing to do
133 }
134 // Destructor -
135
136
137 // Methods +
138 template<typename Cipher, typename Padding>
139 std::size_t
140 CBC<Cipher,Padding>::cipherBlock(std::array<uint8_t,Cipher::getBlockSize()>& input,
141 std::streamsize nbRead,
142 std::array<uint8_t,Cipher::getBlockSize()>& output,
143 uint32_t, Cipher& cipher) {
144 if(static_cast<std::size_t>(nbRead) != Cipher::getBlockSize()) {
145 Padding::pad(input.data(), static_cast<std::size_t>(nbRead), Cipher::getBlockSize());
146 }
147 std::array<uint8_t,Cipher::getBlockSize()> data;
148 for(std::size_t i = 0 ; i < Cipher::getBlockSize() ; ++i) {
149 data[i] = input[i] ^ _ctxtVect[i];
150 }
151 cipher.cipher(data, output);
152 for(std::size_t i = 0 ; i < Cipher::getBlockSize() ; ++i) {
153 _ctxtVect[i] = output[i];
154 }
155 return Cipher::getBlockSize(); // This mode pad data => the number of bytes to write will always be a complete block
156 }
157
158 template<typename Cipher, typename Padding>
159 std::size_t
160 CBC<Cipher,Padding>::decipherBlock(std::array<uint8_t,Cipher::getBlockSize()>& input,
161 std::array<uint8_t,Cipher::getBlockSize()>& prevInput,
162 std::streamsize nbRead,
163 bool lastBlock,
164 std::array<uint8_t,Cipher::getBlockSize()>& output,
165 uint32_t, Cipher& cipher) {
166 if(lastBlock && static_cast<std::size_t>(nbRead) != Cipher::getBlockSize()) {
167 throw InvalidBlockException("Invalid block size");
168 }
169 std::array<uint8_t,Cipher::getBlockSize()> data;
170 cipher.decipher(input, data);
171 for(std::size_t i = 0 ; i < Cipher::getBlockSize() ; ++i) {
172 output[i] = data[i] ^ prevInput[i];
173 }
174 if(lastBlock) {
175 return Padding::length(output.data(), Cipher::getBlockSize());
176 } else {
177 return Cipher::getBlockSize();
178 }
179 }
180
181 template<typename Cipher, typename Padding>
182 const std::array<uint8_t,Cipher::getBlockSize()>&
184 _ctxtVect = _initVect;
185 return _initVect;
186 }
187 // Methods -
188
189 }
190}
BlockCipherModeOfOperation(bool cipherParallelizable, bool decipherParallelizable, unsigned int nbThread=1)
Definition bcModOp.hpp:269
void cipher(std::istream &input, std::ostream &output, const std::string &key)
Definition bcModOp.hpp:300
CBC(const std::array< uint8_t, Cipher::getBlockSize()> &initVect, unsigned int nbThread=1)
Definition cbc.hpp:120
virtual const std::array< uint8_t, Cipher::getBlockSize()> & reset()
Definition cbc.hpp:183
virtual std::size_t decipherBlock(std::array< uint8_t, Cipher::getBlockSize()> &input, std::array< uint8_t, Cipher::getBlockSize()> &prevInput, std::streamsize nbRead, bool lastBlock, std::array< uint8_t, Cipher::getBlockSize()> &output, uint32_t, Cipher &cipher) override
Definition cbc.hpp:160
virtual ~CBC()
Definition cbc.hpp:131
virtual std::size_t cipherBlock(std::array< uint8_t, Cipher::getBlockSize()> &input, std::streamsize nbRead, std::array< uint8_t, Cipher::getBlockSize()> &output, uint32_t, Cipher &cipher) override
Definition cbc.hpp:140
Exception on receiving an invalid block.
Definition invalidBlockException.hpp:38
Cryptography namespace.
Definition base64.hpp:28
AnCH framework base namespace.
Definition app.hpp:28