UltraGrid
UltraGrid Low-Latency High-Resolution Transmission System
Loading...
Searching...
No Matches
crypt_aes.c
Go to the documentation of this file.
1
38#include "config.h"
39#include "config_unix.h"
40#include "config_win32.h"
41#include "debug.h"
42#include "crypt_aes_impl.h"
43#include "crypt_aes.h"
44
45int makeKey(keyInstance * key, BYTE direction, int keyLen, const char *keyMaterial)
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}
104
105int cipherInit(cipherInstance * cipher, BYTE mode, char *IV)
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}
144
146 BYTE * input, int inputLen, BYTE * outBuffer)
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
191memcpy(outBuffer, input, 16);
192 for (k = 0; k < 128; k++) {
193 rijndaelEncrypt(key->ek, key->Nr, iv, block);
194 outBuffer[k >> 3] ^=
195 (block[0] & 0x80U) >> (k & 7);
196 for (t = 0; t < 15; t++) {
197 iv[t] = (iv[t] << 1) | (iv[t + 1] >> 7);
198 }
199 iv[15] =
200 (iv[15] << 1) |
201 ((outBuffer[k >> 3] >> (7 - (k & 7))) & 1);
202 }
203 outBuffer += 16;
204 input += 16;
205 }
206 break;
207
208 default:
209 return BAD_CIPHER_STATE;
210 }
211
212 return 128 * numBlocks;
213}
214
225 BYTE * input, int inputOctets, BYTE * outBuffer)
226{
227 int i, numBlocks, padLen;
228 u8 block[16], *iv;
229
230 if (cipher == NULL || key == NULL || key->direction == DIR_DECRYPT) {
231 return BAD_CIPHER_STATE;
232 }
233 if (input == NULL || inputOctets <= 0) {
234 return 0; /* nothing to do */
235 }
236
237 numBlocks = inputOctets / 16;
238
239 switch (cipher->mode) {
240 case MODE_ECB:
241 for (i = numBlocks; i > 0; i--) {
242 rijndaelEncrypt(key->rk, key->Nr, input, outBuffer);
243 input += 16;
244 outBuffer += 16;
245 }
246 padLen = 16 - (inputOctets - 16 * numBlocks);
247 assert(padLen > 0 && padLen <= 16);
248 memcpy(block, input, 16 - padLen);
249 memset(block + 16 - padLen, padLen, padLen);
250 rijndaelEncrypt(key->rk, key->Nr, block, outBuffer);
251 break;
252
253 case MODE_CBC:
254 iv = cipher->IV;
255 for (i = numBlocks; i > 0; i--) {
256 ((u32 *)(void *) block)[0] =
257 ((u32 *)(void *) input)[0] ^ ((u32 *)(void *) iv)[0];
258 ((u32 *)(void *) block)[1] =
259 ((u32 *)(void *) input)[1] ^ ((u32 *)(void *) iv)[1];
260 ((u32 *)(void *) block)[2] =
261 ((u32 *)(void *) input)[2] ^ ((u32 *)(void *) iv)[2];
262 ((u32 *)(void *) block)[3] =
263 ((u32 *)(void *) input)[3] ^ ((u32 *)(void *) iv)[3];
264 rijndaelEncrypt(key->rk, key->Nr, block, outBuffer);
265 iv = outBuffer;
266 input += 16;
267 outBuffer += 16;
268 }
269 padLen = 16 - (inputOctets - 16 * numBlocks);
270 assert(padLen > 0 && padLen <= 16);
271 for (i = 0; i < 16 - padLen; i++) {
272 block[i] = input[i] ^ iv[i];
273 }
274 for (i = 16 - padLen; i < 16; i++) {
275 block[i] = (BYTE) padLen ^ iv[i];
276 }
277 rijndaelEncrypt(key->rk, key->Nr, block, outBuffer);
278 break;
279
280 default:
281 return BAD_CIPHER_STATE;
282 }
283
284 return 16 * (numBlocks + 1);
285}
286
288 BYTE * input, int inputLen, BYTE * outBuffer)
289{
290 int i, k, t, numBlocks;
291 u8 block[16], *iv;
292
293 if (cipher == NULL ||
294 key == NULL ||
295 (cipher->mode != MODE_CFB1 && key->direction == DIR_ENCRYPT)) {
296 return BAD_CIPHER_STATE;
297 }
298 if (input == NULL || inputLen <= 0) {
299 return 0; /* nothing to do */
300 }
301
302 numBlocks = inputLen / 128;
303
304 switch (cipher->mode) {
305 case MODE_ECB:
306 for (i = numBlocks; i > 0; i--) {
307 rijndaelDecrypt(key->rk, key->Nr, input, outBuffer);
308 input += 16;
309 outBuffer += 16;
310 }
311 break;
312
313 case MODE_CBC:
314 iv = cipher->IV;
315 for (i = numBlocks; i > 0; i--) {
316 rijndaelDecrypt(key->rk, key->Nr, input, block);
317 ((u32 *)(void *) block)[0] ^= ((u32 *)(void *) iv)[0];
318 ((u32 *)(void *) block)[1] ^= ((u32 *)(void *) iv)[1];
319 ((u32 *)(void *) block)[2] ^= ((u32 *)(void *) iv)[2];
320 ((u32 *)(void *) block)[3] ^= ((u32 *)(void *) iv)[3];
321 memcpy(cipher->IV, input, 16);
322 memcpy(outBuffer, block, 16);
323 input += 16;
324 outBuffer += 16;
325 }
326 break;
327
328 case MODE_CFB1:
329 iv = cipher->IV;
330 for (i = numBlocks; i > 0; i--) {
331 memcpy(outBuffer, input, 16);
332
333for (k = 0; k < 128; k++) {
334 rijndaelEncrypt(key->ek, key->Nr, iv, block);
335 for (t = 0; t < 15; t++) {
336 iv[t] = (iv[t] << 1) | (iv[t + 1] >> 7);
337 }
338 iv[15] =
339 (iv[15] << 1) |
340 ((input[k >> 3] >> (7 - (k & 7))) & 1);
341 outBuffer[k >> 3] ^=
342 (block[0] & 0x80U) >> (k & 7);
343 }
344 outBuffer += 16;
345 input += 16;
346 }
347 break;
348
349 default:
350 return BAD_CIPHER_STATE;
351 }
352
353 return 128 * numBlocks;
354}
355
357 BYTE * input, int inputOctets, BYTE * outBuffer)
358{
359 int i, numBlocks, padLen;
360 u8 block[16];
361
362 if (cipher == NULL || key == NULL || key->direction == DIR_ENCRYPT) {
363 return BAD_CIPHER_STATE;
364 }
365 if (input == NULL || inputOctets <= 0) {
366 return 0; /* nothing to do */
367 }
368 if (inputOctets % 16 != 0) {
369 return BAD_DATA;
370 }
371
372 numBlocks = inputOctets / 16;
373
374 switch (cipher->mode) {
375 case MODE_ECB:
376 /* all blocks but last */
377 for (i = numBlocks - 1; i > 0; i--) {
378 rijndaelDecrypt(key->rk, key->Nr, input, outBuffer);
379 input += 16;
380 outBuffer += 16;
381 }
382 /* last block */
383 rijndaelDecrypt(key->rk, key->Nr, input, block);
384 padLen = block[15];
385 if (padLen >= 16) {
386 return BAD_DATA;
387 }
388 for (i = 16 - padLen; i < 16; i++) {
389 if (block[i] != padLen) {
390 return BAD_DATA;
391 }
392 }
393 memcpy(outBuffer, block, 16 - padLen);
394 break;
395
396 case MODE_CBC:
397 /* all blocks but last */
398 for (i = numBlocks - 1; i > 0; i--) {
399 rijndaelDecrypt(key->rk, key->Nr, input, block);
400 ((u32 *)(void *) block)[0] ^= ((u32 *)(void *) cipher->IV)[0];
401 ((u32 *)(void *) block)[1] ^= ((u32 *)(void *) cipher->IV)[1];
402 ((u32 *)(void *) block)[2] ^= ((u32 *)(void *) cipher->IV)[2];
403 ((u32 *)(void *) block)[3] ^= ((u32 *)(void *) cipher->IV)[3];
404 memcpy(cipher->IV, input, 16);
405 memcpy(outBuffer, block, 16);
406 input += 16;
407 outBuffer += 16;
408 }
409 /* last block */
410 rijndaelDecrypt(key->rk, key->Nr, input, block);
411 ((u32 *)(void *) block)[0] ^= ((u32 *)(void *) cipher->IV)[0];
412 ((u32 *)(void *) block)[1] ^= ((u32 *)(void *) cipher->IV)[1];
413 ((u32 *)(void *) block)[2] ^= ((u32 *)(void *) cipher->IV)[2];
414 ((u32 *)(void *) block)[3] ^= ((u32 *)(void *) cipher->IV)[3];
415 padLen = block[15];
416 if (padLen <= 0 || padLen > 16) {
417 return BAD_DATA;
418 }
419 for (i = 16 - padLen; i < 16; i++) {
420 if (block[i] != padLen) {
421 return BAD_DATA;
422 }
423 }
424 memcpy(outBuffer, block, 16 - padLen);
425 break;
426
427 default:
428 return BAD_CIPHER_STATE;
429 }
430
431 return 16 * numBlocks - padLen;
432}
433
445 BYTE * input, int inputLen, BYTE * outBuffer, int rounds)
446{
447 u8 block[16];
448
449 UNUSED(inputLen);
450
451 if (cipher == NULL || key == NULL) {
452 return BAD_CIPHER_STATE;
453 }
454
455 memcpy(block, input, 16);
456
457 switch (key->direction) {
458 case DIR_ENCRYPT:
459 rijndaelEncryptRound(key->rk, key->Nr, block, rounds);
460 break;
461
462 case DIR_DECRYPT:
463 rijndaelDecryptRound(key->rk, key->Nr, block, rounds);
464 break;
465
466 default:
467 return BAD_KEY_DIR;
468 }
469
470 memcpy(outBuffer, block, 16);
471
472 return TRUE;
473}
#define UNUSED(x)
#define TRUE
int blockEncrypt(cipherInstance *cipher, keyInstance *key, BYTE *input, int inputLen, BYTE *outBuffer)
Definition crypt_aes.c:145
int cipherUpdateRounds(cipherInstance *cipher, keyInstance *key, BYTE *input, int inputLen, BYTE *outBuffer, int rounds)
Definition crypt_aes.c:444
int padEncrypt(cipherInstance *cipher, keyInstance *key, BYTE *input, int inputOctets, BYTE *outBuffer)
Definition crypt_aes.c:224
int blockDecrypt(cipherInstance *cipher, keyInstance *key, BYTE *input, int inputLen, BYTE *outBuffer)
Definition crypt_aes.c:287
int makeKey(keyInstance *key, BYTE direction, int keyLen, const char *keyMaterial)
Definition crypt_aes.c:45
int cipherInit(cipherInstance *cipher, BYTE mode, char *IV)
Definition crypt_aes.c:105
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 DIR_DECRYPT
Definition crypt_aes.h:46
#define MODE_ECB
Definition crypt_aes.h:47
unsigned char BYTE
Definition crypt_aes.h:71
#define BAD_KEY_DIR
Definition crypt_aes.h:55
#define BAD_KEY_INSTANCE
Definition crypt_aes.h:57
#define DIR_ENCRYPT
Definition crypt_aes.h:45
#define BAD_DATA
Definition crypt_aes.h:62
#define BAD_KEY_MAT
Definition crypt_aes.h:56
#define BAD_CIPHER_INSTANCE
Definition crypt_aes.h:61
#define MODE_CFB1
Definition crypt_aes.h:49
#define MAX_IV_SIZE
Definition crypt_aes.h:67
#define BAD_CIPHER_MODE
Definition crypt_aes.h:58
int rijndaelKeySetupDec(u32 rk[], const u8 cipherKey[], int keyBits)
void rijndaelEncryptRound(const u32 rk[], int Nr, u8 block[16], int rounds)
void rijndaelDecrypt(const u32 rk[], int Nr, const u8 ct[16], u8 pt[16])
int rijndaelKeySetupEnc(u32 rk[], const u8 cipherKey[], int keyBits)
void rijndaelEncrypt(const u32 rk[], int Nr, const u8 pt[16], u8 ct[16])
void rijndaelDecryptRound(const u32 rk[], int Nr, u8 block[16], int rounds)
#define MAXKB
unsigned int u32
Definition cuda_dxt.cu:12
uint8_t u8
Definition dxt62tga.c:12
enum openssl_mode mode
BYTE IV[MAX_IV_SIZE]
Definition crypt_aes.h:86
const char * key
Definition cineform.cpp:125