AnCH Framework 0.1
Another C++ Hack Framework
 
Loading...
Searching...
No Matches
pcbc.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
24#include <array>
25
26
27namespace anch {
28 namespace crypto {
29
39 template<typename Cipher, typename Padding>
40 class PCBC: public BlockCipherModeOfOperation<PCBC<Cipher,Padding>,Cipher> {
41
42 // Attributes +
43 private:
45 std::array<uint8_t,Cipher::getBlockSize()> _initVect;
46
48 std::array<uint8_t,Cipher::getBlockSize()> _ctxtVect;
49 // Attributes -
50
51
52 // Constructors +
53 public:
61 PCBC(const std::array<uint8_t,Cipher::getBlockSize()>& initVect, unsigned int nbThread = 1);
62 // Constructors -
63
64
65 // Destructor +
69 virtual ~PCBC();
70 // Destructor -
71
72
73 // Methods +
74 protected:
86 virtual std::size_t cipherBlock(std::array<uint8_t,Cipher::getBlockSize()>& input,
87 std::streamsize nbRead,
88 std::array<uint8_t,Cipher::getBlockSize()>& output,
89 uint32_t, Cipher& cipher) override;
90
103 virtual std::size_t decipherBlock(std::array<uint8_t,Cipher::getBlockSize()>& input,
104 std::array<uint8_t,Cipher::getBlockSize()>&,
105 std::streamsize nbRead,
106 bool lastBlock,
107 std::array<uint8_t,Cipher::getBlockSize()>& output,
108 uint32_t, Cipher& cipher) override;
109
115 virtual const std::array<uint8_t,Cipher::getBlockSize()>& reset();
116 // Methods -
117
118 };
119
120 // Constructors +
121 template<typename Cipher, typename Padding>
122 PCBC<Cipher,Padding>::PCBC(const std::array<uint8_t,Cipher::getBlockSize()>& initVect, unsigned int nbThread):
123 BlockCipherModeOfOperation<PCBC<Cipher,Padding>,Cipher>(false, false, nbThread),
124 _initVect(initVect),
125 _ctxtVect() {
126 // Nothing to do
127 }
128 // Constructors -
129
130
131 // Destructor +
132 template<typename Cipher, typename Padding>
134 // Nothing to do
135 }
136 // Destructor -
137
138
139 // Methods +
140 template<typename Cipher, typename Padding>
141 std::size_t
142 PCBC<Cipher,Padding>::cipherBlock(std::array<uint8_t,Cipher::getBlockSize()>& input,
143 std::streamsize nbRead,
144 std::array<uint8_t,Cipher::getBlockSize()>& output,
145 uint32_t, Cipher& cipher) {
146 if(static_cast<std::size_t>(nbRead) != Cipher::getBlockSize()) {
147 Padding::pad(input.data(), static_cast<std::size_t>(nbRead), Cipher::getBlockSize());
148 }
149 std::array<uint8_t,Cipher::getBlockSize()> data;
150 for(std::size_t i = 0 ; i < Cipher::getBlockSize() ; ++i) {
151 data[i] = input[i] ^ _ctxtVect[i];
152 }
153 cipher.cipher(data, output);
154 for(std::size_t i = 0 ; i < Cipher::getBlockSize() ; ++i) {
155 _ctxtVect[i] = input[i] ^ output[i];
156 }
157 return Cipher::getBlockSize(); // This mode pad data => the number of bytes to write will always be a complete block
158 }
159
160 template<typename Cipher, typename Padding>
161 std::size_t
162 PCBC<Cipher,Padding>::decipherBlock(std::array<uint8_t,Cipher::getBlockSize()>& input,
163 std::array<uint8_t,Cipher::getBlockSize()>&,
164 std::streamsize nbRead,
165 bool lastBlock,
166 std::array<uint8_t,Cipher::getBlockSize()>& output,
167 uint32_t, Cipher& cipher) {
168 if(lastBlock && static_cast<std::size_t>(nbRead) != Cipher::getBlockSize()) {
169 throw InvalidBlockException("Invalid block size");
170 }
171 std::array<uint8_t,Cipher::getBlockSize()> data;
172 cipher.decipher(input, data);
173 for(std::size_t i = 0 ; i < Cipher::getBlockSize() ; ++i) {
174 output[i] = data[i] ^ _ctxtVect[i];
175 _ctxtVect[i] = input[i] ^ output[i];
176 }
177 if(lastBlock) {
178 return Padding::length(output.data(), Cipher::getBlockSize());
179 } else {
180 return Cipher::getBlockSize();
181 }
182 }
183
184 template<typename Cipher, typename Padding>
185 const std::array<uint8_t,Cipher::getBlockSize()>&
187 _ctxtVect = _initVect;
188 return _initVect;
189 }
190 // Methods -
191
192 }
193}
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
Exception on receiving an invalid block.
Definition invalidBlockException.hpp:38
virtual ~PCBC()
Definition pcbc.hpp:133
virtual const std::array< uint8_t, Cipher::getBlockSize()> & reset()
Definition pcbc.hpp:186
virtual std::size_t decipherBlock(std::array< uint8_t, Cipher::getBlockSize()> &input, std::array< uint8_t, Cipher::getBlockSize()> &, std::streamsize nbRead, bool lastBlock, std::array< uint8_t, Cipher::getBlockSize()> &output, uint32_t, Cipher &cipher) override
Definition pcbc.hpp:162
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 pcbc.hpp:142
PCBC(const std::array< uint8_t, Cipher::getBlockSize()> &initVect, unsigned int nbThread=1)
Definition pcbc.hpp:122
Cryptography namespace.
Definition base64.hpp:28
AnCH framework base namespace.
Definition app.hpp:28