Arduino Cryptography Library
CTR.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 "CTR.h"
24 #include "Crypto.h"
25 #include <string.h>
26 
43  : blockCipher(0)
44  , posn(16)
45  , counterStart(0)
46 {
47 }
48 
49 CTRCommon::~CTRCommon()
50 {
51  // It is assumed that the subclass will clear sensitive
52  // information in the block cipher.
53  clean(counter);
54  clean(state);
55 }
56 
57 size_t CTRCommon::keySize() const
58 {
59  return blockCipher->keySize();
60 }
61 
62 size_t CTRCommon::ivSize() const
63 {
64  return 16;
65 }
66 
86 bool CTRCommon::setCounterSize(size_t size)
87 {
88  if (size < 1 || size > 16)
89  return false;
90  counterStart = 16 - size;
91  return true;
92 }
93 
94 bool CTRCommon::setKey(const uint8_t *key, size_t len)
95 {
96  // Verify the cipher's block size, just in case.
97  if (blockCipher->blockSize() != 16)
98  return false;
99 
100  // Set the key on the underlying block cipher.
101  return blockCipher->setKey(key, len);
102 }
103 
119 bool CTRCommon::setIV(const uint8_t *iv, size_t len)
120 {
121  if (len != 16)
122  return false;
123  memcpy(counter, iv, len);
124  posn = 16;
125  return true;
126 }
127 
128 void CTRCommon::encrypt(uint8_t *output, const uint8_t *input, size_t len)
129 {
130  while (len > 0) {
131  if (posn >= 16) {
132  // Generate a new encrypted counter block.
133  blockCipher->encryptBlock(state, counter);
134  posn = 0;
135 
136  // Increment the counter, taking care not to reveal
137  // any timing information about the starting value.
138  // We iterate through the entire counter region even
139  // if we could stop earlier because a byte is non-zero.
140  uint16_t temp = 1;
141  uint8_t index = 16;
142  while (index > counterStart) {
143  --index;
144  temp += counter[index];
145  counter[index] = (uint8_t)temp;
146  temp >>= 8;
147  }
148  }
149  uint8_t templen = 16 - posn;
150  if (templen > len)
151  templen = len;
152  len -= templen;
153  while (templen > 0) {
154  *output++ = *input++ ^ state[posn++];
155  --templen;
156  }
157  }
158 }
159 
160 void CTRCommon::decrypt(uint8_t *output, const uint8_t *input, size_t len)
161 {
162  encrypt(output, input, len);
163 }
164 
166 {
167  blockCipher->clear();
168  clean(counter);
169  clean(state);
170  posn = 16;
171 }
172 
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.
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: CTR.cpp:160
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: CTR.cpp:128
bool setKey(const uint8_t *key, size_t len)
Sets the key to use for future encryption and decryption operations.
Definition: CTR.cpp:94
bool setIV(const uint8_t *iv, size_t len)
Sets the initial counter value to use for future encryption and decryption operations.
Definition: CTR.cpp:119
CTRCommon()
Constructs a new cipher in CTR mode.
Definition: CTR.cpp:42
void clear()
Clears all security-sensitive state from this cipher.
Definition: CTR.cpp:165
bool setCounterSize(size_t size)
Sets the counter size for the IV.
Definition: CTR.cpp:86
size_t ivSize() const
Size of the initialization vector for this cipher, in bytes.
Definition: CTR.cpp:62
size_t keySize() const
Default size of the key for this cipher, in bytes.
Definition: CTR.cpp:57