~ubuntu-branches/ubuntu/wily/sflphone/wily

« back to all changes in this revision

Viewing changes to daemon/libs/pjproject-2.2.1/third_party/srtp/crypto/ae_xfm/xfm.c

  • Committer: Package Import Robot
  • Author(s): Jonathan Riddell
  • Date: 2015-01-07 14:51:16 UTC
  • mfrom: (4.3.5 sid)
  • Revision ID: package-import@ubuntu.com-20150107145116-yxnafinf4lrdvrmx
Tags: 1.4.1-0.1ubuntu1
* Merge with Debian, remaining changes:
 - Drop soprano, nepomuk build-dep
* Drop ubuntu patches, now upstream

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * xfm.c
 
3
 *
 
4
 * Crypto transform implementation
 
5
 *
 
6
 * David A. McGrew
 
7
 * Cisco Systems, Inc.
 
8
 */
 
9
 
 
10
#include "cryptoalg.h"
 
11
#include "aes_cbc.h"
 
12
#include "hmac.h"
 
13
#include "crypto_kernel.h"   /* for crypto_get_random() */
 
14
 
 
15
#define KEY_LEN     16
 
16
#define ENC_KEY_LEN 16
 
17
#define MAC_KEY_LEN 16
 
18
#define IV_LEN      16
 
19
#define TAG_LEN     12
 
20
#define MAX_EXPAND  27
 
21
 
 
22
err_status_t
 
23
aes_128_cbc_hmac_sha1_96_func(void *key,            
 
24
                              void *clear,          
 
25
                              unsigned clear_len,       
 
26
                              void *iv,             
 
27
                              void *opaque,         
 
28
                              unsigned *opaque_len, 
 
29
                              void *auth_tag) {
 
30
  aes_cbc_ctx_t aes_ctx;
 
31
  hmac_ctx_t hmac_ctx;
 
32
  unsigned char enc_key[ENC_KEY_LEN];
 
33
  unsigned char mac_key[MAC_KEY_LEN];
 
34
  err_status_t status;
 
35
 
 
36
  /* check if we're doing authentication only */
 
37
  if ((iv == NULL) && (opaque == NULL) && (opaque_len == NULL)) {
 
38
      
 
39
      /* perform authentication only */
 
40
 
 
41
  } else if ((iv == NULL) || (opaque == NULL) || (opaque_len == NULL)) {
 
42
    
 
43
    /*
 
44
     * bad parameter - we expect either all three pointers to be NULL,
 
45
     * or none of those pointers to be NULL 
 
46
     */
 
47
    return err_status_fail;
 
48
 
 
49
  } else {
 
50
 
 
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;
 
56
 
 
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;
 
61
 
 
62
 
 
63
    /* perform encryption and authentication */
 
64
 
 
65
    /* set aes key */
 
66
    status = aes_cbc_context_init(&aes_ctx, key, direction_encrypt);
 
67
    if (status) return status;
 
68
 
 
69
    /* set iv */
 
70
    status = crypto_get_random(iv, IV_LEN);  
 
71
    if (status) return status; 
 
72
    status = aes_cbc_set_iv(&aes_ctx, iv);
 
73
    
 
74
    /* encrypt the opaque data  */
 
75
    status = aes_cbc_nist_encrypt(&aes_ctx, opaque, opaque_len);
 
76
    if (status) return status;
 
77
 
 
78
    /* authenticate clear and opaque data */
 
79
    status = hmac_init(&hmac_ctx, mac_key, MAC_KEY_LEN);
 
80
    if (status) return status;
 
81
 
 
82
    status = hmac_start(&hmac_ctx);
 
83
    if (status) return status;
 
84
 
 
85
    status = hmac_update(&hmac_ctx, clear, clear_len);
 
86
    if (status) return status;
 
87
 
 
88
    status = hmac_compute(&hmac_ctx, opaque, *opaque_len, TAG_LEN, auth_tag);
 
89
    if (status) return status;
 
90
 
 
91
  }
 
92
 
 
93
  return err_status_ok;
 
94
}
 
95
 
 
96
err_status_t
 
97
aes_128_cbc_hmac_sha1_96_inv(void *key,            
 
98
                             void *clear,          
 
99
                             unsigned clear_len,       
 
100
                             void *iv,             
 
101
                             void *opaque,         
 
102
                             unsigned *opaque_len, 
 
103
                             void *auth_tag) {
 
104
  aes_cbc_ctx_t aes_ctx;
 
105
  hmac_ctx_t hmac_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;
 
110
  err_status_t status;
 
111
  int i;
 
112
  
 
113
  /* check if we're doing authentication only */
 
114
  if ((iv == NULL) && (opaque == NULL) && (opaque_len == NULL)) {
 
115
      
 
116
      /* perform authentication only */
 
117
 
 
118
  } else if ((iv == NULL) || (opaque == NULL) || (opaque_len == NULL)) {
 
119
    
 
120
    /*
 
121
     * bad parameter - we expect either all three pointers to be NULL,
 
122
     * or none of those pointers to be NULL 
 
123
     */
 
124
    return err_status_fail;
 
125
 
 
126
  } else {
 
127
 
 
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;
 
133
 
 
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;
 
138
 
 
139
    /* perform encryption and authentication */
 
140
 
 
141
    /* set aes key */
 
142
    status = aes_cbc_context_init(&aes_ctx, key, direction_decrypt);
 
143
    if (status) return status;
 
144
 
 
145
    /* set iv */
 
146
    status = rand_source_get_octet_string(iv, IV_LEN);  
 
147
    if (status) return status; 
 
148
    status = aes_cbc_set_iv(&aes_ctx, iv);
 
149
    
 
150
    /* encrypt the opaque data  */
 
151
    status = aes_cbc_nist_decrypt(&aes_ctx, opaque, opaque_len);
 
152
    if (status) return status;
 
153
 
 
154
    /* authenticate clear and opaque data */
 
155
    status = hmac_init(&hmac_ctx, mac_key, MAC_KEY_LEN);
 
156
    if (status) return status;
 
157
 
 
158
    status = hmac_start(&hmac_ctx);
 
159
    if (status) return status;
 
160
 
 
161
    status = hmac_update(&hmac_ctx, clear, clear_len);
 
162
    if (status) return status;
 
163
 
 
164
    status = hmac_compute(&hmac_ctx, opaque, *opaque_len, TAG_LEN, tmp_tag);
 
165
    if (status) return status;
 
166
 
 
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; 
 
171
 
 
172
  }
 
173
 
 
174
  return err_status_ok;
 
175
}
 
176
 
 
177
 
 
178
#define ENC 1
 
179
 
 
180
// eVC4 declares DEBUG
 
181
#undef DEBUG
 
182
 
 
183
#define DEBUG 0
 
184
 
 
185
err_status_t
 
186
aes_128_cbc_hmac_sha1_96_enc(void *key,            
 
187
                             const void *clear,          
 
188
                             unsigned clear_len,       
 
189
                             void *iv,             
 
190
                             void *opaque,         
 
191
                             unsigned *opaque_len) {
 
192
  aes_cbc_ctx_t aes_ctx;
 
193
  hmac_ctx_t hmac_ctx;
 
194
  unsigned char enc_key[ENC_KEY_LEN];
 
195
  unsigned char mac_key[MAC_KEY_LEN];
 
196
  unsigned char *auth_tag;
 
197
  err_status_t status;
 
198
 
 
199
  /* check if we're doing authentication only */
 
200
  if ((iv == NULL) && (opaque == NULL) && (opaque_len == NULL)) {
 
201
      
 
202
      /* perform authentication only */
 
203
 
 
204
  } else if ((iv == NULL) || (opaque == NULL) || (opaque_len == NULL)) {
 
205
    
 
206
    /*
 
207
     * bad parameter - we expect either all three pointers to be NULL,
 
208
     * or none of those pointers to be NULL 
 
209
     */
 
210
    return err_status_fail;
 
211
 
 
212
  } else {
 
213
 
 
214
#if DEBUG
 
215
    printf("ENC using key %s\n", octet_string_hex_string(key, KEY_LEN));
 
216
#endif
 
217
 
 
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;
 
223
 
 
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;
 
228
 
 
229
 
 
230
    /* perform encryption and authentication */
 
231
 
 
232
    /* set aes key */
 
233
    status = aes_cbc_context_init(&aes_ctx, key, direction_encrypt);
 
234
    if (status) return status;
 
235
 
 
236
    /* set iv */
 
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;
 
241
 
 
242
#if DEBUG
 
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));
 
246
#endif
 
247
 
 
248
#if ENC    
 
249
    /* encrypt the opaque data  */
 
250
    status = aes_cbc_nist_encrypt(&aes_ctx, opaque, opaque_len);
 
251
    if (status) return status;
 
252
#endif
 
253
 
 
254
#if DEBUG
 
255
    printf("ciphertext len: %d\n", *opaque_len);
 
256
    printf("ciphertext: %s\n", octet_string_hex_string(opaque, *opaque_len));
 
257
#endif
 
258
 
 
259
    /*
 
260
     * authenticate clear and opaque data, then write the
 
261
     * authentication tag to the location immediately following the
 
262
     * ciphertext
 
263
     */
 
264
    status = hmac_init(&hmac_ctx, mac_key, MAC_KEY_LEN);
 
265
    if (status) return status;
 
266
 
 
267
    status = hmac_start(&hmac_ctx);
 
268
    if (status) return status;
 
269
 
 
270
    status = hmac_update(&hmac_ctx, clear, clear_len);
 
271
    if (status) return status;
 
272
#if DEBUG
 
273
    printf("hmac input: %s\n", 
 
274
           octet_string_hex_string(clear, clear_len));
 
275
#endif
 
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;
 
280
#if DEBUG
 
281
    printf("hmac input: %s\n", 
 
282
           octet_string_hex_string(opaque, *opaque_len));
 
283
#endif
 
284
    /* bump up the opaque_len to reflect the authentication tag */
 
285
    *opaque_len += TAG_LEN;
 
286
 
 
287
#if DEBUG
 
288
    printf("prot data len:  %d\n", *opaque_len);
 
289
    printf("prot data: %s\n", octet_string_hex_string(opaque, *opaque_len));
 
290
#endif
 
291
  }
 
292
 
 
293
  return err_status_ok;
 
294
}
 
295
 
 
296
err_status_t
 
297
aes_128_cbc_hmac_sha1_96_dec(void *key,            
 
298
                             const void *clear,          
 
299
                             unsigned clear_len,       
 
300
                             void *iv,             
 
301
                             void *opaque,         
 
302
                             unsigned *opaque_len) {
 
303
  aes_cbc_ctx_t aes_ctx;
 
304
  hmac_ctx_t hmac_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;
 
310
  err_status_t status;
 
311
  int i;
 
312
  
 
313
  /* check if we're doing authentication only */
 
314
  if ((iv == NULL) && (opaque == NULL) && (opaque_len == NULL)) {
 
315
      
 
316
      /* perform authentication only */
 
317
 
 
318
  } else if ((iv == NULL) || (opaque == NULL) || (opaque_len == NULL)) {
 
319
    
 
320
    /*
 
321
     * bad parameter - we expect either all three pointers to be NULL,
 
322
     * or none of those pointers to be NULL 
 
323
     */
 
324
    return err_status_fail;
 
325
 
 
326
  } else {
 
327
#if DEBUG
 
328
    printf("DEC using key %s\n", octet_string_hex_string(key, KEY_LEN));
 
329
#endif
 
330
 
 
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;
 
336
 
 
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;
 
341
 
 
342
#if DEBUG
 
343
    printf("prot data len:  %d\n", *opaque_len);
 
344
    printf("prot data: %s\n", octet_string_hex_string(opaque, *opaque_len));
 
345
#endif
 
346
 
 
347
    /* 
 
348
     * set the protected data length to that of the ciphertext, by
 
349
     * subtracting out the length of the authentication tag 
 
350
     */
 
351
    ciphertext_len = *opaque_len - TAG_LEN;
 
352
 
 
353
#if DEBUG
 
354
    printf("ciphertext len: %d\n", ciphertext_len);
 
355
#endif    
 
356
    /* verify the authentication tag */
 
357
 
 
358
    /* 
 
359
     * compute the authentication tag for the clear and opaque data,
 
360
     * and write it to a temporary location
 
361
     */
 
362
    status = hmac_init(&hmac_ctx, mac_key, MAC_KEY_LEN);
 
363
    if (status) return status;
 
364
 
 
365
    status = hmac_start(&hmac_ctx);
 
366
    if (status) return status;
 
367
 
 
368
    status = hmac_update(&hmac_ctx, clear, clear_len);
 
369
    if (status) return status;
 
370
 
 
371
#if DEBUG
 
372
    printf("hmac input: %s\n", 
 
373
           octet_string_hex_string(clear, clear_len));
 
374
#endif
 
375
 
 
376
    status = hmac_compute(&hmac_ctx, opaque, ciphertext_len, TAG_LEN, tmp_tag);
 
377
    if (status) return status;
 
378
 
 
379
#if DEBUG
 
380
    printf("hmac input: %s\n", 
 
381
           octet_string_hex_string(opaque, ciphertext_len));
 
382
#endif
 
383
 
 
384
    /* 
 
385
     * compare the computed tag with the one provided as input (which
 
386
     * immediately follows the ciphertext)
 
387
     */
 
388
    auth_tag = (unsigned char *)opaque;
 
389
    auth_tag += ciphertext_len;  
 
390
#if DEBUG
 
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));
 
393
#endif
 
394
    for (i=0; i < TAG_LEN; i++) {
 
395
      if (tmp_tag[i] != auth_tag[i]) 
 
396
        return err_status_auth_fail; 
 
397
    }
 
398
 
 
399
    /* bump down the opaque_len to reflect the authentication tag */
 
400
    *opaque_len -= TAG_LEN;
 
401
 
 
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;
 
407
 
 
408
#if DEBUG
 
409
    printf("ciphertext: %s\n", octet_string_hex_string(opaque, *opaque_len));
 
410
    printf("iv:         %s\n", octet_string_hex_string(iv, IV_LEN));
 
411
#endif
 
412
 
 
413
#if ENC
 
414
    status = aes_cbc_nist_decrypt(&aes_ctx, opaque, &ciphertext_len);
 
415
    if (status) return status;
 
416
#endif
 
417
 
 
418
#if DEBUG
 
419
    printf("plaintext len:  %d\n", ciphertext_len);
 
420
    printf("plaintext:  %s\n", 
 
421
           octet_string_hex_string(opaque, ciphertext_len));
 
422
#endif
 
423
 
 
424
    /* indicate the length of the plaintext  */
 
425
    *opaque_len = ciphertext_len;
 
426
  }
 
427
 
 
428
  return err_status_ok;
 
429
}
 
430
 
 
431
cryptoalg_ctx_t cryptoalg_ctx = {
 
432
  aes_128_cbc_hmac_sha1_96_enc,
 
433
  aes_128_cbc_hmac_sha1_96_dec,
 
434
  KEY_LEN,
 
435
  IV_LEN,
 
436
  TAG_LEN,
 
437
  MAX_EXPAND,
 
438
};
 
439
 
 
440
cryptoalg_t cryptoalg = &cryptoalg_ctx;
 
441
 
 
442
#define NULL_TAG_LEN 12
 
443
 
 
444
err_status_t
 
445
null_enc(void *key,            
 
446
         const void *clear,          
 
447
         unsigned clear_len,       
 
448
         void *iv,             
 
449
         void *opaque,         
 
450
         unsigned *opaque_len) {
 
451
  int i;
 
452
  unsigned char *auth_tag;
 
453
  unsigned char *init_vec = iv;
 
454
 
 
455
  /* check if we're doing authentication only */
 
456
  if ((iv == NULL) && (opaque == NULL) && (opaque_len == NULL)) {
 
457
      
 
458
      /* perform authentication only */
 
459
 
 
460
  } else if ((iv == NULL) || (opaque == NULL) || (opaque_len == NULL)) {
 
461
    
 
462
    /*
 
463
     * bad parameter - we expect either all three pointers to be NULL,
 
464
     * or none of those pointers to be NULL 
 
465
     */
 
466
    return err_status_fail;
 
467
 
 
468
  } else {
 
469
 
 
470
#if DEBUG
 
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);
 
474
#endif
 
475
    for (i=0; i < IV_LEN; i++)
 
476
      init_vec[i] = i + (i * 16);
 
477
#if DEBUG
 
478
    printf("iv:                %s\n", 
 
479
           octet_string_hex_string(iv, IV_LEN));
 
480
    printf("plaintext:         %s\n", 
 
481
           octet_string_hex_string(opaque, *opaque_len));
 
482
#endif
 
483
    auth_tag = opaque;
 
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;
 
488
#if DEBUG
 
489
    printf("protected data len: %d\n", *opaque_len);
 
490
    printf("protected data:    %s\n", 
 
491
           octet_string_hex_string(opaque, *opaque_len));
 
492
#endif
 
493
 
 
494
  }
 
495
 
 
496
  return err_status_ok;
 
497
}
 
498
 
 
499
err_status_t
 
500
null_dec(void *key,            
 
501
         const void *clear,          
 
502
         unsigned clear_len,       
 
503
         void *iv,             
 
504
         void *opaque,         
 
505
         unsigned *opaque_len) {
 
506
  unsigned char *auth_tag;
 
507
  
 
508
  /* check if we're doing authentication only */
 
509
  if ((iv == NULL) && (opaque == NULL) && (opaque_len == NULL)) {
 
510
      
 
511
      /* perform authentication only */
 
512
 
 
513
  } else if ((iv == NULL) || (opaque == NULL) || (opaque_len == NULL)) {
 
514
    
 
515
    /*
 
516
     * bad parameter - we expect either all three pointers to be NULL,
 
517
     * or none of those pointers to be NULL 
 
518
     */
 
519
    return err_status_fail;
 
520
 
 
521
  } else {
 
522
 
 
523
#if DEBUG
 
524
    printf("NULL DEC using key %s\n", octet_string_hex_string(key, KEY_LEN));
 
525
 
 
526
    printf("protected data len: %d\n", *opaque_len);
 
527
    printf("protected data:    %s\n", 
 
528
           octet_string_hex_string(opaque, *opaque_len));
 
529
#endif
 
530
    auth_tag = opaque;
 
531
    auth_tag += (*opaque_len - NULL_TAG_LEN);
 
532
#if DEBUG
 
533
    printf("iv:         %s\n", octet_string_hex_string(iv, IV_LEN));
 
534
#endif
 
535
    *opaque_len -= NULL_TAG_LEN;
 
536
#if DEBUG
 
537
    printf("plaintext len:  %d\n", *opaque_len);
 
538
    printf("plaintext:  %s\n", 
 
539
           octet_string_hex_string(opaque, *opaque_len));
 
540
#endif
 
541
  }
 
542
 
 
543
  return err_status_ok;
 
544
}
 
545
 
 
546
cryptoalg_ctx_t null_cryptoalg_ctx = {
 
547
  null_enc,
 
548
  null_dec,
 
549
  KEY_LEN,
 
550
  IV_LEN,
 
551
  NULL_TAG_LEN,
 
552
  MAX_EXPAND,
 
553
};
 
554
 
 
555
cryptoalg_t null_cryptoalg = &null_cryptoalg_ctx;
 
556
 
 
557
int
 
558
cryptoalg_get_id(cryptoalg_t c) {
 
559
  if (c == cryptoalg)
 
560
    return 1;
 
561
  return 0;
 
562
}
 
563
 
 
564
cryptoalg_t 
 
565
cryptoalg_find_by_id(int id) {
 
566
  switch(id) {
 
567
  case 1:
 
568
    return cryptoalg;
 
569
  default:
 
570
    break;
 
571
  }
 
572
  return 0;
 
573
}