1/*
2 * dtls_srtp_driver.c
3 *
4 * test driver for DTLS-SRTP functions
5 *
6 * David 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#include <stdio.h>    /* for printf()          */
46#include "getopt_s.h" /* for local getopt()    */
47#include "srtp_priv.h"
48
49err_status_t
50test_dtls_srtp();
51
52srtp_hdr_t *
53srtp_create_test_packet(int pkt_octet_len, uint32_t ssrc);
54
55void
56usage(char *prog_name) {
57  printf("usage: %s [ -t ][ -c ][ -v ][-d <debug_module> ]* [ -l ]\n"
58         "  -d <mod>   turn on debugging module <mod>\n"
59         "  -l         list debugging modules\n", prog_name);
60  exit(1);
61}
62
63int
64main(int argc, char *argv[]) {
65  unsigned do_list_mods      = 0;
66  char q;
67  err_status_t err;
68
69  printf("dtls_srtp_driver\n");
70
71  /* initialize srtp library */
72  err = srtp_init();
73  if (err) {
74    printf("error: srtp init failed with error code %d\n", err);
75    exit(1);
76  }
77
78  /* process input arguments */
79  while (1) {
80    q = getopt_s(argc, argv, "ld:");
81    if (q == -1)
82      break;
83    switch (q) {
84    case 'l':
85      do_list_mods = 1;
86      break;
87    case 'd':
88      err = crypto_kernel_set_debug_module(optarg_s, 1);
89      if (err) {
90        printf("error: set debug module (%s) failed\n", optarg_s);
91        exit(1);
92      }
93      break;
94    default:
95      usage(argv[0]);
96    }
97  }
98
99  if (do_list_mods) {
100    err = crypto_kernel_list_debug_modules();
101    if (err) {
102      printf("error: list of debug modules failed\n");
103      exit(1);
104    }
105  }
106
107  printf("testing dtls_srtp...");
108  err = test_dtls_srtp();
109  if (err) {
110    printf("\nerror (code %d)\n", err);
111    exit(1);
112  }
113  printf("passed\n");
114
115  return 0;
116}
117
118
119err_status_t
120test_dtls_srtp() {
121  srtp_hdr_t *test_packet;
122  int test_packet_len = 80;
123  srtp_t s;
124  srtp_policy_t policy;
125  uint8_t key[SRTP_MAX_KEY_LEN];
126  uint8_t salt[SRTP_MAX_KEY_LEN];
127  unsigned int key_len, salt_len;
128  srtp_profile_t profile;
129  err_status_t err;
130
131  /* create a 'null' SRTP session */
132  err = srtp_create(&s, NULL);
133  if (err)
134    return err;
135
136  /*
137   * verify that packet-processing functions behave properly - we
138   * expect that these functions will return err_status_no_ctx
139   */
140  test_packet = srtp_create_test_packet(80, 0xa5a5a5a5);
141  if (test_packet == NULL)
142    return err_status_alloc_fail;
143  err = srtp_protect(s, test_packet, &test_packet_len);
144  if (err != err_status_no_ctx) {
145    printf("wrong return value from srtp_protect() (got code %d)\n",
146	   err);
147    return err_status_fail;
148  }
149  err = srtp_unprotect(s, test_packet, &test_packet_len);
150  if (err != err_status_no_ctx) {
151    printf("wrong return value from srtp_unprotect() (got code %d)\n",
152	   err);
153    return err_status_fail;
154  }
155  err = srtp_protect_rtcp(s, test_packet, &test_packet_len);
156  if (err != err_status_no_ctx) {
157    printf("wrong return value from srtp_protect_rtcp() (got code %d)\n",
158	   err);
159    return err_status_fail;
160  }
161  err = srtp_unprotect_rtcp(s, test_packet, &test_packet_len);
162  if (err != err_status_no_ctx) {
163    printf("wrong return value from srtp_unprotect_rtcp() (got code %d)\n",
164	   err);
165    return err_status_fail;
166  }
167
168
169  /*
170   * set keys to known values for testing
171   */
172  profile = srtp_profile_aes128_cm_sha1_80;
173  key_len = srtp_profile_get_master_key_length(profile);
174  salt_len = srtp_profile_get_master_salt_length(profile);
175  memset(key, 0xff, key_len);
176  memset(salt, 0xee, salt_len);
177  append_salt_to_key(key, key_len, salt, salt_len);
178  policy.key  = key;
179
180  /* initialize SRTP policy from profile  */
181  err = crypto_policy_set_from_profile_for_rtp(&policy.rtp, profile);
182  if (err) return err;
183  err = crypto_policy_set_from_profile_for_rtcp(&policy.rtcp, profile);
184  if (err) return err;
185  policy.ssrc.type  = ssrc_any_inbound;
186  policy.ekt = NULL;
187  policy.window_size = 128;
188  policy.allow_repeat_tx = 0;
189  policy.next = NULL;
190
191  err = srtp_add_stream(s, &policy);
192  if (err)
193    return err;
194
195  return err_status_ok;
196}
197
198
199
200/*
201 * srtp_create_test_packet(len, ssrc) returns a pointer to a
202 * (malloced) example RTP packet whose data field has the length given
203 * by pkt_octet_len and the SSRC value ssrc.  The total length of the
204 * packet is twelve octets longer, since the header is at the
205 * beginning.  There is room at the end of the packet for a trailer,
206 * and the four octets following the packet are filled with 0xff
207 * values to enable testing for overwrites.
208 *
209 * note that the location of the test packet can (and should) be
210 * deallocated with the free() call once it is no longer needed.
211 */
212
213srtp_hdr_t *
214srtp_create_test_packet(int pkt_octet_len, uint32_t ssrc) {
215  int i;
216  uint8_t *buffer;
217  srtp_hdr_t *hdr;
218  int bytes_in_hdr = 12;
219
220  /* allocate memory for test packet */
221  hdr = malloc(pkt_octet_len + bytes_in_hdr
222	       + SRTP_MAX_TRAILER_LEN + 4);
223  if (!hdr)
224    return NULL;
225
226  hdr->version = 2;              /* RTP version two     */
227  hdr->p    = 0;                 /* no padding needed   */
228  hdr->x    = 0;                 /* no header extension */
229  hdr->cc   = 0;                 /* no CSRCs            */
230  hdr->m    = 0;                 /* marker bit          */
231  hdr->pt   = 0xf;               /* payload type        */
232  hdr->seq  = htons(0x1234);     /* sequence number     */
233  hdr->ts   = htonl(0xdecafbad); /* timestamp           */
234  hdr->ssrc = htonl(ssrc);       /* synch. source       */
235
236  buffer = (uint8_t *)hdr;
237  buffer += bytes_in_hdr;
238
239  /* set RTP data to 0xab */
240  for (i=0; i < pkt_octet_len; i++)
241    *buffer++ = 0xab;
242
243  /* set post-data value to 0xffff to enable overrun checking */
244  for (i=0; i < SRTP_MAX_TRAILER_LEN+4; i++)
245    *buffer++ = 0xff;
246
247  return hdr;
248}
249