UltraGrid
UltraGrid Low-Latency High-Resolution Transmission System
Loading...
Searching...
No Matches
crypt_aes.c File Reference
#include "config.h"
#include "config_unix.h"
#include "config_win32.h"
#include "debug.h"
#include "crypt_aes_impl.h"
#include "crypt_aes.h"
Include dependency graph for crypt_aes.c:

Go to the source code of this file.

Functions

int blockDecrypt (cipherInstance *cipher, keyInstance *key, BYTE *input, int inputLen, BYTE *outBuffer)
 
int blockEncrypt (cipherInstance *cipher, keyInstance *key, BYTE *input, int inputLen, BYTE *outBuffer)
 
int cipherInit (cipherInstance *cipher, BYTE mode, char *IV)
 
int cipherUpdateRounds (cipherInstance *cipher, keyInstance *key, BYTE *input, int inputLen, BYTE *outBuffer, int rounds)
 
int makeKey (keyInstance *key, BYTE direction, int keyLen, const char *keyMaterial)
 
int padDecrypt (cipherInstance *cipher, keyInstance *key, BYTE *input, int inputOctets, BYTE *outBuffer)
 
int padEncrypt (cipherInstance *cipher, keyInstance *key, BYTE *input, int inputOctets, BYTE *outBuffer)
 

Function Documentation

◆ blockDecrypt()

int blockDecrypt ( cipherInstance * cipher,
keyInstance * key,
BYTE * input,
int inputLen,
BYTE * outBuffer )

Definition at line 287 of file crypt_aes.c.

288{
289 int i, k, t, numBlocks;
290 u8 block[16], *iv;
291
292 if (cipher == NULL ||
293 key == NULL ||
294 (cipher->mode != MODE_CFB1 && key->direction == DIR_ENCRYPT)) {
295 return BAD_CIPHER_STATE;
296 }
297 if (input == NULL || inputLen <= 0) {
298 return 0; /* nothing to do */
299 }
300
301 numBlocks = inputLen / 128;
302
303 switch (cipher->mode) {
304 case MODE_ECB:
305 for (i = numBlocks; i > 0; i--) {
306 rijndaelDecrypt(key->rk, key->Nr, input, outBuffer);
307 input += 16;
308 outBuffer += 16;
309 }
310 break;
311
312 case MODE_CBC:
313 iv = cipher->IV;
314 for (i = numBlocks; i > 0; i--) {
315 rijndaelDecrypt(key->rk, key->Nr, input, block);
316 ((u32 *)(void *) block)[0] ^= ((u32 *)(void *) iv)[0];
317 ((u32 *)(void *) block)[1] ^= ((u32 *)(void *) iv)[1];
318 ((u32 *)(void *) block)[2] ^= ((u32 *)(void *) iv)[2];
319 ((u32 *)(void *) block)[3] ^= ((u32 *)(void *) iv)[3];
320 memcpy(cipher->IV, input, 16);
321 memcpy(outBuffer, block, 16);
322 input += 16;
323 outBuffer += 16;
324 }
325 break;
326
327 case MODE_CFB1:
328 iv = cipher->IV;
329 for (i = numBlocks; i > 0; i--) {
330 memcpy(outBuffer, input, 16);
331 for (k = 0; k < 128; k++) {
332 rijndaelEncrypt(key->ek, key->Nr, iv, block);
333 for (t = 0; t < 15; t++) {
334 iv[t] = (iv[t] << 1) | (iv[t + 1] >> 7);
335 }
336 iv[15] =
337 (iv[15] << 1) |
338 ((input[k >> 3] >> (7 - (k & 7))) & 1);
339 outBuffer[k >> 3] ^=
340 (block[0] & 0x80U) >> (k & 7);
341 }
342 outBuffer += 16;
343 input += 16;
344 }
345 break;
346
347 default:
348 return BAD_CIPHER_STATE;
349 }
350
351 return 128 * numBlocks;
352}
353
int padDecrypt(cipherInstance *cipher, keyInstance *key, BYTE *input, int inputOctets, BYTE *outBuffer)
Definition crypt_aes.c:356
#define MODE_CBC
Definition crypt_aes.h:48
#define BAD_CIPHER_STATE
Definition crypt_aes.h:59
#define MODE_ECB
Definition crypt_aes.h:47
#define DIR_ENCRYPT
Definition crypt_aes.h:45
#define MODE_CFB1
Definition crypt_aes.h:49
void rijndaelDecrypt(const u32 rk[], int Nr, const u8 ct[16], u8 pt[16])
void rijndaelEncrypt(const u32 rk[], int Nr, const u8 pt[16], u8 ct[16])
unsigned int u32
Definition cuda_dxt.cu:12
uint8_t u8
Definition dxt62tga.c:12
BYTE IV[MAX_IV_SIZE]
Definition crypt_aes.h:86
const char * key
Definition cineform.cpp:125

References BAD_CIPHER_STATE, DIR_ENCRYPT, cipherInstance::IV, key, cipherInstance::mode, MODE_CBC, MODE_CFB1, MODE_ECB, rijndaelDecrypt(), and rijndaelEncrypt().

Referenced by rijndael_decrypt(), rijndaelCBC_MCT(), rijndaelECB_MCT(), rijndaelTKAT(), and rijndaelVKKAT().

Here is the call graph for this function:

◆ blockEncrypt()

int blockEncrypt ( cipherInstance * cipher,
keyInstance * key,
BYTE * input,
int inputLen,
BYTE * outBuffer )

Definition at line 145 of file crypt_aes.c.

147{
148 int i, k, t, numBlocks;
149 u8 block[16], *iv;
150
151 if (cipher == NULL || key == NULL || key->direction == DIR_DECRYPT) {
152 return BAD_CIPHER_STATE;
153 }
154 if (input == NULL || inputLen <= 0) {
155 return 0; /* nothing to do */
156 }
157
158 numBlocks = inputLen / 128;
159
160 switch (cipher->mode) {
161 case MODE_ECB:
162 for (i = numBlocks; i > 0; i--) {
163 rijndaelEncrypt(key->rk, key->Nr, input, outBuffer);
164 input += 16;
165 outBuffer += 16;
166 }
167 break;
168
169 case MODE_CBC:
170 iv = cipher->IV;
171 for (i = numBlocks; i > 0; i--) {
172 ((u32 *)(void *) block)[0] =
173 ((u32 *)(void *) input)[0] ^ ((u32 *)(void *) iv)[0];
174 ((u32 *)(void *) block)[1] =
175 ((u32 *)(void *) input)[1] ^ ((u32 *)(void *) iv)[1];
176 ((u32 *)(void *) block)[2] =
177 ((u32 *)(void *) input)[2] ^ ((u32 *)(void *) iv)[2];
178 ((u32 *)(void *) block)[3] =
179 ((u32 *)(void *) input)[3] ^ ((u32 *)(void *) iv)[3];
180 rijndaelEncrypt(key->rk, key->Nr, block, outBuffer);
181 iv = outBuffer;
182 input += 16;
183 outBuffer += 16;
184 }
185 break;
186
187 case MODE_CFB1:
188 iv = cipher->IV;
189 for (i = numBlocks; i > 0; i--) {
190 memcpy(outBuffer, input, 16);
191 for (k = 0; k < 128; k++) {
192 rijndaelEncrypt(key->ek, key->Nr, iv, block);
193 outBuffer[k >> 3] ^=
194 (block[0] & 0x80U) >> (k & 7);
195 for (t = 0; t < 15; t++) {
196 iv[t] = (iv[t] << 1) | (iv[t + 1] >> 7);
197 }
198 iv[15] =
199 (iv[15] << 1) |
200 ((outBuffer[k >> 3] >> (7 - (k & 7))) & 1);
201 }
202 outBuffer += 16;
203 input += 16;
204 }
205 break;
206
207 default:
208 return BAD_CIPHER_STATE;
209 }
210
211 return 128 * numBlocks;
212}
213
#define DIR_DECRYPT
Definition crypt_aes.h:46

References BAD_CIPHER_STATE, DIR_DECRYPT, cipherInstance::IV, key, cipherInstance::mode, MODE_CBC, MODE_CFB1, MODE_ECB, and rijndaelEncrypt().

Referenced by rijndael_encrypt(), rijndaelCBC_MCT(), rijndaelECB_MCT(), rijndaelTKAT(), rijndaelVKKAT(), and rijndaelVTKAT().

Here is the call graph for this function:

◆ cipherInit()

int cipherInit ( cipherInstance * cipher,
BYTE mode,
char * IV )

Definition at line 105 of file crypt_aes.c.

106{
107 if ((mode == MODE_ECB) || (mode == MODE_CBC) || (mode == MODE_CFB1)) {
108 cipher->mode = mode;
109 } else {
110 return BAD_CIPHER_MODE;
111 }
112 if (IV != NULL) {
113 int i;
114 for (i = 0; i < MAX_IV_SIZE; i++) {
115 int t, j;
116
117 t = IV[2 * i];
118 if ((t >= '0') && (t <= '9'))
119 j = (t - '0') << 4;
120 else if ((t >= 'a') && (t <= 'f'))
121 j = (t - 'a' + 10) << 4;
122 else if ((t >= 'A') && (t <= 'F'))
123 j = (t - 'A' + 10) << 4;
124 else
125 return BAD_CIPHER_INSTANCE;
126
127 t = IV[2 * i + 1];
128 if ((t >= '0') && (t <= '9'))
129 j ^= (t - '0');
130 else if ((t >= 'a') && (t <= 'f'))
131 j ^= (t - 'a' + 10);
132 else if ((t >= 'A') && (t <= 'F'))
133 j ^= (t - 'A' + 10);
134 else
135 return BAD_CIPHER_INSTANCE;
136
137 cipher->IV[i] = (u8) j;
138 }
139 } else {
140 memset(cipher->IV, 0, MAX_IV_SIZE);
141 }
142 return TRUE;
143}
#define TRUE
#define BAD_CIPHER_INSTANCE
Definition crypt_aes.h:61
#define MAX_IV_SIZE
Definition crypt_aes.h:67
#define BAD_CIPHER_MODE
Definition crypt_aes.h:58
enum openssl_mode mode

References BAD_CIPHER_INSTANCE, BAD_CIPHER_MODE, cipherInstance::IV, MAX_IV_SIZE, cipherInstance::mode, mode, MODE_CBC, MODE_CFB1, MODE_ECB, and TRUE.

Referenced by rijndael_initialize(), rijndaelCBC_MCT(), rijndaelECB_MCT(), rijndaelIVKAT(), rijndaelTKAT(), rijndaelVKKAT(), and rijndaelVTKAT().

◆ cipherUpdateRounds()

int cipherUpdateRounds ( cipherInstance * cipher,
keyInstance * key,
BYTE * input,
int inputLen,
BYTE * outBuffer,
int rounds )

cipherUpdateRounds:

Encrypts/Decrypts exactly one full block a specified number of rounds. Only used in the Intermediate Value Known Answer Test.

Returns: TRUE - on success BAD_CIPHER_STATE - cipher in bad state (e.g., not initialized)

Definition at line 444 of file crypt_aes.c.

444{
445 u8 block[16];
446
447 UNUSED(inputLen);
448
449 if (cipher == NULL || key == NULL) {
450 return BAD_CIPHER_STATE;
451 }
452
453 memcpy(block, input, 16);
454
455 switch (key->direction) {
456 case DIR_ENCRYPT:
457 rijndaelEncryptRound(key->rk, key->Nr, block, rounds);
458 break;
459
460 case DIR_DECRYPT:
461 rijndaelDecryptRound(key->rk, key->Nr, block, rounds);
462 break;
463
464 default:
465 return BAD_KEY_DIR;
466 }
467
468 memcpy(outBuffer, block, 16);
469
470 return TRUE;
471}
#define UNUSED(x)
#define BAD_KEY_DIR
Definition crypt_aes.h:55
void rijndaelEncryptRound(const u32 rk[], int Nr, u8 block[16], int rounds)
void rijndaelDecryptRound(const u32 rk[], int Nr, u8 block[16], int rounds)

References BAD_CIPHER_STATE, BAD_KEY_DIR, DIR_DECRYPT, DIR_ENCRYPT, key, rijndaelDecryptRound(), rijndaelEncryptRound(), TRUE, and UNUSED.

Referenced by rijndaelIVKAT().

Here is the call graph for this function:

◆ makeKey()

int makeKey ( keyInstance * key,
BYTE direction,
int keyLen,
const char * keyMaterial )

rijndael-api-fst.c

Version
2.9 (December 2000)

Optimised ANSI C code for the Rijndael cipher (now AES)

Author
Vincent Rijmen vince.nosp@m.nt.r.nosp@m.ijmen.nosp@m.@esa.nosp@m.t.kul.nosp@m.euve.nosp@m.n.ac..nosp@m.be
Antoon Bosselaers antoo.nosp@m.n.bo.nosp@m.ssela.nosp@m.ers@.nosp@m.esat..nosp@m.kule.nosp@m.uven..nosp@m.ac.b.nosp@m.e
Paulo Barreto paulo.nosp@m..bar.nosp@m.reto@.nosp@m.terr.nosp@m.a.com.nosp@m..br

This code is hereby placed in the public domain.

THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

Acknowledgements:

We are deeply indebted to the following people for their bug reports, fixes, and improvement suggestions to this implementation. Though we tried to list all contributions, we apologise in advance for any missing reference.

Andrew Bales Andre.nosp@m.w.Ba.nosp@m.les@H.nosp@m.oney.nosp@m.well..nosp@m.com Markus Friedl marku.nosp@m.s.fr.nosp@m.iedl@.nosp@m.info.nosp@m.rmati.nosp@m.k.un.nosp@m.i-erl.nosp@m.ange.nosp@m.n.de John Skodon skodo.nosp@m.nj@w.nosp@m.ebqui.nosp@m.ll.c.nosp@m.om

Definition at line 45 of file crypt_aes.c.

46{
47 u8 cipherKey[MAXKB];
48
49 if (key == NULL) {
50 return BAD_KEY_INSTANCE;
51 }
52
53 if ((direction == DIR_ENCRYPT) || (direction == DIR_DECRYPT)) {
54 key->direction = direction;
55 } else {
56 return BAD_KEY_DIR;
57 }
58
59 if ((keyLen == 128) || (keyLen == 192) || (keyLen == 256)) {
60 key->keyLen = keyLen;
61 } else {
62 return BAD_KEY_MAT;
63 }
64
65 if (keyMaterial != NULL) {
66 strncpy(key->keyMaterial, keyMaterial, keyLen / 4);
67 }
68
69 /* initialize key schedule: */
70 const char *keyMat = key->keyMaterial;
71 for (int i = 0; i < key->keyLen / 8; i++) {
72 int t = *keyMat++;
73 int v;
74
75 if ((t >= '0') && (t <= '9'))
76 v = (t - '0') << 4;
77 else if ((t >= 'a') && (t <= 'f'))
78 v = (t - 'a' + 10) << 4;
79 else if ((t >= 'A') && (t <= 'F'))
80 v = (t - 'A' + 10) << 4;
81 else
82 return BAD_KEY_MAT;
83
84 t = *keyMat++;
85 if ((t >= '0') && (t <= '9'))
86 v ^= (t - '0');
87 else if ((t >= 'a') && (t <= 'f'))
88 v ^= (t - 'a' + 10);
89 else if ((t >= 'A') && (t <= 'F'))
90 v ^= (t - 'A' + 10);
91 else
92 return BAD_KEY_MAT;
93
94 cipherKey[i] = (u8) v;
95 }
96 if (direction == DIR_ENCRYPT) {
97 key->Nr = rijndaelKeySetupEnc(key->rk, cipherKey, keyLen);
98 } else {
99 key->Nr = rijndaelKeySetupDec(key->rk, cipherKey, keyLen);
100 }
101 rijndaelKeySetupEnc(key->ek, cipherKey, keyLen);
102 return TRUE;
103}
#define BAD_KEY_INSTANCE
Definition crypt_aes.h:57
#define BAD_KEY_MAT
Definition crypt_aes.h:56
int rijndaelKeySetupDec(u32 rk[], const u8 cipherKey[], int keyBits)
int rijndaelKeySetupEnc(u32 rk[], const u8 cipherKey[], int keyBits)
#define MAXKB

References BAD_KEY_DIR, BAD_KEY_INSTANCE, BAD_KEY_MAT, DIR_DECRYPT, DIR_ENCRYPT, key, MAXKB, rijndaelKeySetupDec(), rijndaelKeySetupEnc(), and TRUE.

Referenced by rijndael_initialize(), rijndaelCBC_MCT(), rijndaelECB_MCT(), rijndaelIVKAT(), rijndaelTKAT(), rijndaelVKKAT(), and rijndaelVTKAT().

Here is the call graph for this function:

◆ padDecrypt()

int padDecrypt ( cipherInstance * cipher,
keyInstance * key,
BYTE * input,
int inputOctets,
BYTE * outBuffer )

Definition at line 356 of file crypt_aes.c.

356{
357 int i, numBlocks, padLen;
358 u8 block[16];
359
360 if (cipher == NULL || key == NULL || key->direction == DIR_ENCRYPT) {
361 return BAD_CIPHER_STATE;
362 }
363 if (input == NULL || inputOctets <= 0) {
364 return 0; /* nothing to do */
365 }
366 if (inputOctets % 16 != 0) {
367 return BAD_DATA;
368 }
369
370 numBlocks = inputOctets / 16;
371
372 switch (cipher->mode) {
373 case MODE_ECB:
374 /* all blocks but last */
375 for (i = numBlocks - 1; i > 0; i--) {
376 rijndaelDecrypt(key->rk, key->Nr, input, outBuffer);
377 input += 16;
378 outBuffer += 16;
379 }
380 /* last block */
381 rijndaelDecrypt(key->rk, key->Nr, input, block);
382 padLen = block[15];
383 if (padLen >= 16) {
384 return BAD_DATA;
385 }
386 for (i = 16 - padLen; i < 16; i++) {
387 if (block[i] != padLen) {
388 return BAD_DATA;
389 }
390 }
391 memcpy(outBuffer, block, 16 - padLen);
392 break;
393
394 case MODE_CBC:
395 /* all blocks but last */
396 for (i = numBlocks - 1; i > 0; i--) {
397 rijndaelDecrypt(key->rk, key->Nr, input, block);
398 ((u32 *)(void *) block)[0] ^= ((u32 *)(void *) cipher->IV)[0];
399 ((u32 *)(void *) block)[1] ^= ((u32 *)(void *) cipher->IV)[1];
400 ((u32 *)(void *) block)[2] ^= ((u32 *)(void *) cipher->IV)[2];
401 ((u32 *)(void *) block)[3] ^= ((u32 *)(void *) cipher->IV)[3];
402 memcpy(cipher->IV, input, 16);
403 memcpy(outBuffer, block, 16);
404 input += 16;
405 outBuffer += 16;
406 }
407 /* last block */
408 rijndaelDecrypt(key->rk, key->Nr, input, block);
409 ((u32 *)(void *) block)[0] ^= ((u32 *)(void *) cipher->IV)[0];
410 ((u32 *)(void *) block)[1] ^= ((u32 *)(void *) cipher->IV)[1];
411 ((u32 *)(void *) block)[2] ^= ((u32 *)(void *) cipher->IV)[2];
412 ((u32 *)(void *) block)[3] ^= ((u32 *)(void *) cipher->IV)[3];
413 padLen = block[15];
414 if (padLen <= 0 || padLen > 16) {
415 return BAD_DATA;
416 }
417 for (i = 16 - padLen; i < 16; i++) {
418 if (block[i] != padLen) {
419 return BAD_DATA;
420 }
421 }
422 memcpy(outBuffer, block, 16 - padLen);
423 break;
424
425 default:
426 return BAD_CIPHER_STATE;
427 }
428
429 return 16 * numBlocks - padLen;
430}
431
#define BAD_DATA
Definition crypt_aes.h:62

References BAD_CIPHER_STATE, BAD_DATA, DIR_ENCRYPT, cipherInstance::IV, key, cipherInstance::mode, MODE_CBC, MODE_ECB, and rijndaelDecrypt().

Here is the call graph for this function:

◆ padEncrypt()

int padEncrypt ( cipherInstance * cipher,
keyInstance * key,
BYTE * input,
int inputOctets,
BYTE * outBuffer )

Encrypt data partitioned in octets, using RFC 2040-like padding.

Parameters
inputdata to be encrypted (octet sequence)
inputOctetsinput length in octets (not bits)
outBufferencrypted output data
Returns
length in octets (not bits) of the encrypted output buffer.

Definition at line 224 of file crypt_aes.c.

225{
226 int i, numBlocks, padLen;
227 u8 block[16], *iv;
228
229 if (cipher == NULL || key == NULL || key->direction == DIR_DECRYPT) {
230 return BAD_CIPHER_STATE;
231 }
232 if (input == NULL || inputOctets <= 0) {
233 return 0; /* nothing to do */
234 }
235
236 numBlocks = inputOctets / 16;
237
238 switch (cipher->mode) {
239 case MODE_ECB:
240 for (i = numBlocks; i > 0; i--) {
241 rijndaelEncrypt(key->rk, key->Nr, input, outBuffer);
242 input += 16;
243 outBuffer += 16;
244 }
245 padLen = 16 - (inputOctets - 16 * numBlocks);
246 assert(padLen > 0 && padLen <= 16);
247 memcpy(block, input, 16 - padLen);
248 memset(block + 16 - padLen, padLen, padLen);
249 rijndaelEncrypt(key->rk, key->Nr, block, outBuffer);
250 break;
251
252 case MODE_CBC:
253 iv = cipher->IV;
254 for (i = numBlocks; i > 0; i--) {
255 ((u32 *)(void *) block)[0] =
256 ((u32 *)(void *) input)[0] ^ ((u32 *)(void *) iv)[0];
257 ((u32 *)(void *) block)[1] =
258 ((u32 *)(void *) input)[1] ^ ((u32 *)(void *) iv)[1];
259 ((u32 *)(void *) block)[2] =
260 ((u32 *)(void *) input)[2] ^ ((u32 *)(void *) iv)[2];
261 ((u32 *)(void *) block)[3] =
262 ((u32 *)(void *) input)[3] ^ ((u32 *)(void *) iv)[3];
263 rijndaelEncrypt(key->rk, key->Nr, block, outBuffer);
264 iv = outBuffer;
265 input += 16;
266 outBuffer += 16;
267 }
268 padLen = 16 - (inputOctets - 16 * numBlocks);
269 assert(padLen > 0 && padLen <= 16);
270 for (i = 0; i < 16 - padLen; i++) {
271 block[i] = input[i] ^ iv[i];
272 }
273 for (i = 16 - padLen; i < 16; i++) {
274 block[i] = (BYTE) padLen ^ iv[i];
275 }
276 rijndaelEncrypt(key->rk, key->Nr, block, outBuffer);
277 break;
278
279 default:
280 return BAD_CIPHER_STATE;
281 }
282
283 return 16 * (numBlocks + 1);
284}
285
unsigned char BYTE
Definition crypt_aes.h:71

References BAD_CIPHER_STATE, DIR_DECRYPT, cipherInstance::IV, key, cipherInstance::mode, MODE_CBC, MODE_ECB, and rijndaelEncrypt().

Here is the call graph for this function: