AnCH Framework  0.1
Another C++ Hack Framework
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 #ifndef _ANCH_CRYPTO_PCBC_H_
21 #define _ANCH_CRYPTO_PCBC_H_
22 
23 #include "crypto/cipher/bcModOp.hpp"
24 
25 #include <array>
26 
27 
28 namespace anch {
29  namespace crypto {
30 
40  template<typename Cipher, typename Padding>
41  class PCBC: public BlockCipherModeOfOperation<PCBC<Cipher,Padding>,Cipher> {
42 
43  // Attributes +
44  private:
46  std::array<uint8_t,Cipher::getBlockSize()> _initVect;
47 
49  std::array<uint8_t,Cipher::getBlockSize()> _ctxtVect;
50  // Attributes -
51 
52 
53  // Constructors +
54  public:
62  PCBC(const std::array<uint8_t,Cipher::getBlockSize()>& initVect, unsigned int nbThread = 1):
63  BlockCipherModeOfOperation<PCBC<Cipher,Padding>,Cipher>(false, false, nbThread),
64  _initVect(initVect),
65  _ctxtVect() {
66  // Nothing to do
67  }
68  // Constructors -
69 
70 
71  // Destructor +
75  virtual ~PCBC() {
76  // Nothing to do
77  }
78  // Destructor -
79 
80 
81  // Methods +
82  protected:
94  virtual std::size_t cipherBlock(std::array<uint8_t,Cipher::getBlockSize()>& input,
95  std::streamsize nbRead,
96  std::array<uint8_t,Cipher::getBlockSize()>& output,
97  uint32_t, Cipher& cipher) override {
98  if(static_cast<std::size_t>(nbRead) != Cipher::getBlockSize()) {
99  Padding::pad(input.data(), nbRead, Cipher::getBlockSize());
100  }
101  std::array<uint8_t,Cipher::getBlockSize()> data;
102  for(std::size_t i = 0 ; i < Cipher::getBlockSize() ; ++i) {
103  data[i] = input[i] ^ _ctxtVect[i];
104  }
105  cipher.cipher(data, output);
106  for(std::size_t i = 0 ; i < Cipher::getBlockSize() ; ++i) {
107  _ctxtVect[i] = input[i] ^ output[i];
108  }
109  return Cipher::getBlockSize(); // This mode pad data => the number of bytes to write will always be a complete block
110  }
111 
124  virtual std::size_t decipherBlock(std::array<uint8_t,Cipher::getBlockSize()>& input,
125  std::array<uint8_t,Cipher::getBlockSize()>&,
126  std::streamsize nbRead,
127  bool lastBlock,
128  std::array<uint8_t,Cipher::getBlockSize()>& output,
129  uint32_t, Cipher& cipher) override {
130  if(lastBlock && static_cast<std::size_t>(nbRead) != Cipher::getBlockSize()) {
131  throw InvalidBlockException("Invalid block size");
132  }
133  std::array<uint8_t,Cipher::getBlockSize()> data;
134  cipher.decipher(input, data);
135  for(std::size_t i = 0 ; i < Cipher::getBlockSize() ; ++i) {
136  output[i] = data[i] ^ _ctxtVect[i];
137  _ctxtVect[i] = input[i] ^ output[i];
138  }
139  if(lastBlock) {
140  return Padding::length(output.data(), Cipher::getBlockSize());
141  } else {
142  return Cipher::getBlockSize();
143  }
144  }
145 
151  virtual const std::array<uint8_t,Cipher::getBlockSize()>& reset() {
152  _ctxtVect = _initVect;
153  return _initVect;
154  }
155  // Methods -
156 
157  };
158 
159  }
160 }
161 
162 #endif // _ANCH_CRYPTO_PCBC_H_
virtual ~PCBC()
Definition: pcbc.hpp:75
PCBC(const std::array< uint8_t, Cipher::getBlockSize()> &initVect, unsigned int nbThread=1)
Definition: pcbc.hpp:62
Propagating cipher-block chaining implementation.
Definition: pcbc.hpp:41
virtual const std::array< uint8_t, Cipher::getBlockSize()> & reset()
Definition: pcbc.hpp:151
Exception on receiving an invalid block.
Definition: invalidBlockException.hpp:39
AnCH framework base namespace.
Definition: base64.hpp:28
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:124
void cipher(std::istream &input, std::ostream &output, const std::string &key)
Definition: bcModOp.hpp:133
Block cipher mode of operation interface.
Definition: bcModOp.hpp:49
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:94