4
* Crypto transform implementation
10
#include "cryptoalg.h"
13
#include "crypto_kernel.h" /* for crypto_get_random() */
16
#define ENC_KEY_LEN 16
17
#define MAC_KEY_LEN 16
23
aes_128_cbc_hmac_sha1_96_func(void *key,
30
aes_cbc_ctx_t aes_ctx;
32
unsigned char enc_key[ENC_KEY_LEN];
33
unsigned char mac_key[MAC_KEY_LEN];
36
/* check if we're doing authentication only */
37
if ((iv == NULL) && (opaque == NULL) && (opaque_len == NULL)) {
39
/* perform authentication only */
41
} else if ((iv == NULL) || (opaque == NULL) || (opaque_len == NULL)) {
44
* bad parameter - we expect either all three pointers to be NULL,
45
* or none of those pointers to be NULL
47
return err_status_fail;
51
/* derive encryption and authentication keys from the input key */
52
status = hmac_init(&hmac_ctx, key, KEY_LEN);
53
if (status) return status;
54
status = hmac_compute(&hmac_ctx, "ENC", 3, ENC_KEY_LEN, enc_key);
55
if (status) return status;
57
status = hmac_init(&hmac_ctx, key, KEY_LEN);
58
if (status) return status;
59
status = hmac_compute(&hmac_ctx, "MAC", 3, MAC_KEY_LEN, mac_key);
60
if (status) return status;
63
/* perform encryption and authentication */
66
status = aes_cbc_context_init(&aes_ctx, key, direction_encrypt);
67
if (status) return status;
70
status = crypto_get_random(iv, IV_LEN);
71
if (status) return status;
72
status = aes_cbc_set_iv(&aes_ctx, iv);
74
/* encrypt the opaque data */
75
status = aes_cbc_nist_encrypt(&aes_ctx, opaque, opaque_len);
76
if (status) return status;
78
/* authenticate clear and opaque data */
79
status = hmac_init(&hmac_ctx, mac_key, MAC_KEY_LEN);
80
if (status) return status;
82
status = hmac_start(&hmac_ctx);
83
if (status) return status;
85
status = hmac_update(&hmac_ctx, clear, clear_len);
86
if (status) return status;
88
status = hmac_compute(&hmac_ctx, opaque, *opaque_len, TAG_LEN, auth_tag);
89
if (status) return status;
97
aes_128_cbc_hmac_sha1_96_inv(void *key,
102
unsigned *opaque_len,
104
aes_cbc_ctx_t aes_ctx;
106
unsigned char enc_key[ENC_KEY_LEN];
107
unsigned char mac_key[MAC_KEY_LEN];
108
unsigned char tmp_tag[TAG_LEN];
109
unsigned char *tag = auth_tag;
113
/* check if we're doing authentication only */
114
if ((iv == NULL) && (opaque == NULL) && (opaque_len == NULL)) {
116
/* perform authentication only */
118
} else if ((iv == NULL) || (opaque == NULL) || (opaque_len == NULL)) {
121
* bad parameter - we expect either all three pointers to be NULL,
122
* or none of those pointers to be NULL
124
return err_status_fail;
128
/* derive encryption and authentication keys from the input key */
129
status = hmac_init(&hmac_ctx, key, KEY_LEN);
130
if (status) return status;
131
status = hmac_compute(&hmac_ctx, "ENC", 3, ENC_KEY_LEN, enc_key);
132
if (status) return status;
134
status = hmac_init(&hmac_ctx, key, KEY_LEN);
135
if (status) return status;
136
status = hmac_compute(&hmac_ctx, "MAC", 3, MAC_KEY_LEN, mac_key);
137
if (status) return status;
139
/* perform encryption and authentication */
142
status = aes_cbc_context_init(&aes_ctx, key, direction_decrypt);
143
if (status) return status;
146
status = rand_source_get_octet_string(iv, IV_LEN);
147
if (status) return status;
148
status = aes_cbc_set_iv(&aes_ctx, iv);
150
/* encrypt the opaque data */
151
status = aes_cbc_nist_decrypt(&aes_ctx, opaque, opaque_len);
152
if (status) return status;
154
/* authenticate clear and opaque data */
155
status = hmac_init(&hmac_ctx, mac_key, MAC_KEY_LEN);
156
if (status) return status;
158
status = hmac_start(&hmac_ctx);
159
if (status) return status;
161
status = hmac_update(&hmac_ctx, clear, clear_len);
162
if (status) return status;
164
status = hmac_compute(&hmac_ctx, opaque, *opaque_len, TAG_LEN, tmp_tag);
165
if (status) return status;
167
/* compare the computed tag with the one provided as input */
168
for (i=0; i < TAG_LEN; i++)
169
if (tmp_tag[i] != tag[i])
170
return err_status_auth_fail;
174
return err_status_ok;
180
// eVC4 declares DEBUG
186
aes_128_cbc_hmac_sha1_96_enc(void *key,
191
unsigned *opaque_len) {
192
aes_cbc_ctx_t aes_ctx;
194
unsigned char enc_key[ENC_KEY_LEN];
195
unsigned char mac_key[MAC_KEY_LEN];
196
unsigned char *auth_tag;
199
/* check if we're doing authentication only */
200
if ((iv == NULL) && (opaque == NULL) && (opaque_len == NULL)) {
202
/* perform authentication only */
204
} else if ((iv == NULL) || (opaque == NULL) || (opaque_len == NULL)) {
207
* bad parameter - we expect either all three pointers to be NULL,
208
* or none of those pointers to be NULL
210
return err_status_fail;
215
printf("ENC using key %s\n", octet_string_hex_string(key, KEY_LEN));
218
/* derive encryption and authentication keys from the input key */
219
status = hmac_init(&hmac_ctx, key, KEY_LEN);
220
if (status) return status;
221
status = hmac_compute(&hmac_ctx, "ENC", 3, ENC_KEY_LEN, enc_key);
222
if (status) return status;
224
status = hmac_init(&hmac_ctx, key, KEY_LEN);
225
if (status) return status;
226
status = hmac_compute(&hmac_ctx, "MAC", 3, MAC_KEY_LEN, mac_key);
227
if (status) return status;
230
/* perform encryption and authentication */
233
status = aes_cbc_context_init(&aes_ctx, key, direction_encrypt);
234
if (status) return status;
237
status = rand_source_get_octet_string(iv, IV_LEN);
238
if (status) return status;
239
status = aes_cbc_set_iv(&aes_ctx, iv);
240
if (status) return status;
243
printf("plaintext len: %d\n", *opaque_len);
244
printf("iv: %s\n", octet_string_hex_string(iv, IV_LEN));
245
printf("plaintext: %s\n", octet_string_hex_string(opaque, *opaque_len));
249
/* encrypt the opaque data */
250
status = aes_cbc_nist_encrypt(&aes_ctx, opaque, opaque_len);
251
if (status) return status;
255
printf("ciphertext len: %d\n", *opaque_len);
256
printf("ciphertext: %s\n", octet_string_hex_string(opaque, *opaque_len));
260
* authenticate clear and opaque data, then write the
261
* authentication tag to the location immediately following the
264
status = hmac_init(&hmac_ctx, mac_key, MAC_KEY_LEN);
265
if (status) return status;
267
status = hmac_start(&hmac_ctx);
268
if (status) return status;
270
status = hmac_update(&hmac_ctx, clear, clear_len);
271
if (status) return status;
273
printf("hmac input: %s\n",
274
octet_string_hex_string(clear, clear_len));
276
auth_tag = (unsigned char *)opaque;
277
auth_tag += *opaque_len;
278
status = hmac_compute(&hmac_ctx, opaque, *opaque_len, TAG_LEN, auth_tag);
279
if (status) return status;
281
printf("hmac input: %s\n",
282
octet_string_hex_string(opaque, *opaque_len));
284
/* bump up the opaque_len to reflect the authentication tag */
285
*opaque_len += TAG_LEN;
288
printf("prot data len: %d\n", *opaque_len);
289
printf("prot data: %s\n", octet_string_hex_string(opaque, *opaque_len));
293
return err_status_ok;
297
aes_128_cbc_hmac_sha1_96_dec(void *key,
302
unsigned *opaque_len) {
303
aes_cbc_ctx_t aes_ctx;
305
unsigned char enc_key[ENC_KEY_LEN];
306
unsigned char mac_key[MAC_KEY_LEN];
307
unsigned char tmp_tag[TAG_LEN];
308
unsigned char *auth_tag;
309
unsigned ciphertext_len;
313
/* check if we're doing authentication only */
314
if ((iv == NULL) && (opaque == NULL) && (opaque_len == NULL)) {
316
/* perform authentication only */
318
} else if ((iv == NULL) || (opaque == NULL) || (opaque_len == NULL)) {
321
* bad parameter - we expect either all three pointers to be NULL,
322
* or none of those pointers to be NULL
324
return err_status_fail;
328
printf("DEC using key %s\n", octet_string_hex_string(key, KEY_LEN));
331
/* derive encryption and authentication keys from the input key */
332
status = hmac_init(&hmac_ctx, key, KEY_LEN);
333
if (status) return status;
334
status = hmac_compute(&hmac_ctx, "ENC", 3, ENC_KEY_LEN, enc_key);
335
if (status) return status;
337
status = hmac_init(&hmac_ctx, key, KEY_LEN);
338
if (status) return status;
339
status = hmac_compute(&hmac_ctx, "MAC", 3, MAC_KEY_LEN, mac_key);
340
if (status) return status;
343
printf("prot data len: %d\n", *opaque_len);
344
printf("prot data: %s\n", octet_string_hex_string(opaque, *opaque_len));
348
* set the protected data length to that of the ciphertext, by
349
* subtracting out the length of the authentication tag
351
ciphertext_len = *opaque_len - TAG_LEN;
354
printf("ciphertext len: %d\n", ciphertext_len);
356
/* verify the authentication tag */
359
* compute the authentication tag for the clear and opaque data,
360
* and write it to a temporary location
362
status = hmac_init(&hmac_ctx, mac_key, MAC_KEY_LEN);
363
if (status) return status;
365
status = hmac_start(&hmac_ctx);
366
if (status) return status;
368
status = hmac_update(&hmac_ctx, clear, clear_len);
369
if (status) return status;
372
printf("hmac input: %s\n",
373
octet_string_hex_string(clear, clear_len));
376
status = hmac_compute(&hmac_ctx, opaque, ciphertext_len, TAG_LEN, tmp_tag);
377
if (status) return status;
380
printf("hmac input: %s\n",
381
octet_string_hex_string(opaque, ciphertext_len));
385
* compare the computed tag with the one provided as input (which
386
* immediately follows the ciphertext)
388
auth_tag = (unsigned char *)opaque;
389
auth_tag += ciphertext_len;
391
printf("auth_tag: %s\n", octet_string_hex_string(auth_tag, TAG_LEN));
392
printf("tmp_tag: %s\n", octet_string_hex_string(tmp_tag, TAG_LEN));
394
for (i=0; i < TAG_LEN; i++) {
395
if (tmp_tag[i] != auth_tag[i])
396
return err_status_auth_fail;
399
/* bump down the opaque_len to reflect the authentication tag */
400
*opaque_len -= TAG_LEN;
402
/* decrypt the confidential data */
403
status = aes_cbc_context_init(&aes_ctx, key, direction_decrypt);
404
if (status) return status;
405
status = aes_cbc_set_iv(&aes_ctx, iv);
406
if (status) return status;
409
printf("ciphertext: %s\n", octet_string_hex_string(opaque, *opaque_len));
410
printf("iv: %s\n", octet_string_hex_string(iv, IV_LEN));
414
status = aes_cbc_nist_decrypt(&aes_ctx, opaque, &ciphertext_len);
415
if (status) return status;
419
printf("plaintext len: %d\n", ciphertext_len);
420
printf("plaintext: %s\n",
421
octet_string_hex_string(opaque, ciphertext_len));
424
/* indicate the length of the plaintext */
425
*opaque_len = ciphertext_len;
428
return err_status_ok;
431
cryptoalg_ctx_t cryptoalg_ctx = {
432
aes_128_cbc_hmac_sha1_96_enc,
433
aes_128_cbc_hmac_sha1_96_dec,
440
cryptoalg_t cryptoalg = &cryptoalg_ctx;
442
#define NULL_TAG_LEN 12
450
unsigned *opaque_len) {
452
unsigned char *auth_tag;
453
unsigned char *init_vec = iv;
455
/* check if we're doing authentication only */
456
if ((iv == NULL) && (opaque == NULL) && (opaque_len == NULL)) {
458
/* perform authentication only */
460
} else if ((iv == NULL) || (opaque == NULL) || (opaque_len == NULL)) {
463
* bad parameter - we expect either all three pointers to be NULL,
464
* or none of those pointers to be NULL
466
return err_status_fail;
471
printf("NULL ENC using key %s\n", octet_string_hex_string(key, KEY_LEN));
472
printf("NULL_TAG_LEN: %d\n", NULL_TAG_LEN);
473
printf("plaintext len: %d\n", *opaque_len);
475
for (i=0; i < IV_LEN; i++)
476
init_vec[i] = i + (i * 16);
479
octet_string_hex_string(iv, IV_LEN));
480
printf("plaintext: %s\n",
481
octet_string_hex_string(opaque, *opaque_len));
484
auth_tag += *opaque_len;
485
for (i=0; i < NULL_TAG_LEN; i++)
486
auth_tag[i] = i + (i * 16);
487
*opaque_len += NULL_TAG_LEN;
489
printf("protected data len: %d\n", *opaque_len);
490
printf("protected data: %s\n",
491
octet_string_hex_string(opaque, *opaque_len));
496
return err_status_ok;
505
unsigned *opaque_len) {
506
unsigned char *auth_tag;
508
/* check if we're doing authentication only */
509
if ((iv == NULL) && (opaque == NULL) && (opaque_len == NULL)) {
511
/* perform authentication only */
513
} else if ((iv == NULL) || (opaque == NULL) || (opaque_len == NULL)) {
516
* bad parameter - we expect either all three pointers to be NULL,
517
* or none of those pointers to be NULL
519
return err_status_fail;
524
printf("NULL DEC using key %s\n", octet_string_hex_string(key, KEY_LEN));
526
printf("protected data len: %d\n", *opaque_len);
527
printf("protected data: %s\n",
528
octet_string_hex_string(opaque, *opaque_len));
531
auth_tag += (*opaque_len - NULL_TAG_LEN);
533
printf("iv: %s\n", octet_string_hex_string(iv, IV_LEN));
535
*opaque_len -= NULL_TAG_LEN;
537
printf("plaintext len: %d\n", *opaque_len);
538
printf("plaintext: %s\n",
539
octet_string_hex_string(opaque, *opaque_len));
543
return err_status_ok;
546
cryptoalg_ctx_t null_cryptoalg_ctx = {
555
cryptoalg_t null_cryptoalg = &null_cryptoalg_ctx;
558
cryptoalg_get_id(cryptoalg_t c) {
565
cryptoalg_find_by_id(int id) {