~noskcaj/ubuntu/saucy/sflphone/merge-1.2.3-2

« back to all changes in this revision

Viewing changes to daemon/libs/pjproject-2.0.1/third_party/srtp/test/srtp_driver.c

  • Committer: Jackson Doak
  • Date: 2013-07-10 21:04:46 UTC
  • mfrom: (20.1.3 sid)
  • Revision ID: noskcaj@ubuntu.com-20130710210446-y8f587vza807icr9
Properly merged from upstream.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * srtp_driver.c
 
3
 *
 
4
 * a test driver for libSRTP
 
5
 *
 
6
 * David A. McGrew
 
7
 * Cisco Systems, Inc.
 
8
 */
 
9
/*
 
10
 *
 
11
 * Copyright (c) 2001-2006, Cisco Systems, Inc.
 
12
 * All rights reserved.
 
13
 *
 
14
 * Redistribution and use in source and binary forms, with or without
 
15
 * modification, are permitted provided that the following conditions
 
16
 * are met:
 
17
 *
 
18
 *   Redistributions of source code must retain the above copyright
 
19
 *   notice, this list of conditions and the following disclaimer.
 
20
 *
 
21
 *   Redistributions in binary form must reproduce the above
 
22
 *   copyright notice, this list of conditions and the following
 
23
 *   disclaimer in the documentation and/or other materials provided
 
24
 *   with the distribution.
 
25
 *
 
26
 *   Neither the name of the Cisco Systems, Inc. nor the names of its
 
27
 *   contributors may be used to endorse or promote products derived
 
28
 *   from this software without specific prior written permission.
 
29
 *
 
30
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 
31
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 
32
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 
33
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 
34
 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
 
35
 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 
36
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 
37
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 
38
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 
39
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 
40
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 
41
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 
42
 *
 
43
 */
 
44
 
 
45
 
 
46
#include <string.h>   /* for memcpy()          */
 
47
#include <time.h>     /* for clock()           */
 
48
#include <stdlib.h>   /* for malloc(), free()  */
 
49
#include <stdio.h>    /* for print(), fflush() */
 
50
#include "getopt_s.h" /* for local getopt()    */
 
51
 
 
52
#include "srtp_priv.h"
 
53
 
 
54
#ifdef HAVE_NETINET_IN_H
 
55
# include <netinet/in.h>
 
56
#elif defined HAVE_WINSOCK2_H
 
57
# include <winsock2.h>
 
58
#endif
 
59
 
 
60
#define PRINT_REFERENCE_PACKET 1
 
61
 
 
62
err_status_t
 
63
srtp_validate(void);
 
64
 
 
65
err_status_t
 
66
srtp_create_big_policy(srtp_policy_t **list);
 
67
 
 
68
err_status_t
 
69
srtp_test_remove_stream(void);
 
70
 
 
71
double
 
72
srtp_bits_per_second(int msg_len_octets, const srtp_policy_t *policy);
 
73
 
 
74
double
 
75
srtp_rejections_per_second(int msg_len_octets, const srtp_policy_t *policy);
 
76
 
 
77
void
 
78
srtp_do_timing(const srtp_policy_t *policy);
 
79
 
 
80
void
 
81
srtp_do_rejection_timing(const srtp_policy_t *policy);
 
82
 
 
83
err_status_t
 
84
srtp_test(const srtp_policy_t *policy);
 
85
 
 
86
err_status_t
 
87
srtcp_test(const srtp_policy_t *policy);
 
88
 
 
89
err_status_t
 
90
srtp_session_print_policy(srtp_t srtp);
 
91
 
 
92
err_status_t
 
93
srtp_print_policy(const srtp_policy_t *policy);
 
94
 
 
95
char *
 
96
srtp_packet_to_string(srtp_hdr_t *hdr, int packet_len);
 
97
 
 
98
double
 
99
mips_estimate(int num_trials, int *ignore);
 
100
 
 
101
extern uint8_t test_key[30];
 
102
 
 
103
void
 
104
usage(char *prog_name) {
 
105
  printf("usage: %s [ -t ][ -c ][ -v ][-d <debug_module> ]* [ -l ]\n"
 
106
         "  -t         run timing test\n"
 
107
         "  -r         run rejection timing test\n"
 
108
         "  -c         run codec timing test\n"
 
109
         "  -v         run validation tests\n"
 
110
         "  -d <mod>   turn on debugging module <mod>\n"
 
111
         "  -l         list debugging modules\n", prog_name);
 
112
  exit(1);
 
113
}
 
114
 
 
115
/*
 
116
 * The policy_array is a null-terminated array of policy structs. it
 
117
 * is declared at the end of this file
 
118
 */
 
119
 
 
120
extern const srtp_policy_t *policy_array[];
 
121
 
 
122
 
 
123
/* the wildcard_policy is declared below; it has a wildcard ssrc */
 
124
 
 
125
extern const srtp_policy_t wildcard_policy;
 
126
 
 
127
/*
 
128
 * mod_driver debug module - debugging module for this test driver
 
129
 *
 
130
 * we use the crypto_kernel debugging system in this driver, which
 
131
 * makes the interface uniform and increases portability
 
132
 */
 
133
 
 
134
debug_module_t mod_driver = {
 
135
  0,                  /* debugging is off by default */
 
136
  "driver"            /* printable name for module   */
 
137
};
 
138
 
 
139
int
 
140
main (int argc, char *argv[]) {
 
141
  char q;
 
142
  unsigned do_timing_test    = 0;
 
143
  unsigned do_rejection_test = 0;
 
144
  unsigned do_codec_timing   = 0;
 
145
  unsigned do_validation     = 0;
 
146
  unsigned do_list_mods      = 0;
 
147
  err_status_t status;
 
148
 
 
149
  /*
 
150
   * verify that the compiler has interpreted the header data
 
151
   * structure srtp_hdr_t correctly
 
152
   */
 
153
  if (sizeof(srtp_hdr_t) != 12) {
 
154
     printf("error: srtp_hdr_t has incorrect size"
 
155
            "(size is %ld bytes, expected 12)\n",
 
156
            sizeof(srtp_hdr_t));
 
157
    exit(1);
 
158
  }
 
159
 
 
160
  /* initialize srtp library */
 
161
  status = srtp_init();
 
162
  if (status) {
 
163
    printf("error: srtp init failed with error code %d\n", status);
 
164
    exit(1);
 
165
  }
 
166
 
 
167
  /*  load srtp_driver debug module */
 
168
  status = crypto_kernel_load_debug_module(&mod_driver);
 
169
    if (status) {
 
170
    printf("error: load of srtp_driver debug module failed "
 
171
           "with error code %d\n", status);
 
172
    exit(1);
 
173
  }
 
174
 
 
175
  /* process input arguments */
 
176
  while (1) {
 
177
    q = getopt_s(argc, argv, "trcvld:");
 
178
    if (q == -1)
 
179
      break;
 
180
    switch (q) {
 
181
    case 't':
 
182
      do_timing_test = 1;
 
183
      break;
 
184
    case 'r':
 
185
      do_rejection_test = 1;
 
186
      break;
 
187
    case 'c':
 
188
      do_codec_timing = 1;
 
189
      break;
 
190
    case 'v':
 
191
      do_validation = 1;
 
192
      break;
 
193
    case 'l':
 
194
      do_list_mods = 1;
 
195
      break;
 
196
    case 'd':
 
197
      status = crypto_kernel_set_debug_module(optarg_s, 1);
 
198
      if (status) {
 
199
        printf("error: set debug module (%s) failed\n", optarg_s);
 
200
        exit(1);
 
201
      }
 
202
      break;
 
203
    default:
 
204
      usage(argv[0]);
 
205
    }
 
206
  }
 
207
 
 
208
  if (!do_validation && !do_timing_test && !do_codec_timing
 
209
      && !do_list_mods && !do_rejection_test)
 
210
    usage(argv[0]);
 
211
 
 
212
  if (do_list_mods) {
 
213
    status = crypto_kernel_list_debug_modules();
 
214
    if (status) {
 
215
      printf("error: list of debug modules failed\n");
 
216
      exit(1);
 
217
    }
 
218
  }
 
219
 
 
220
  if (do_validation) {
 
221
    const srtp_policy_t **policy = policy_array;
 
222
    srtp_policy_t *big_policy;
 
223
 
 
224
    /* loop over policy array, testing srtp and srtcp for each policy */
 
225
    while (*policy != NULL) {
 
226
      printf("testing srtp_protect and srtp_unprotect\n");
 
227
      if (srtp_test(*policy) == err_status_ok)
 
228
        printf("passed\n\n");
 
229
      else {
 
230
        printf("failed\n");
 
231
        exit(1);
 
232
      }
 
233
      printf("testing srtp_protect_rtcp and srtp_unprotect_rtcp\n");
 
234
      if (srtcp_test(*policy) == err_status_ok)
 
235
        printf("passed\n\n");
 
236
      else {
 
237
        printf("failed\n");
 
238
        exit(1);
 
239
      }
 
240
      policy++;
 
241
    }
 
242
 
 
243
    /* create a big policy list and run tests on it */
 
244
    status = srtp_create_big_policy(&big_policy);
 
245
    if (status) {
 
246
      printf("unexpected failure with error code %d\n", status);
 
247
      exit(1);
 
248
    }
 
249
    printf("testing srtp_protect and srtp_unprotect with big policy\n");
 
250
    if (srtp_test(big_policy) == err_status_ok)
 
251
      printf("passed\n\n");
 
252
    else {
 
253
      printf("failed\n");
 
254
      exit(1);
 
255
    }
 
256
 
 
257
    /* run test on wildcard policy */
 
258
    printf("testing srtp_protect and srtp_unprotect on "
 
259
           "wildcard ssrc policy\n");
 
260
    if (srtp_test(&wildcard_policy) == err_status_ok)
 
261
      printf("passed\n\n");
 
262
    else {
 
263
      printf("failed\n");
 
264
      exit(1);
 
265
    }
 
266
 
 
267
    /*
 
268
     * run validation test against the reference packets - note
 
269
     * that this test only covers the default policy
 
270
     */
 
271
    printf("testing srtp_protect and srtp_unprotect against "
 
272
           "reference packets\n");
 
273
    if (srtp_validate() == err_status_ok)
 
274
      printf("passed\n\n");
 
275
    else {
 
276
      printf("failed\n");
 
277
       exit(1);
 
278
    }
 
279
 
 
280
    /*
 
281
     * test the function srtp_remove_stream()
 
282
     */
 
283
    printf("testing srtp_remove_stream()...");
 
284
    if (srtp_test_remove_stream() == err_status_ok)
 
285
      printf("passed\n");
 
286
    else {
 
287
      printf("failed\n");
 
288
      exit(1);
 
289
    }
 
290
  }
 
291
 
 
292
  if (do_timing_test) {
 
293
    const srtp_policy_t **policy = policy_array;
 
294
 
 
295
    /* loop over policies, run timing test for each */
 
296
    while (*policy != NULL) {
 
297
      srtp_print_policy(*policy);
 
298
      srtp_do_timing(*policy);
 
299
      policy++;
 
300
    }
 
301
  }
 
302
 
 
303
  if (do_rejection_test) {
 
304
    const srtp_policy_t **policy = policy_array;
 
305
 
 
306
    /* loop over policies, run rejection timing test for each */
 
307
    while (*policy != NULL) {
 
308
      srtp_print_policy(*policy);
 
309
      srtp_do_rejection_timing(*policy);
 
310
      policy++;
 
311
    }
 
312
  }
 
313
 
 
314
  if (do_codec_timing) {
 
315
    srtp_policy_t policy;
 
316
    int ignore;
 
317
    double mips = mips_estimate(1000000000, &ignore);
 
318
 
 
319
    crypto_policy_set_rtp_default(&policy.rtp);
 
320
    crypto_policy_set_rtcp_default(&policy.rtcp);
 
321
    policy.ssrc.type  = ssrc_specific;
 
322
    policy.ssrc.value = 0xdecafbad;
 
323
    policy.key  = test_key;
 
324
    policy.next = NULL;
 
325
 
 
326
    printf("mips estimate: %e\n", mips);
 
327
 
 
328
    printf("testing srtp processing time for voice codecs:\n");
 
329
    printf("codec\t\tlength (octets)\t\tsrtp instructions/second\n");
 
330
    printf("G.711\t\t%d\t\t\t%e\n", 80,
 
331
           (double) mips * (80 * 8) /
 
332
           srtp_bits_per_second(80, &policy) / .01 );
 
333
    printf("G.711\t\t%d\t\t\t%e\n", 160,
 
334
           (double) mips * (160 * 8) /
 
335
           srtp_bits_per_second(160, &policy) / .02);
 
336
    printf("G.726-32\t%d\t\t\t%e\n", 40,
 
337
           (double) mips * (40 * 8) /
 
338
           srtp_bits_per_second(40, &policy) / .01 );
 
339
    printf("G.726-32\t%d\t\t\t%e\n", 80,
 
340
           (double) mips * (80 * 8) /
 
341
           srtp_bits_per_second(80, &policy) / .02);
 
342
    printf("G.729\t\t%d\t\t\t%e\n", 10,
 
343
           (double) mips * (10 * 8) /
 
344
           srtp_bits_per_second(10, &policy) / .01 );
 
345
    printf("G.729\t\t%d\t\t\t%e\n", 20,
 
346
           (double) mips * (20 * 8) /
 
347
           srtp_bits_per_second(20, &policy) / .02 );
 
348
    printf("Wideband\t%d\t\t\t%e\n", 320,
 
349
           (double) mips * (320 * 8) /
 
350
           srtp_bits_per_second(320, &policy) / .01 );
 
351
    printf("Wideband\t%d\t\t\t%e\n", 640,
 
352
           (double) mips * (640 * 8) /
 
353
           srtp_bits_per_second(640, &policy) / .02 );
 
354
  }
 
355
 
 
356
  return 0;
 
357
}
 
358
 
 
359
 
 
360
 
 
361
/*
 
362
 * srtp_create_test_packet(len, ssrc) returns a pointer to a
 
363
 * (malloced) example RTP packet whose data field has the length given
 
364
 * by pkt_octet_len and the SSRC value ssrc.  The total length of the
 
365
 * packet is twelve octets longer, since the header is at the
 
366
 * beginning.  There is room at the end of the packet for a trailer,
 
367
 * and the four octets following the packet are filled with 0xff
 
368
 * values to enable testing for overwrites.
 
369
 *
 
370
 * note that the location of the test packet can (and should) be
 
371
 * deallocated with the free() call once it is no longer needed.
 
372
 */
 
373
 
 
374
srtp_hdr_t *
 
375
srtp_create_test_packet(int pkt_octet_len, uint32_t ssrc) {
 
376
  int i;
 
377
  uint8_t *buffer;
 
378
  srtp_hdr_t *hdr;
 
379
  int bytes_in_hdr = 12;
 
380
 
 
381
  /* allocate memory for test packet */
 
382
  hdr = (srtp_hdr_t*) malloc(pkt_octet_len + bytes_in_hdr
 
383
               + SRTP_MAX_TRAILER_LEN + 4);
 
384
  if (!hdr)
 
385
    return NULL;
 
386
 
 
387
  hdr->version = 2;              /* RTP version two     */
 
388
  hdr->p    = 0;                 /* no padding needed   */
 
389
  hdr->x    = 0;                 /* no header extension */
 
390
  hdr->cc   = 0;                 /* no CSRCs            */
 
391
  hdr->m    = 0;                 /* marker bit          */
 
392
  hdr->pt   = 0xf;               /* payload type        */
 
393
  hdr->seq  = htons(0x1234);     /* sequence number     */
 
394
  hdr->ts   = htonl(0xdecafbad); /* timestamp           */
 
395
  hdr->ssrc = htonl(ssrc);       /* synch. source       */
 
396
 
 
397
  buffer = (uint8_t *)hdr;
 
398
  buffer += bytes_in_hdr;
 
399
 
 
400
  /* set RTP data to 0xab */
 
401
  for (i=0; i < pkt_octet_len; i++)
 
402
    *buffer++ = 0xab;
 
403
 
 
404
  /* set post-data value to 0xffff to enable overrun checking */
 
405
  for (i=0; i < SRTP_MAX_TRAILER_LEN+4; i++)
 
406
    *buffer++ = 0xff;
 
407
 
 
408
  return hdr;
 
409
}
 
410
 
 
411
void
 
412
srtp_do_timing(const srtp_policy_t *policy) {
 
413
  int len;
 
414
 
 
415
  /*
 
416
   * note: the output of this function is formatted so that it
 
417
   * can be used in gnuplot.  '#' indicates a comment, and "\r\n"
 
418
   * terminates a record
 
419
   */
 
420
 
 
421
  printf("# testing srtp throughput:\r\n");
 
422
  printf("# mesg length (octets)\tthroughput (megabits per second)\r\n");
 
423
 
 
424
  for (len=16; len <= 2048; len *= 2)
 
425
    printf("%d\t\t\t%f\r\n", len,
 
426
           srtp_bits_per_second(len, policy) / 1.0E6);
 
427
 
 
428
  /* these extra linefeeds let gnuplot know that a dataset is done */
 
429
  printf("\r\n\r\n");
 
430
 
 
431
}
 
432
 
 
433
void
 
434
srtp_do_rejection_timing(const srtp_policy_t *policy) {
 
435
  int len;
 
436
 
 
437
  /*
 
438
   * note: the output of this function is formatted so that it
 
439
   * can be used in gnuplot.  '#' indicates a comment, and "\r\n"
 
440
   * terminates a record
 
441
   */
 
442
 
 
443
  printf("# testing srtp rejection throughput:\r\n");
 
444
  printf("# mesg length (octets)\trejections per second\r\n");
 
445
 
 
446
  for (len=8; len <= 2048; len *= 2)
 
447
    printf("%d\t\t\t%e\r\n", len, srtp_rejections_per_second(len, policy));
 
448
 
 
449
  /* these extra linefeeds let gnuplot know that a dataset is done */
 
450
  printf("\r\n\r\n");
 
451
 
 
452
}
 
453
 
 
454
 
 
455
#define MAX_MSG_LEN 1024
 
456
 
 
457
double
 
458
srtp_bits_per_second(int msg_len_octets, const srtp_policy_t *policy) {
 
459
  srtp_t srtp;
 
460
  srtp_hdr_t *mesg;
 
461
  int i;
 
462
  clock_t timer;
 
463
  int num_trials = 100000;
 
464
  int len;
 
465
  uint32_t ssrc;
 
466
  err_status_t status;
 
467
 
 
468
  /*
 
469
   * allocate and initialize an srtp session
 
470
   */
 
471
  status = srtp_create(&srtp, policy);
 
472
  if (status) {
 
473
    printf("error: srtp_create() failed with error code %d\n", status);
 
474
    exit(1);
 
475
  }
 
476
 
 
477
  /*
 
478
   * if the ssrc is unspecified, use a predetermined one
 
479
   */
 
480
  if (policy->ssrc.type != ssrc_specific) {
 
481
    ssrc = 0xdeadbeef;
 
482
  } else {
 
483
    ssrc = policy->ssrc.value;
 
484
  }
 
485
 
 
486
  /*
 
487
   * create a test packet
 
488
   */
 
489
  mesg = srtp_create_test_packet(msg_len_octets, ssrc);
 
490
  if (mesg == NULL)
 
491
    return 0.0;   /* indicate failure by returning zero */
 
492
 
 
493
  timer = clock();
 
494
  for (i=0; i < num_trials; i++) {
 
495
    err_status_t status;
 
496
    len = msg_len_octets + 12;  /* add in rtp header length */
 
497
 
 
498
    /* srtp protect message */
 
499
    status = srtp_protect(srtp, mesg, &len);
 
500
    if (status) {
 
501
      printf("error: srtp_protect() failed with error code %d\n", status);
 
502
      exit(1);
 
503
    }
 
504
 
 
505
    /* increment message number */
 
506
    mesg->seq = htons(ntohs(mesg->seq) + 1);
 
507
 
 
508
  }
 
509
  timer = clock() - timer;
 
510
 
 
511
  free(mesg);
 
512
 
 
513
  return (double) (msg_len_octets) * 8 *
 
514
                  num_trials * CLOCKS_PER_SEC / timer;
 
515
}
 
516
 
 
517
double
 
518
srtp_rejections_per_second(int msg_len_octets, const srtp_policy_t *policy) {
 
519
  srtp_ctx_t *srtp;
 
520
  srtp_hdr_t *mesg;
 
521
  int i;
 
522
  int len;
 
523
  clock_t timer;
 
524
  int num_trials = 1000000;
 
525
  uint32_t ssrc = policy->ssrc.value;
 
526
  err_status_t status;
 
527
 
 
528
  /*
 
529
   * allocate and initialize an srtp session
 
530
   */
 
531
  status = srtp_create(&srtp, policy);
 
532
  if (status) {
 
533
    printf("error: srtp_create() failed with error code %d\n", status);
 
534
    exit(1);
 
535
  }
 
536
 
 
537
  mesg = srtp_create_test_packet(msg_len_octets, ssrc);
 
538
  if (mesg == NULL)
 
539
    return 0.0;  /* indicate failure by returning zero */
 
540
 
 
541
  len = msg_len_octets;
 
542
  srtp_protect(srtp, (srtp_hdr_t *)mesg, &len);
 
543
 
 
544
  timer = clock();
 
545
  for (i=0; i < num_trials; i++) {
 
546
    len = msg_len_octets;
 
547
    srtp_unprotect(srtp, (srtp_hdr_t *)mesg, &len);
 
548
  }
 
549
  timer = clock() - timer;
 
550
 
 
551
  free(mesg);
 
552
 
 
553
  return (double) num_trials * CLOCKS_PER_SEC / timer;
 
554
}
 
555
 
 
556
 
 
557
void
 
558
err_check(err_status_t s) {
 
559
  if (s == err_status_ok)
 
560
    return;
 
561
  else
 
562
    fprintf(stderr, "error: unexpected srtp failure (code %d)\n", s);
 
563
  exit (1);
 
564
}
 
565
 
 
566
err_status_t
 
567
srtp_test(const srtp_policy_t *policy) {
 
568
  int i;
 
569
  srtp_t srtp_sender;
 
570
  srtp_t srtp_rcvr;
 
571
  err_status_t status = err_status_ok;
 
572
  srtp_hdr_t *hdr, *hdr2;
 
573
  uint8_t hdr_enc[64];
 
574
  uint8_t *pkt_end;
 
575
  int msg_len_octets, msg_len_enc;
 
576
  int len;
 
577
  int tag_length = policy->rtp.auth_tag_len;
 
578
  uint32_t ssrc;
 
579
  srtp_policy_t *rcvr_policy;
 
580
 
 
581
  err_check(srtp_create(&srtp_sender, policy));
 
582
 
 
583
  /* print out policy */
 
584
  err_check(srtp_session_print_policy(srtp_sender));
 
585
 
 
586
  /*
 
587
   * initialize data buffer, using the ssrc in the policy unless that
 
588
   * value is a wildcard, in which case we'll just use an arbitrary
 
589
   * one
 
590
   */
 
591
  if (policy->ssrc.type != ssrc_specific)
 
592
    ssrc = 0xdecafbad;
 
593
  else
 
594
    ssrc = policy->ssrc.value;
 
595
  msg_len_octets = 28;
 
596
  hdr = srtp_create_test_packet(msg_len_octets, ssrc);
 
597
 
 
598
  if (hdr == NULL)
 
599
    return err_status_alloc_fail;
 
600
  hdr2 = srtp_create_test_packet(msg_len_octets, ssrc);
 
601
  if (hdr2 == NULL) {
 
602
    free(hdr);
 
603
    return err_status_alloc_fail;
 
604
  }
 
605
 
 
606
  /* set message length */
 
607
  len = msg_len_octets;
 
608
 
 
609
  debug_print(mod_driver, "before protection:\n%s",
 
610
              srtp_packet_to_string(hdr, len));
 
611
 
 
612
#if PRINT_REFERENCE_PACKET
 
613
  debug_print(mod_driver, "reference packet before protection:\n%s",
 
614
              octet_string_hex_string((uint8_t *)hdr, len));
 
615
#endif
 
616
  err_check(srtp_protect(srtp_sender, hdr, &len));
 
617
 
 
618
  debug_print(mod_driver, "after protection:\n%s",
 
619
              srtp_packet_to_string(hdr, len));
 
620
#if PRINT_REFERENCE_PACKET
 
621
  debug_print(mod_driver, "after protection:\n%s",
 
622
              octet_string_hex_string((uint8_t *)hdr, len));
 
623
#endif
 
624
 
 
625
  /* save protected message and length */
 
626
  memcpy(hdr_enc, hdr, len);
 
627
  msg_len_enc = len;
 
628
 
 
629
  /*
 
630
   * check for overrun of the srtp_protect() function
 
631
   *
 
632
   * The packet is followed by a value of 0xfffff; if the value of the
 
633
   * data following the packet is different, then we know that the
 
634
   * protect function is overwriting the end of the packet.
 
635
   */
 
636
  pkt_end = (uint8_t *)hdr + sizeof(srtp_hdr_t)
 
637
    + msg_len_octets + tag_length;
 
638
  for (i = 0; i < 4; i++)
 
639
    if (pkt_end[i] != 0xff) {
 
640
      fprintf(stdout, "overwrite in srtp_protect() function "
 
641
              "(expected %x, found %x in trailing octet %d)\n",
 
642
              0xff, ((uint8_t *)hdr)[i], i);
 
643
      free(hdr);
 
644
      free(hdr2);
 
645
      return err_status_algo_fail;
 
646
    }
 
647
 
 
648
  /*
 
649
   * if the policy includes confidentiality, check that ciphertext is
 
650
   * different than plaintext
 
651
   *
 
652
   * Note that this check will give false negatives, with some small
 
653
   * probability, especially if the packets are short.  For that
 
654
   * reason, we skip this check if the plaintext is less than four
 
655
   * octets long.
 
656
   */
 
657
  if ((policy->rtp.sec_serv & sec_serv_conf) && (msg_len_octets >= 4)) {
 
658
    printf("testing that ciphertext is distinct from plaintext...");
 
659
    status = err_status_algo_fail;
 
660
    for (i=12; i < msg_len_octets+12; i++)
 
661
      if (((uint8_t *)hdr)[i] != ((uint8_t *)hdr2)[i]) {
 
662
        status = err_status_ok;
 
663
      }
 
664
    if (status) {
 
665
      printf("failed\n");
 
666
      free(hdr);
 
667
      free(hdr2);
 
668
      return status;
 
669
    }
 
670
    printf("passed\n");
 
671
  }
 
672
 
 
673
  /*
 
674
   * if the policy uses a 'wildcard' ssrc, then we need to make a copy
 
675
   * of the policy that changes the direction to inbound
 
676
   *
 
677
   * we always copy the policy into the rcvr_policy, since otherwise
 
678
   * the compiler would fret about the constness of the policy
 
679
   */
 
680
  rcvr_policy = (srtp_policy_t*) malloc(sizeof(srtp_policy_t));
 
681
  if (rcvr_policy == NULL)
 
682
    return err_status_alloc_fail;
 
683
  memcpy(rcvr_policy, policy, sizeof(srtp_policy_t));
 
684
  if (policy->ssrc.type == ssrc_any_outbound) {
 
685
    rcvr_policy->ssrc.type = ssrc_any_inbound;
 
686
  }
 
687
 
 
688
  err_check(srtp_create(&srtp_rcvr, rcvr_policy));
 
689
 
 
690
  err_check(srtp_unprotect(srtp_rcvr, hdr, &len));
 
691
 
 
692
  debug_print(mod_driver, "after unprotection:\n%s",
 
693
              srtp_packet_to_string(hdr, len));
 
694
 
 
695
  /* verify that the unprotected packet matches the origial one */
 
696
  for (i=0; i < msg_len_octets; i++)
 
697
    if (((uint8_t *)hdr)[i] != ((uint8_t *)hdr2)[i]) {
 
698
      fprintf(stdout, "mismatch at octet %d\n", i);
 
699
      status = err_status_algo_fail;
 
700
    }
 
701
  if (status) {
 
702
    free(hdr);
 
703
    free(hdr2);
 
704
    return status;
 
705
  }
 
706
 
 
707
  /*
 
708
   * if the policy includes authentication, then test for false positives
 
709
   */
 
710
  if (policy->rtp.sec_serv & sec_serv_auth) {
 
711
    char *data = ((char *)hdr) + 12;
 
712
 
 
713
    printf("testing for false positives in replay check...");
 
714
 
 
715
    /* set message length */
 
716
    len = msg_len_enc;
 
717
 
 
718
    /* unprotect a second time - should fail with a replay error */
 
719
    status = srtp_unprotect(srtp_rcvr, hdr_enc, &len);
 
720
    if (status != err_status_replay_fail) {
 
721
      printf("failed with error code %d\n", status);
 
722
      free(hdr);
 
723
      free(hdr2);
 
724
      return status;
 
725
    } else {
 
726
      printf("passed\n");
 
727
    }
 
728
 
 
729
    printf("testing for false positives in auth check...");
 
730
 
 
731
    /* increment sequence number in header */
 
732
    hdr->seq++;
 
733
 
 
734
    /* set message length */
 
735
    len = msg_len_octets;
 
736
 
 
737
    /* apply protection */
 
738
    err_check(srtp_protect(srtp_sender, hdr, &len));
 
739
 
 
740
    /* flip bits in packet */
 
741
    data[0] ^= 0xff;
 
742
 
 
743
    /* unprotect, and check for authentication failure */
 
744
    status = srtp_unprotect(srtp_rcvr, hdr, &len);
 
745
    if (status != err_status_auth_fail) {
 
746
      printf("failed\n");
 
747
      free(hdr);
 
748
      free(hdr2);
 
749
      return status;
 
750
    } else {
 
751
      printf("passed\n");
 
752
    }
 
753
 
 
754
  }
 
755
 
 
756
  err_check(srtp_dealloc(srtp_sender));
 
757
  err_check(srtp_dealloc(srtp_rcvr));
 
758
 
 
759
  free(hdr);
 
760
  free(hdr2);
 
761
  return err_status_ok;
 
762
}
 
763
 
 
764
 
 
765
err_status_t
 
766
srtcp_test(const srtp_policy_t *policy) {
 
767
  int i;
 
768
  srtp_t srtcp_sender;
 
769
  srtp_t srtcp_rcvr;
 
770
  err_status_t status = err_status_ok;
 
771
  srtp_hdr_t *hdr, *hdr2;
 
772
  uint8_t hdr_enc[64];
 
773
  uint8_t *pkt_end;
 
774
  int msg_len_octets, msg_len_enc;
 
775
  int len;
 
776
  int tag_length = policy->rtp.auth_tag_len;
 
777
  uint32_t ssrc;
 
778
  srtp_policy_t *rcvr_policy;
 
779
 
 
780
  err_check(srtp_create(&srtcp_sender, policy));
 
781
 
 
782
  /* print out policy */
 
783
  err_check(srtp_session_print_policy(srtcp_sender));
 
784
 
 
785
  /*
 
786
   * initialize data buffer, using the ssrc in the policy unless that
 
787
   * value is a wildcard, in which case we'll just use an arbitrary
 
788
   * one
 
789
   */
 
790
  if (policy->ssrc.type != ssrc_specific)
 
791
    ssrc = 0xdecafbad;
 
792
  else
 
793
    ssrc = policy->ssrc.value;
 
794
  msg_len_octets = 28;
 
795
  hdr = srtp_create_test_packet(msg_len_octets, ssrc);
 
796
 
 
797
  if (hdr == NULL)
 
798
    return err_status_alloc_fail;
 
799
  hdr2 = srtp_create_test_packet(msg_len_octets, ssrc);
 
800
  if (hdr2 == NULL) {
 
801
    free(hdr);
 
802
    return err_status_alloc_fail;
 
803
  }
 
804
 
 
805
  /* set message length */
 
806
  len = msg_len_octets;
 
807
 
 
808
  debug_print(mod_driver, "before protection:\n%s",
 
809
              srtp_packet_to_string(hdr, len));
 
810
 
 
811
#if PRINT_REFERENCE_PACKET
 
812
  debug_print(mod_driver, "reference packet before protection:\n%s",
 
813
              octet_string_hex_string((uint8_t *)hdr, len));
 
814
#endif
 
815
  err_check(srtp_protect_rtcp(srtcp_sender, hdr, &len));
 
816
 
 
817
  debug_print(mod_driver, "after protection:\n%s",
 
818
              srtp_packet_to_string(hdr, len));
 
819
#if PRINT_REFERENCE_PACKET
 
820
  debug_print(mod_driver, "after protection:\n%s",
 
821
              octet_string_hex_string((uint8_t *)hdr, len));
 
822
#endif
 
823
 
 
824
  /* save protected message and length */
 
825
  memcpy(hdr_enc, hdr, len);
 
826
  msg_len_enc = len;
 
827
 
 
828
  /*
 
829
   * check for overrun of the srtp_protect() function
 
830
   *
 
831
   * The packet is followed by a value of 0xfffff; if the value of the
 
832
   * data following the packet is different, then we know that the
 
833
   * protect function is overwriting the end of the packet.
 
834
   */
 
835
  pkt_end = (uint8_t *)hdr + sizeof(srtp_hdr_t)
 
836
    + msg_len_octets + tag_length;
 
837
  for (i = 0; i < 4; i++)
 
838
    if (pkt_end[i] != 0xff) {
 
839
      fprintf(stdout, "overwrite in srtp_protect_rtcp() function "
 
840
              "(expected %x, found %x in trailing octet %d)\n",
 
841
              0xff, ((uint8_t *)hdr)[i], i);
 
842
      free(hdr);
 
843
      free(hdr2);
 
844
      return err_status_algo_fail;
 
845
    }
 
846
 
 
847
  /*
 
848
   * if the policy includes confidentiality, check that ciphertext is
 
849
   * different than plaintext
 
850
   *
 
851
   * Note that this check will give false negatives, with some small
 
852
   * probability, especially if the packets are short.  For that
 
853
   * reason, we skip this check if the plaintext is less than four
 
854
   * octets long.
 
855
   */
 
856
  if ((policy->rtp.sec_serv & sec_serv_conf) && (msg_len_octets >= 4)) {
 
857
    printf("testing that ciphertext is distinct from plaintext...");
 
858
    status = err_status_algo_fail;
 
859
    for (i=12; i < msg_len_octets+12; i++)
 
860
      if (((uint8_t *)hdr)[i] != ((uint8_t *)hdr2)[i]) {
 
861
        status = err_status_ok;
 
862
      }
 
863
    if (status) {
 
864
      printf("failed\n");
 
865
      free(hdr);
 
866
      free(hdr2);
 
867
      return status;
 
868
    }
 
869
    printf("passed\n");
 
870
  }
 
871
 
 
872
  /*
 
873
   * if the policy uses a 'wildcard' ssrc, then we need to make a copy
 
874
   * of the policy that changes the direction to inbound
 
875
   *
 
876
   * we always copy the policy into the rcvr_policy, since otherwise
 
877
   * the compiler would fret about the constness of the policy
 
878
   */
 
879
  rcvr_policy = (srtp_policy_t*) malloc(sizeof(srtp_policy_t));
 
880
  if (rcvr_policy == NULL)
 
881
    return err_status_alloc_fail;
 
882
  memcpy(rcvr_policy, policy, sizeof(srtp_policy_t));
 
883
  if (policy->ssrc.type == ssrc_any_outbound) {
 
884
    rcvr_policy->ssrc.type = ssrc_any_inbound;
 
885
  }
 
886
 
 
887
  err_check(srtp_create(&srtcp_rcvr, rcvr_policy));
 
888
 
 
889
  err_check(srtp_unprotect_rtcp(srtcp_rcvr, hdr, &len));
 
890
 
 
891
  debug_print(mod_driver, "after unprotection:\n%s",
 
892
              srtp_packet_to_string(hdr, len));
 
893
 
 
894
  /* verify that the unprotected packet matches the origial one */
 
895
  for (i=0; i < msg_len_octets; i++)
 
896
    if (((uint8_t *)hdr)[i] != ((uint8_t *)hdr2)[i]) {
 
897
      fprintf(stdout, "mismatch at octet %d\n", i);
 
898
      status = err_status_algo_fail;
 
899
    }
 
900
  if (status) {
 
901
    free(hdr);
 
902
    free(hdr2);
 
903
    return status;
 
904
  }
 
905
 
 
906
  /*
 
907
   * if the policy includes authentication, then test for false positives
 
908
   */
 
909
  if (policy->rtp.sec_serv & sec_serv_auth) {
 
910
    char *data = ((char *)hdr) + 12;
 
911
 
 
912
    printf("testing for false positives in replay check...");
 
913
 
 
914
    /* set message length */
 
915
    len = msg_len_enc;
 
916
 
 
917
    /* unprotect a second time - should fail with a replay error */
 
918
    status = srtp_unprotect_rtcp(srtcp_rcvr, hdr_enc, &len);
 
919
    if (status != err_status_replay_fail) {
 
920
      printf("failed with error code %d\n", status);
 
921
      free(hdr);
 
922
      free(hdr2);
 
923
      return status;
 
924
    } else {
 
925
      printf("passed\n");
 
926
    }
 
927
 
 
928
    printf("testing for false positives in auth check...");
 
929
 
 
930
    /* increment sequence number in header */
 
931
    hdr->seq++;
 
932
 
 
933
    /* set message length */
 
934
    len = msg_len_octets;
 
935
 
 
936
    /* apply protection */
 
937
    err_check(srtp_protect_rtcp(srtcp_sender, hdr, &len));
 
938
 
 
939
    /* flip bits in packet */
 
940
    data[0] ^= 0xff;
 
941
 
 
942
    /* unprotect, and check for authentication failure */
 
943
    status = srtp_unprotect_rtcp(srtcp_rcvr, hdr, &len);
 
944
    if (status != err_status_auth_fail) {
 
945
      printf("failed\n");
 
946
      free(hdr);
 
947
      free(hdr2);
 
948
      return status;
 
949
    } else {
 
950
      printf("passed\n");
 
951
    }
 
952
 
 
953
  }
 
954
 
 
955
  err_check(srtp_dealloc(srtcp_sender));
 
956
  err_check(srtp_dealloc(srtcp_rcvr));
 
957
 
 
958
  free(hdr);
 
959
  free(hdr2);
 
960
  return err_status_ok;
 
961
}
 
962
 
 
963
 
 
964
err_status_t
 
965
srtp_session_print_policy(srtp_t srtp) {
 
966
  char *serv_descr[4] = {
 
967
    "none",
 
968
    "confidentiality",
 
969
    "authentication",
 
970
    "confidentiality and authentication"
 
971
  };
 
972
  char *direction[3] = {
 
973
    "unknown",
 
974
    "outbound",
 
975
    "inbound"
 
976
  };
 
977
  srtp_stream_t stream;
 
978
 
 
979
  /* sanity checking */
 
980
  if (srtp == NULL)
 
981
    return err_status_fail;
 
982
 
 
983
  /* if there's a template stream, print it out */
 
984
  if (srtp->stream_template != NULL) {
 
985
    stream = srtp->stream_template;
 
986
    printf("# SSRC:          any %s\r\n"
 
987
           "# rtp cipher:    %s\r\n"
 
988
           "# rtp auth:      %s\r\n"
 
989
           "# rtp services:  %s\r\n"
 
990
           "# rtcp cipher:   %s\r\n"
 
991
           "# rtcp auth:     %s\r\n"
 
992
           "# rtcp services: %s\r\n",
 
993
           direction[stream->direction],
 
994
           stream->rtp_cipher->type->description,
 
995
           stream->rtp_auth->type->description,
 
996
           serv_descr[stream->rtp_services],
 
997
           stream->rtcp_cipher->type->description,
 
998
           stream->rtcp_auth->type->description,
 
999
           serv_descr[stream->rtcp_services]);
 
1000
  }
 
1001
 
 
1002
  /* loop over streams in session, printing the policy of each */
 
1003
  stream = srtp->stream_list;
 
1004
  while (stream != NULL) {
 
1005
    if (stream->rtp_services > sec_serv_conf_and_auth)
 
1006
      return err_status_bad_param;
 
1007
 
 
1008
    printf("# SSRC:          0x%08x\r\n"
 
1009
           "# rtp cipher:    %s\r\n"
 
1010
           "# rtp auth:      %s\r\n"
 
1011
           "# rtp services:  %s\r\n"
 
1012
           "# rtcp cipher:   %s\r\n"
 
1013
           "# rtcp auth:     %s\r\n"
 
1014
           "# rtcp services: %s\r\n",
 
1015
           stream->ssrc,
 
1016
           stream->rtp_cipher->type->description,
 
1017
           stream->rtp_auth->type->description,
 
1018
           serv_descr[stream->rtp_services],
 
1019
           stream->rtcp_cipher->type->description,
 
1020
           stream->rtcp_auth->type->description,
 
1021
           serv_descr[stream->rtcp_services]);
 
1022
 
 
1023
    /* advance to next stream in the list */
 
1024
    stream = stream->next;
 
1025
  }
 
1026
  return err_status_ok;
 
1027
}
 
1028
 
 
1029
err_status_t
 
1030
srtp_print_policy(const srtp_policy_t *policy) {
 
1031
  err_status_t status;
 
1032
  srtp_t session;
 
1033
 
 
1034
  status = srtp_create(&session, policy);
 
1035
  if (status)
 
1036
    return status;
 
1037
  status = srtp_session_print_policy(session);
 
1038
  if (status)
 
1039
    return status;
 
1040
  status = srtp_dealloc(session);
 
1041
  if (status)
 
1042
    return status;
 
1043
  return err_status_ok;
 
1044
}
 
1045
 
 
1046
/*
 
1047
 * srtp_print_packet(...) is for debugging only
 
1048
 * it prints an RTP packet to the stdout
 
1049
 *
 
1050
 * note that this function is *not* threadsafe
 
1051
 */
 
1052
 
 
1053
#include <stdio.h>
 
1054
 
 
1055
#define MTU 2048
 
1056
 
 
1057
char packet_string[MTU];
 
1058
 
 
1059
char *
 
1060
srtp_packet_to_string(srtp_hdr_t *hdr, int pkt_octet_len) {
 
1061
  int octets_in_rtp_header = 12;
 
1062
  uint8_t *data = ((uint8_t *)hdr)+octets_in_rtp_header;
 
1063
  int hex_len = pkt_octet_len-octets_in_rtp_header;
 
1064
 
 
1065
  /* sanity checking */
 
1066
  if ((hdr == NULL) || (pkt_octet_len > MTU))
 
1067
    return NULL;
 
1068
 
 
1069
  /* write packet into string */
 
1070
  sprintf(packet_string,
 
1071
          "(s)rtp packet: {\n"
 
1072
          "   version:\t%d\n"
 
1073
          "   p:\t\t%d\n"
 
1074
          "   x:\t\t%d\n"
 
1075
          "   cc:\t\t%d\n"
 
1076
          "   m:\t\t%d\n"
 
1077
          "   pt:\t\t%x\n"
 
1078
          "   seq:\t\t%x\n"
 
1079
          "   ts:\t\t%x\n"
 
1080
          "   ssrc:\t%x\n"
 
1081
          "   data:\t%s\n"
 
1082
          "} (%d octets in total)\n",
 
1083
          hdr->version,
 
1084
          hdr->p,
 
1085
          hdr->x,
 
1086
          hdr->cc,
 
1087
          hdr->m,
 
1088
          hdr->pt,
 
1089
          hdr->seq,
 
1090
          hdr->ts,
 
1091
          hdr->ssrc,
 
1092
          octet_string_hex_string(data, hex_len),
 
1093
          pkt_octet_len);
 
1094
 
 
1095
  return packet_string;
 
1096
}
 
1097
 
 
1098
/*
 
1099
 * mips_estimate() is a simple function to estimate the number of
 
1100
 * instructions per second that the host can perform.  note that this
 
1101
 * function can be grossly wrong; you may want to have a manual sanity
 
1102
 * check of its output!
 
1103
 *
 
1104
 * the 'ignore' pointer is there to convince the compiler to not just
 
1105
 * optimize away the function
 
1106
 */
 
1107
 
 
1108
double
 
1109
mips_estimate(int num_trials, int *ignore) {
 
1110
  clock_t t;
 
1111
  int i, sum;
 
1112
 
 
1113
  sum = 0;
 
1114
  t = clock();
 
1115
  for (i=0; i<num_trials; i++)
 
1116
    sum += i;
 
1117
  t = clock() - t;
 
1118
 
 
1119
/*   printf("%d\n", sum); */
 
1120
  *ignore = sum;
 
1121
 
 
1122
  return (double) num_trials * CLOCKS_PER_SEC / t;
 
1123
}
 
1124
 
 
1125
 
 
1126
/*
 
1127
 * srtp_validate() verifies the correctness of libsrtp by comparing
 
1128
 * some computed packets against some pre-computed reference values.
 
1129
 * These packets were made with the default SRTP policy.
 
1130
 */
 
1131
 
 
1132
 
 
1133
err_status_t
 
1134
srtp_validate() {
 
1135
  unsigned char test_key[30] = {
 
1136
    0xe1, 0xf9, 0x7a, 0x0d, 0x3e, 0x01, 0x8b, 0xe0,
 
1137
    0xd6, 0x4f, 0xa3, 0x2c, 0x06, 0xde, 0x41, 0x39,
 
1138
    0x0e, 0xc6, 0x75, 0xad, 0x49, 0x8a, 0xfe, 0xeb,
 
1139
    0xb6, 0x96, 0x0b, 0x3a, 0xab, 0xe6
 
1140
  };
 
1141
  uint8_t srtp_plaintext_ref[28] = {
 
1142
    0x80, 0x0f, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad,
 
1143
    0xca, 0xfe, 0xba, 0xbe, 0xab, 0xab, 0xab, 0xab,
 
1144
    0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
 
1145
    0xab, 0xab, 0xab, 0xab
 
1146
  };
 
1147
  uint8_t srtp_plaintext[38] = {
 
1148
    0x80, 0x0f, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad,
 
1149
    0xca, 0xfe, 0xba, 0xbe, 0xab, 0xab, 0xab, 0xab,
 
1150
    0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
 
1151
    0xab, 0xab, 0xab, 0xab, 0x00, 0x00, 0x00, 0x00,
 
1152
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00
 
1153
  };
 
1154
  uint8_t srtp_ciphertext[38] = {
 
1155
    0x80, 0x0f, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad,
 
1156
    0xca, 0xfe, 0xba, 0xbe, 0x4e, 0x55, 0xdc, 0x4c,
 
1157
    0xe7, 0x99, 0x78, 0xd8, 0x8c, 0xa4, 0xd2, 0x15,
 
1158
    0x94, 0x9d, 0x24, 0x02, 0xb7, 0x8d, 0x6a, 0xcc,
 
1159
    0x99, 0xea, 0x17, 0x9b, 0x8d, 0xbb
 
1160
  };
 
1161
  srtp_t srtp_snd, srtp_recv;
 
1162
  err_status_t status;
 
1163
  int len;
 
1164
  srtp_policy_t policy;
 
1165
 
 
1166
  /*
 
1167
   * create a session with a single stream using the default srtp
 
1168
   * policy and with the SSRC value 0xcafebabe
 
1169
   */
 
1170
  crypto_policy_set_rtp_default(&policy.rtp);
 
1171
  crypto_policy_set_rtcp_default(&policy.rtcp);
 
1172
  policy.ssrc.type  = ssrc_specific;
 
1173
  policy.ssrc.value = 0xcafebabe;
 
1174
  policy.key  = test_key;
 
1175
  policy.next = NULL;
 
1176
 
 
1177
  status = srtp_create(&srtp_snd, &policy);
 
1178
  if (status)
 
1179
    return status;
 
1180
 
 
1181
  /*
 
1182
   * protect plaintext, then compare with ciphertext
 
1183
   */
 
1184
  len = 28;
 
1185
  status = srtp_protect(srtp_snd, srtp_plaintext, &len);
 
1186
  if (status || (len != 38))
 
1187
    return err_status_fail;
 
1188
 
 
1189
  debug_print(mod_driver, "ciphertext:\n  %s",
 
1190
              octet_string_hex_string(srtp_plaintext, len));
 
1191
  debug_print(mod_driver, "ciphertext reference:\n  %s",
 
1192
              octet_string_hex_string(srtp_ciphertext, len));
 
1193
 
 
1194
  if (octet_string_is_eq(srtp_plaintext, srtp_ciphertext, len))
 
1195
    return err_status_fail;
 
1196
 
 
1197
  /*
 
1198
   * create a receiver session context comparable to the one created
 
1199
   * above - we need to do this so that the replay checking doesn't
 
1200
   * complain
 
1201
   */
 
1202
  status = srtp_create(&srtp_recv, &policy);
 
1203
  if (status)
 
1204
    return status;
 
1205
 
 
1206
  /*
 
1207
   * unprotect ciphertext, then compare with plaintext
 
1208
   */
 
1209
  status = srtp_unprotect(srtp_recv, srtp_ciphertext, &len);
 
1210
  if (status || (len != 28))
 
1211
    return status;
 
1212
 
 
1213
  if (octet_string_is_eq(srtp_ciphertext, srtp_plaintext_ref, len))
 
1214
    return err_status_fail;
 
1215
 
 
1216
  return err_status_ok;
 
1217
}
 
1218
 
 
1219
 
 
1220
err_status_t
 
1221
srtp_create_big_policy(srtp_policy_t **list) {
 
1222
  extern const srtp_policy_t *policy_array[];
 
1223
  srtp_policy_t *p, *tmp;
 
1224
  int i = 0;
 
1225
  uint32_t ssrc = 0;
 
1226
 
 
1227
  /* sanity checking */
 
1228
  if ((list == NULL) || (policy_array[0] == NULL))
 
1229
    return err_status_bad_param;
 
1230
 
 
1231
  /*
 
1232
   * loop over policy list, mallocing a new list and copying values
 
1233
   * into it (and incrementing the SSRC value as we go along)
 
1234
   */
 
1235
  tmp = NULL;
 
1236
  while (policy_array[i] != NULL) {
 
1237
    p  = (srtp_policy_t*) malloc(sizeof(srtp_policy_t));
 
1238
    if (p == NULL)
 
1239
      return err_status_bad_param;
 
1240
    memcpy(p, policy_array[i], sizeof(srtp_policy_t));
 
1241
    p->ssrc.type = ssrc_specific;
 
1242
    p->ssrc.value = ssrc++;
 
1243
    p->next = tmp;
 
1244
    tmp = p;
 
1245
    i++;
 
1246
  }
 
1247
  *list = p;
 
1248
 
 
1249
  return err_status_ok;
 
1250
}
 
1251
 
 
1252
err_status_t
 
1253
srtp_test_remove_stream() {
 
1254
  err_status_t status;
 
1255
  srtp_policy_t *policy_list;
 
1256
  srtp_t session;
 
1257
  srtp_stream_t stream;
 
1258
  /*
 
1259
   * srtp_get_stream() is a libSRTP internal function that we declare
 
1260
   * here so that we can use it to verify the correct operation of the
 
1261
   * library
 
1262
   */
 
1263
  extern srtp_stream_t srtp_get_stream(srtp_t srtp, uint32_t ssrc);
 
1264
 
 
1265
 
 
1266
  status = srtp_create_big_policy(&policy_list);
 
1267
  if (status)
 
1268
    return status;
 
1269
 
 
1270
  status = srtp_create(&session, policy_list);
 
1271
  if (status)
 
1272
    return status;
 
1273
 
 
1274
  /*
 
1275
   * check for false positives by trying to remove a stream that's not
 
1276
   * in the session
 
1277
   */
 
1278
  status = srtp_remove_stream(session, htonl(0xaaaaaaaa));
 
1279
  if (status != err_status_no_ctx)
 
1280
    return err_status_fail;
 
1281
 
 
1282
  /*
 
1283
   * check for false negatives by removing stream 0x1, then
 
1284
   * searching for streams 0x0 and 0x2
 
1285
   */
 
1286
  status = srtp_remove_stream(session, htonl(0x1));
 
1287
  if (status != err_status_ok)
 
1288
    return err_status_fail;
 
1289
  stream = srtp_get_stream(session, htonl(0x0));
 
1290
  if (stream == NULL)
 
1291
    return err_status_fail;
 
1292
  stream = srtp_get_stream(session, htonl(0x2));
 
1293
  if (stream == NULL)
 
1294
    return err_status_fail;
 
1295
 
 
1296
  return err_status_ok;
 
1297
}
 
1298
 
 
1299
/*
 
1300
 * srtp policy definitions - these definitions are used above
 
1301
 */
 
1302
 
 
1303
unsigned char test_key[30] = {
 
1304
    0xe1, 0xf9, 0x7a, 0x0d, 0x3e, 0x01, 0x8b, 0xe0,
 
1305
    0xd6, 0x4f, 0xa3, 0x2c, 0x06, 0xde, 0x41, 0x39,
 
1306
    0x0e, 0xc6, 0x75, 0xad, 0x49, 0x8a, 0xfe, 0xeb,
 
1307
    0xb6, 0x96, 0x0b, 0x3a, 0xab, 0xe6
 
1308
};
 
1309
 
 
1310
 
 
1311
const srtp_policy_t default_policy = {
 
1312
  { ssrc_any_outbound, 0 },  /* SSRC                           */
 
1313
  {                      /* SRTP policy                    */
 
1314
    AES_128_ICM,            /* cipher type                 */
 
1315
    30,                     /* cipher key length in octets */
 
1316
    HMAC_SHA1,              /* authentication func type    */
 
1317
    16,                     /* auth key length in octets   */
 
1318
    10,                     /* auth tag length in octets   */
 
1319
    sec_serv_conf_and_auth  /* security services flag      */
 
1320
  },
 
1321
  {                      /* SRTCP policy                   */
 
1322
    AES_128_ICM,            /* cipher type                 */
 
1323
    30,                     /* cipher key length in octets */
 
1324
    HMAC_SHA1,              /* authentication func type    */
 
1325
    16,                     /* auth key length in octets   */
 
1326
    10,                     /* auth tag length in octets   */
 
1327
    sec_serv_conf_and_auth  /* security services flag      */
 
1328
  },
 
1329
  test_key,
 
1330
  NULL
 
1331
};
 
1332
 
 
1333
const srtp_policy_t aes_tmmh_policy = {
 
1334
  { ssrc_any_outbound, 0 },     /* SSRC                        */
 
1335
  {
 
1336
    AES_128_ICM,            /* cipher type                 */
 
1337
    30,                     /* cipher key length in octets */
 
1338
    UST_TMMHv2,             /* authentication func type    */
 
1339
    94,                     /* auth key length in octets   */
 
1340
    4,                      /* auth tag length in octets   */
 
1341
    sec_serv_conf_and_auth  /* security services flag      */
 
1342
  },
 
1343
  {
 
1344
    AES_128_ICM,            /* cipher type                 */
 
1345
    30,                     /* cipher key length in octets */
 
1346
    UST_TMMHv2,             /* authentication func type    */
 
1347
    94,                     /* auth key length in octets   */
 
1348
    4,                      /* auth tag length in octets   */
 
1349
    sec_serv_conf_and_auth  /* security services flag      */
 
1350
  },
 
1351
  test_key,
 
1352
  NULL
 
1353
};
 
1354
 
 
1355
const srtp_policy_t tmmh_only_policy = {
 
1356
  { ssrc_any_outbound, 0 },     /* SSRC                        */
 
1357
  {
 
1358
    AES_128_ICM,            /* cipher type                 */
 
1359
    30,                     /* cipher key length in octets */
 
1360
    UST_TMMHv2,             /* authentication func type    */
 
1361
    94,                     /* auth key length in octets   */
 
1362
    4,                      /* auth tag length in octets   */
 
1363
    sec_serv_auth           /* security services flag      */
 
1364
  },
 
1365
  {
 
1366
    AES_128_ICM,            /* cipher type                 */
 
1367
    30,                     /* cipher key length in octets */
 
1368
    UST_TMMHv2,             /* authentication func type    */
 
1369
    94,                     /* auth key length in octets   */
 
1370
    4,                      /* auth tag length in octets   */
 
1371
    sec_serv_auth           /* security services flag      */
 
1372
  },
 
1373
  test_key,
 
1374
  NULL
 
1375
};
 
1376
 
 
1377
const srtp_policy_t aes_only_policy = {
 
1378
  { ssrc_any_outbound, 0 },     /* SSRC                        */
 
1379
  {
 
1380
    AES_128_ICM,            /* cipher type                 */
 
1381
    30,                     /* cipher key length in octets */
 
1382
    NULL_AUTH,              /* authentication func type    */
 
1383
    0,                      /* auth key length in octets   */
 
1384
    0,                      /* auth tag length in octets   */
 
1385
    sec_serv_conf           /* security services flag      */
 
1386
  },
 
1387
  {
 
1388
    AES_128_ICM,            /* cipher type                 */
 
1389
    30,                     /* cipher key length in octets */
 
1390
    NULL_AUTH,              /* authentication func type    */
 
1391
    0,                      /* auth key length in octets   */
 
1392
    0,                      /* auth tag length in octets   */
 
1393
    sec_serv_conf           /* security services flag      */
 
1394
  },
 
1395
  test_key,
 
1396
  NULL
 
1397
};
 
1398
 
 
1399
const srtp_policy_t hmac_only_policy = {
 
1400
  { ssrc_any_outbound, 0 },     /* SSRC                        */
 
1401
  {
 
1402
    NULL_CIPHER,            /* cipher type                 */
 
1403
    0,                      /* cipher key length in octets */
 
1404
    HMAC_SHA1,              /* authentication func type    */
 
1405
    20,                     /* auth key length in octets   */
 
1406
    4,                      /* auth tag length in octets   */
 
1407
    sec_serv_auth           /* security services flag      */
 
1408
  },
 
1409
  {
 
1410
    NULL_CIPHER,            /* cipher type                 */
 
1411
    0,                      /* cipher key length in octets */
 
1412
    HMAC_SHA1,              /* authentication func type    */
 
1413
    20,                     /* auth key length in octets   */
 
1414
    4,                      /* auth tag length in octets   */
 
1415
    sec_serv_auth           /* security services flag      */
 
1416
  },
 
1417
  test_key,
 
1418
  NULL
 
1419
};
 
1420
 
 
1421
const srtp_policy_t null_policy = {
 
1422
  { ssrc_any_outbound, 0 },     /* SSRC                        */
 
1423
  {
 
1424
    NULL_CIPHER,            /* cipher type                 */
 
1425
    0,                      /* cipher key length in octets */
 
1426
    NULL_AUTH,              /* authentication func type    */
 
1427
    0,                      /* auth key length in octets   */
 
1428
    0,                      /* auth tag length in octets   */
 
1429
    sec_serv_none           /* security services flag      */
 
1430
  },
 
1431
  {
 
1432
    NULL_CIPHER,            /* cipher type                 */
 
1433
    0,                      /* cipher key length in octets */
 
1434
    NULL_AUTH,              /* authentication func type    */
 
1435
    0,                      /* auth key length in octets   */
 
1436
    0,                      /* auth tag length in octets   */
 
1437
    sec_serv_none           /* security services flag      */
 
1438
  },
 
1439
  test_key,
 
1440
  NULL
 
1441
};
 
1442
 
 
1443
 
 
1444
/*
 
1445
 * an array of pointers to the policies listed above
 
1446
 *
 
1447
 * This array is used to test various aspects of libSRTP for
 
1448
 * different cryptographic policies.  The order of the elements
 
1449
 * matters - the timing test generates output that can be used
 
1450
 * in a plot (see the gnuplot script file 'timing').  If you
 
1451
 * add to this list, you should do it at the end.
 
1452
 */
 
1453
 
 
1454
#define USE_TMMH 0
 
1455
 
 
1456
const srtp_policy_t *
 
1457
policy_array[] = {
 
1458
  &hmac_only_policy,
 
1459
#if USE_TMMH
 
1460
  &tmmh_only_policy,
 
1461
#endif
 
1462
  &aes_only_policy,
 
1463
#if USE_TMMH
 
1464
  &aes_tmmh_policy,
 
1465
#endif
 
1466
  &default_policy,
 
1467
  &null_policy,
 
1468
  NULL
 
1469
};
 
1470
 
 
1471
const srtp_policy_t wildcard_policy = {
 
1472
  { ssrc_any_outbound, 0 }, /* SSRC                        */
 
1473
  {                      /* SRTP policy                    */
 
1474
    AES_128_ICM,            /* cipher type                 */
 
1475
    30,                     /* cipher key length in octets */
 
1476
    HMAC_SHA1,              /* authentication func type    */
 
1477
    16,                     /* auth key length in octets   */
 
1478
    10,                     /* auth tag length in octets   */
 
1479
    sec_serv_conf_and_auth  /* security services flag      */
 
1480
  },
 
1481
  {                      /* SRTCP policy                   */
 
1482
    AES_128_ICM,            /* cipher type                 */
 
1483
    30,                     /* cipher key length in octets */
 
1484
    HMAC_SHA1,              /* authentication func type    */
 
1485
    16,                     /* auth key length in octets   */
 
1486
    10,                     /* auth tag length in octets   */
 
1487
    sec_serv_conf_and_auth  /* security services flag      */
 
1488
  },
 
1489
  test_key,
 
1490
  NULL
 
1491
};