1 /*
2 * Copyright (c) 2010 SURFnet bv
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
15 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
16 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
18 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
20 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
22 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
23 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
24 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 */
26
27 /*****************************************************************************
28 SymmetricAlgorithm.cpp
29
30 Base class for symmetric algorithm classes
31 *****************************************************************************/
32
33 #include "SymmetricAlgorithm.h"
34 #include <algorithm>
35 #include <string.h>
36
SymmetricAlgorithm()37 SymmetricAlgorithm::SymmetricAlgorithm()
38 {
39 currentKey = NULL;
40 currentCipherMode = SymMode::Unknown;
41 currentPaddingMode = true;
42 currentCounterBits = 0;
43 currentTagBytes = 0;
44 currentOperation = NONE;
45 currentBufferSize = 0;
46 }
47
encryptInit(const SymmetricKey * key,const SymMode::Type mode,const ByteString &,bool padding,size_t counterBits,const ByteString &,size_t tagBytes)48 bool SymmetricAlgorithm::encryptInit(const SymmetricKey* key, const SymMode::Type mode /* = SymMode::CBC */, const ByteString& /*IV = ByteString() */, bool padding /* = true */, size_t counterBits /* = 0 */, const ByteString& /*aad = ByteString()*/, size_t tagBytes /* = 0 */)
49 {
50 if ((key == NULL) || (currentOperation != NONE))
51 {
52 return false;
53 }
54
55 currentKey = key;
56 currentCipherMode = mode;
57 currentPaddingMode = padding;
58 currentCounterBits = counterBits;
59 currentTagBytes = tagBytes;
60 currentOperation = ENCRYPT;
61 currentBufferSize = 0;
62
63 return true;
64 }
65
encryptUpdate(const ByteString & data,ByteString &)66 bool SymmetricAlgorithm::encryptUpdate(const ByteString& data, ByteString& /*encryptedData*/)
67 {
68 if (currentOperation != ENCRYPT)
69 {
70 return false;
71 }
72
73 currentBufferSize += data.size();
74
75 return true;
76 }
77
encryptFinal(ByteString &)78 bool SymmetricAlgorithm::encryptFinal(ByteString& /*encryptedData*/)
79 {
80 if (currentOperation != ENCRYPT)
81 {
82 return false;
83 }
84
85 currentKey = NULL;
86 currentCipherMode = SymMode::Unknown;
87 currentPaddingMode = true;
88 currentCounterBits = 0;
89 currentTagBytes = 0;
90 currentOperation = NONE;
91 currentBufferSize = 0;
92
93 return true;
94 }
95
decryptInit(const SymmetricKey * key,const SymMode::Type mode,const ByteString &,bool padding,size_t counterBits,const ByteString &,size_t tagBytes)96 bool SymmetricAlgorithm::decryptInit(const SymmetricKey* key, const SymMode::Type mode /* = SymMode::CBC */, const ByteString& /*IV = ByteString() */, bool padding /* = true */, size_t counterBits /* = 0 */, const ByteString& /*aad = ByteString()*/, size_t tagBytes /* = 0 */)
97 {
98 if ((key == NULL) || (currentOperation != NONE))
99 {
100 return false;
101 }
102
103 currentKey = key;
104 currentCipherMode = mode;
105 currentPaddingMode = padding;
106 currentCounterBits = counterBits;
107 currentTagBytes = tagBytes;
108 currentOperation = DECRYPT;
109 currentBufferSize = 0;
110 currentAEADBuffer.wipe();
111
112 return true;
113 }
114
115
decryptUpdate(const ByteString & encryptedData,ByteString &)116 bool SymmetricAlgorithm::decryptUpdate(const ByteString& encryptedData, ByteString& /*data*/)
117 {
118 if (currentOperation != DECRYPT)
119 {
120 return false;
121 }
122
123 currentBufferSize += encryptedData.size();
124 currentAEADBuffer += encryptedData;
125
126 return true;
127 }
128
decryptFinal(ByteString &)129 bool SymmetricAlgorithm::decryptFinal(ByteString& /*data*/)
130 {
131 if (currentOperation != DECRYPT)
132 {
133 return false;
134 }
135
136 currentKey = NULL;
137 currentCipherMode = SymMode::Unknown;
138 currentPaddingMode = true;
139 currentCounterBits = 0;
140 currentTagBytes = 0;
141 currentOperation = NONE;
142 currentBufferSize = 0;
143 currentAEADBuffer.wipe();
144
145 return true;
146 }
147
148 // Key factory
recycleKey(SymmetricKey * toRecycle)149 void SymmetricAlgorithm::recycleKey(SymmetricKey* toRecycle)
150 {
151 delete toRecycle;
152 }
153
generateKey(SymmetricKey & key,RNG * rng)154 bool SymmetricAlgorithm::generateKey(SymmetricKey& key, RNG* rng /* = NULL */)
155 {
156 if (rng == NULL)
157 {
158 return false;
159 }
160
161 if (key.getBitLen() == 0)
162 {
163 return false;
164 }
165
166 ByteString keyBits;
167
168 if (!rng->generateRandom(keyBits, key.getBitLen()/8))
169 {
170 return false;
171 }
172
173 return key.setKeyBits(keyBits);
174 }
175
reconstructKey(SymmetricKey & key,const ByteString & serialisedData)176 bool SymmetricAlgorithm::reconstructKey(SymmetricKey& key, const ByteString& serialisedData)
177 {
178 return key.setKeyBits(serialisedData);
179 }
180
getCipherMode()181 SymMode::Type SymmetricAlgorithm::getCipherMode()
182 {
183 return currentCipherMode;
184 }
185
getPaddingMode()186 bool SymmetricAlgorithm::getPaddingMode()
187 {
188 return currentPaddingMode;
189 }
190
getBufferSize()191 unsigned long SymmetricAlgorithm::getBufferSize()
192 {
193 return currentBufferSize;
194 }
195
getTagBytes()196 size_t SymmetricAlgorithm::getTagBytes()
197 {
198 return currentTagBytes;
199 }
200
isStreamCipher()201 bool SymmetricAlgorithm::isStreamCipher()
202 {
203 switch (currentCipherMode)
204 {
205 case SymMode::CFB:
206 case SymMode::CTR:
207 case SymMode::GCM:
208 case SymMode::OFB:
209 return true;
210 default:
211 break;
212 }
213
214 return false;
215 }
216
isBlockCipher()217 bool SymmetricAlgorithm::isBlockCipher()
218 {
219 switch (currentCipherMode)
220 {
221 case SymMode::CBC:
222 case SymMode::ECB:
223 return true;
224 default:
225 break;
226 }
227
228 return false;
229 }
230