Arduino Cryptography Library
CFB.cpp
1 /*
2  * Copyright (C) 2015 Southern Storm Software, Pty Ltd.
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included
12  * in all copies or substantial portions of the Software.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20  * DEALINGS IN THE SOFTWARE.
21  */
22 
23 #include "CFB.h"
24 #include "Crypto.h"
25 #include <string.h>
26 
43  : blockCipher(0)
44  , posn(16)
45 {
46 }
47 
52 {
53  clean(iv);
54 }
55 
56 size_t CFBCommon::keySize() const
57 {
58  return blockCipher->keySize();
59 }
60 
61 size_t CFBCommon::ivSize() const
62 {
63  return 16;
64 }
65 
66 bool CFBCommon::setKey(const uint8_t *key, size_t len)
67 {
68  // Verify the cipher's block size, just in case.
69  if (blockCipher->blockSize() != 16)
70  return false;
71 
72  // Set the key on the underlying block cipher.
73  return blockCipher->setKey(key, len);
74 }
75 
76 bool CFBCommon::setIV(const uint8_t *iv, size_t len)
77 {
78  if (len != 16)
79  return false;
80  memcpy(this->iv, iv, 16);
81  posn = 16;
82  return true;
83 }
84 
85 void CFBCommon::encrypt(uint8_t *output, const uint8_t *input, size_t len)
86 {
87  uint8_t size;
88  while (len > 0) {
89  // If we have exhausted the current keystream block, then encrypt
90  // the IV/ciphertext to get another keystream block.
91  if (posn >= 16) {
92  blockCipher->encryptBlock(iv, iv);
93  posn = 0;
94  }
95 
96  // XOR the plaintext with the encrypted IV to get the new ciphertext.
97  // We keep building up the ciphertext byte by byte in the IV buffer
98  // until we have a full block's worth, and then the IV is encrypted
99  // again by the code above.
100  size = 16 - posn;
101  if (size > len)
102  size = len;
103  len -= size;
104  while (size > 0) {
105  iv[posn] ^= *input++;
106  *output++ = iv[posn++];
107  --size;
108  }
109  }
110 }
111 
112 void CFBCommon::decrypt(uint8_t *output, const uint8_t *input, size_t len)
113 {
114  uint8_t size;
115  while (len > 0) {
116  // If we have exhausted the current keystream block, then encrypt
117  // the IV/ciphertext to get another keystream block.
118  if (posn >= 16) {
119  blockCipher->encryptBlock(iv, iv);
120  posn = 0;
121  }
122 
123  // XOR the ciphertext with the encrypted IV to get the new plaintext.
124  // We keep building up the ciphertext byte by byte in the IV buffer
125  // until we have a full block's worth, and then the IV is encrypted
126  // again by the code above.
127  size = 16 - posn;
128  if (size > len)
129  size = len;
130  len -= size;
131  while (size > 0) {
132  uint8_t in = *input++;
133  *output++ = iv[posn] ^ in;
134  iv[posn++] = in;
135  --size;
136  }
137  }
138 }
139 
141 {
142  blockCipher->clear();
143  clean(iv);
144  posn = 16;
145 }
146 
virtual void clear()=0
Clears all security-sensitive state from this block cipher.
virtual size_t blockSize() const =0
Size of a single block processed by this cipher, in bytes.
virtual bool setKey(const uint8_t *key, size_t len)=0
Sets the key to use for future encryption and decryption operations.
virtual void encryptBlock(uint8_t *output, const uint8_t *input)=0
Encrypts a single block using this cipher.
virtual size_t keySize() const =0
Default size of the key for this block cipher, in bytes.
size_t keySize() const
Default size of the key for this cipher, in bytes.
Definition: CFB.cpp:56
bool setKey(const uint8_t *key, size_t len)
Sets the key to use for future encryption and decryption operations.
Definition: CFB.cpp:66
void encrypt(uint8_t *output, const uint8_t *input, size_t len)
Encrypts an input buffer and writes the ciphertext to an output buffer.
Definition: CFB.cpp:85
bool setIV(const uint8_t *iv, size_t len)
Sets the initialization vector to use for future encryption and decryption operations.
Definition: CFB.cpp:76
size_t ivSize() const
Size of the initialization vector for this cipher, in bytes.
Definition: CFB.cpp:61
void clear()
Clears all security-sensitive state from this cipher.
Definition: CFB.cpp:140
void decrypt(uint8_t *output, const uint8_t *input, size_t len)
Decrypts an input buffer and writes the plaintext to an output buffer.
Definition: CFB.cpp:112
CFBCommon()
Constructs a new cipher in CFB mode.
Definition: CFB.cpp:42
virtual ~CFBCommon()
Destroys this cipher object after clearing sensitive information.
Definition: CFB.cpp:51