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

« back to all changes in this revision

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

  • Committer: Package Import Robot
  • Author(s): Mark Purcell
  • Date: 2014-01-28 18:23:36 UTC
  • mfrom: (1.1.11)
  • mto: This revision was merged to the branch mainline in revision 24.
  • Revision ID: package-import@ubuntu.com-20140128182336-3xenud1kbnwmf3mz
* New upstream release 
  - Fixes "New Upstream Release" (Closes: #735846)
  - Fixes "Ringtone does not stop" (Closes: #727164)
  - Fixes "[sflphone-kde] crash on startup" (Closes: #718178)
  - Fixes "sflphone GUI crashes when call is hung up" (Closes: #736583)
* Build-Depends: ensure GnuTLS 2.6
  - libucommon-dev (>= 6.0.7-1.1), libccrtp-dev (>= 2.0.6-3)
  - Fixes "FTBFS Build-Depends libgnutls{26,28}-dev" (Closes: #722040)
* Fix "boost 1.49 is going away" unversioned Build-Depends: (Closes: #736746)
* Add Build-Depends: libsndfile-dev, nepomuk-core-dev

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
 
}