update to cvs head srtp
This commit is contained in:
parent
aad4da5b71
commit
72e2d183c1
|
@ -1 +0,0 @@
|
|||
Fri Mar 16 17:20:27 EDT 2007
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
*
|
||||
* Copyright (c) 2001-2005 Cisco Systems, Inc.
|
||||
* Copyright (c) 2001-2006 Cisco Systems, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
Secure RTP (SRTP) and UST Reference Implementations
|
||||
Secure RTP (SRTP) Reference Implementation
|
||||
David A. McGrew
|
||||
Cisco Systems, Inc.
|
||||
mcgrew@cisco.com
|
||||
|
@ -9,7 +9,9 @@ Transport Protocol (SRTP), the Universal Security Transform (UST), and
|
|||
a supporting cryptographic kernel. These mechanisms are documented in
|
||||
the Internet Drafts in the doc/ subdirectory. The SRTP API is
|
||||
documented in include/srtp.h, and the library is in libsrtp.a (after
|
||||
compilation).
|
||||
compilation). An overview and reference manual is available in
|
||||
doc/libsrtp.pdf. The PDF documentation is more up to date than this
|
||||
file.
|
||||
|
||||
|
||||
Installation:
|
||||
|
|
|
@ -1 +1 @@
|
|||
1.4.2
|
||||
1.4.4
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
/* crypto/include/config.h. Generated by configure. */
|
||||
/* config_in.h. Generated from configure.in by autoheader. */
|
||||
|
||||
#if (_MSC_VER >= 1400)
|
||||
# define HAVE_RAND_S 1
|
||||
#endif
|
||||
|
||||
/* Define if building for a CISC machine (e.g. Intel). */
|
||||
#define CPU_CISC 1
|
||||
|
||||
|
@ -161,11 +165,8 @@
|
|||
/* Define to empty if `const' does not conform to ANSI C. */
|
||||
/* #undef const */
|
||||
|
||||
/* Define to `__inline__' or `__inline' if that's what the C compiler
|
||||
calls it, or to nothing if 'inline' is not supported under any name. */
|
||||
#ifndef __cplusplus
|
||||
#define inline __inline
|
||||
#endif
|
||||
/* Define 'inline' to nothing, since the MSVC compiler doesn't support it. */
|
||||
#define inline
|
||||
|
||||
/* Define to `unsigned' if <sys/types.h> does not define. */
|
||||
/* #undef size_t */
|
||||
|
|
|
@ -144,10 +144,10 @@ fi
|
|||
|
||||
AC_MSG_CHECKING(which random device to use)
|
||||
if test "$enable_kernel_linux" = "yes"; then
|
||||
RNG_OBJS=rand_linux_kernel.c
|
||||
RNG_OBJS=rand_linux_kernel.o
|
||||
AC_MSG_RESULT([Linux kernel builtin])
|
||||
else
|
||||
RNG_OBJS=rand_source.c
|
||||
RNG_OBJS=rand_source.o
|
||||
if test -n "$DEV_URANDOM"; then
|
||||
AC_DEFINE_UNQUOTED(DEV_URANDOM, "$DEV_URANDOM",[Path to random device])
|
||||
AC_MSG_RESULT([$DEV_URANDOM])
|
||||
|
@ -197,7 +197,7 @@ AC_C_INLINE
|
|||
AC_TYPE_SIZE_T
|
||||
|
||||
dnl Checks for library functions.
|
||||
AC_CHECK_FUNCS(socket inet_aton usleep)
|
||||
AC_CHECK_FUNCS(socket inet_aton usleep sigaction)
|
||||
|
||||
dnl Find socket function if not found yet.
|
||||
if test "x$ac_cv_func_socket" = "xno"; then
|
||||
|
@ -222,7 +222,7 @@ AC_C_BIGENDIAN
|
|||
|
||||
dnl check host_cpu type, set defines appropriately
|
||||
case $host_cpu in
|
||||
i*86 )
|
||||
i*86 | x86_64 )
|
||||
AC_DEFINE(CPU_CISC, 1,
|
||||
[Define if building for a CISC machine (e.g. Intel).])
|
||||
AC_DEFINE(HAVE_X86, 1,
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
Makefile
|
|
@ -41,21 +41,28 @@ dummy : all runtest
|
|||
|
||||
# test applications
|
||||
|
||||
testapp = test/cipher_driver$(EXE) test/datatypes_driver$(EXE) \
|
||||
test/stat_driver$(EXE) test/sha1_driver$(EXE) \
|
||||
test/kernel_driver$(EXE) test/aes_calc$(EXE) test/rand_gen$(EXE) \
|
||||
test/env$(EXE)
|
||||
testapp = #test/cipher_driver$(EXE) test/datatypes_driver$(EXE) \
|
||||
#test/stat_driver$(EXE) test/sha1_driver$(EXE) \
|
||||
#test/kernel_driver$(EXE) test/aes_calc$(EXE) test/rand_gen$(EXE) \
|
||||
#test/env$(EXE)
|
||||
|
||||
# data values used to test the aes_calc application
|
||||
# data values used to test the aes_calc application for AES-128
|
||||
k128=000102030405060708090a0b0c0d0e0f
|
||||
p128=00112233445566778899aabbccddeeff
|
||||
c128=69c4e0d86a7b0430d8cdb78070b4c55a
|
||||
|
||||
|
||||
# data values used to test the aes_calc application for AES-256
|
||||
k256=000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f
|
||||
p256=00112233445566778899aabbccddeeff
|
||||
c256=8ea2b7ca516745bfeafc49904b496089
|
||||
|
||||
k=000102030405060708090a0b0c0d0e0f
|
||||
p=00112233445566778899aabbccddeeff
|
||||
c=69c4e0d86a7b0430d8cdb78070b4c55a
|
||||
|
||||
runtest: libcryptomodule.a $(testapp)
|
||||
test/env$(EXE) # print out information on the build environment
|
||||
@echo "running libcryptomodule test applications..."
|
||||
test `test/aes_calc $k $p` = $c
|
||||
test `test/aes_calc $(k128) $(p128)` = $(c128)
|
||||
test `test/aes_calc $(k256) $(p256)` = $(c256)
|
||||
test/cipher_driver$(EXE) -v >/dev/null
|
||||
test/datatypes_driver$(EXE) -v >/dev/null
|
||||
test/stat_driver$(EXE) >/dev/null
|
||||
|
|
|
@ -63,7 +63,7 @@ aes_128_cbc_hmac_sha1_96_func(void *key,
|
|||
/* perform encryption and authentication */
|
||||
|
||||
/* set aes key */
|
||||
status = aes_cbc_context_init(&aes_ctx, key, direction_encrypt);
|
||||
status = aes_cbc_context_init(&aes_ctx, key, ENC_KEY_LEN, direction_encrypt);
|
||||
if (status) return status;
|
||||
|
||||
/* set iv */
|
||||
|
@ -139,7 +139,7 @@ aes_128_cbc_hmac_sha1_96_inv(void *key,
|
|||
/* perform encryption and authentication */
|
||||
|
||||
/* set aes key */
|
||||
status = aes_cbc_context_init(&aes_ctx, key, direction_decrypt);
|
||||
status = aes_cbc_context_init(&aes_ctx, key, ENC_KEY_LEN, direction_decrypt);
|
||||
if (status) return status;
|
||||
|
||||
/* set iv */
|
||||
|
@ -227,7 +227,7 @@ aes_128_cbc_hmac_sha1_96_enc(void *key,
|
|||
/* perform encryption and authentication */
|
||||
|
||||
/* set aes key */
|
||||
status = aes_cbc_context_init(&aes_ctx, key, direction_encrypt);
|
||||
status = aes_cbc_context_init(&aes_ctx, key, ENC_KEY_LEN, direction_encrypt);
|
||||
if (status) return status;
|
||||
|
||||
/* set iv */
|
||||
|
@ -397,7 +397,7 @@ aes_128_cbc_hmac_sha1_96_dec(void *key,
|
|||
*opaque_len -= TAG_LEN;
|
||||
|
||||
/* decrypt the confidential data */
|
||||
status = aes_cbc_context_init(&aes_ctx, key, direction_decrypt);
|
||||
status = aes_cbc_context_init(&aes_ctx, key, ENC_KEY_LEN, direction_decrypt);
|
||||
if (status) return status;
|
||||
status = aes_cbc_set_iv(&aes_ctx, iv);
|
||||
if (status) return status;
|
||||
|
@ -564,7 +564,7 @@ cryptoalg_find_by_id(int id) {
|
|||
case 1:
|
||||
return cryptoalg;
|
||||
default:
|
||||
return 0;
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2001-2005, Cisco Systems, Inc.
|
||||
* Copyright (c) 2001-2006, Cisco Systems, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -1358,51 +1358,50 @@ static uint32_t U4[256] = {
|
|||
|
||||
extern debug_module_t mod_aes_icm;
|
||||
|
||||
void
|
||||
aes_expand_encryption_key(const v128_t *key,
|
||||
aes_expanded_key_t expanded_key) {
|
||||
static void
|
||||
aes_128_expand_encryption_key(const uint8_t *key,
|
||||
aes_expanded_key_t *expanded_key) {
|
||||
int i;
|
||||
gf2_8 rc;
|
||||
|
||||
/* initialize round constant */
|
||||
rc = 1;
|
||||
|
||||
expanded_key[0].v32[0] = key->v32[0];
|
||||
expanded_key[0].v32[1] = key->v32[1];
|
||||
expanded_key[0].v32[2] = key->v32[2];
|
||||
expanded_key[0].v32[3] = key->v32[3];
|
||||
expanded_key->num_rounds = 10;
|
||||
|
||||
v128_copy_octet_string(&expanded_key->round[0], key);
|
||||
|
||||
#if 0
|
||||
debug_print(mod_aes_icm,
|
||||
"expanded key[0]: %s", v128_hex_string(&expanded_key[0]));
|
||||
"expanded key[0]: %s", v128_hex_string(&expanded_key->round[0]));
|
||||
#endif
|
||||
|
||||
/* loop over round keys */
|
||||
for (i=1; i < 11; i++) {
|
||||
|
||||
/* munge first word of round key */
|
||||
expanded_key[i].v8[0] = aes_sbox[expanded_key[i-1].v8[13]] ^ rc;
|
||||
expanded_key[i].v8[1] = aes_sbox[expanded_key[i-1].v8[14]];
|
||||
expanded_key[i].v8[2] = aes_sbox[expanded_key[i-1].v8[15]];
|
||||
expanded_key[i].v8[3] = aes_sbox[expanded_key[i-1].v8[12]];
|
||||
expanded_key->round[i].v8[0] = aes_sbox[expanded_key->round[i-1].v8[13]] ^ rc;
|
||||
expanded_key->round[i].v8[1] = aes_sbox[expanded_key->round[i-1].v8[14]];
|
||||
expanded_key->round[i].v8[2] = aes_sbox[expanded_key->round[i-1].v8[15]];
|
||||
expanded_key->round[i].v8[3] = aes_sbox[expanded_key->round[i-1].v8[12]];
|
||||
|
||||
expanded_key[i].v32[0] ^= expanded_key[i-1].v32[0];
|
||||
expanded_key->round[i].v32[0] ^= expanded_key->round[i-1].v32[0];
|
||||
|
||||
/* set remaining 32 bit words to the exor of the one previous with
|
||||
* the one four words previous */
|
||||
|
||||
expanded_key[i].v32[1] =
|
||||
expanded_key[i].v32[0] ^ expanded_key[i-1].v32[1];
|
||||
expanded_key->round[i].v32[1] =
|
||||
expanded_key->round[i].v32[0] ^ expanded_key->round[i-1].v32[1];
|
||||
|
||||
expanded_key[i].v32[2] =
|
||||
expanded_key[i].v32[1] ^ expanded_key[i-1].v32[2];
|
||||
expanded_key->round[i].v32[2] =
|
||||
expanded_key->round[i].v32[1] ^ expanded_key->round[i-1].v32[2];
|
||||
|
||||
expanded_key[i].v32[3] =
|
||||
expanded_key[i].v32[2] ^ expanded_key[i-1].v32[3];
|
||||
expanded_key->round[i].v32[3] =
|
||||
expanded_key->round[i].v32[2] ^ expanded_key->round[i-1].v32[3];
|
||||
|
||||
#if 0
|
||||
debug_print2(mod_aes_icm,
|
||||
"expanded key[%d]: %s", i,v128_hex_string(&expanded_key[i]));
|
||||
"expanded key[%d]: %s", i,v128_hex_string(&expanded_key->round[i]));
|
||||
#endif
|
||||
|
||||
/* modify round constant */
|
||||
|
@ -1411,19 +1410,107 @@ aes_expand_encryption_key(const v128_t *key,
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
aes_expand_decryption_key(const v128_t *key,
|
||||
aes_expanded_key_t expanded_key) {
|
||||
static void
|
||||
aes_256_expand_encryption_key(const unsigned char *key,
|
||||
aes_expanded_key_t *expanded_key) {
|
||||
int i;
|
||||
gf2_8 rc;
|
||||
|
||||
aes_expand_encryption_key(key, expanded_key);
|
||||
/* initialize round constant */
|
||||
rc = 1;
|
||||
|
||||
expanded_key->num_rounds = 14;
|
||||
|
||||
v128_copy_octet_string(&expanded_key->round[0], key);
|
||||
v128_copy_octet_string(&expanded_key->round[1], key+16);
|
||||
|
||||
#if 0
|
||||
debug_print(mod_aes_icm,
|
||||
"expanded key[0]: %s", v128_hex_string(&expanded_key->round[0]));
|
||||
debug_print(mod_aes_icm,
|
||||
"expanded key[1]: %s", v128_hex_string(&expanded_key->round[1]));
|
||||
#endif
|
||||
|
||||
/* loop over rest of round keys */
|
||||
for (i=2; i < 15; i++) {
|
||||
|
||||
/* munge first word of round key */
|
||||
if ((i & 1) == 0) {
|
||||
expanded_key->round[i].v8[0] = aes_sbox[expanded_key->round[i-1].v8[13]] ^ rc;
|
||||
expanded_key->round[i].v8[1] = aes_sbox[expanded_key->round[i-1].v8[14]];
|
||||
expanded_key->round[i].v8[2] = aes_sbox[expanded_key->round[i-1].v8[15]];
|
||||
expanded_key->round[i].v8[3] = aes_sbox[expanded_key->round[i-1].v8[12]];
|
||||
|
||||
/* modify round constant */
|
||||
rc = gf2_8_shift(rc);
|
||||
}
|
||||
else {
|
||||
expanded_key->round[i].v8[0] = aes_sbox[expanded_key->round[i-1].v8[12]];
|
||||
expanded_key->round[i].v8[1] = aes_sbox[expanded_key->round[i-1].v8[13]];
|
||||
expanded_key->round[i].v8[2] = aes_sbox[expanded_key->round[i-1].v8[14]];
|
||||
expanded_key->round[i].v8[3] = aes_sbox[expanded_key->round[i-1].v8[15]];
|
||||
}
|
||||
|
||||
expanded_key->round[i].v32[0] ^= expanded_key->round[i-2].v32[0];
|
||||
|
||||
/* set remaining 32 bit words to the exor of the one previous with
|
||||
* the one eight words previous */
|
||||
|
||||
expanded_key->round[i].v32[1] =
|
||||
expanded_key->round[i].v32[0] ^ expanded_key->round[i-2].v32[1];
|
||||
|
||||
expanded_key->round[i].v32[2] =
|
||||
expanded_key->round[i].v32[1] ^ expanded_key->round[i-2].v32[2];
|
||||
|
||||
expanded_key->round[i].v32[3] =
|
||||
expanded_key->round[i].v32[2] ^ expanded_key->round[i-2].v32[3];
|
||||
|
||||
#if 0
|
||||
debug_print2(mod_aes_icm,
|
||||
"expanded key[%d]: %s", i,v128_hex_string(&expanded_key->round[i]));
|
||||
#endif
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
err_status_t
|
||||
aes_expand_encryption_key(const uint8_t *key,
|
||||
int key_len,
|
||||
aes_expanded_key_t *expanded_key) {
|
||||
if (key_len == 16) {
|
||||
aes_128_expand_encryption_key(key, expanded_key);
|
||||
return err_status_ok;
|
||||
}
|
||||
else if (key_len == 24) {
|
||||
/* AES-192 not yet supported */
|
||||
return err_status_bad_param;
|
||||
}
|
||||
else if (key_len == 32) {
|
||||
aes_256_expand_encryption_key(key, expanded_key);
|
||||
return err_status_ok;
|
||||
}
|
||||
else
|
||||
return err_status_bad_param;
|
||||
}
|
||||
|
||||
err_status_t
|
||||
aes_expand_decryption_key(const uint8_t *key,
|
||||
int key_len,
|
||||
aes_expanded_key_t *expanded_key) {
|
||||
int i;
|
||||
err_status_t status;
|
||||
int num_rounds = expanded_key->num_rounds;
|
||||
|
||||
status = aes_expand_encryption_key(key, key_len, expanded_key);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
/* invert the order of the round keys */
|
||||
for (i=0; i < 5; i++) {
|
||||
for (i=0; i < num_rounds/2; i++) {
|
||||
v128_t tmp;
|
||||
v128_copy(&tmp, &expanded_key[10-i]);
|
||||
v128_copy(&expanded_key[10-i], &expanded_key[i]);
|
||||
v128_copy(&expanded_key[i], &tmp);
|
||||
v128_copy(&tmp, &expanded_key->round[num_rounds-i]);
|
||||
v128_copy(&expanded_key->round[num_rounds-i], &expanded_key->round[i]);
|
||||
v128_copy(&expanded_key->round[i], &tmp);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1434,33 +1521,33 @@ aes_expand_decryption_key(const v128_t *key,
|
|||
* followed by the T4 table (which cancels out the use of the sbox
|
||||
* in the U-tables)
|
||||
*/
|
||||
for (i=1; i < 10; i++) {
|
||||
for (i=1; i < num_rounds; i++) {
|
||||
#ifdef CPU_RISC
|
||||
uint32_t tmp;
|
||||
|
||||
tmp = expanded_key[i].v32[0];
|
||||
expanded_key[i].v32[0] =
|
||||
tmp = expanded_key->round[i].v32[0];
|
||||
expanded_key->round[i].v32[0] =
|
||||
U0[T4[(tmp >> 24) ] & 0xff] ^
|
||||
U1[T4[(tmp >> 16) & 0xff] & 0xff] ^
|
||||
U2[T4[(tmp >> 8) & 0xff] & 0xff] ^
|
||||
U3[T4[(tmp) & 0xff] & 0xff];
|
||||
|
||||
tmp = expanded_key[i].v32[1];
|
||||
expanded_key[i].v32[1] =
|
||||
tmp = expanded_key->round[i].v32[1];
|
||||
expanded_key->round[i].v32[1] =
|
||||
U0[T4[(tmp >> 24) ] & 0xff] ^
|
||||
U1[T4[(tmp >> 16) & 0xff] & 0xff] ^
|
||||
U2[T4[(tmp >> 8) & 0xff] & 0xff] ^
|
||||
U3[T4[(tmp) & 0xff] & 0xff];
|
||||
|
||||
tmp = expanded_key[i].v32[2];
|
||||
expanded_key[i].v32[2] =
|
||||
tmp = expanded_key->round[i].v32[2];
|
||||
expanded_key->round[i].v32[2] =
|
||||
U0[T4[(tmp >> 24) ] & 0xff] ^
|
||||
U1[T4[(tmp >> 16) & 0xff] & 0xff] ^
|
||||
U2[T4[(tmp >> 8) & 0xff] & 0xff] ^
|
||||
U3[T4[(tmp) & 0xff] & 0xff];
|
||||
|
||||
tmp = expanded_key[i].v32[3];
|
||||
expanded_key[i].v32[3] =
|
||||
tmp = expanded_key->round[i].v32[3];
|
||||
expanded_key->round[i].v32[3] =
|
||||
U0[T4[(tmp >> 24) ] & 0xff] ^
|
||||
U1[T4[(tmp >> 16) & 0xff] & 0xff] ^
|
||||
U2[T4[(tmp >> 8) & 0xff] & 0xff] ^
|
||||
|
@ -1469,33 +1556,35 @@ aes_expand_decryption_key(const v128_t *key,
|
|||
|
||||
uint32_t c0, c1, c2, c3;
|
||||
|
||||
c0 = U0[aes_sbox[expanded_key[i].v8[0]]]
|
||||
^ U1[aes_sbox[expanded_key[i].v8[1]]]
|
||||
^ U2[aes_sbox[expanded_key[i].v8[2]]]
|
||||
^ U3[aes_sbox[expanded_key[i].v8[3]]];
|
||||
c0 = U0[aes_sbox[expanded_key->round[i].v8[0]]]
|
||||
^ U1[aes_sbox[expanded_key->round[i].v8[1]]]
|
||||
^ U2[aes_sbox[expanded_key->round[i].v8[2]]]
|
||||
^ U3[aes_sbox[expanded_key->round[i].v8[3]]];
|
||||
|
||||
c1 = U0[aes_sbox[expanded_key[i].v8[4]]]
|
||||
^ U1[aes_sbox[expanded_key[i].v8[5]]]
|
||||
^ U2[aes_sbox[expanded_key[i].v8[6]]]
|
||||
^ U3[aes_sbox[expanded_key[i].v8[7]]];
|
||||
c1 = U0[aes_sbox[expanded_key->round[i].v8[4]]]
|
||||
^ U1[aes_sbox[expanded_key->round[i].v8[5]]]
|
||||
^ U2[aes_sbox[expanded_key->round[i].v8[6]]]
|
||||
^ U3[aes_sbox[expanded_key->round[i].v8[7]]];
|
||||
|
||||
c2 = U0[aes_sbox[expanded_key[i].v8[8]]]
|
||||
^ U1[aes_sbox[expanded_key[i].v8[9]]]
|
||||
^ U2[aes_sbox[expanded_key[i].v8[10]]]
|
||||
^ U3[aes_sbox[expanded_key[i].v8[11]]];
|
||||
c2 = U0[aes_sbox[expanded_key->round[i].v8[8]]]
|
||||
^ U1[aes_sbox[expanded_key->round[i].v8[9]]]
|
||||
^ U2[aes_sbox[expanded_key->round[i].v8[10]]]
|
||||
^ U3[aes_sbox[expanded_key->round[i].v8[11]]];
|
||||
|
||||
c3 = U0[aes_sbox[expanded_key[i].v8[12]]]
|
||||
^ U1[aes_sbox[expanded_key[i].v8[13]]]
|
||||
^ U2[aes_sbox[expanded_key[i].v8[14]]]
|
||||
^ U3[aes_sbox[expanded_key[i].v8[15]]];
|
||||
c3 = U0[aes_sbox[expanded_key->round[i].v8[12]]]
|
||||
^ U1[aes_sbox[expanded_key->round[i].v8[13]]]
|
||||
^ U2[aes_sbox[expanded_key->round[i].v8[14]]]
|
||||
^ U3[aes_sbox[expanded_key->round[i].v8[15]]];
|
||||
|
||||
expanded_key[i].v32[0] = c0;
|
||||
expanded_key[i].v32[1] = c1;
|
||||
expanded_key[i].v32[2] = c2;
|
||||
expanded_key[i].v32[3] = c3;
|
||||
expanded_key->round[i].v32[0] = c0;
|
||||
expanded_key->round[i].v32[1] = c1;
|
||||
expanded_key->round[i].v32[2] = c2;
|
||||
expanded_key->round[i].v32[3] = c3;
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
return err_status_ok;
|
||||
}
|
||||
|
||||
#ifdef CPU_CISC
|
||||
|
@ -1910,42 +1999,67 @@ aes_inv_final_round(v128_t *state, const v128_t *round_key) {
|
|||
|
||||
|
||||
void
|
||||
aes_encrypt(v128_t *plaintext, const aes_expanded_key_t exp_key) {
|
||||
aes_encrypt(v128_t *plaintext, const aes_expanded_key_t *exp_key) {
|
||||
|
||||
/* add in the subkey */
|
||||
v128_xor_eq(plaintext, exp_key + 0);
|
||||
v128_xor_eq(plaintext, &exp_key->round[0]);
|
||||
|
||||
/* now do nine rounds */
|
||||
aes_round(plaintext, exp_key + 1);
|
||||
aes_round(plaintext, exp_key + 2);
|
||||
aes_round(plaintext, exp_key + 3);
|
||||
aes_round(plaintext, exp_key + 4);
|
||||
aes_round(plaintext, exp_key + 5);
|
||||
aes_round(plaintext, exp_key + 6);
|
||||
aes_round(plaintext, exp_key + 7);
|
||||
aes_round(plaintext, exp_key + 8);
|
||||
aes_round(plaintext, exp_key + 9);
|
||||
/* the last round is different */
|
||||
|
||||
aes_final_round(plaintext, exp_key + 10);
|
||||
/* now do the rounds */
|
||||
aes_round(plaintext, &exp_key->round[1]);
|
||||
aes_round(plaintext, &exp_key->round[2]);
|
||||
aes_round(plaintext, &exp_key->round[3]);
|
||||
aes_round(plaintext, &exp_key->round[4]);
|
||||
aes_round(plaintext, &exp_key->round[5]);
|
||||
aes_round(plaintext, &exp_key->round[6]);
|
||||
aes_round(plaintext, &exp_key->round[7]);
|
||||
aes_round(plaintext, &exp_key->round[8]);
|
||||
aes_round(plaintext, &exp_key->round[9]);
|
||||
if (exp_key->num_rounds == 10) {
|
||||
aes_final_round(plaintext, &exp_key->round[10]);
|
||||
}
|
||||
else if (exp_key->num_rounds == 12) {
|
||||
aes_round(plaintext, &exp_key->round[10]);
|
||||
aes_round(plaintext, &exp_key->round[11]);
|
||||
aes_final_round(plaintext, &exp_key->round[12]);
|
||||
}
|
||||
else if (exp_key->num_rounds == 14) {
|
||||
aes_round(plaintext, &exp_key->round[10]);
|
||||
aes_round(plaintext, &exp_key->round[11]);
|
||||
aes_round(plaintext, &exp_key->round[12]);
|
||||
aes_round(plaintext, &exp_key->round[13]);
|
||||
aes_final_round(plaintext, &exp_key->round[14]);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
aes_decrypt(v128_t *plaintext, const aes_expanded_key_t exp_key) {
|
||||
aes_decrypt(v128_t *plaintext, const aes_expanded_key_t *exp_key) {
|
||||
|
||||
/* add in the subkey */
|
||||
v128_xor_eq(plaintext, exp_key + 0);
|
||||
v128_xor_eq(plaintext, &exp_key->round[0]);
|
||||
|
||||
/* now do nine rounds */
|
||||
aes_inv_round(plaintext, exp_key + 1);
|
||||
aes_inv_round(plaintext, exp_key + 2);
|
||||
aes_inv_round(plaintext, exp_key + 3);
|
||||
aes_inv_round(plaintext, exp_key + 4);
|
||||
aes_inv_round(plaintext, exp_key + 5);
|
||||
aes_inv_round(plaintext, exp_key + 6);
|
||||
aes_inv_round(plaintext, exp_key + 7);
|
||||
aes_inv_round(plaintext, exp_key + 8);
|
||||
aes_inv_round(plaintext, exp_key + 9);
|
||||
/* the last round is different */
|
||||
aes_inv_final_round(plaintext, exp_key + 10);
|
||||
/* now do the rounds */
|
||||
aes_inv_round(plaintext, &exp_key->round[1]);
|
||||
aes_inv_round(plaintext, &exp_key->round[2]);
|
||||
aes_inv_round(plaintext, &exp_key->round[3]);
|
||||
aes_inv_round(plaintext, &exp_key->round[4]);
|
||||
aes_inv_round(plaintext, &exp_key->round[5]);
|
||||
aes_inv_round(plaintext, &exp_key->round[6]);
|
||||
aes_inv_round(plaintext, &exp_key->round[7]);
|
||||
aes_inv_round(plaintext, &exp_key->round[8]);
|
||||
aes_inv_round(plaintext, &exp_key->round[9]);
|
||||
if (exp_key->num_rounds == 10) {
|
||||
aes_inv_final_round(plaintext, &exp_key->round[10]);
|
||||
}
|
||||
else if (exp_key->num_rounds == 12) {
|
||||
aes_inv_round(plaintext, &exp_key->round[10]);
|
||||
aes_inv_round(plaintext, &exp_key->round[11]);
|
||||
aes_inv_final_round(plaintext, &exp_key->round[12]);
|
||||
}
|
||||
else if (exp_key->num_rounds == 14) {
|
||||
aes_inv_round(plaintext, &exp_key->round[10]);
|
||||
aes_inv_round(plaintext, &exp_key->round[11]);
|
||||
aes_inv_round(plaintext, &exp_key->round[12]);
|
||||
aes_inv_round(plaintext, &exp_key->round[13]);
|
||||
aes_inv_final_round(plaintext, &exp_key->round[14]);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2001-2005, Cisco Systems, Inc.
|
||||
* Copyright (c) 2001-2006, Cisco Systems, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -63,12 +63,12 @@ aes_cbc_alloc(cipher_t **c, int key_len) {
|
|||
debug_print(mod_aes_cbc,
|
||||
"allocating cipher with key length %d", key_len);
|
||||
|
||||
if (key_len != 16)
|
||||
if (key_len != 16 && key_len != 24 && key_len != 32)
|
||||
return err_status_bad_param;
|
||||
|
||||
/* allocate memory a cipher of type aes_icm */
|
||||
/* allocate memory a cipher of type aes_cbc */
|
||||
tmp = (sizeof(aes_cbc_ctx_t) + sizeof(cipher_t));
|
||||
pointer = crypto_alloc(tmp);
|
||||
pointer = (uint8_t*)crypto_alloc(tmp);
|
||||
if (pointer == NULL)
|
||||
return err_status_alloc_fail;
|
||||
|
||||
|
@ -104,23 +104,24 @@ aes_cbc_dealloc(cipher_t *c) {
|
|||
}
|
||||
|
||||
err_status_t
|
||||
aes_cbc_context_init(aes_cbc_ctx_t *c, const uint8_t *key,
|
||||
aes_cbc_context_init(aes_cbc_ctx_t *c, const uint8_t *key, int key_len,
|
||||
cipher_direction_t dir) {
|
||||
v128_t tmp_key;
|
||||
|
||||
/* set tmp_key (for alignment) */
|
||||
v128_copy_octet_string(&tmp_key, key);
|
||||
err_status_t status;
|
||||
|
||||
debug_print(mod_aes_cbc,
|
||||
"key: %s", v128_hex_string(&tmp_key));
|
||||
"key: %s", octet_string_hex_string(key, key_len));
|
||||
|
||||
/* expand key for the appropriate direction */
|
||||
switch (dir) {
|
||||
case (direction_encrypt):
|
||||
aes_expand_encryption_key(&tmp_key, c->expanded_key);
|
||||
status = aes_expand_encryption_key(key, key_len, &c->expanded_key);
|
||||
if (status)
|
||||
return status;
|
||||
break;
|
||||
case (direction_decrypt):
|
||||
aes_expand_decryption_key(&tmp_key, c->expanded_key);
|
||||
status = aes_expand_decryption_key(key, key_len, &c->expanded_key);
|
||||
if (status)
|
||||
return status;
|
||||
break;
|
||||
default:
|
||||
return err_status_bad_param;
|
||||
|
@ -135,7 +136,7 @@ err_status_t
|
|||
aes_cbc_set_iv(aes_cbc_ctx_t *c, void *iv) {
|
||||
int i;
|
||||
/* v128_t *input = iv; */
|
||||
uint8_t *input = iv;
|
||||
uint8_t *input = (uint8_t*) iv;
|
||||
|
||||
/* set state and 'previous' block to iv */
|
||||
for (i=0; i < 16; i++)
|
||||
|
@ -181,7 +182,7 @@ aes_cbc_encrypt(aes_cbc_ctx_t *c,
|
|||
debug_print(mod_aes_cbc, "inblock: %s",
|
||||
v128_hex_string(&c->state));
|
||||
|
||||
aes_encrypt(&c->state, c->expanded_key);
|
||||
aes_encrypt(&c->state, &c->expanded_key);
|
||||
|
||||
debug_print(mod_aes_cbc, "outblock: %s",
|
||||
v128_hex_string(&c->state));
|
||||
|
@ -236,7 +237,7 @@ aes_cbc_decrypt(aes_cbc_ctx_t *c,
|
|||
v128_hex_string(&state));
|
||||
|
||||
/* decrypt state */
|
||||
aes_decrypt(&state, c->expanded_key);
|
||||
aes_decrypt(&state, &c->expanded_key);
|
||||
|
||||
debug_print(mod_aes_cbc, "outblock: %s",
|
||||
v128_hex_string(&state));
|
||||
|
@ -332,7 +333,7 @@ char
|
|||
aes_cbc_description[] = "aes cipher block chaining (cbc) mode";
|
||||
|
||||
/*
|
||||
* Test case 0 is derived from FIPS 197 Appendix A; it uses an
|
||||
* Test case 0 is derived from FIPS 197 Appendix C; it uses an
|
||||
* all-zero IV, so that the first block encryption matches the test
|
||||
* case in that appendix. This property provides a check of the base
|
||||
* AES encryption and decryption algorithms; if CBC fails on some
|
||||
|
@ -428,6 +429,100 @@ cipher_test_case_t aes_cbc_test_case_1 = {
|
|||
&aes_cbc_test_case_0 /* pointer to next testcase */
|
||||
};
|
||||
|
||||
/*
|
||||
* Test case 2 is like test case 0, but for 256-bit keys. (FIPS 197
|
||||
* appendix C.3).
|
||||
*/
|
||||
|
||||
|
||||
uint8_t aes_cbc_test_case_2_key[32] = {
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
||||
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
|
||||
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
|
||||
0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f
|
||||
};
|
||||
|
||||
uint8_t aes_cbc_test_case_2_plaintext[64] = {
|
||||
0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
|
||||
0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff
|
||||
};
|
||||
|
||||
uint8_t aes_cbc_test_case_2_ciphertext[80] = {
|
||||
0x8e, 0xa2, 0xb7, 0xca, 0x51, 0x67, 0x45, 0xbf,
|
||||
0xea, 0xfc, 0x49, 0x90, 0x4b, 0x49, 0x60, 0x89,
|
||||
0x72, 0x72, 0x6e, 0xe7, 0x71, 0x39, 0xbf, 0x11,
|
||||
0xe5, 0x40, 0xe2, 0x7c, 0x54, 0x65, 0x1d, 0xee
|
||||
};
|
||||
|
||||
uint8_t aes_cbc_test_case_2_iv[16] = {
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
|
||||
cipher_test_case_t aes_cbc_test_case_2 = {
|
||||
32, /* octets in key */
|
||||
aes_cbc_test_case_2_key, /* key */
|
||||
aes_cbc_test_case_2_iv, /* initialization vector */
|
||||
16, /* octets in plaintext */
|
||||
aes_cbc_test_case_2_plaintext, /* plaintext */
|
||||
32, /* octets in ciphertext */
|
||||
aes_cbc_test_case_2_ciphertext, /* ciphertext */
|
||||
&aes_cbc_test_case_1 /* pointer to next testcase */
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* this test case is taken directly from Appendix F.2 of NIST Special
|
||||
* Publication SP 800-38A
|
||||
*/
|
||||
|
||||
uint8_t aes_cbc_test_case_3_key[32] = {
|
||||
0x60, 0x3d, 0xeb, 0x10, 0x15, 0xca, 0x71, 0xbe,
|
||||
0x2b, 0x73, 0xae, 0xf0, 0x85, 0x7d, 0x77, 0x81,
|
||||
0x1f, 0x35, 0x2c, 0x07, 0x3b, 0x61, 0x08, 0xd7,
|
||||
0x2d, 0x98, 0x10, 0xa3, 0x09, 0x14, 0xdf, 0xf4
|
||||
};
|
||||
|
||||
uint8_t aes_cbc_test_case_3_plaintext[64] = {
|
||||
0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
|
||||
0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
|
||||
0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c,
|
||||
0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51,
|
||||
0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11,
|
||||
0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef,
|
||||
0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17,
|
||||
0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10
|
||||
};
|
||||
|
||||
uint8_t aes_cbc_test_case_3_ciphertext[80] = {
|
||||
0xf5, 0x8c, 0x4c, 0x04, 0xd6, 0xe5, 0xf1, 0xba,
|
||||
0x77, 0x9e, 0xab, 0xfb, 0x5f, 0x7b, 0xfb, 0xd6,
|
||||
0x9c, 0xfc, 0x4e, 0x96, 0x7e, 0xdb, 0x80, 0x8d,
|
||||
0x67, 0x9f, 0x77, 0x7b, 0xc6, 0x70, 0x2c, 0x7d,
|
||||
0x39, 0xf2, 0x33, 0x69, 0xa9, 0xd9, 0xba, 0xcf,
|
||||
0xa5, 0x30, 0xe2, 0x63, 0x04, 0x23, 0x14, 0x61,
|
||||
0xb2, 0xeb, 0x05, 0xe2, 0xc3, 0x9b, 0xe9, 0xfc,
|
||||
0xda, 0x6c, 0x19, 0x07, 0x8c, 0x6a, 0x9d, 0x1b,
|
||||
0xfb, 0x98, 0x20, 0x2c, 0x45, 0xb2, 0xe4, 0xa0,
|
||||
0x63, 0xc4, 0x68, 0xba, 0x84, 0x39, 0x16, 0x5a
|
||||
};
|
||||
|
||||
uint8_t aes_cbc_test_case_3_iv[16] = {
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
||||
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f
|
||||
};
|
||||
|
||||
cipher_test_case_t aes_cbc_test_case_3 = {
|
||||
32, /* octets in key */
|
||||
aes_cbc_test_case_3_key, /* key */
|
||||
aes_cbc_test_case_3_iv, /* initialization vector */
|
||||
64, /* octets in plaintext */
|
||||
aes_cbc_test_case_3_plaintext, /* plaintext */
|
||||
80, /* octets in ciphertext */
|
||||
aes_cbc_test_case_3_ciphertext, /* ciphertext */
|
||||
&aes_cbc_test_case_2 /* pointer to next testcase */
|
||||
};
|
||||
|
||||
cipher_type_t aes_cbc = {
|
||||
(cipher_alloc_func_t) aes_cbc_alloc,
|
||||
(cipher_dealloc_func_t) aes_cbc_dealloc,
|
||||
|
@ -437,8 +532,9 @@ cipher_type_t aes_cbc = {
|
|||
(cipher_set_iv_func_t) aes_cbc_set_iv,
|
||||
(char *) aes_cbc_description,
|
||||
(int) 0, /* instance count */
|
||||
(cipher_test_case_t *) &aes_cbc_test_case_0,
|
||||
(debug_module_t *) &mod_aes_cbc
|
||||
(cipher_test_case_t *) &aes_cbc_test_case_3,
|
||||
(debug_module_t *) &mod_aes_cbc,
|
||||
(cipher_type_id_t) AES_CBC
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2001-2005, Cisco Systems, Inc.
|
||||
* Copyright (c) 2001-2006, Cisco Systems, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -49,9 +49,6 @@
|
|||
#include "aes_icm.h"
|
||||
#include "alloc.h"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(disable:4100)
|
||||
#endif
|
||||
|
||||
debug_module_t mod_aes_icm = {
|
||||
0, /* debugging is off by default */
|
||||
|
@ -98,21 +95,24 @@ aes_icm_alloc_ismacryp(cipher_t **c, int key_len, int forIsmacryp) {
|
|||
uint8_t *pointer;
|
||||
int tmp;
|
||||
|
||||
debug_print(mod_aes_icm, "allocating cipher with key length %d", key_len);
|
||||
debug_print(mod_aes_icm,
|
||||
"allocating cipher with key length %d", key_len);
|
||||
|
||||
/* Ismacryp, for example, uses 16 byte key + 8 byte
|
||||
salt so this function is called with key_len = 24.
|
||||
The check for key_len = 30 does not apply. Our usage
|
||||
of aes functions with key_len = values other than 30
|
||||
has not broken anything. Don't know what would be the
|
||||
effect of skipping this check for srtp in general.
|
||||
/*
|
||||
* Ismacryp, for example, uses 16 byte key + 8 byte
|
||||
* salt so this function is called with key_len = 24.
|
||||
* The check for key_len = 30/38/46 does not apply. Our usage
|
||||
* of aes functions with key_len = values other than 30
|
||||
* has not broken anything. Don't know what would be the
|
||||
* effect of skipping this check for srtp in general.
|
||||
*/
|
||||
if (!forIsmacryp && key_len != 30)
|
||||
if (!(forIsmacryp && key_len > 16 && key_len < 30) &&
|
||||
key_len != 30 && key_len != 38 && key_len != 46)
|
||||
return err_status_bad_param;
|
||||
|
||||
/* allocate memory a cipher of type aes_icm */
|
||||
tmp = (sizeof(aes_icm_ctx_t) + sizeof(cipher_t));
|
||||
pointer = crypto_alloc(tmp);
|
||||
pointer = (uint8_t*)crypto_alloc(tmp);
|
||||
if (pointer == NULL)
|
||||
return err_status_alloc_fail;
|
||||
|
||||
|
@ -163,30 +163,38 @@ aes_icm_dealloc(cipher_t *c) {
|
|||
*/
|
||||
|
||||
err_status_t
|
||||
aes_icm_context_init(aes_icm_ctx_t *c, const uint8_t *key) {
|
||||
v128_t tmp_key;
|
||||
aes_icm_context_init(aes_icm_ctx_t *c, const uint8_t *key, int key_len) {
|
||||
err_status_t status;
|
||||
int base_key_len;
|
||||
|
||||
if (key_len > 16 && key_len < 30) /* Ismacryp */
|
||||
base_key_len = 16;
|
||||
else if (key_len == 30 || key_len == 38 || key_len == 46)
|
||||
base_key_len = key_len - 14;
|
||||
else
|
||||
return err_status_bad_param;
|
||||
|
||||
/* set counter and initial values to 'offset' value */
|
||||
/* FIX!!! this assumes the salt is at key + 16, and thus that the */
|
||||
/* FIX!!! cipher key length is 16! Also note this copies past the
|
||||
end of the 'key' array by 2 bytes! */
|
||||
v128_copy_octet_string(&c->counter, key + 16);
|
||||
v128_copy_octet_string(&c->offset, key + 16);
|
||||
/* Note this copies past the end of the 'key' array by 2 bytes! */
|
||||
v128_copy_octet_string(&c->counter, key + base_key_len);
|
||||
v128_copy_octet_string(&c->offset, key + base_key_len);
|
||||
|
||||
/* force last two octets of the offset to zero (for srtp compatibility) */
|
||||
c->offset.v8[14] = c->offset.v8[15] = 0;
|
||||
c->counter.v8[14] = c->counter.v8[15] = 0;
|
||||
|
||||
/* set tmp_key (for alignment) */
|
||||
v128_copy_octet_string(&tmp_key, key);
|
||||
|
||||
debug_print(mod_aes_icm,
|
||||
"key: %s", v128_hex_string(&tmp_key));
|
||||
"key: %s", octet_string_hex_string(key, base_key_len));
|
||||
debug_print(mod_aes_icm,
|
||||
"offset: %s", v128_hex_string(&c->offset));
|
||||
|
||||
/* expand key */
|
||||
aes_expand_encryption_key(&tmp_key, c->expanded_key);
|
||||
status = aes_expand_encryption_key(key, base_key_len, &c->expanded_key);
|
||||
if (status) {
|
||||
v128_set_to_zero(&c->counter);
|
||||
v128_set_to_zero(&c->offset);
|
||||
return status;
|
||||
}
|
||||
|
||||
/* indicate that the keystream_buffer is empty */
|
||||
c->bytes_in_buffer = 0;
|
||||
|
@ -232,7 +240,7 @@ aes_icm_set_octet(aes_icm_ctx_t *c,
|
|||
/* fill keystream buffer, if needed */
|
||||
if (tail_num) {
|
||||
v128_copy(&c->keystream_buffer, &c->counter);
|
||||
aes_encrypt(&c->keystream_buffer, c->expanded_key);
|
||||
aes_encrypt(&c->keystream_buffer, &c->expanded_key);
|
||||
c->bytes_in_buffer = sizeof(v128_t);
|
||||
|
||||
debug_print(mod_aes_icm, "counter: %s",
|
||||
|
@ -259,7 +267,7 @@ aes_icm_set_octet(aes_icm_ctx_t *c,
|
|||
|
||||
err_status_t
|
||||
aes_icm_set_iv(aes_icm_ctx_t *c, void *iv) {
|
||||
v128_t *nonce = iv;
|
||||
v128_t *nonce = (v128_t *) iv;
|
||||
|
||||
debug_print(mod_aes_icm,
|
||||
"setting iv: %s", v128_hex_string(nonce));
|
||||
|
@ -284,11 +292,11 @@ aes_icm_set_iv(aes_icm_ctx_t *c, void *iv) {
|
|||
* this is an internal, hopefully inlined function
|
||||
*/
|
||||
|
||||
inline void
|
||||
static inline void
|
||||
aes_icm_advance_ismacryp(aes_icm_ctx_t *c, uint8_t forIsmacryp) {
|
||||
/* fill buffer with new keystream */
|
||||
v128_copy(&c->keystream_buffer, &c->counter);
|
||||
aes_encrypt(&c->keystream_buffer, c->expanded_key);
|
||||
aes_encrypt(&c->keystream_buffer, &c->expanded_key);
|
||||
c->bytes_in_buffer = sizeof(v128_t);
|
||||
|
||||
debug_print(mod_aes_icm, "counter: %s",
|
||||
|
@ -300,7 +308,7 @@ aes_icm_advance_ismacryp(aes_icm_ctx_t *c, uint8_t forIsmacryp) {
|
|||
|
||||
if (forIsmacryp) {
|
||||
uint32_t temp;
|
||||
/* alex's clock counter forward */
|
||||
//alex's clock counter forward
|
||||
temp = ntohl(c->counter.v32[3]);
|
||||
c->counter.v32[3] = htonl(++temp);
|
||||
} else {
|
||||
|
@ -309,7 +317,7 @@ aes_icm_advance_ismacryp(aes_icm_ctx_t *c, uint8_t forIsmacryp) {
|
|||
}
|
||||
}
|
||||
|
||||
inline void aes_icm_advance(aes_icm_ctx_t *c) {
|
||||
static inline void aes_icm_advance(aes_icm_ctx_t *c) {
|
||||
aes_icm_advance_ismacryp(c, 0);
|
||||
}
|
||||
|
||||
|
@ -341,7 +349,7 @@ aes_icm_encrypt_ismacryp(aes_icm_ctx_t *c,
|
|||
|
||||
debug_print(mod_aes_icm, "block index: %d",
|
||||
htons(c->counter.v16[7]));
|
||||
if (bytes_to_encr <= c->bytes_in_buffer) {
|
||||
if (bytes_to_encr <= (unsigned int)c->bytes_in_buffer) {
|
||||
|
||||
/* deal with odd case of small bytes_to_encr */
|
||||
for (i = (sizeof(v128_t) - c->bytes_in_buffer);
|
||||
|
@ -370,7 +378,7 @@ aes_icm_encrypt_ismacryp(aes_icm_ctx_t *c,
|
|||
for (i=0; i < (bytes_to_encr/sizeof(v128_t)); i++) {
|
||||
|
||||
/* fill buffer with new keystream */
|
||||
aes_icm_advance_ismacryp(c, (uint8_t)forIsmacryp);
|
||||
aes_icm_advance_ismacryp(c, forIsmacryp);
|
||||
|
||||
/*
|
||||
* add keystream into the data buffer (this would be a lot faster
|
||||
|
@ -418,7 +426,7 @@ aes_icm_encrypt_ismacryp(aes_icm_ctx_t *c,
|
|||
if ((bytes_to_encr & 0xf) != 0) {
|
||||
|
||||
/* fill buffer with new keystream */
|
||||
aes_icm_advance_ismacryp(c, (uint8_t)forIsmacryp);
|
||||
aes_icm_advance_ismacryp(c, forIsmacryp);
|
||||
|
||||
for (i=0; i < (bytes_to_encr & 0xf); i++)
|
||||
*buf++ ^= c->keystream_buffer.v8[i];
|
||||
|
@ -492,6 +500,46 @@ cipher_test_case_t aes_icm_test_case_0 = {
|
|||
NULL /* pointer to next testcase */
|
||||
};
|
||||
|
||||
uint8_t aes_icm_test_case_1_key[46] = {
|
||||
0x57, 0xf8, 0x2f, 0xe3, 0x61, 0x3f, 0xd1, 0x70,
|
||||
0xa8, 0x5e, 0xc9, 0x3c, 0x40, 0xb1, 0xf0, 0x92,
|
||||
0x2e, 0xc4, 0xcb, 0x0d, 0xc0, 0x25, 0xb5, 0x82,
|
||||
0x72, 0x14, 0x7c, 0xc4, 0x38, 0x94, 0x4a, 0x98,
|
||||
0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
|
||||
0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd
|
||||
};
|
||||
|
||||
uint8_t aes_icm_test_case_1_nonce[16] = {
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
|
||||
uint8_t aes_icm_test_case_1_plaintext[32] = {
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
};
|
||||
|
||||
uint8_t aes_icm_test_case_1_ciphertext[32] = {
|
||||
0x92, 0xbd, 0xd2, 0x8a, 0x93, 0xc3, 0xf5, 0x25,
|
||||
0x11, 0xc6, 0x77, 0xd0, 0x8b, 0x55, 0x15, 0xa4,
|
||||
0x9d, 0xa7, 0x1b, 0x23, 0x78, 0xa8, 0x54, 0xf6,
|
||||
0x70, 0x50, 0x75, 0x6d, 0xed, 0x16, 0x5b, 0xac
|
||||
};
|
||||
|
||||
cipher_test_case_t aes_icm_test_case_1 = {
|
||||
46, /* octets in key */
|
||||
aes_icm_test_case_1_key, /* key */
|
||||
aes_icm_test_case_1_nonce, /* packet index */
|
||||
32, /* octets in plaintext */
|
||||
aes_icm_test_case_1_plaintext, /* plaintext */
|
||||
32, /* octets in ciphertext */
|
||||
aes_icm_test_case_1_ciphertext, /* ciphertext */
|
||||
&aes_icm_test_case_0 /* pointer to next testcase */
|
||||
};
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* note: the encrypt function is identical to the decrypt function
|
||||
|
@ -506,7 +554,8 @@ cipher_type_t aes_icm = {
|
|||
(cipher_set_iv_func_t) aes_icm_set_iv,
|
||||
(char *) aes_icm_description,
|
||||
(int) 0, /* instance count */
|
||||
(cipher_test_case_t *) &aes_icm_test_case_0,
|
||||
(debug_module_t *) &mod_aes_icm
|
||||
(cipher_test_case_t *) &aes_icm_test_case_1,
|
||||
(debug_module_t *) &mod_aes_icm,
|
||||
(cipher_type_id_t) AES_ICM
|
||||
};
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2001-2005, Cisco Systems, Inc.
|
||||
* Copyright (c) 2001-2006, Cisco Systems, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -71,8 +71,8 @@ cipher_get_key_length(const cipher_t *c) {
|
|||
}
|
||||
|
||||
/*
|
||||
* cipher_type_self_test(ct) tests a cipher of type ct against test cases
|
||||
* provided in an array of values of key, salt, xtd_seq_num_t,
|
||||
* cipher_type_test(ct, test_data) tests a cipher of type ct against
|
||||
* test cases provided in a list test_data of values of key, salt, iv,
|
||||
* plaintext, and ciphertext that is known to be good
|
||||
*/
|
||||
|
||||
|
@ -81,8 +81,8 @@ cipher_get_key_length(const cipher_t *c) {
|
|||
#define MAX_KEY_LEN 64
|
||||
|
||||
err_status_t
|
||||
cipher_type_self_test(const cipher_type_t *ct) {
|
||||
const cipher_test_case_t *test_case = ct->test_data;
|
||||
cipher_type_test(const cipher_type_t *ct, const cipher_test_case_t *test_data) {
|
||||
const cipher_test_case_t *test_case = test_data;
|
||||
cipher_t *c;
|
||||
err_status_t status;
|
||||
uint8_t buffer[SELF_TEST_BUF_OCTETS];
|
||||
|
@ -155,7 +155,7 @@ cipher_type_self_test(const cipher_type_t *ct) {
|
|||
test_case->ciphertext_length_octets));
|
||||
|
||||
/* compare the resulting ciphertext with that in the test case */
|
||||
if ((int)len != test_case->ciphertext_length_octets)
|
||||
if (len != test_case->ciphertext_length_octets)
|
||||
return err_status_algo_fail;
|
||||
status = err_status_ok;
|
||||
for (i=0; i < test_case->ciphertext_length_octets; i++)
|
||||
|
@ -222,7 +222,7 @@ cipher_type_self_test(const cipher_type_t *ct) {
|
|||
test_case->plaintext_length_octets));
|
||||
|
||||
/* compare the resulting plaintext with that in the test case */
|
||||
if ((int)len != test_case->plaintext_length_octets)
|
||||
if (len != test_case->plaintext_length_octets)
|
||||
return err_status_algo_fail;
|
||||
status = err_status_ok;
|
||||
for (i=0; i < test_case->plaintext_length_octets; i++)
|
||||
|
@ -260,7 +260,7 @@ cipher_type_self_test(const cipher_type_t *ct) {
|
|||
/* now run some random invertibility tests */
|
||||
|
||||
/* allocate cipher, using paramaters from the first test case */
|
||||
test_case = ct->test_data;
|
||||
test_case = test_data;
|
||||
status = cipher_type_alloc(ct, &c, test_case->key_length_octets);
|
||||
if (status)
|
||||
return status;
|
||||
|
@ -344,7 +344,7 @@ cipher_type_self_test(const cipher_type_t *ct) {
|
|||
octet_string_hex_string(buffer, length));
|
||||
|
||||
/* compare the resulting plaintext with the original one */
|
||||
if ((int)length != plaintext_len)
|
||||
if (length != plaintext_len)
|
||||
return err_status_algo_fail;
|
||||
status = err_status_ok;
|
||||
for (i=0; i < plaintext_len; i++)
|
||||
|
@ -360,10 +360,24 @@ cipher_type_self_test(const cipher_type_t *ct) {
|
|||
|
||||
}
|
||||
|
||||
status = cipher_dealloc(c);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
return err_status_ok;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* cipher_type_self_test(ct) performs cipher_type_test on ct's internal
|
||||
* list of test data.
|
||||
*/
|
||||
|
||||
err_status_t
|
||||
cipher_type_self_test(const cipher_type_t *ct) {
|
||||
return cipher_type_test(ct, ct->test_data);
|
||||
}
|
||||
|
||||
/*
|
||||
* cipher_bits_per_second(c, l, t) computes (an estimate of) the
|
||||
* number of bits that a cipher implementation can encrypt in a second
|
||||
|
@ -383,7 +397,7 @@ cipher_bits_per_second(cipher_t *c, int octets_in_buffer, int num_trials) {
|
|||
unsigned char *enc_buf;
|
||||
unsigned int len = octets_in_buffer;
|
||||
|
||||
enc_buf = crypto_alloc(octets_in_buffer);
|
||||
enc_buf = (unsigned char*) crypto_alloc(octets_in_buffer);
|
||||
if (enc_buf == NULL)
|
||||
return 0; /* indicate bad parameters by returning null */
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2001-2005, Cisco Systems, Inc.
|
||||
* Copyright (c) 2001-2006, Cisco Systems, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -48,10 +48,6 @@
|
|||
#include "null_cipher.h"
|
||||
#include "alloc.h"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(disable:4100)
|
||||
#endif
|
||||
|
||||
/* the null_cipher uses the cipher debug module */
|
||||
|
||||
extern debug_module_t mod_cipher;
|
||||
|
@ -65,7 +61,7 @@ null_cipher_alloc(cipher_t **c, int key_len) {
|
|||
"allocating cipher with key length %d", key_len);
|
||||
|
||||
/* allocate memory a cipher of type null_cipher */
|
||||
pointer = crypto_alloc(sizeof(null_cipher_ctx_t) + sizeof(cipher_t));
|
||||
pointer = (uint8_t*)crypto_alloc(sizeof(null_cipher_ctx_t) + sizeof(cipher_t));
|
||||
if (pointer == NULL)
|
||||
return err_status_alloc_fail;
|
||||
|
||||
|
@ -103,7 +99,7 @@ null_cipher_dealloc(cipher_t *c) {
|
|||
}
|
||||
|
||||
err_status_t
|
||||
null_cipher_init(null_cipher_ctx_t *ctx, const uint8_t *key) {
|
||||
null_cipher_init(null_cipher_ctx_t *ctx, const uint8_t *key, int key_len) {
|
||||
|
||||
debug_print(mod_cipher, "initializing null cipher", NULL);
|
||||
|
||||
|
@ -151,6 +147,7 @@ cipher_type_t null_cipher = {
|
|||
(char *) null_cipher_description,
|
||||
(int) 0,
|
||||
(cipher_test_case_t *) &null_cipher_test_0,
|
||||
(debug_module_t *) NULL
|
||||
(debug_module_t *) NULL,
|
||||
(cipher_type_id_t) NULL_CIPHER
|
||||
};
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2001-2005, Cisco Systems, Inc.
|
||||
* Copyright (c) 2001-2006, Cisco Systems, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -74,8 +74,8 @@ auth_type_get_ref_count(const auth_type_t *at) {
|
|||
}
|
||||
|
||||
/*
|
||||
* auth_type_self_test() tests an auth function of type ct against
|
||||
* test cases provided in an array of values of key, data, and tag
|
||||
* auth_type_test() tests an auth function of type ct against
|
||||
* test cases provided in a list test_data of values of key, data, and tag
|
||||
* that is known to be good
|
||||
*/
|
||||
|
||||
|
@ -83,8 +83,8 @@ auth_type_get_ref_count(const auth_type_t *at) {
|
|||
#define SELF_TEST_TAG_BUF_OCTETS 32
|
||||
|
||||
err_status_t
|
||||
auth_type_self_test(const auth_type_t *at) {
|
||||
auth_test_case_t *test_case = at->test_data;
|
||||
auth_type_test(const auth_type_t *at, const auth_test_case_t *test_data) {
|
||||
const auth_test_case_t *test_case = test_data;
|
||||
auth_t *a;
|
||||
err_status_t status;
|
||||
uint8_t tag[SELF_TEST_TAG_BUF_OCTETS];
|
||||
|
@ -171,3 +171,13 @@ auth_type_self_test(const auth_type_t *at) {
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
* auth_type_self_test(at) performs auth_type_test on at's internal
|
||||
* list of test data.
|
||||
*/
|
||||
|
||||
err_status_t
|
||||
auth_type_self_test(const auth_type_t *at) {
|
||||
return auth_type_test(at, at->test_data);
|
||||
}
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
*/
|
||||
/*
|
||||
*
|
||||
* Copyright(c) 2001-2005 Cisco Systems, Inc.
|
||||
* Copyright(c) 2001-2006 Cisco Systems, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -57,7 +57,6 @@ err_status_t
|
|||
hmac_alloc(auth_t **a, int key_len, int out_len) {
|
||||
extern auth_type_t hmac;
|
||||
uint8_t *pointer;
|
||||
hmac_ctx_t *new_hmac_ctx;
|
||||
|
||||
debug_print(mod_hmac, "allocating auth func with key length %d", key_len);
|
||||
debug_print(mod_hmac, " tag length %d", out_len);
|
||||
|
@ -74,7 +73,7 @@ hmac_alloc(auth_t **a, int key_len, int out_len) {
|
|||
return err_status_bad_param;
|
||||
|
||||
/* allocate memory for auth and hmac_ctx_t structures */
|
||||
pointer = crypto_alloc(sizeof(hmac_ctx_t) + sizeof(auth_t));
|
||||
pointer = (uint8_t*)crypto_alloc(sizeof(hmac_ctx_t) + sizeof(auth_t));
|
||||
if (pointer == NULL)
|
||||
return err_status_alloc_fail;
|
||||
|
||||
|
@ -85,7 +84,6 @@ hmac_alloc(auth_t **a, int key_len, int out_len) {
|
|||
(*a)->out_len = out_len;
|
||||
(*a)->key_len = key_len;
|
||||
(*a)->prefix_len = 0;
|
||||
new_hmac_ctx = (hmac_ctx_t *)((*a)->state);
|
||||
|
||||
/* increment global count of all hmac uses */
|
||||
hmac.ref_count++;
|
||||
|
@ -180,7 +178,7 @@ hmac_compute(hmac_ctx_t *state, const void *message,
|
|||
return err_status_bad_param;
|
||||
|
||||
/* hash message, copy output into H */
|
||||
hmac_update(state, message, msg_octets);
|
||||
hmac_update(state, (const uint8_t*)message, msg_octets);
|
||||
sha1_final(&state->ctx, H);
|
||||
|
||||
/*
|
||||
|
@ -264,6 +262,7 @@ hmac = {
|
|||
(char *) hmac_description,
|
||||
(int) 0, /* instance count */
|
||||
(auth_test_case_t *) &hmac_test_case_0,
|
||||
(debug_module_t *) &mod_hmac
|
||||
(debug_module_t *) &mod_hmac,
|
||||
(auth_type_id_t) HMAC_SHA1
|
||||
};
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2001-2005, Cisco Systems, Inc.
|
||||
* Copyright (c) 2001-2006, Cisco Systems, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -48,10 +48,6 @@
|
|||
#include "null_auth.h"
|
||||
#include "alloc.h"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(disable:4100)
|
||||
#endif
|
||||
|
||||
/* null_auth uses the auth debug module */
|
||||
|
||||
extern debug_module_t mod_auth;
|
||||
|
@ -65,7 +61,7 @@ null_auth_alloc(auth_t **a, int key_len, int out_len) {
|
|||
debug_print(mod_auth, " tag length %d", out_len);
|
||||
|
||||
/* allocate memory for auth and null_auth_ctx_t structures */
|
||||
pointer = crypto_alloc(sizeof(null_auth_ctx_t) + sizeof(auth_t));
|
||||
pointer = (uint8_t*)crypto_alloc(sizeof(null_auth_ctx_t) + sizeof(auth_t));
|
||||
if (pointer == NULL)
|
||||
return err_status_alloc_fail;
|
||||
|
||||
|
@ -159,6 +155,8 @@ null_auth = {
|
|||
(auth_start_func) null_auth_start,
|
||||
(char *) null_auth_description,
|
||||
(int) 0, /* instance count */
|
||||
(auth_test_case_t *) &null_auth_test_case_0
|
||||
(auth_test_case_t *) &null_auth_test_case_0,
|
||||
(debug_module_t *) NULL,
|
||||
(auth_type_id_t) NULL_AUTH
|
||||
};
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2001-2005, Cisco Systems, Inc.
|
||||
* Copyright (c) 2001-2006, Cisco Systems, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -299,7 +299,8 @@ sha1_final(sha1_ctx_t *ctx, uint32_t *output) {
|
|||
else if (ctx->octets_in_buffer < 60)
|
||||
W[15] = 0x0;
|
||||
|
||||
/* process the word array */ for (t=16; t < 80; t++) {
|
||||
/* process the word array */
|
||||
for (t=16; t < 80; t++) {
|
||||
TEMP = W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16];
|
||||
W[t] = S1(TEMP);
|
||||
}
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
config.h
|
|
@ -9,7 +9,7 @@
|
|||
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2001-2005, Cisco Systems, Inc.
|
||||
* Copyright (c) 2001-2006, Cisco Systems, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -50,24 +50,30 @@
|
|||
|
||||
#include "datatypes.h"
|
||||
#include "gf2_8.h"
|
||||
#include "err.h"
|
||||
|
||||
/* aes internals */
|
||||
|
||||
typedef v128_t aes_expanded_key_t[11];
|
||||
typedef struct {
|
||||
v128_t round[15];
|
||||
int num_rounds;
|
||||
} aes_expanded_key_t;
|
||||
|
||||
err_status_t
|
||||
aes_expand_encryption_key(const uint8_t *key,
|
||||
int key_len,
|
||||
aes_expanded_key_t *expanded_key);
|
||||
|
||||
err_status_t
|
||||
aes_expand_decryption_key(const uint8_t *key,
|
||||
int key_len,
|
||||
aes_expanded_key_t *expanded_key);
|
||||
|
||||
void
|
||||
aes_expand_encryption_key(const v128_t *key,
|
||||
aes_expanded_key_t expanded_key);
|
||||
aes_encrypt(v128_t *plaintext, const aes_expanded_key_t *exp_key);
|
||||
|
||||
void
|
||||
aes_expand_decryption_key(const v128_t *key,
|
||||
aes_expanded_key_t expanded_key);
|
||||
|
||||
void
|
||||
aes_encrypt(v128_t *plaintext, const aes_expanded_key_t exp_key);
|
||||
|
||||
void
|
||||
aes_decrypt(v128_t *plaintext, const aes_expanded_key_t exp_key);
|
||||
aes_decrypt(v128_t *plaintext, const aes_expanded_key_t *exp_key);
|
||||
|
||||
#if 0
|
||||
/*
|
||||
|
|
|
@ -31,7 +31,7 @@ aes_cbc_encrypt(aes_cbc_ctx_t *c,
|
|||
|
||||
err_status_t
|
||||
aes_cbc_context_init(aes_cbc_ctx_t *c, const uint8_t *key,
|
||||
cipher_direction_t dir);
|
||||
int key_len, cipher_direction_t dir);
|
||||
|
||||
err_status_t
|
||||
aes_cbc_set_iv(aes_cbc_ctx_t *c, void *iv);
|
||||
|
|
|
@ -19,13 +19,14 @@ typedef struct {
|
|||
v128_t offset; /* initial offset value */
|
||||
v128_t keystream_buffer; /* buffers bytes of keystream */
|
||||
aes_expanded_key_t expanded_key; /* the cipher key */
|
||||
unsigned int bytes_in_buffer; /* number of unused bytes in buffer */
|
||||
int bytes_in_buffer; /* number of unused bytes in buffer */
|
||||
} aes_icm_ctx_t;
|
||||
|
||||
|
||||
err_status_t
|
||||
aes_icm_context_init(aes_icm_ctx_t *c,
|
||||
const unsigned char *key);
|
||||
const unsigned char *key,
|
||||
int key_len);
|
||||
|
||||
err_status_t
|
||||
aes_icm_set_iv(aes_icm_ctx_t *c, void *iv);
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
*/
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2001-2005 Cisco Systems, Inc.
|
||||
* Copyright (c) 2001-2006 Cisco Systems, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2001-2005, Cisco Systems, Inc.
|
||||
* Copyright (c) 2001-2006, Cisco Systems, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -48,6 +48,8 @@
|
|||
|
||||
#include "datatypes.h"
|
||||
#include "err.h" /* error codes */
|
||||
#include "crypto.h" /* for auth_type_id_t */
|
||||
#include "crypto_types.h" /* for values of auth_type_id_t */
|
||||
|
||||
typedef struct auth_type_t *auth_type_pointer;
|
||||
typedef struct auth_t *auth_pointer_t;
|
||||
|
@ -129,6 +131,7 @@ typedef struct auth_type_t {
|
|||
int ref_count;
|
||||
auth_test_case_t *test_data;
|
||||
debug_module_t *debug;
|
||||
auth_type_id_t id;
|
||||
} auth_type_t;
|
||||
|
||||
typedef struct auth_t {
|
||||
|
@ -148,6 +151,15 @@ typedef struct auth_t {
|
|||
err_status_t
|
||||
auth_type_self_test(const auth_type_t *at);
|
||||
|
||||
/*
|
||||
* auth_type_test() tests an auth_type against external test cases
|
||||
* provided in an array of values of key/message/tag that is known to
|
||||
* be good
|
||||
*/
|
||||
|
||||
err_status_t
|
||||
auth_type_test(const auth_type_t *at, const auth_test_case_t *test_data);
|
||||
|
||||
/*
|
||||
* auth_type_get_ref_count(at) returns the reference count (the number
|
||||
* of instantiations) of the auth_type_t at
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
*/
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2001-2005, Cisco Systems, Inc.
|
||||
* Copyright (c) 2001-2006, Cisco Systems, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -49,6 +49,8 @@
|
|||
#include "datatypes.h"
|
||||
#include "rdbx.h" /* for xtd_seq_num_t */
|
||||
#include "err.h" /* for error codes */
|
||||
#include "crypto.h" /* for cipher_type_id_t */
|
||||
#include "crypto_types.h" /* for values of cipher_type_id_t */
|
||||
|
||||
|
||||
/**
|
||||
|
@ -86,7 +88,7 @@ typedef err_status_t (*cipher_alloc_func_t)
|
|||
*/
|
||||
|
||||
typedef err_status_t (*cipher_init_func_t)
|
||||
(void *state, const uint8_t *key, cipher_direction_t dir);
|
||||
(void *state, const uint8_t *key, int key_len, cipher_direction_t dir);
|
||||
|
||||
/* a cipher_dealloc_func_t de-allocates a cipher_t */
|
||||
|
||||
|
@ -108,8 +110,7 @@ typedef err_status_t (*cipher_decrypt_func_t)
|
|||
(void *state, uint8_t *buffer, unsigned int *octets_to_decrypt);
|
||||
|
||||
/*
|
||||
* a cipher_set_nonce_seq_func_t function sets both the nonce
|
||||
* and the extended sequence number
|
||||
* a cipher_set_iv_func_t function sets the current initialization vector
|
||||
*/
|
||||
|
||||
typedef err_status_t (*cipher_set_iv_func_t)
|
||||
|
@ -147,6 +148,7 @@ typedef struct cipher_type_t {
|
|||
int ref_count;
|
||||
cipher_test_case_t *test_data;
|
||||
debug_module_t *debug;
|
||||
cipher_type_id_t id;
|
||||
} cipher_type_t;
|
||||
|
||||
/*
|
||||
|
@ -169,7 +171,7 @@ typedef struct cipher_t {
|
|||
|
||||
#define cipher_dealloc(c) (((c)->type)->dealloc(c))
|
||||
|
||||
#define cipher_init(c, k, dir) (((c)->type)->init(((c)->state), (k), (dir)))
|
||||
#define cipher_init(c, k, dir) (((c)->type)->init(((c)->state), (k), ((c)->key_len), (dir)))
|
||||
|
||||
#define cipher_encrypt(c, buf, len) \
|
||||
(((c)->type)->encrypt(((c)->state), (buf), (len)))
|
||||
|
@ -178,7 +180,7 @@ typedef struct cipher_t {
|
|||
(((c)->type)->decrypt(((c)->state), (buf), (len)))
|
||||
|
||||
#define cipher_set_iv(c, n) \
|
||||
((c) ? (((c)->type)->set_iv(((c)->state), (n))) : \
|
||||
((c) ? (((c)->type)->set_iv(((cipher_pointer_t)(c)->state), (n))) : \
|
||||
err_status_no_such_op)
|
||||
|
||||
err_status_t
|
||||
|
@ -201,6 +203,16 @@ err_status_t
|
|||
cipher_type_self_test(const cipher_type_t *ct);
|
||||
|
||||
|
||||
/*
|
||||
* cipher_type_test() tests a cipher against external test cases provided in
|
||||
* an array of values of key/xtd_seq_num_t/plaintext/ciphertext
|
||||
* that is known to be good
|
||||
*/
|
||||
|
||||
err_status_t
|
||||
cipher_type_test(const cipher_type_t *ct, const cipher_test_case_t *test_data);
|
||||
|
||||
|
||||
/*
|
||||
* cipher_bits_per_second(c, l, t) computes (and estimate of) the
|
||||
* number of bits that a cipher implementation can encrypt in a second
|
||||
|
|
|
@ -10,7 +10,33 @@
|
|||
#ifndef CRYPTO_H
|
||||
#define CRYPTO_H
|
||||
|
||||
#include "crypto_kernel.h"
|
||||
/**
|
||||
* @brief A cipher_type_id_t is an identifier for a particular cipher
|
||||
* type.
|
||||
*
|
||||
* A cipher_type_id_t is an integer that represents a particular
|
||||
* cipher type, e.g. the Advanced Encryption Standard (AES). A
|
||||
* NULL_CIPHER is avaliable; this cipher leaves the data unchanged,
|
||||
* and can be selected to indicate that no encryption is to take
|
||||
* place.
|
||||
*
|
||||
* @ingroup Ciphers
|
||||
*/
|
||||
typedef uint32_t cipher_type_id_t;
|
||||
|
||||
/**
|
||||
* @brief An auth_type_id_t is an identifier for a particular authentication
|
||||
* function.
|
||||
*
|
||||
* An auth_type_id_t is an integer that represents a particular
|
||||
* authentication function type, e.g. HMAC-SHA1. A NULL_AUTH is
|
||||
* avaliable; this authentication function performs no computation,
|
||||
* and can be selected to indicate that no authentication is to take
|
||||
* place.
|
||||
*
|
||||
* @ingroup Authentication
|
||||
*/
|
||||
typedef uint32_t auth_type_id_t;
|
||||
|
||||
#endif /* CRYPTO_H */
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
*/
|
||||
/*
|
||||
*
|
||||
* Copyright(c) 2001-2005 Cisco Systems, Inc.
|
||||
* Copyright(c) 2001-2006 Cisco Systems, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -55,7 +55,7 @@
|
|||
#include "err.h"
|
||||
#include "crypto_types.h"
|
||||
#include "key.h"
|
||||
|
||||
#include "crypto.h"
|
||||
|
||||
/*
|
||||
* crypto_kernel_state_t defines the possible states:
|
||||
|
@ -69,36 +69,6 @@ typedef enum {
|
|||
crypto_kernel_state_secure
|
||||
} crypto_kernel_state_t;
|
||||
|
||||
|
||||
/**
|
||||
* @brief A cipher_type_id_t is an identifier for a particular cipher
|
||||
* type.
|
||||
*
|
||||
* A cipher_type_id_t is an integer that represents a particular
|
||||
* cipher type, e.g. the Advanced Encryption Standard (AES). A
|
||||
* NULL_CIPHER is avaliable; this cipher leaves the data unchanged,
|
||||
* and can be selected to indicate that no encryption is to take
|
||||
* place.
|
||||
*
|
||||
* @ingroup Ciphers
|
||||
*/
|
||||
typedef uint32_t cipher_type_id_t;
|
||||
|
||||
/**
|
||||
* @brief An auth_type_id_t is an identifier for a particular authentication
|
||||
* function.
|
||||
*
|
||||
* An auth_type_id_t is an integer that represents a particular
|
||||
* authentication function type, e.g. HMAC-SHA1. A NULL_AUTH is
|
||||
* avaliable; this authentication function performs no computation,
|
||||
* and can be selected to indicate that no authentication is to take
|
||||
* place.
|
||||
*
|
||||
* @ingroup Authentication
|
||||
*/
|
||||
typedef uint32_t auth_type_id_t;
|
||||
|
||||
|
||||
/*
|
||||
* linked list of cipher types
|
||||
*/
|
||||
|
@ -212,6 +182,28 @@ crypto_kernel_load_cipher_type(cipher_type_t *ct, cipher_type_id_t id);
|
|||
err_status_t
|
||||
crypto_kernel_load_auth_type(auth_type_t *ct, auth_type_id_t id);
|
||||
|
||||
/*
|
||||
* crypto_kernel_replace_cipher_type(ct, id)
|
||||
*
|
||||
* replaces the crypto kernel's existing cipher for the cipher_type id
|
||||
* with a new one passed in externally. The new cipher must pass all the
|
||||
* existing cipher_type's self tests as well as its own.
|
||||
*/
|
||||
err_status_t
|
||||
crypto_kernel_replace_cipher_type(cipher_type_t *ct, cipher_type_id_t id);
|
||||
|
||||
|
||||
/*
|
||||
* crypto_kernel_replace_auth_type(ct, id)
|
||||
*
|
||||
* replaces the crypto kernel's existing cipher for the auth_type id
|
||||
* with a new one passed in externally. The new auth type must pass all the
|
||||
* existing auth_type's self tests as well as its own.
|
||||
*/
|
||||
err_status_t
|
||||
crypto_kernel_replace_auth_type(auth_type_t *ct, auth_type_id_t id);
|
||||
|
||||
|
||||
err_status_t
|
||||
crypto_kernel_load_debug_module(debug_module_t *new_dm);
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
*/
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2001-2005 Cisco Systems, Inc.
|
||||
* Copyright (c) 2001-2006 Cisco Systems, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -233,40 +233,6 @@ void
|
|||
octet_string_set_to_zero(uint8_t *s, int len);
|
||||
|
||||
|
||||
/*
|
||||
* functions manipulating bit_vector_t
|
||||
*
|
||||
* A bitvector_t consists of an array of words and an integer
|
||||
* representing the number of significant bits stored in the array.
|
||||
* The bits are packed as follows: the least significant bit is that
|
||||
* of word[0], while the most significant bit is the nth most
|
||||
* significant bit of word[m], where length = bits_per_word * m + n.
|
||||
*
|
||||
*/
|
||||
|
||||
#define bits_per_word 32
|
||||
#define bytes_per_word 4
|
||||
|
||||
typedef struct {
|
||||
uint32_t length;
|
||||
uint32_t *word;
|
||||
} bitvector_t;
|
||||
|
||||
int
|
||||
bitvector_alloc(bitvector_t *v, unsigned long length);
|
||||
|
||||
void
|
||||
bitvector_set_bit(bitvector_t *v, int bit_index);
|
||||
|
||||
int
|
||||
bitvector_get_bit(const bitvector_t *v, int bit_index);
|
||||
|
||||
int
|
||||
bitvector_print_hex(const bitvector_t *v, FILE *stream);
|
||||
|
||||
int
|
||||
bitvector_set_from_hex(bitvector_t *v, char *string);
|
||||
|
||||
#endif /* MATH_H */
|
||||
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
*/
|
||||
/*
|
||||
*
|
||||
* Copyright(c) 2001-2005 Cisco Systems, Inc.
|
||||
* Copyright(c) 2001-2006 Cisco Systems, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -97,12 +97,19 @@
|
|||
#define NULL_CIPHER 0
|
||||
|
||||
/**
|
||||
* @brief AES-128 Integer Counter Mode (AES ICM)
|
||||
* @brief AES Integer Counter Mode (AES ICM)
|
||||
*
|
||||
* AES-128 ICM is the variant of counter mode that is used by Secure RTP.
|
||||
* This cipher uses a 16-octet key and a 30-octet offset (or salt) value.
|
||||
* AES ICM is the variant of counter mode that is used by Secure RTP.
|
||||
* This cipher uses a 16-, 24-, or 32-octet key concatenated with a
|
||||
* 14-octet offset (or salt) value.
|
||||
*/
|
||||
#define AES_128_ICM 1
|
||||
#define AES_ICM 1
|
||||
|
||||
/**
|
||||
* @brief AES-128 Integer Counter Mode (AES ICM)
|
||||
* AES-128 ICM is a deprecated alternate name for AES ICM.
|
||||
*/
|
||||
#define AES_128_ICM AES_ICM
|
||||
|
||||
/**
|
||||
* @brief SEAL 3.0
|
||||
|
@ -113,19 +120,26 @@
|
|||
#define SEAL 2
|
||||
|
||||
/**
|
||||
* @brief AES-128 Integer Counter Mode (AES ICM)
|
||||
* @brief AES Cipher Block Chaining mode (AES CBC)
|
||||
*
|
||||
* AES-128 ICM is the variant of counter mode that is used by Secure RTP.
|
||||
* This cipher uses a 16-octet key and a 30-octet offset (or salt) value.
|
||||
* AES CBC is the AES Cipher Block Chaining mode.
|
||||
* This cipher uses a 16-, 24-, or 32-octet key.
|
||||
*/
|
||||
#define AES_128_CBC 3
|
||||
#define AES_CBC 3
|
||||
|
||||
/**
|
||||
* @brief AES-128 Cipher Block Chaining mode (AES CBC)
|
||||
*
|
||||
* AES-128 CBC is a deprecated alternate name for AES CBC.
|
||||
*/
|
||||
#define AES_128_CBC AES_CBC
|
||||
|
||||
/**
|
||||
* @brief Strongest available cipher.
|
||||
*
|
||||
* This identifier resolves to the strongest cipher type available.
|
||||
*/
|
||||
#define STRONGHOLD_CIPHER AES_128_ICM
|
||||
#define STRONGHOLD_CIPHER AES_ICM
|
||||
|
||||
/**
|
||||
* @}
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
*/
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2001-2005 Cisco Systems, Inc.
|
||||
* Copyright (c) 2001-2006 Cisco Systems, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2001-2005, Cisco Systems, Inc.
|
||||
* Copyright (c) 2001-2006, Cisco Systems, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -63,6 +63,7 @@
|
|||
# endif
|
||||
#endif
|
||||
|
||||
|
||||
/* if DATATYPES_USE_MACROS is defined, then little functions are macros */
|
||||
#define DATATYPES_USE_MACROS
|
||||
|
||||
|
@ -154,10 +155,10 @@ void
|
|||
v128_copy_octet_string(v128_t *x, const uint8_t s[16]);
|
||||
|
||||
void
|
||||
v128_left_shift(v128_t *x, int index);
|
||||
v128_left_shift(v128_t *x, int shift_index);
|
||||
|
||||
void
|
||||
v128_right_shift(v128_t *x, int index);
|
||||
v128_right_shift(v128_t *x, int shift_index);
|
||||
|
||||
/*
|
||||
* the following macros define the data manipulation functions
|
||||
|
@ -392,22 +393,114 @@ octet_string_set_to_zero(uint8_t *s, int len);
|
|||
# define be64_to_cpu(x) bswap_64((x))
|
||||
#else
|
||||
|
||||
#if defined(__GNUC__) && defined(HAVE_X86)
|
||||
/* Fall back. */
|
||||
static inline uint32_t be32_to_cpu(uint32_t v) {
|
||||
/* optimized for x86. */
|
||||
asm("bswap %0" : "=r" (v) : "0" (v));
|
||||
return v;
|
||||
}
|
||||
# else /* HAVE_X86 */
|
||||
# ifdef HAVE_NETINET_IN_H
|
||||
# include <netinet/in.h>
|
||||
# elif defined HAVE_WINSOCK2_H
|
||||
# include <winsock2.h>
|
||||
# endif
|
||||
# define be32_to_cpu(x) ntohl((x))
|
||||
# endif /* HAVE_X86 */
|
||||
|
||||
static inline uint64_t be64_to_cpu(uint64_t v) {
|
||||
# ifdef NO_64BIT_MATH
|
||||
/* use the make64 functions to do 64-bit math */
|
||||
# define be64_to_cpu(v) (make64(htonl(low32(v)),htonl(high32(v))))
|
||||
v = make64(htonl(low32(v)),htonl(high32(v)));
|
||||
# else
|
||||
# define be64_to_cpu(v) ((ntohl((uint32_t)(v >> 32))) | (((uint64_t)ntohl((uint32_t)v)) << 32))
|
||||
/* use the native 64-bit math */
|
||||
v= (uint64_t)((be32_to_cpu((uint32_t)(v >> 32))) | (((uint64_t)be32_to_cpu((uint32_t)v)) << 32));
|
||||
# endif
|
||||
return v;
|
||||
}
|
||||
|
||||
#endif /* ! SRTP_KERNEL_LINUX */
|
||||
|
||||
#endif /* WORDS_BIGENDIAN */
|
||||
|
||||
/*
|
||||
* functions manipulating bitvector_t
|
||||
*
|
||||
* A bitvector_t consists of an array of words and an integer
|
||||
* representing the number of significant bits stored in the array.
|
||||
* The bits are packed as follows: the least significant bit is that
|
||||
* of word[0], while the most significant bit is the nth most
|
||||
* significant bit of word[m], where length = bits_per_word * m + n.
|
||||
*
|
||||
*/
|
||||
|
||||
#define bits_per_word 32
|
||||
#define bytes_per_word 4
|
||||
|
||||
typedef struct {
|
||||
uint32_t length;
|
||||
uint32_t *word;
|
||||
} bitvector_t;
|
||||
|
||||
|
||||
#define _bitvector_get_bit(v, bit_index) \
|
||||
( \
|
||||
((((v)->word[((bit_index) >> 5)]) >> ((bit_index) & 31)) & 1) \
|
||||
)
|
||||
|
||||
|
||||
#define _bitvector_set_bit(v, bit_index) \
|
||||
( \
|
||||
(((v)->word[((bit_index) >> 5)] |= ((uint32_t)1 << ((bit_index) & 31)))) \
|
||||
)
|
||||
|
||||
#define _bitvector_clear_bit(v, bit_index) \
|
||||
( \
|
||||
(((v)->word[((bit_index) >> 5)] &= ~((uint32_t)1 << ((bit_index) & 31)))) \
|
||||
)
|
||||
|
||||
#define _bitvector_get_length(v) \
|
||||
( \
|
||||
((v)->length) \
|
||||
)
|
||||
|
||||
#ifdef DATATYPES_USE_MACROS /* little functions are really macros */
|
||||
|
||||
#define bitvector_get_bit(v, bit_index) _bitvector_get_bit(v, bit_index)
|
||||
#define bitvector_set_bit(v, bit_index) _bitvector_set_bit(v, bit_index)
|
||||
#define bitvector_clear_bit(v, bit_index) _bitvector_clear_bit(v, bit_index)
|
||||
#define bitvector_get_length(v) _bitvector_get_length(v)
|
||||
|
||||
#else
|
||||
|
||||
int
|
||||
bitvector_get_bit(const bitvector_t *v, int bit_index);
|
||||
|
||||
void
|
||||
bitvector_set_bit(bitvector_t *v, int bit_index);
|
||||
|
||||
void
|
||||
bitvector_clear_bit(bitvector_t *v, int bit_index);
|
||||
|
||||
unsigned long
|
||||
bitvector_get_length(const bitvector_t *v);
|
||||
|
||||
#endif
|
||||
|
||||
int
|
||||
bitvector_alloc(bitvector_t *v, unsigned long length);
|
||||
|
||||
void
|
||||
bitvector_dealloc(bitvector_t *v);
|
||||
|
||||
void
|
||||
bitvector_set_to_zero(bitvector_t *x);
|
||||
|
||||
void
|
||||
bitvector_left_shift(bitvector_t *x, int index);
|
||||
|
||||
char *
|
||||
bitvector_bit_string(bitvector_t *x, char* buf, int len);
|
||||
|
||||
#endif /* _DATATYPES_H */
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
*/
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2001-2005, Cisco Systems, Inc.
|
||||
* Copyright (c) 2001-2006, Cisco Systems, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -90,7 +90,7 @@ typedef enum {
|
|||
err_status_parse_err = 21, /**< error pasring data */
|
||||
err_status_encode_err = 22, /**< error encoding data */
|
||||
err_status_semaphore_err = 23,/**< error while using semaphores */
|
||||
err_status_pfkey_err = 24 ,/**< error while using pfkey */
|
||||
err_status_pfkey_err = 24 /**< error while using pfkey */
|
||||
} err_status_t;
|
||||
|
||||
/**
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2001-2005, Cisco Systems, Inc.
|
||||
* Copyright (c) 2001-2006, Cisco Systems, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
*/
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2001-2005, Cisco Systems, Inc.
|
||||
* Copyright (c) 2001-2006, Cisco Systems, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2001-2005, Cisco Systems, Inc.
|
||||
* Copyright (c) 2001-2006, Cisco Systems, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -113,7 +113,7 @@ extern uint32_t low32(uint64_t value);
|
|||
addresses. This is required for processors that do not allow unaligned
|
||||
loads. */
|
||||
#ifdef ALIGNMENT_32BIT_REQUIRED
|
||||
// Note that if it's in a variable, you can memcpy it
|
||||
/* Note that if it's in a variable, you can memcpy it */
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
#define PUT_32(addr,value) \
|
||||
{ \
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
*/
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2001-2005 Cisco Systems, Inc.
|
||||
* Copyright (c) 2001-2006 Cisco Systems, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2001-2005, Cisco Systems, Inc.
|
||||
* Copyright (c) 2001-2006, Cisco Systems, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2001-2005, Cisco Systems, Inc.
|
||||
* Copyright (c) 2001-2006, Cisco Systems, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -62,11 +62,11 @@ typedef struct {
|
|||
*/
|
||||
|
||||
err_status_t
|
||||
null_cipher_init(null_cipher_ctx_t *c, const uint8_t *key);
|
||||
null_cipher_init(null_cipher_ctx_t *c, const uint8_t *key, int key_len);
|
||||
|
||||
err_status_t
|
||||
null_cipher_set_segment(null_cipher_ctx_t *c,
|
||||
unsigned long index);
|
||||
unsigned long segment_index);
|
||||
|
||||
err_status_t
|
||||
null_cipher_encrypt(null_cipher_ctx_t *c,
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
*/
|
||||
/*
|
||||
*
|
||||
* Copyright(c) 2001-2005 Cisco Systems, Inc.
|
||||
* Copyright(c) 2001-2006 Cisco Systems, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
|
|
@ -49,7 +49,7 @@ rdb_init(rdb_t *rdb);
|
|||
*/
|
||||
|
||||
err_status_t
|
||||
rdb_check(const rdb_t *rdb, uint32_t index);
|
||||
rdb_check(const rdb_t *rdb, uint32_t rdb_index);
|
||||
|
||||
/*
|
||||
* rdb_add_index
|
||||
|
@ -61,7 +61,7 @@ rdb_check(const rdb_t *rdb, uint32_t index);
|
|||
*/
|
||||
|
||||
err_status_t
|
||||
rdb_add_index(rdb_t *rdb, uint32_t index);
|
||||
rdb_add_index(rdb_t *rdb, uint32_t rdb_index);
|
||||
|
||||
/*
|
||||
* the functions rdb_increment() and rdb_get_value() are for use by
|
||||
|
|
|
@ -46,19 +46,29 @@ typedef uint64_t xtd_seq_num_t;
|
|||
|
||||
typedef struct {
|
||||
xtd_seq_num_t index;
|
||||
v128_t bitmask;
|
||||
bitvector_t bitmask;
|
||||
} rdbx_t;
|
||||
|
||||
|
||||
/*
|
||||
* rdbx_init(rdbx_ptr)
|
||||
* rdbx_init(rdbx_ptr, ws)
|
||||
*
|
||||
* initializes the rdbx pointed to by its argument, setting the
|
||||
* rollover counter and sequence number to zero
|
||||
* initializes the rdbx pointed to by its argument with the window size ws,
|
||||
* setting the rollover counter and sequence number to zero
|
||||
*/
|
||||
|
||||
err_status_t
|
||||
rdbx_init(rdbx_t *rdbx);
|
||||
rdbx_init(rdbx_t *rdbx, unsigned long ws);
|
||||
|
||||
|
||||
/*
|
||||
* rdbx_dealloc(rdbx_ptr)
|
||||
*
|
||||
* frees memory associated with the rdbx
|
||||
*/
|
||||
|
||||
err_status_t
|
||||
rdbx_dealloc(rdbx_t *rdbx);
|
||||
|
||||
|
||||
/*
|
||||
|
@ -100,12 +110,42 @@ rdbx_check(const rdbx_t *rdbx, int difference);
|
|||
err_status_t
|
||||
rdbx_add_index(rdbx_t *rdbx, int delta);
|
||||
|
||||
|
||||
/*
|
||||
* rdbx_set_roc(rdbx, roc) initalizes the rdbx_t at the location rdbx
|
||||
* to have the rollover counter value roc. If that value is less than
|
||||
* the current rollover counter value, then the function returns
|
||||
* err_status_replay_old; otherwise, err_status_ok is returned.
|
||||
*
|
||||
*/
|
||||
|
||||
err_status_t
|
||||
rdbx_set_roc(rdbx_t *rdbx, uint32_t roc);
|
||||
|
||||
/*
|
||||
* rdbx_get_roc(rdbx) returns the value of the rollover counter for
|
||||
* the rdbx_t pointed to by rdbx
|
||||
*
|
||||
*/
|
||||
|
||||
xtd_seq_num_t
|
||||
rdbx_get_packet_index(const rdbx_t *rdbx);
|
||||
|
||||
/*
|
||||
* xtd_seq_num_t functions - these are *internal* functions of rdbx, and
|
||||
* shouldn't be used to manipulate rdbx internal values. use the rdbx
|
||||
* api instead!
|
||||
*/
|
||||
|
||||
/*
|
||||
* rdbx_get_ws(rdbx_ptr)
|
||||
*
|
||||
* gets the window size which was used to initialize the rdbx
|
||||
*/
|
||||
|
||||
unsigned long
|
||||
rdbx_get_window_size(const rdbx_t *rdbx);
|
||||
|
||||
|
||||
/* index_init(&pi) initializes a packet index pi (sets it to zero) */
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2001-2005, Cisco Systems, Inc.
|
||||
* Copyright (c) 2001-2006, Cisco Systems, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
|
||||
/*
|
||||
*
|
||||
* Copyright(c) 2001-2005, Cisco Systems, Inc.
|
||||
* Copyright(c) 2001-2006, Cisco Systems, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
*/
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2001-2005 Cisco Systems, Inc.
|
||||
* Copyright (c) 2001-2006 Cisco Systems, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
*/
|
||||
/*
|
||||
*
|
||||
* Copyright(c) 2001-2005 Cisco Systems, Inc.
|
||||
* Copyright(c) 2001-2006 Cisco Systems, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -151,10 +151,10 @@ crypto_kernel_init() {
|
|||
status = crypto_kernel_load_cipher_type(&null_cipher, NULL_CIPHER);
|
||||
if (status)
|
||||
return status;
|
||||
status = crypto_kernel_load_cipher_type(&aes_icm, AES_128_ICM);
|
||||
status = crypto_kernel_load_cipher_type(&aes_icm, AES_ICM);
|
||||
if (status)
|
||||
return status;
|
||||
status = crypto_kernel_load_cipher_type(&aes_cbc, AES_128_CBC);
|
||||
status = crypto_kernel_load_cipher_type(&aes_cbc, AES_CBC);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
|
@ -297,15 +297,19 @@ crypto_kernel_shutdown() {
|
|||
return err_status_ok;
|
||||
}
|
||||
|
||||
err_status_t
|
||||
crypto_kernel_load_cipher_type(cipher_type_t *new_ct, cipher_type_id_t id) {
|
||||
kernel_cipher_type_t *ctype, *new;
|
||||
static inline err_status_t
|
||||
crypto_kernel_do_load_cipher_type(cipher_type_t *new_ct, cipher_type_id_t id,
|
||||
int replace) {
|
||||
kernel_cipher_type_t *ctype, *new_ctype;
|
||||
err_status_t status;
|
||||
|
||||
/* defensive coding */
|
||||
if (new_ct == NULL)
|
||||
return err_status_bad_param;
|
||||
|
||||
if (new_ct->id != id)
|
||||
return err_status_bad_param;
|
||||
|
||||
/* check cipher type by running self-test */
|
||||
status = cipher_type_self_test(new_ct);
|
||||
if (status) {
|
||||
|
@ -315,24 +319,35 @@ crypto_kernel_load_cipher_type(cipher_type_t *new_ct, cipher_type_id_t id) {
|
|||
/* walk down list, checking if this type is in the list already */
|
||||
ctype = crypto_kernel.cipher_type_list;
|
||||
while (ctype != NULL) {
|
||||
if ((new_ct == ctype->cipher_type) || (id == ctype->id))
|
||||
if (id == ctype->id) {
|
||||
if (!replace)
|
||||
return err_status_bad_param;
|
||||
status = cipher_type_test(new_ct, ctype->cipher_type->test_data);
|
||||
if (status)
|
||||
return status;
|
||||
new_ctype = ctype;
|
||||
break;
|
||||
}
|
||||
else if (new_ct == ctype->cipher_type)
|
||||
return err_status_bad_param;
|
||||
ctype = ctype->next;
|
||||
}
|
||||
|
||||
/* put new_ct at the head of the list */
|
||||
/* if not found, put new_ct at the head of the list */
|
||||
if (ctype == NULL) {
|
||||
/* allocate memory */
|
||||
new = (kernel_cipher_type_t *) crypto_alloc(sizeof(kernel_cipher_type_t));
|
||||
if (new == NULL)
|
||||
new_ctype = (kernel_cipher_type_t *) crypto_alloc(sizeof(kernel_cipher_type_t));
|
||||
if (new_ctype == NULL)
|
||||
return err_status_alloc_fail;
|
||||
|
||||
/* set fields */
|
||||
new->cipher_type = new_ct;
|
||||
new->id = id;
|
||||
new->next = crypto_kernel.cipher_type_list;
|
||||
new_ctype->next = crypto_kernel.cipher_type_list;
|
||||
|
||||
/* set head of list to new cipher type */
|
||||
crypto_kernel.cipher_type_list = new;
|
||||
crypto_kernel.cipher_type_list = new_ctype;
|
||||
}
|
||||
|
||||
/* set fields */
|
||||
new_ctype->cipher_type = new_ct;
|
||||
new_ctype->id = id;
|
||||
|
||||
/* load debug module, if there is one present */
|
||||
if (new_ct->debug != NULL)
|
||||
|
@ -343,14 +358,28 @@ crypto_kernel_load_cipher_type(cipher_type_t *new_ct, cipher_type_id_t id) {
|
|||
}
|
||||
|
||||
err_status_t
|
||||
crypto_kernel_load_auth_type(auth_type_t *new_at, auth_type_id_t id) {
|
||||
kernel_auth_type_t *atype, *new;
|
||||
crypto_kernel_load_cipher_type(cipher_type_t *new_ct, cipher_type_id_t id) {
|
||||
return crypto_kernel_do_load_cipher_type(new_ct, id, 0);
|
||||
}
|
||||
|
||||
err_status_t
|
||||
crypto_kernel_replace_cipher_type(cipher_type_t *new_ct, cipher_type_id_t id) {
|
||||
return crypto_kernel_do_load_cipher_type(new_ct, id, 1);
|
||||
}
|
||||
|
||||
err_status_t
|
||||
crypto_kernel_do_load_auth_type(auth_type_t *new_at, auth_type_id_t id,
|
||||
int replace) {
|
||||
kernel_auth_type_t *atype, *new_atype;
|
||||
err_status_t status;
|
||||
|
||||
/* defensive coding */
|
||||
if (new_at == NULL)
|
||||
return err_status_bad_param;
|
||||
|
||||
if (new_at->id != id)
|
||||
return err_status_bad_param;
|
||||
|
||||
/* check auth type by running self-test */
|
||||
status = auth_type_self_test(new_at);
|
||||
if (status) {
|
||||
|
@ -360,24 +389,35 @@ crypto_kernel_load_auth_type(auth_type_t *new_at, auth_type_id_t id) {
|
|||
/* walk down list, checking if this type is in the list already */
|
||||
atype = crypto_kernel.auth_type_list;
|
||||
while (atype != NULL) {
|
||||
if ((new_at == atype->auth_type) || (id == atype->id))
|
||||
if (id == atype->id) {
|
||||
if (!replace)
|
||||
return err_status_bad_param;
|
||||
status = auth_type_test(new_at, atype->auth_type->test_data);
|
||||
if (status)
|
||||
return status;
|
||||
new_atype = atype;
|
||||
break;
|
||||
}
|
||||
else if (new_at == atype->auth_type)
|
||||
return err_status_bad_param;
|
||||
atype = atype->next;
|
||||
}
|
||||
|
||||
/* put new_at at the head of the list */
|
||||
/* if not found, put new_at at the head of the list */
|
||||
if (atype == NULL) {
|
||||
/* allocate memory */
|
||||
new = (kernel_auth_type_t *)crypto_alloc(sizeof(kernel_auth_type_t));
|
||||
if (new == NULL)
|
||||
new_atype = (kernel_auth_type_t *)crypto_alloc(sizeof(kernel_auth_type_t));
|
||||
if (new_atype == NULL)
|
||||
return err_status_alloc_fail;
|
||||
|
||||
/* set fields */
|
||||
new->auth_type = new_at;
|
||||
new->id = id;
|
||||
new->next = crypto_kernel.auth_type_list;
|
||||
|
||||
new_atype->next = crypto_kernel.auth_type_list;
|
||||
/* set head of list to new auth type */
|
||||
crypto_kernel.auth_type_list = new;
|
||||
crypto_kernel.auth_type_list = new_atype;
|
||||
}
|
||||
|
||||
/* set fields */
|
||||
new_atype->auth_type = new_at;
|
||||
new_atype->id = id;
|
||||
|
||||
/* load debug module, if there is one present */
|
||||
if (new_at->debug != NULL)
|
||||
|
@ -388,6 +428,16 @@ crypto_kernel_load_auth_type(auth_type_t *new_at, auth_type_id_t id) {
|
|||
|
||||
}
|
||||
|
||||
err_status_t
|
||||
crypto_kernel_load_auth_type(auth_type_t *new_at, auth_type_id_t id) {
|
||||
return crypto_kernel_do_load_auth_type(new_at, id, 0);
|
||||
}
|
||||
|
||||
err_status_t
|
||||
crypto_kernel_replace_auth_type(auth_type_t *new_at, auth_type_id_t id) {
|
||||
return crypto_kernel_do_load_auth_type(new_at, id, 1);
|
||||
}
|
||||
|
||||
|
||||
cipher_type_t *
|
||||
crypto_kernel_get_cipher_type(cipher_type_id_t id) {
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
*/
|
||||
/*
|
||||
*
|
||||
* Copyright(c) 2001-2005 Cisco Systems, Inc.
|
||||
* Copyright(c) 2001-2006 Cisco Systems, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -42,10 +42,6 @@
|
|||
*
|
||||
*/
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(disable:4100)
|
||||
#endif
|
||||
|
||||
#include "err.h"
|
||||
|
||||
#ifdef ERR_REPORTING_SYSLOG
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
*/
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2001-2005 Cisco Systems, Inc.
|
||||
* Copyright (c) 2001-2006 Cisco Systems, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
*/
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2001-2005 Cisco Systems, Inc.
|
||||
* Copyright (c) 2001-2006 Cisco Systems, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -95,7 +95,7 @@ octet_get_weight(uint8_t octet) {
|
|||
|
||||
/* the value MAX_PRINT_STRING_LEN is defined in datatypes.h */
|
||||
|
||||
static char bit_string[MAX_PRINT_STRING_LEN];
|
||||
char bit_string[MAX_PRINT_STRING_LEN];
|
||||
|
||||
uint8_t
|
||||
nibble_to_hex_char(uint8_t nibble) {
|
||||
|
@ -106,7 +106,7 @@ nibble_to_hex_char(uint8_t nibble) {
|
|||
|
||||
char *
|
||||
octet_string_hex_string(const void *s, int length) {
|
||||
const uint8_t *str = s;
|
||||
const uint8_t *str = (const uint8_t *)s;
|
||||
int i;
|
||||
|
||||
/* double length, since one octet takes two hex characters */
|
||||
|
@ -124,7 +124,7 @@ octet_string_hex_string(const void *s, int length) {
|
|||
return bit_string;
|
||||
}
|
||||
|
||||
inline int
|
||||
static inline int
|
||||
hex_char_to_nibble(uint8_t c) {
|
||||
switch(c) {
|
||||
case ('0'): return 0x0;
|
||||
|
@ -149,9 +149,10 @@ hex_char_to_nibble(uint8_t c) {
|
|||
case ('E'): return 0xe;
|
||||
case ('f'): return 0xf;
|
||||
case ('F'): return 0xf;
|
||||
default: return -1; /* this flags an error */
|
||||
}
|
||||
/* this flags an error */
|
||||
return -1;
|
||||
/* NOTREACHED */
|
||||
return -1; /* this keeps compilers from complaining */
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -178,7 +179,7 @@ hex_string_to_octet_string(char *raw, char *hex, int len) {
|
|||
tmp = hex_char_to_nibble(hex[0]);
|
||||
if (tmp == -1)
|
||||
return hex_len;
|
||||
x = (uint8_t)(tmp << 4);
|
||||
x = (tmp << 4);
|
||||
hex_len++;
|
||||
tmp = hex_char_to_nibble(hex[1]);
|
||||
if (tmp == -1)
|
||||
|
@ -206,16 +207,16 @@ v128_hex_string(v128_t *x) {
|
|||
|
||||
char *
|
||||
v128_bit_string(v128_t *x) {
|
||||
int j, index;
|
||||
int j, i;
|
||||
uint32_t mask;
|
||||
|
||||
for (j=index=0; j < 4; j++) {
|
||||
for (j=i=0; j < 4; j++) {
|
||||
for (mask=0x80000000; mask > 0; mask >>= 1) {
|
||||
if (x->v32[j] & mask)
|
||||
bit_string[index] = '1';
|
||||
bit_string[i] = '1';
|
||||
else
|
||||
bit_string[index] = '0';
|
||||
++index;
|
||||
bit_string[i] = '0';
|
||||
++i;
|
||||
}
|
||||
}
|
||||
bit_string[128] = 0; /* null terminate string */
|
||||
|
@ -322,13 +323,13 @@ v128_set_bit_to(v128_t *x, int i, int y){
|
|||
#endif /* DATATYPES_USE_MACROS */
|
||||
|
||||
void
|
||||
v128_right_shift(v128_t *x, int index) {
|
||||
const int base_index = index >> 5;
|
||||
const int bit_index = index & 31;
|
||||
v128_right_shift(v128_t *x, int shift) {
|
||||
const int base_index = shift >> 5;
|
||||
const int bit_index = shift & 31;
|
||||
int i, from;
|
||||
uint32_t b;
|
||||
|
||||
if (index > 127) {
|
||||
if (shift > 127) {
|
||||
v128_set_to_zero(x);
|
||||
return;
|
||||
}
|
||||
|
@ -360,12 +361,12 @@ v128_right_shift(v128_t *x, int index) {
|
|||
}
|
||||
|
||||
void
|
||||
v128_left_shift(v128_t *x, int index) {
|
||||
v128_left_shift(v128_t *x, int shift) {
|
||||
int i;
|
||||
const int base_index = index >> 5;
|
||||
const int bit_index = index & 31;
|
||||
const int base_index = shift >> 5;
|
||||
const int bit_index = shift & 31;
|
||||
|
||||
if (index > 127) {
|
||||
if (shift > 127) {
|
||||
v128_set_to_zero(x);
|
||||
return;
|
||||
}
|
||||
|
@ -386,6 +387,124 @@ v128_left_shift(v128_t *x, int index) {
|
|||
|
||||
}
|
||||
|
||||
/* functions manipulating bitvector_t */
|
||||
|
||||
#ifndef DATATYPES_USE_MACROS /* little functions are not macros */
|
||||
|
||||
int
|
||||
bitvector_get_bit(const bitvector_t *v, int bit_index)
|
||||
{
|
||||
return _bitvector_get_bit(v, bit_index);
|
||||
}
|
||||
|
||||
void
|
||||
bitvector_set_bit(bitvector_t *v, int bit_index)
|
||||
{
|
||||
_bitvector_set_bit(v, bit_index);
|
||||
}
|
||||
|
||||
void
|
||||
bitvector_clear_bit(bitvector_t *v, int bit_index)
|
||||
{
|
||||
_bitvector_clear_bit(v, bit_index);
|
||||
}
|
||||
|
||||
|
||||
#endif /* DATATYPES_USE_MACROS */
|
||||
|
||||
int
|
||||
bitvector_alloc(bitvector_t *v, unsigned long length) {
|
||||
unsigned long l;
|
||||
|
||||
/* Round length up to a multiple of bits_per_word */
|
||||
length = (length + bits_per_word - 1) & ~(unsigned long)((bits_per_word - 1));
|
||||
|
||||
l = length / bits_per_word * bytes_per_word;
|
||||
|
||||
/* allocate memory, then set parameters */
|
||||
if (l == 0)
|
||||
v->word = NULL;
|
||||
else {
|
||||
v->word = (uint32_t*)crypto_alloc(l);
|
||||
if (v->word == NULL) {
|
||||
v->word = NULL;
|
||||
v->length = 0;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
v->length = length;
|
||||
|
||||
/* initialize bitvector to zero */
|
||||
bitvector_set_to_zero(v);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
bitvector_dealloc(bitvector_t *v) {
|
||||
if (v->word != NULL)
|
||||
crypto_free(v->word);
|
||||
v->word = NULL;
|
||||
v->length = 0;
|
||||
}
|
||||
|
||||
void
|
||||
bitvector_set_to_zero(bitvector_t *x)
|
||||
{
|
||||
/* C99 guarantees that memset(0) will set the value 0 for uint32_t */
|
||||
memset(x->word, 0, x->length >> 3);
|
||||
}
|
||||
|
||||
char *
|
||||
bitvector_bit_string(bitvector_t *x, char* buf, int len) {
|
||||
int j, i;
|
||||
uint32_t mask;
|
||||
|
||||
for (j=i=0; j < (int)(x->length>>5) && i < len-1; j++) {
|
||||
for (mask=0x80000000; mask > 0; mask >>= 1) {
|
||||
if (x->word[j] & mask)
|
||||
buf[i] = '1';
|
||||
else
|
||||
buf[i] = '0';
|
||||
++i;
|
||||
if (i >= len-1)
|
||||
break;
|
||||
}
|
||||
}
|
||||
buf[i] = 0; /* null terminate string */
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
void
|
||||
bitvector_left_shift(bitvector_t *x, int shift) {
|
||||
int i;
|
||||
const int base_index = shift >> 5;
|
||||
const int bit_index = shift & 31;
|
||||
const int word_length = x->length >> 5;
|
||||
|
||||
if (shift >= (int)x->length) {
|
||||
bitvector_set_to_zero(x);
|
||||
return;
|
||||
}
|
||||
|
||||
if (bit_index == 0) {
|
||||
for (i=0; i < word_length - base_index; i++)
|
||||
x->word[i] = x->word[i+base_index];
|
||||
} else {
|
||||
for (i=0; i < word_length - base_index - 1; i++)
|
||||
x->word[i] = (x->word[i+base_index] >> bit_index) ^
|
||||
(x->word[i+base_index+1] << (32 - bit_index));
|
||||
x->word[word_length - base_index-1] = x->word[word_length-1] >> bit_index;
|
||||
}
|
||||
|
||||
/* now wrap up the final portion */
|
||||
for (i = word_length - base_index; i < word_length; i++)
|
||||
x->word[i] = 0;
|
||||
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
octet_string_is_eq(uint8_t *a, uint8_t *b, int len) {
|
||||
|
@ -563,6 +682,8 @@ base64_char_to_sextet(uint8_t c) {
|
|||
return 63;
|
||||
case '=':
|
||||
return 64;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
@ -583,7 +704,7 @@ base64_string_to_octet_string(char *raw, char *base64, int len) {
|
|||
tmp = base64_char_to_sextet(base64[0]);
|
||||
if (tmp == -1)
|
||||
return base64_len;
|
||||
x = (uint8_t)(tmp << 6);
|
||||
x = (tmp << 6);
|
||||
base64_len++;
|
||||
tmp = base64_char_to_sextet(base64[1]);
|
||||
if (tmp == -1)
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2001-2005, Cisco Systems, Inc.
|
||||
* Copyright (c) 2001-2006, Cisco Systems, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -50,7 +50,7 @@
|
|||
|
||||
/* gf2_8_shift() moved to gf2_8.h as an inline function */
|
||||
|
||||
inline gf2_8
|
||||
gf2_8
|
||||
gf2_8_multiply(gf2_8 x, gf2_8 y) {
|
||||
gf2_8 z = 0;
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
*/
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2001-2005 Cisco Systems, Inc.
|
||||
* Copyright (c) 2001-2006 Cisco Systems, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -43,7 +43,6 @@
|
|||
*/
|
||||
|
||||
#include "crypto_math.h"
|
||||
#include <stdlib.h> /* malloc() used in bitvector_alloc */
|
||||
|
||||
int
|
||||
octet_weight[256] = {
|
||||
|
@ -173,7 +172,7 @@ v32_weight(v32_t a) {
|
|||
return wt;
|
||||
}
|
||||
|
||||
inline unsigned char
|
||||
unsigned char
|
||||
v32_distance(v32_t x, v32_t y) {
|
||||
x.value ^= y.value;
|
||||
return v32_weight(x);
|
||||
|
@ -192,7 +191,7 @@ v32_dot_product(v32_t a, v32_t b) {
|
|||
|
||||
#define MAX_STRING_LENGTH 1024
|
||||
|
||||
static char bit_string[MAX_STRING_LENGTH];
|
||||
char bit_string[MAX_STRING_LENGTH];
|
||||
|
||||
char *
|
||||
octet_bit_string(uint8_t x) {
|
||||
|
@ -524,13 +523,13 @@ A_times_x_plus_b(uint8_t A[8], uint8_t x, uint8_t b) {
|
|||
return b;
|
||||
}
|
||||
|
||||
inline void
|
||||
void
|
||||
v16_copy_octet_string(v16_t *x, const uint8_t s[2]) {
|
||||
x->v8[0] = s[0];
|
||||
x->v8[1] = s[1];
|
||||
}
|
||||
|
||||
inline void
|
||||
void
|
||||
v32_copy_octet_string(v32_t *x, const uint8_t s[4]) {
|
||||
x->v8[0] = s[0];
|
||||
x->v8[1] = s[1];
|
||||
|
@ -538,7 +537,7 @@ v32_copy_octet_string(v32_t *x, const uint8_t s[4]) {
|
|||
x->v8[3] = s[3];
|
||||
}
|
||||
|
||||
inline void
|
||||
void
|
||||
v64_copy_octet_string(v64_t *x, const uint8_t s[8]) {
|
||||
x->v8[0] = s[0];
|
||||
x->v8[1] = s[1];
|
||||
|
@ -632,7 +631,7 @@ v128_set_bit_to(v128_t *x, int i, int y){
|
|||
#endif /* DATATYPES_USE_MACROS */
|
||||
|
||||
|
||||
inline void
|
||||
static inline void
|
||||
v128_left_shift2(v128_t *x, int num_bits) {
|
||||
int i;
|
||||
int word_shift = num_bits >> 5;
|
||||
|
@ -773,165 +772,6 @@ octet_string_set_to_zero(uint8_t *s, int len) {
|
|||
|
||||
}
|
||||
|
||||
/* functions manipulating bit_vector_t */
|
||||
|
||||
#define BITVECTOR_MAX_WORDS 5
|
||||
|
||||
int
|
||||
bitvector_alloc(bitvector_t *v, unsigned long length) {
|
||||
unsigned long l = (length + bytes_per_word - 1) / bytes_per_word;
|
||||
int i;
|
||||
|
||||
/* allocate memory, then set parameters */
|
||||
if (l > BITVECTOR_MAX_WORDS)
|
||||
return -1;
|
||||
else
|
||||
l = BITVECTOR_MAX_WORDS;
|
||||
v->word = malloc(l);
|
||||
if (v->word == NULL)
|
||||
return -1;
|
||||
v->length = length;
|
||||
|
||||
/* initialize bitvector to zero */
|
||||
for (i=0; i < (length >> 5); i++) {
|
||||
v->word = 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
bitvector_set_bit(bitvector_t *v, int bit_index) {
|
||||
|
||||
v->word[(bit_index >> 5)] |= (1 << (bit_index & 31));
|
||||
|
||||
}
|
||||
|
||||
int
|
||||
bitvector_get_bit(const bitvector_t *v, int bit_index) {
|
||||
|
||||
return ((v->word[(bit_index >> 5)]) >> (bit_index & 31)) & 1;
|
||||
|
||||
}
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
int
|
||||
bitvector_print_hex(const bitvector_t *v, FILE *stream) {
|
||||
int i;
|
||||
int m = v->length >> 5;
|
||||
int n = v->length & 31;
|
||||
char string[9];
|
||||
uint32_t tmp;
|
||||
|
||||
/* if length isn't a multiple of four, we can't hex_print */
|
||||
if (n & 3)
|
||||
return -1;
|
||||
|
||||
/* if the length is zero, do nothing */
|
||||
if (v->length == 0)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* loop over words from most significant to least significant -
|
||||
*/
|
||||
|
||||
for (i=m; i > 0; i++) {
|
||||
char *str = string + 7;
|
||||
tmp = v->word[i];
|
||||
|
||||
/* null terminate string */
|
||||
string[8] = 0;
|
||||
|
||||
/* loop over nibbles */
|
||||
*str-- = nibble_to_hex_char(tmp & 0xf); tmp >>= 4;
|
||||
*str-- = nibble_to_hex_char(tmp & 0xf); tmp >>= 4;
|
||||
*str-- = nibble_to_hex_char(tmp & 0xf); tmp >>= 4;
|
||||
*str-- = nibble_to_hex_char(tmp & 0xf); tmp >>= 4;
|
||||
*str-- = nibble_to_hex_char(tmp & 0xf); tmp >>= 4;
|
||||
*str-- = nibble_to_hex_char(tmp & 0xf); tmp >>= 4;
|
||||
*str-- = nibble_to_hex_char(tmp & 0xf); tmp >>= 4;
|
||||
*str-- = nibble_to_hex_char(tmp & 0xf);
|
||||
|
||||
/* now print stream */
|
||||
fprintf(stream, string);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
hex_string_length(char *s) {
|
||||
int count = 0;
|
||||
|
||||
/* ignore leading zeros */
|
||||
while ((*s != 0) && *s == '0')
|
||||
s++;
|
||||
|
||||
/* count remaining characters */
|
||||
while (*s != 0) {
|
||||
if (hex_char_to_nibble(*s++) == -1)
|
||||
return -1;
|
||||
count++;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
int
|
||||
bitvector_set_from_hex(bitvector_t *v, char *string) {
|
||||
int num_hex_chars, m, n, i, j;
|
||||
uint32_t tmp;
|
||||
|
||||
num_hex_chars = hex_string_length(string);
|
||||
if (num_hex_chars == -1)
|
||||
return -1;
|
||||
|
||||
/* set length */
|
||||
v->length = num_hex_chars * 4;
|
||||
/*
|
||||
* at this point, we should subtract away a bit if the high
|
||||
* bit of the first character is zero, but we ignore that
|
||||
* for now and assume that we're four-bit aligned - DAM
|
||||
*/
|
||||
|
||||
|
||||
m = num_hex_chars / 8; /* number of words */
|
||||
n = num_hex_chars % 8; /* number of nibbles in last word */
|
||||
|
||||
/* if the length is greater than the bitvector, return an error */
|
||||
if (m > BITVECTOR_MAX_WORDS)
|
||||
return -1;
|
||||
|
||||
/*
|
||||
* loop over words from most significant - first word is a special
|
||||
* case
|
||||
*/
|
||||
|
||||
if (n) {
|
||||
tmp = 0;
|
||||
for (i=0; i < n; i++) {
|
||||
tmp = hex_char_to_nibble(*string++);
|
||||
tmp <<= 4;
|
||||
}
|
||||
v->word[m] = tmp;
|
||||
}
|
||||
|
||||
/* now loop over the rest of the words */
|
||||
for (i=m-1; i >= 0; i--) {
|
||||
tmp = 0;
|
||||
for (j=0; j < 8; j++) {
|
||||
tmp = hex_char_to_nibble(*string++);
|
||||
tmp <<= 4;
|
||||
}
|
||||
v->word[i] = tmp;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* functions below not yet tested! */
|
||||
|
||||
|
|
|
@ -28,7 +28,7 @@ stat_test_monobit(uint8_t *data) {
|
|||
|
||||
ones_count = 0;
|
||||
while (data < data_end) {
|
||||
ones_count = (uint16_t)(ones_count + octet_get_weight(*data));
|
||||
ones_count += octet_get_weight(*data);
|
||||
data++;
|
||||
}
|
||||
|
||||
|
@ -83,7 +83,7 @@ stat_test_runs(uint8_t *data) {
|
|||
uint16_t gaps[6] = { 0, 0, 0, 0, 0, 0 };
|
||||
uint16_t lo_value[6] = { 2315, 1114, 527, 240, 103, 103 };
|
||||
uint16_t hi_value[6] = { 2685, 1386, 723, 384, 209, 209 };
|
||||
int16_t state = 0;
|
||||
int state = 0;
|
||||
uint16_t mask;
|
||||
int i;
|
||||
|
||||
|
@ -208,7 +208,7 @@ stat_test_rand_source(rand_source_func_t get_rand_bytes) {
|
|||
uint16_t gaps[6] = { 0, 0, 0, 0, 0, 0 };
|
||||
uint16_t lo_value[6] = { 2315, 1114, 527, 240, 103, 103 };
|
||||
uint16_t hi_value[6] = { 2685, 1386, 723, 384, 209, 209 };
|
||||
int16_t state = 0;
|
||||
int state = 0;
|
||||
uint16_t mask;
|
||||
|
||||
/* counters for monobit, poker, and runs tests are initialized above */
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2001-2005, Cisco Systems, Inc.
|
||||
* Copyright (c) 2001-2006, Cisco Systems, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -70,19 +70,19 @@ rdb_init(rdb_t *rdb) {
|
|||
*/
|
||||
|
||||
err_status_t
|
||||
rdb_check(const rdb_t *rdb, uint32_t index) {
|
||||
rdb_check(const rdb_t *rdb, uint32_t p_index) {
|
||||
|
||||
/* if the index appears after (or at very end of) the window, its good */
|
||||
if (index >= rdb->window_start + rdb_bits_in_bitmask)
|
||||
if (p_index >= rdb->window_start + rdb_bits_in_bitmask)
|
||||
return err_status_ok;
|
||||
|
||||
/* if the index appears before the window, its bad */
|
||||
if (index < rdb->window_start)
|
||||
return err_status_fail;
|
||||
if (p_index < rdb->window_start)
|
||||
return err_status_replay_old;
|
||||
|
||||
/* otherwise, the index appears within the window, so check the bitmask */
|
||||
if (v128_get_bit(&rdb->bitmask, (index - rdb->window_start)) == 1)
|
||||
return err_status_fail;
|
||||
if (v128_get_bit(&rdb->bitmask, (p_index - rdb->window_start)) == 1)
|
||||
return err_status_replay_fail;
|
||||
|
||||
/* otherwise, the index is okay */
|
||||
return err_status_ok;
|
||||
|
@ -98,15 +98,15 @@ rdb_check(const rdb_t *rdb, uint32_t index) {
|
|||
*/
|
||||
|
||||
err_status_t
|
||||
rdb_add_index(rdb_t *rdb, uint32_t index) {
|
||||
rdb_add_index(rdb_t *rdb, uint32_t p_index) {
|
||||
int delta;
|
||||
|
||||
/* here we *assume* that index > rdb->window_start */
|
||||
/* here we *assume* that p_index > rdb->window_start */
|
||||
|
||||
delta = (index - rdb->window_start);
|
||||
delta = (p_index - rdb->window_start);
|
||||
if (delta < rdb_bits_in_bitmask) {
|
||||
|
||||
/* if the index is within the window, set the appropriate bit */
|
||||
/* if the p_index is within the window, set the appropriate bit */
|
||||
v128_set_bit(&rdb->bitmask, delta);
|
||||
|
||||
} else {
|
||||
|
@ -115,7 +115,7 @@ rdb_add_index(rdb_t *rdb, uint32_t index) {
|
|||
|
||||
/* shift the window forward by delta bits*/
|
||||
v128_left_shift(&rdb->bitmask, delta);
|
||||
v128_set_bit(&rdb->bitmask, rdb_bits_in_bitmask-delta);
|
||||
v128_set_bit(&rdb->bitmask, rdb_bits_in_bitmask-1);
|
||||
rdb->window_start += delta;
|
||||
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2001-2005, Cisco Systems, Inc.
|
||||
* Copyright (c) 2001-2006, Cisco Systems, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -45,18 +45,17 @@
|
|||
|
||||
#include "rdbx.h"
|
||||
|
||||
#define rdbx_high_bit_in_bitmask 127
|
||||
|
||||
/*
|
||||
* from draft-ietf-avt-srtp-00.txt:
|
||||
* from RFC 3711:
|
||||
*
|
||||
* A receiver reconstructs the index i of a packet with sequence
|
||||
* number s using the estimate
|
||||
* number SEQ using the estimate
|
||||
*
|
||||
* i = 65,536 * t + s,
|
||||
* i = 2^16 * v + SEQ,
|
||||
*
|
||||
* where t is chosen from the set { r-1, r, r+1 } such that i is
|
||||
* closest to the value 65,536 * r + s_l. If the value r+1 is used,
|
||||
* where v is chosen from the set { ROC-1, ROC, ROC+1 } such that i is
|
||||
* closest to the value 2^16 * ROC + s_l. If the value r+1 is used,
|
||||
* then the rollover counter r in the cryptographic context is
|
||||
* incremented by one (if the packet containing s is authentic).
|
||||
*/
|
||||
|
@ -146,18 +145,18 @@ index_guess(const xtd_seq_num_t *local,
|
|||
if (local_seq < seq_num_median) {
|
||||
if (s - local_seq > seq_num_median) {
|
||||
guess_roc = local_roc - 1;
|
||||
difference = seq_num_max - s + local_seq;
|
||||
difference = s - local_seq - seq_num_max;
|
||||
} else {
|
||||
guess_roc = local_roc;
|
||||
difference = s - local_seq;
|
||||
}
|
||||
} else {
|
||||
if (local_seq - seq_num_median > s) {
|
||||
guess_roc = local_roc+1;
|
||||
difference = seq_num_max - local_seq + s;
|
||||
guess_roc = local_roc + 1;
|
||||
difference = s - local_seq + seq_num_max;
|
||||
} else {
|
||||
difference = s - local_seq;
|
||||
guess_roc = local_roc;
|
||||
difference = s - local_seq;
|
||||
}
|
||||
}
|
||||
guess_seq = s;
|
||||
|
@ -180,17 +179,81 @@ index_guess(const xtd_seq_num_t *local,
|
|||
|
||||
|
||||
/*
|
||||
* rdbx_init(&r) initalizes the rdbx_t pointed to by r
|
||||
* rdbx_init(&r, ws) initializes the rdbx_t pointed to by r with window size ws
|
||||
*/
|
||||
|
||||
err_status_t
|
||||
rdbx_init(rdbx_t *rdbx) {
|
||||
v128_set_to_zero(&rdbx->bitmask);
|
||||
rdbx_init(rdbx_t *rdbx, unsigned long ws) {
|
||||
if (ws == 0)
|
||||
return err_status_bad_param;
|
||||
|
||||
if (bitvector_alloc(&rdbx->bitmask, ws) != 0)
|
||||
return err_status_alloc_fail;
|
||||
|
||||
index_init(&rdbx->index);
|
||||
|
||||
return err_status_ok;
|
||||
}
|
||||
|
||||
/*
|
||||
* rdbx_dealloc(&r) frees memory for the rdbx_t pointed to by r
|
||||
*/
|
||||
|
||||
err_status_t
|
||||
rdbx_dealloc(rdbx_t *rdbx) {
|
||||
bitvector_dealloc(&rdbx->bitmask);
|
||||
|
||||
return err_status_ok;
|
||||
}
|
||||
|
||||
/*
|
||||
* rdbx_set_roc(rdbx, roc) initalizes the rdbx_t at the location rdbx
|
||||
* to have the rollover counter value roc. If that value is less than
|
||||
* the current rollover counter value, then the function returns
|
||||
* err_status_replay_old; otherwise, err_status_ok is returned.
|
||||
*
|
||||
*/
|
||||
|
||||
err_status_t
|
||||
rdbx_set_roc(rdbx_t *rdbx, uint32_t roc) {
|
||||
bitvector_set_to_zero(&rdbx->bitmask);
|
||||
|
||||
#ifdef NO_64BIT_MATH
|
||||
#error not yet implemented
|
||||
#else
|
||||
|
||||
/* make sure that we're not moving backwards */
|
||||
if (roc < (rdbx->index >> 16))
|
||||
return err_status_replay_old;
|
||||
|
||||
rdbx->index &= 0xffff; /* retain lowest 16 bits */
|
||||
rdbx->index |= ((uint64_t)roc) << 16; /* set ROC */
|
||||
#endif
|
||||
|
||||
return err_status_ok;
|
||||
}
|
||||
|
||||
/*
|
||||
* rdbx_get_packet_index(rdbx) returns the value of the packet index
|
||||
* for the rdbx_t pointed to by rdbx
|
||||
*
|
||||
*/
|
||||
|
||||
xtd_seq_num_t
|
||||
rdbx_get_packet_index(const rdbx_t *rdbx) {
|
||||
return rdbx->index;
|
||||
}
|
||||
|
||||
/*
|
||||
* rdbx_get_window_size(rdbx) returns the value of the window size
|
||||
* for the rdbx_t pointed to by rdbx
|
||||
*
|
||||
*/
|
||||
|
||||
unsigned long
|
||||
rdbx_get_window_size(const rdbx_t *rdbx) {
|
||||
return bitvector_get_length(&rdbx->bitmask);
|
||||
}
|
||||
|
||||
/*
|
||||
* rdbx_check(&r, delta) checks to see if the xtd_seq_num_t
|
||||
|
@ -202,11 +265,11 @@ rdbx_check(const rdbx_t *rdbx, int delta) {
|
|||
|
||||
if (delta > 0) { /* if delta is positive, it's good */
|
||||
return err_status_ok;
|
||||
} else if (rdbx_high_bit_in_bitmask + delta < 0) {
|
||||
} else if ((int)(bitvector_get_length(&rdbx->bitmask) - 1) + delta < 0) {
|
||||
/* if delta is lower than the bitmask, it's bad */
|
||||
return err_status_replay_old;
|
||||
} else if (v128_get_bit(&rdbx->bitmask,
|
||||
rdbx_high_bit_in_bitmask + delta) == 1) {
|
||||
} else if (bitvector_get_bit(&rdbx->bitmask,
|
||||
(int)(bitvector_get_length(&rdbx->bitmask) - 1) + delta) == 1) {
|
||||
/* delta is within the window, so check the bitmask */
|
||||
return err_status_replay_fail;
|
||||
}
|
||||
|
@ -229,12 +292,12 @@ rdbx_add_index(rdbx_t *rdbx, int delta) {
|
|||
|
||||
if (delta > 0) {
|
||||
/* shift forward by delta */
|
||||
index_advance(&rdbx->index, (sequence_number_t)delta);
|
||||
v128_left_shift(&rdbx->bitmask, delta);
|
||||
v128_set_bit(&rdbx->bitmask, 127);
|
||||
index_advance(&rdbx->index, delta);
|
||||
bitvector_left_shift(&rdbx->bitmask, delta);
|
||||
bitvector_set_bit(&rdbx->bitmask, bitvector_get_length(&rdbx->bitmask) - 1);
|
||||
} else {
|
||||
/* delta is in window, so flip bit in bitmask */
|
||||
v128_set_bit(&rdbx->bitmask, -delta);
|
||||
/* delta is in window */
|
||||
bitvector_set_bit(&rdbx->bitmask, bitvector_get_length(&rdbx->bitmask) -1 + delta);
|
||||
}
|
||||
|
||||
/* note that we need not consider the case that delta == 0 */
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2001-2005, Cisco Systems, Inc.
|
||||
* Copyright (c) 2001-2006, Cisco Systems, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -47,9 +47,6 @@
|
|||
|
||||
#include "ut_sim.h"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(disable:4100)
|
||||
#endif
|
||||
|
||||
int
|
||||
ut_compar(const void *a, const void *b) {
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
*/
|
||||
/*
|
||||
*
|
||||
* Copyright(c) 2001-2005 Cisco Systems, Inc.
|
||||
* Copyright(c) 2001-2006 Cisco Systems, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -47,7 +47,7 @@
|
|||
|
||||
/* single, global prng structure */
|
||||
|
||||
static ctr_prng_t ctr_prng;
|
||||
ctr_prng_t ctr_prng;
|
||||
|
||||
err_status_t
|
||||
ctr_prng_init(rand_source_func_t random_source) {
|
||||
|
@ -66,7 +66,7 @@ ctr_prng_init(rand_source_func_t random_source) {
|
|||
return status;
|
||||
|
||||
/* initialize aes ctr context with random key */
|
||||
status = aes_icm_context_init(&ctr_prng.state, tmp_key);
|
||||
status = aes_icm_context_init(&ctr_prng.state, tmp_key, 30);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
|
@ -92,7 +92,7 @@ ctr_prng_get_octet_string(void *dest, uint32_t len) {
|
|||
/*
|
||||
* write prng output
|
||||
*/
|
||||
status = aes_icm_output(&ctr_prng.state, dest, len);
|
||||
status = aes_icm_output(&ctr_prng.state, (uint8_t*)dest, len);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
*/
|
||||
/*
|
||||
*
|
||||
* Copyright(c) 2001-2005 Cisco Systems, Inc.
|
||||
* Copyright(c) 2001-2006 Cisco Systems, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -47,11 +47,11 @@
|
|||
|
||||
/* single, global prng structure */
|
||||
|
||||
static x917_prng_t x917_prng;
|
||||
x917_prng_t x917_prng;
|
||||
|
||||
err_status_t
|
||||
x917_prng_init(rand_source_func_t random_source) {
|
||||
v128_t tmp_key;
|
||||
uint8_t tmp_key[16];
|
||||
err_status_t status;
|
||||
|
||||
/* initialize output count to zero */
|
||||
|
@ -61,12 +61,12 @@ x917_prng_init(rand_source_func_t random_source) {
|
|||
x917_prng.rand = random_source;
|
||||
|
||||
/* initialize secret key from random source */
|
||||
status = random_source((uint8_t *)&tmp_key, 16);
|
||||
status = random_source(tmp_key, 16);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
/* expand aes key */
|
||||
aes_expand_encryption_key(&tmp_key, x917_prng.key);
|
||||
aes_expand_encryption_key(tmp_key, 16, &x917_prng.key);
|
||||
|
||||
/* initialize prng state from random source */
|
||||
status = x917_prng.rand((uint8_t *)&x917_prng.state, 16);
|
||||
|
@ -80,7 +80,7 @@ err_status_t
|
|||
x917_prng_get_octet_string(uint8_t *dest, uint32_t len) {
|
||||
uint32_t t;
|
||||
v128_t buffer;
|
||||
int i, tail_len;
|
||||
uint32_t i, tail_len;
|
||||
err_status_t status;
|
||||
|
||||
/*
|
||||
|
@ -99,7 +99,7 @@ x917_prng_get_octet_string(uint8_t *dest, uint32_t len) {
|
|||
t = (uint32_t)time(NULL);
|
||||
|
||||
/* loop until we have output enough data */
|
||||
for (i=0; (uint32_t)i < len/16; i++) {
|
||||
for (i=0; i < len/16; i++) {
|
||||
|
||||
/* exor time into state */
|
||||
x917_prng.state.v32[0] ^= t;
|
||||
|
@ -108,7 +108,7 @@ x917_prng_get_octet_string(uint8_t *dest, uint32_t len) {
|
|||
v128_copy(&buffer, &x917_prng.state);
|
||||
|
||||
/* apply aes to buffer */
|
||||
aes_encrypt(&buffer, x917_prng.key);
|
||||
aes_encrypt(&buffer, &x917_prng.key);
|
||||
|
||||
/* write data to output */
|
||||
*dest++ = buffer.v8[0];
|
||||
|
@ -132,7 +132,7 @@ x917_prng_get_octet_string(uint8_t *dest, uint32_t len) {
|
|||
buffer.v32[0] ^= t;
|
||||
|
||||
/* encrypt buffer */
|
||||
aes_encrypt(&buffer, x917_prng.key);
|
||||
aes_encrypt(&buffer, &x917_prng.key);
|
||||
|
||||
/* copy buffer into state */
|
||||
v128_copy(&x917_prng.state, &buffer);
|
||||
|
@ -150,7 +150,7 @@ x917_prng_get_octet_string(uint8_t *dest, uint32_t len) {
|
|||
v128_copy(&buffer, &x917_prng.state);
|
||||
|
||||
/* apply aes to buffer */
|
||||
aes_encrypt(&buffer, x917_prng.key);
|
||||
aes_encrypt(&buffer, &x917_prng.key);
|
||||
|
||||
/* write data to output */
|
||||
for (i=0; i < tail_len; i++) {
|
||||
|
@ -163,7 +163,7 @@ x917_prng_get_octet_string(uint8_t *dest, uint32_t len) {
|
|||
buffer.v32[0] ^= t;
|
||||
|
||||
/* encrypt buffer */
|
||||
aes_encrypt(&buffer, x917_prng.key);
|
||||
aes_encrypt(&buffer, &x917_prng.key);
|
||||
|
||||
/* copy buffer into state */
|
||||
v128_copy(&x917_prng.state, &buffer);
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
*/
|
||||
/*
|
||||
*
|
||||
* Copyright(c) 2001-2005 Cisco Systems, Inc.
|
||||
* Copyright(c) 2001-2006 Cisco Systems, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -43,18 +43,36 @@
|
|||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "rand_source.h"
|
||||
|
||||
#ifdef DEV_URANDOM
|
||||
# include <fcntl.h> /* for open() */
|
||||
# include <unistd.h> /* for close() */
|
||||
#elif defined(HAVE_RAND_S)
|
||||
# define _CRT_RAND_S
|
||||
# include <stdlib.h>
|
||||
#else
|
||||
# include <stdio.h>
|
||||
#endif
|
||||
|
||||
/* global dev_rand_fdes is file descriptor for /dev/random */
|
||||
#include "rand_source.h"
|
||||
|
||||
static int dev_random_fdes = -1;
|
||||
|
||||
/*
|
||||
* global dev_rand_fdes is file descriptor for /dev/random
|
||||
*
|
||||
* This variable is also used to indicate that the random source has
|
||||
* been initialized. When this variable is set to the value of the
|
||||
* #define RAND_SOURCE_NOT_READY, it indicates that the random source
|
||||
* is not ready to be used. The value of the #define
|
||||
* RAND_SOURCE_READY is for use whenever that variable is used as an
|
||||
* indicator of the state of the random source, but not as a file
|
||||
* descriptor.
|
||||
*/
|
||||
|
||||
#define RAND_SOURCE_NOT_READY (-1)
|
||||
#define RAND_SOURCE_READY (17)
|
||||
|
||||
static int dev_random_fdes = RAND_SOURCE_NOT_READY;
|
||||
|
||||
|
||||
err_status_t
|
||||
|
@ -68,10 +86,12 @@ rand_source_init(void) {
|
|||
dev_random_fdes = open(DEV_URANDOM, O_RDONLY);
|
||||
if (dev_random_fdes < 0)
|
||||
return err_status_init_fail;
|
||||
#elif defined(HAVE_RAND_S)
|
||||
dev_random_fdes = RAND_SOURCE_READY;
|
||||
#else
|
||||
/* no random source available; let the user know */
|
||||
fprintf(stderr, "WARNING: no real random source present!\n");
|
||||
dev_random_fdes = 17;
|
||||
dev_random_fdes = RAND_SOURCE_READY;
|
||||
#endif
|
||||
return err_status_ok;
|
||||
}
|
||||
|
@ -85,19 +105,39 @@ rand_source_get_octet_string(void *dest, uint32_t len) {
|
|||
* written
|
||||
*/
|
||||
#ifdef DEV_URANDOM
|
||||
if (read(dev_random_fdes, dest, len) != len)
|
||||
uint8_t *dst = (uint8_t *)dest;
|
||||
while (len)
|
||||
{
|
||||
ssize_t num_read = read(dev_random_fdes, dst, len);
|
||||
if (num_read <= 0 || num_read > len)
|
||||
return err_status_fail;
|
||||
len -= num_read;
|
||||
dst += num_read;
|
||||
}
|
||||
#elif defined(HAVE_RAND_S)
|
||||
uint8_t *dst = (uint8_t *)dest;
|
||||
while (len)
|
||||
{
|
||||
unsigned int val;
|
||||
errno_t err = rand_s(&val);
|
||||
|
||||
if (err != 0)
|
||||
return err_status_fail;
|
||||
|
||||
*dst++ = val & 0xff;
|
||||
len--;
|
||||
}
|
||||
#else
|
||||
/* Generic C-library (rand()) version */
|
||||
/* This is a random source of last resort */
|
||||
uint8_t *dst = dest;
|
||||
uint8_t *dst = (uint8_t *)dest;
|
||||
while (len)
|
||||
{
|
||||
int val = rand();
|
||||
/* rand() returns 0-32767 (ugh) */
|
||||
/* Is this a good enough way to get random bytes?
|
||||
It is if it passes FIPS-140... */
|
||||
*dst++ = (uint8_t)(val & 0xff);
|
||||
*dst++ = val & 0xff;
|
||||
len--;
|
||||
}
|
||||
#endif
|
||||
|
@ -112,7 +152,7 @@ rand_source_deinit(void) {
|
|||
#ifdef DEV_URANDOM
|
||||
close(dev_random_fdes);
|
||||
#endif
|
||||
dev_random_fdes = -1;
|
||||
dev_random_fdes = RAND_SOURCE_NOT_READY;
|
||||
|
||||
return err_status_ok;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
aes_calc
|
||||
cipher_driver
|
||||
datatypes_driver
|
||||
env
|
||||
kernel_driver
|
||||
rand_gen
|
||||
sha1_driver
|
||||
stat_driver
|
Binary file not shown.
|
@ -28,14 +28,16 @@ usage(char *prog_name) {
|
|||
exit(255);
|
||||
}
|
||||
|
||||
#define AES_KEY_LEN 16
|
||||
#define AES_MAX_KEY_LEN 32
|
||||
|
||||
int
|
||||
main (int argc, char *argv[]) {
|
||||
v128_t data, key;
|
||||
v128_t data;
|
||||
uint8_t key[AES_MAX_KEY_LEN];
|
||||
aes_expanded_key_t exp_key;
|
||||
int len;
|
||||
int key_len, len;
|
||||
int verbose;
|
||||
err_status_t status;
|
||||
|
||||
if (argc == 3) {
|
||||
/* we're not in verbose mode */
|
||||
|
@ -54,22 +56,23 @@ main (int argc, char *argv[]) {
|
|||
}
|
||||
|
||||
/* read in key, checking length */
|
||||
if (strlen(argv[1]) > AES_KEY_LEN*2) {
|
||||
if (strlen(argv[1]) > AES_MAX_KEY_LEN*2) {
|
||||
fprintf(stderr,
|
||||
"error: too many digits in key "
|
||||
"(should be %d hexadecimal digits, found %u)\n",
|
||||
AES_KEY_LEN*2, (unsigned)strlen(argv[1]));
|
||||
"(should be at most %d hexadecimal digits, found %u)\n",
|
||||
AES_MAX_KEY_LEN*2, (unsigned)strlen(argv[1]));
|
||||
exit(1);
|
||||
}
|
||||
len = hex_string_to_octet_string((char *)&key, argv[1], AES_KEY_LEN*2);
|
||||
len = hex_string_to_octet_string((char*)key, argv[1], AES_MAX_KEY_LEN*2);
|
||||
/* check that hex string is the right length */
|
||||
if (len < AES_KEY_LEN*2) {
|
||||
if (len != 32 && len != 48 && len != 64) {
|
||||
fprintf(stderr,
|
||||
"error: too few digits in key "
|
||||
"(should be %d hexadecimal digits, found %d)\n",
|
||||
AES_KEY_LEN*2, len);
|
||||
"error: bad number of digits in key "
|
||||
"(should be 32/48/64 hexadecimal digits, found %d)\n",
|
||||
len);
|
||||
exit(1);
|
||||
}
|
||||
key_len = len/2;
|
||||
|
||||
/* read in plaintext, checking length */
|
||||
if (strlen(argv[2]) > 16*2) {
|
||||
|
@ -95,13 +98,18 @@ main (int argc, char *argv[]) {
|
|||
}
|
||||
|
||||
/* encrypt plaintext */
|
||||
aes_expand_encryption_key(&key, exp_key);
|
||||
status = aes_expand_encryption_key(key, key_len, &exp_key);
|
||||
if (status) {
|
||||
fprintf(stderr,
|
||||
"error: AES key expansion failed.\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
aes_encrypt(&data, exp_key);
|
||||
aes_encrypt(&data, &exp_key);
|
||||
|
||||
/* write ciphertext to output */
|
||||
if (verbose) {
|
||||
printf("key:\t\t%s\n", v128_hex_string(&key));
|
||||
printf("key:\t\t%s\n", octet_string_hex_string(key, key_len));
|
||||
printf("ciphertext:\t");
|
||||
}
|
||||
printf("%s\n", v128_hex_string(&data));
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2001-2005, Cisco Systems, Inc.
|
||||
* Copyright (c) 2001-2006, Cisco Systems, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2001-2005, Cisco Systems, Inc.
|
||||
* Copyright (c) 2001-2006, Cisco Systems, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -120,10 +120,13 @@ int
|
|||
main(int argc, char *argv[]) {
|
||||
cipher_t *c = NULL;
|
||||
err_status_t status;
|
||||
unsigned char test_key[20] = {
|
||||
unsigned char test_key[48] = {
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
||||
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
|
||||
0x10, 0x11, 0x12, 0x13
|
||||
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
|
||||
0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
|
||||
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
|
||||
0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
|
||||
};
|
||||
int q;
|
||||
unsigned do_timing_test = 0;
|
||||
|
@ -168,9 +171,14 @@ main(int argc, char *argv[]) {
|
|||
for (num_cipher=1; num_cipher < max_num_cipher; num_cipher *=8)
|
||||
cipher_driver_test_array_throughput(&aes_icm, 30, num_cipher);
|
||||
|
||||
for (num_cipher=1; num_cipher < max_num_cipher; num_cipher *=8)
|
||||
cipher_driver_test_array_throughput(&aes_icm, 46, num_cipher);
|
||||
|
||||
for (num_cipher=1; num_cipher < max_num_cipher; num_cipher *=8)
|
||||
cipher_driver_test_array_throughput(&aes_cbc, 16, num_cipher);
|
||||
|
||||
for (num_cipher=1; num_cipher < max_num_cipher; num_cipher *=8)
|
||||
cipher_driver_test_array_throughput(&aes_cbc, 32, num_cipher);
|
||||
}
|
||||
|
||||
if (do_validation) {
|
||||
|
@ -196,7 +204,7 @@ main(int argc, char *argv[]) {
|
|||
check_status(status);
|
||||
|
||||
|
||||
/* run the throughput test on the aes_icm cipher */
|
||||
/* run the throughput test on the aes_icm cipher (128-bit key) */
|
||||
status = cipher_type_alloc(&aes_icm, &c, 30);
|
||||
if (status) {
|
||||
fprintf(stderr, "error: can't allocate cipher\n");
|
||||
|
@ -217,6 +225,27 @@ main(int argc, char *argv[]) {
|
|||
status = cipher_dealloc(c);
|
||||
check_status(status);
|
||||
|
||||
/* repeat the tests with 256-bit keys */
|
||||
status = cipher_type_alloc(&aes_icm, &c, 46);
|
||||
if (status) {
|
||||
fprintf(stderr, "error: can't allocate cipher\n");
|
||||
exit(status);
|
||||
}
|
||||
|
||||
status = cipher_init(c, test_key, direction_encrypt);
|
||||
check_status(status);
|
||||
|
||||
if (do_timing_test)
|
||||
cipher_driver_test_throughput(c);
|
||||
|
||||
if (do_validation) {
|
||||
status = cipher_driver_test_buffering(c);
|
||||
check_status(status);
|
||||
}
|
||||
|
||||
status = cipher_dealloc(c);
|
||||
check_status(status);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -225,9 +254,9 @@ cipher_driver_test_throughput(cipher_t *c) {
|
|||
int i;
|
||||
int min_enc_len = 32;
|
||||
int max_enc_len = 2048; /* should be a power of two */
|
||||
int num_trials = 100000;
|
||||
int num_trials = 1000000;
|
||||
|
||||
printf("timing %s throughput:\n", c->type->description);
|
||||
printf("timing %s throughput, key length %d:\n", c->type->description, c->key_len);
|
||||
fflush(stdout);
|
||||
for (i=min_enc_len; i <= max_enc_len; i = i * 2)
|
||||
printf("msg len: %d\tgigabits per second: %f\n",
|
||||
|
@ -348,6 +377,9 @@ cipher_array_alloc_init(cipher_t ***ca, int num_ciphers,
|
|||
err_status_t status;
|
||||
uint8_t *key;
|
||||
cipher_t **cipher_array;
|
||||
/* pad klen allocation, to handle aes_icm reading 16 bytes for the
|
||||
14-byte salt */
|
||||
int klen_pad = ((klen + 15) >> 4) << 4;
|
||||
|
||||
/* allocate array of pointers to ciphers */
|
||||
cipher_array = (cipher_t **) malloc(sizeof(cipher_t *) * num_ciphers);
|
||||
|
@ -358,7 +390,7 @@ cipher_array_alloc_init(cipher_t ***ca, int num_ciphers,
|
|||
*ca = cipher_array;
|
||||
|
||||
/* allocate key */
|
||||
key = crypto_alloc(klen);
|
||||
key = crypto_alloc(klen_pad);
|
||||
if (key == NULL) {
|
||||
free(cipher_array);
|
||||
return err_status_alloc_fail;
|
||||
|
@ -375,6 +407,8 @@ cipher_array_alloc_init(cipher_t ***ca, int num_ciphers,
|
|||
/* generate random key and initialize cipher */
|
||||
for (j=0; j < klen; j++)
|
||||
key[j] = (uint8_t) rand();
|
||||
for (; j < klen_pad; j++)
|
||||
key[j] = 0;
|
||||
status = cipher_init(*cipher_array, key, direction_encrypt);
|
||||
if (status)
|
||||
return status;
|
||||
|
@ -387,6 +421,8 @@ cipher_array_alloc_init(cipher_t ***ca, int num_ciphers,
|
|||
cipher_array++;
|
||||
}
|
||||
|
||||
crypto_free(key);
|
||||
|
||||
return err_status_ok;
|
||||
}
|
||||
|
||||
|
@ -423,24 +459,28 @@ cipher_array_bits_per_second(cipher_t *cipher_array[], int num_cipher,
|
|||
v128_t nonce;
|
||||
clock_t timer;
|
||||
unsigned char *enc_buf;
|
||||
int cipher_index = 0;
|
||||
int cipher_index = rand() % num_cipher;
|
||||
|
||||
|
||||
enc_buf = crypto_alloc(octets_in_buffer);
|
||||
/* Over-alloc, for NIST CBC padding */
|
||||
enc_buf = crypto_alloc(octets_in_buffer+17);
|
||||
if (enc_buf == NULL)
|
||||
return 0; /* indicate bad parameters by returning null */
|
||||
memset(enc_buf, 0, octets_in_buffer);
|
||||
|
||||
/* time repeated trials */
|
||||
v128_set_to_zero(&nonce);
|
||||
timer = clock();
|
||||
for(i=0; i < num_trials; i++, nonce.v32[3] = i) {
|
||||
|
||||
/* choose a cipher at random from the array*/
|
||||
cipher_index = (*((uint32_t *)enc_buf)) % num_cipher;
|
||||
/* length parameter to cipher_encrypt is in/out -- out is total, padded
|
||||
* length -- so reset it each time. */
|
||||
unsigned octets_to_encrypt = octets_in_buffer;
|
||||
|
||||
/* encrypt buffer with cipher */
|
||||
cipher_set_iv(cipher_array[cipher_index], &nonce);
|
||||
cipher_encrypt(cipher_array[cipher_index], enc_buf, &octets_in_buffer);
|
||||
cipher_encrypt(cipher_array[cipher_index], enc_buf, &octets_to_encrypt);
|
||||
|
||||
/* choose a cipher at random from the array*/
|
||||
cipher_index = (*((uint32_t *)enc_buf)) % num_cipher;
|
||||
}
|
||||
timer = clock() - timer;
|
||||
|
||||
|
@ -451,7 +491,7 @@ cipher_array_bits_per_second(cipher_t *cipher_array[], int num_cipher,
|
|||
return 0;
|
||||
}
|
||||
|
||||
return CLOCKS_PER_SEC * num_trials * 8 * octets_in_buffer / timer;
|
||||
return (uint64_t)CLOCKS_PER_SEC * num_trials * 8 * octets_in_buffer / timer;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -459,10 +499,10 @@ cipher_array_test_throughput(cipher_t *ca[], int num_cipher) {
|
|||
int i;
|
||||
int min_enc_len = 16;
|
||||
int max_enc_len = 2048; /* should be a power of two */
|
||||
int num_trials = 10000;
|
||||
int num_trials = 1000000;
|
||||
|
||||
printf("timing %s throughput with array size %d:\n",
|
||||
(ca[0])->type->description, num_cipher);
|
||||
printf("timing %s throughput with key length %d, array size %d:\n",
|
||||
(ca[0])->type->description, (ca[0])->key_len, num_cipher);
|
||||
fflush(stdout);
|
||||
for (i=min_enc_len; i <= max_enc_len; i = i * 4)
|
||||
printf("msg len: %d\tgigabits per second: %f\n", i,
|
||||
|
|
Binary file not shown.
|
@ -9,7 +9,7 @@
|
|||
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2001-2005, Cisco Systems, Inc.
|
||||
* Copyright (c) 2001-2006, Cisco Systems, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
*/
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2001-2005 Cisco Systems, Inc.
|
||||
* Copyright (c) 2001-2006 Cisco Systems, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
*/
|
||||
/*
|
||||
*
|
||||
* Copyright(c) 2001-2005 Cisco Systems, Inc.
|
||||
* Copyright(c) 2001-2006 Cisco Systems, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
*/
|
||||
/*
|
||||
*
|
||||
* Copyright(c) 2001-2005 Cisco Systems, Inc.
|
||||
* Copyright(c) 2001-2006 Cisco Systems, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
|
Binary file not shown.
|
@ -113,17 +113,17 @@ sha1_test_case_validate(const hash_test_case_t *test_case) {
|
|||
if (0 == memcmp(test_case->hash, hash_value, 20)) {
|
||||
#if VERBOSE
|
||||
printf("PASSED: reference value: %s\n",
|
||||
octet_string_hex_string((uint8_t *)test_case->hash, 20));
|
||||
octet_string_hex_string((const uint8_t *)test_case->hash, 20));
|
||||
printf("PASSED: computed value: %s\n",
|
||||
octet_string_hex_string((uint8_t *)hash_value, 20));
|
||||
octet_string_hex_string((const uint8_t *)hash_value, 20));
|
||||
#endif
|
||||
return err_status_ok;
|
||||
}
|
||||
|
||||
printf("reference value: %s\n",
|
||||
octet_string_hex_string((uint8_t *)test_case->hash, 20));
|
||||
octet_string_hex_string((const uint8_t *)test_case->hash, 20));
|
||||
printf("computed value: %s\n",
|
||||
octet_string_hex_string((uint8_t *)hash_value, 20));
|
||||
octet_string_hex_string((const uint8_t *)hash_value, 20));
|
||||
|
||||
return err_status_algo_fail;
|
||||
|
||||
|
@ -136,7 +136,7 @@ struct hex_sha1_test_case_t {
|
|||
};
|
||||
|
||||
err_status_t
|
||||
sha1_add_test_cases() {
|
||||
sha1_add_test_cases(void) {
|
||||
int i;
|
||||
err_status_t err;
|
||||
|
||||
|
@ -485,6 +485,21 @@ sha1_add_test_cases() {
|
|||
return err_status_ok;
|
||||
}
|
||||
|
||||
err_status_t
|
||||
sha1_dealloc_test_cases(void) {
|
||||
hash_test_case_t *t, *next;
|
||||
|
||||
for (t = sha1_test_case_list; t != NULL; t = next) {
|
||||
next = t->next_test_case;
|
||||
free(t);
|
||||
}
|
||||
|
||||
sha1_test_case_list = NULL;
|
||||
|
||||
return err_status_ok;
|
||||
}
|
||||
|
||||
|
||||
|
||||
err_status_t
|
||||
sha1_validate(void) {
|
||||
|
@ -510,6 +525,8 @@ sha1_validate(void) {
|
|||
test_case = test_case->next_test_case;
|
||||
}
|
||||
|
||||
sha1_dealloc_test_cases();
|
||||
|
||||
return err_status_ok;
|
||||
}
|
||||
|
||||
|
|
Binary file not shown.
|
@ -37,7 +37,9 @@ main (int argc, char *argv[]) {
|
|||
int i, j;
|
||||
extern cipher_type_t aes_icm;
|
||||
cipher_t *c;
|
||||
uint8_t key[30] = {
|
||||
uint8_t key[46] = {
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
||||
|
@ -97,5 +99,41 @@ main (int argc, char *argv[]) {
|
|||
printf("(nota bene: a small fraction of stat_test failures does not \n"
|
||||
"indicate that the random source is invalid)\n");
|
||||
|
||||
err_check(cipher_dealloc(c));
|
||||
|
||||
printf("running stat_tests on AES-256-ICM, expecting success\n");
|
||||
/* set buffer to cipher output */
|
||||
for (i=0; i < 2500; i++)
|
||||
buffer[i] = 0;
|
||||
err_check(cipher_type_alloc(&aes_icm, &c, 46));
|
||||
err_check(cipher_init(c, key, direction_encrypt));
|
||||
err_check(cipher_set_iv(c, &nonce));
|
||||
err_check(cipher_encrypt(c, buffer, &buf_len));
|
||||
/* run tests on cipher outout */
|
||||
printf("monobit %d\n", stat_test_monobit(buffer));
|
||||
printf("poker %d\n", stat_test_poker(buffer));
|
||||
printf("runs %d\n", stat_test_runs(buffer));
|
||||
|
||||
printf("runs test (please be patient): ");
|
||||
fflush(stdout);
|
||||
num_fail = 0;
|
||||
v128_set_to_zero(&nonce);
|
||||
for(j=0; j < num_trials; j++) {
|
||||
for (i=0; i < 2500; i++)
|
||||
buffer[i] = 0;
|
||||
nonce.v32[3] = i;
|
||||
err_check(cipher_set_iv(c, &nonce));
|
||||
err_check(cipher_encrypt(c, buffer, &buf_len));
|
||||
if (stat_test_runs(buffer)) {
|
||||
num_fail++;
|
||||
}
|
||||
}
|
||||
|
||||
printf("%d failures in %d tests\n", num_fail, num_trials);
|
||||
printf("(nota bene: a small fraction of stat_test failures does not \n"
|
||||
"indicate that the random source is invalid)\n");
|
||||
|
||||
err_check(cipher_dealloc(c));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -346,7 +346,7 @@ WARN_LOGFILE =
|
|||
# directories like "/usr/src/myproject". Separate the files or directories
|
||||
# with spaces.
|
||||
|
||||
INPUT = intro.txt ../include/srtp.h ../crypto/include/crypto_types.h ../crypto/include/err.h ../crypto/include/crypto_kernel.h crypto_kernel.txt
|
||||
INPUT = intro.txt ../include/srtp.h ../crypto/include/crypto_types.h ../crypto/include/err.h ../crypto/include/crypto.h crypto_kernel.txt
|
||||
|
||||
# If the value of the INPUT tag contains directories, you can use the
|
||||
# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
|
||||
|
|
|
@ -86,14 +86,17 @@ libSRTP LIBSRTPVERSION Overview and Reference Manual\\
|
|||
|
||||
The original implementation and documentation of libSRTP was written
|
||||
by David McGrew of Cisco Systems, Inc. in order to promote the use,
|
||||
understanding, and interoperability of Secure RTP. Randell Jesup
|
||||
contributed a working SRTCP implementation and other fixes. Alex
|
||||
Vanzella and Will Clark contributed changes so that the AES ICM
|
||||
implementation can be used for ISMA media encryption. Steve Underwood
|
||||
contributed x86\_64 portability changes. We also give thanks to Brian
|
||||
Weis, Mark Baugher, Jeff Chan, Bill Simon, Douglas Smith, Bill May,
|
||||
Richard Preistley, Joe Tardo and others for contributions, comments,
|
||||
and corrections.
|
||||
understanding, and interoperability of Secure RTP. Michael Jerris
|
||||
contributed support for building under MSVC. Andris Pavenis
|
||||
contributed many important fixes. Brian West contributed changes to
|
||||
enable dynamic linking. Yves Shumann reported documentation bugs.
|
||||
Randell Jesup contributed a working SRTCP implementation and other
|
||||
fixes. Alex Vanzella and Will Clark contributed changes so that the
|
||||
AES ICM implementation can be used for ISMA media encryption. Steve
|
||||
Underwood contributed x86\_64 portability changes. We also give
|
||||
thanks to Fredrik Thulin, Brian Weis, Mark Baugher, Jeff Chan, Bill
|
||||
Simon, Douglas Smith, Bill May, Richard Preistley, Joe Tardo and
|
||||
others for contributions, comments, and corrections.
|
||||
|
||||
This reference material in this documenation was generated using the
|
||||
\texttt{doxygen} utility for automatic documentation of source code.
|
||||
|
|
|
@ -5,10 +5,10 @@
|
|||
This document describes libSRTP, the Open Source Secure RTP library
|
||||
from Cisco Systems, Inc. RTP is the Real-time Transport Protocol, an
|
||||
IETF standard for the transport of real-time data such as telephony,
|
||||
audio, and video, defined by RFC1889. Secure RTP (SRTP) is an RTP
|
||||
audio, and video, defined by RFC 3550. Secure RTP (SRTP) is an RTP
|
||||
profile for providing confidentiality to RTP data and authentication
|
||||
to the RTP header and payload. SRTP is an IETF Proposed Standard, and
|
||||
is defined in RFC 3711, and was developed in the IETF Audio/Video
|
||||
to the RTP header and payload. SRTP is an IETF Proposed Standard,
|
||||
defined in RFC 3711, and was developed in the IETF Audio/Video
|
||||
Transport (AVT) Working Group. This library supports all of the
|
||||
mandatory features of SRTP, but not all of the optional features. See
|
||||
the @ref Features section for more detailed information.
|
||||
|
@ -110,7 +110,7 @@ the minor release number, and \texttt{tgz} is the file
|
|||
extension\footnote{The extension \texttt{.tgz} is identical to
|
||||
\texttt{tar.gz}, and indicates a compressed tar file.} You probably
|
||||
want to get the most recent release. Unpack the distribution and
|
||||
extract the source files; the directory into which the soruce files
|
||||
extract the source files; the directory into which the source files
|
||||
will go is named \texttt{srtp}.
|
||||
|
||||
libSRTP uses the GNU \texttt{autoconf} and \texttt{make}
|
||||
|
@ -135,7 +135,7 @@ The configure script accepts the following options:
|
|||
\end{description}
|
||||
\end{quote}
|
||||
|
||||
By default, dynamic debbuging is enabled and stdout is used for
|
||||
By default, dynamic debugging is enabled and stdout is used for
|
||||
debugging. You can use the configure options to have the debugging
|
||||
output sent to syslog or the system console. Alternatively, you can
|
||||
define ERR\_REPORTING\_FILE in \texttt{include/conf.h} to be any other
|
||||
|
@ -181,7 +181,7 @@ using gdoi will be added later.
|
|||
The usage for rtpw is
|
||||
|
||||
\texttt{rtpw [[-d $<$debug$>$]* [-k $<$key$>$ [-a][-e]] [-s | -r] dest\_ip
|
||||
dest\_port][-l]}
|
||||
dest\_port] | [-l]}
|
||||
|
||||
Either the -s (sender) or -r (receiver) option must be chosen. The
|
||||
values dest\_ip, dest\_port are the IP address and UDP port to which
|
||||
|
@ -189,7 +189,7 @@ the dictionary will be sent, respectively. The options are:
|
|||
\begin{center}
|
||||
\begin{tabular}{ll}
|
||||
-s & (S)RTP sender - causes app to send words \\
|
||||
-r & (S)RTP receive - causes app to receve words \\
|
||||
-r & (S)RTP receive - causes app to receive words \\
|
||||
-k $<$key$>$ & use SRTP master key $<$key$>$, where the
|
||||
key is a hexadecimal value (without the
|
||||
leading "0x") \\
|
||||
|
@ -197,7 +197,7 @@ the dictionary will be sent, respectively. The options are:
|
|||
(requires use of -k option as well)\\
|
||||
-a & message authentication
|
||||
(requires use of -k option as well) \\
|
||||
-l & list the avaliable debug modules \\
|
||||
-l & list the available debug modules \\
|
||||
-d $<$debug$>$ & turn on debugging for module $<$debug$>$ \\
|
||||
\end{tabular}
|
||||
\end{center}
|
||||
|
@ -359,7 +359,7 @@ length as its second argument.
|
|||
crypto_get_random(key, 30);
|
||||
|
||||
// allocate and initialize the SRTP session
|
||||
srtp_create(&session, policy);
|
||||
srtp_create(&session, &policy);
|
||||
|
||||
// main loop: get rtp packets, send srtp packets
|
||||
while (1) {
|
||||
|
|
Binary file not shown.
|
@ -0,0 +1,201 @@
|
|||
/*
|
||||
* ekt.h
|
||||
*
|
||||
* interface to Encrypted Key Transport for SRTP
|
||||
*
|
||||
* David McGrew
|
||||
* Cisco Systems, Inc.
|
||||
*/
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2001-2005 Cisco Systems, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
*
|
||||
* Neither the name of the Cisco Systems, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* EKT implementation strategy
|
||||
*
|
||||
* use stream_template approach
|
||||
*
|
||||
* in srtp_unprotect, when a new stream appears, check if template has
|
||||
* EKT defined, and if it does, then apply EKT processing
|
||||
*
|
||||
* question: will we want to allow key-sharing templates in addition
|
||||
* to EKT templates? could define a new ssrc_type_t that's associated
|
||||
* with an EKT, e.g. ssrc_any_ekt.
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef EKT_H
|
||||
#define EKT_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "srtp_priv.h"
|
||||
|
||||
#define EKT_CIPHER_DEFAULT 1
|
||||
#define EKT_CIPHER_AES_128_ECB 1
|
||||
#define EKT_CIPHER_AES_192_KEY_WRAP 2
|
||||
#define EKT_CIPHER_AES_256_KEY_WRAP 3
|
||||
|
||||
typedef uint16_t ekt_spi_t;
|
||||
|
||||
|
||||
unsigned
|
||||
ekt_octets_after_base_tag(ekt_stream_t ekt);
|
||||
|
||||
/*
|
||||
* an srtp_policy_t structure can contain a pointer to an
|
||||
* ekt_policy_t structure
|
||||
*
|
||||
* this structure holds all of the high level EKT information, and it
|
||||
* is passed into libsrtp to indicate what policy should be in effect
|
||||
*/
|
||||
|
||||
typedef struct ekt_policy_ctx_t {
|
||||
ekt_spi_t spi; /* security parameter index */
|
||||
uint8_t ekt_cipher_type;
|
||||
uint8_t *ekt_key;
|
||||
struct ekt_policy_ctx_t *next_ekt_policy;
|
||||
} ekt_policy_ctx_t;
|
||||
|
||||
|
||||
/*
|
||||
* an ekt_data_t structure holds the data corresponding to an ekt key,
|
||||
* spi, and so on
|
||||
*/
|
||||
|
||||
typedef struct ekt_data_t {
|
||||
ekt_spi_t spi;
|
||||
uint8_t ekt_cipher_type;
|
||||
aes_expanded_key_t ekt_enc_key;
|
||||
aes_expanded_key_t ekt_dec_key;
|
||||
struct ekt_data_t *next_ekt_data;
|
||||
} ekt_data_t;
|
||||
|
||||
/*
|
||||
* an srtp_stream_ctx_t can contain an ekt_stream_ctx_t
|
||||
*
|
||||
* an ekt_stream_ctx_t structure holds all of the EKT information for
|
||||
* a specific SRTP stream
|
||||
*/
|
||||
|
||||
typedef struct ekt_stream_ctx_t {
|
||||
ekt_data_t *data;
|
||||
uint16_t isn; /* initial sequence number */
|
||||
uint8_t encrypted_master_key[SRTP_MAX_KEY_LEN];
|
||||
} ekt_stream_ctx_t;
|
||||
|
||||
|
||||
|
||||
err_status_t
|
||||
ekt_alloc(ekt_stream_t *stream_data, ekt_policy_t policy);
|
||||
|
||||
err_status_t
|
||||
ekt_stream_init(ekt_stream_t e,
|
||||
ekt_spi_t spi,
|
||||
void *ekt_key,
|
||||
unsigned ekt_cipher_type);
|
||||
|
||||
err_status_t
|
||||
ekt_stream_init_from_policy(ekt_stream_t e, ekt_policy_t p);
|
||||
|
||||
|
||||
|
||||
err_status_t
|
||||
srtp_stream_init_from_ekt(srtp_stream_t stream,
|
||||
const void *srtcp_hdr,
|
||||
unsigned pkt_octet_len);
|
||||
|
||||
|
||||
void
|
||||
ekt_write_data(ekt_stream_t ekt,
|
||||
uint8_t *base_tag,
|
||||
unsigned base_tag_len,
|
||||
int *packet_len,
|
||||
xtd_seq_num_t pkt_index);
|
||||
|
||||
/*
|
||||
* We handle EKT by performing some additional steps before
|
||||
* authentication (copying the auth tag into a temporary location,
|
||||
* zeroizing the "base tag" field in the packet)
|
||||
*
|
||||
* With EKT, the tag_len parameter is actually the base tag
|
||||
* length
|
||||
*/
|
||||
|
||||
err_status_t
|
||||
ekt_tag_verification_preproces(uint8_t *pkt_tag,
|
||||
uint8_t *pkt_tag_copy,
|
||||
unsigned tag_len);
|
||||
|
||||
err_status_t
|
||||
ekt_tag_verification_postproces(uint8_t *pkt_tag,
|
||||
uint8_t *pkt_tag_copy,
|
||||
unsigned tag_len);
|
||||
|
||||
|
||||
/*
|
||||
* @brief EKT pre-processing for srtcp tag generation
|
||||
*
|
||||
* This function does the pre-processing of the SRTCP authentication
|
||||
* tag format. When EKT is used, it consists of writing the Encrypted
|
||||
* Master Key, the SRTP ROC, the Initial Sequence Number, and SPI
|
||||
* fields. The Base Authentication Tag field is set to the all-zero
|
||||
* value
|
||||
*
|
||||
* When EKT is not used, this function is a no-op.
|
||||
*
|
||||
*/
|
||||
|
||||
err_status_t
|
||||
srtp_stream_srtcp_auth_tag_generation_preprocess(const srtp_stream_t *s,
|
||||
uint8_t *pkt_tag,
|
||||
unsigned pkt_octet_len);
|
||||
|
||||
/* it's not clear that a tag_generation_postprocess function is needed */
|
||||
|
||||
err_status_t
|
||||
srtcp_auth_tag_generation_postprocess(void);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* EKT_H */
|
|
@ -0,0 +1,60 @@
|
|||
/*
|
||||
* getopt.h
|
||||
*
|
||||
* interface to a minimal implementation of the getopt() function,
|
||||
* written so that test applications that use that function can run on
|
||||
* non-POSIX platforms
|
||||
*
|
||||
*/
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2001-2006 Cisco Systems, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
*
|
||||
* Neither the name of the Cisco Systems, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef GETOPT_S_H
|
||||
#define GETOPT_S_H
|
||||
|
||||
/*
|
||||
* getopt_s(), optarg_s, and optind_s are small, locally defined
|
||||
* versions of the POSIX standard getopt() interface.
|
||||
*/
|
||||
|
||||
int
|
||||
getopt_s(int argc, char * const argv[], const char *optstring);
|
||||
|
||||
extern char *optarg_s; /* defined in getopt.c */
|
||||
|
||||
extern int optind_s; /* defined in getopt.c */
|
||||
|
||||
#endif /* GETOPT_S_H */
|
|
@ -16,7 +16,7 @@
|
|||
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2001-2005, Cisco Systems, Inc.
|
||||
* Copyright (c) 2001-2006, Cisco Systems, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -54,72 +54,86 @@
|
|||
#ifndef RTP_H
|
||||
#define RTP_H
|
||||
|
||||
#include "srtp.h"
|
||||
|
||||
#ifdef HAVE_NETINET_IN_H
|
||||
# include <netinet/in.h>
|
||||
#elif defined HAVE_WINSOCK2_H
|
||||
# include <winsock2.h>
|
||||
#endif
|
||||
|
||||
#define rtp_header_len 12
|
||||
#include "srtp.h"
|
||||
|
||||
typedef srtp_hdr_t rtp_hdr_t;
|
||||
typedef struct rtp_sender_ctx_t *rtp_sender_t;
|
||||
|
||||
#define RTP_MAX_BUF_LEN 16384
|
||||
|
||||
typedef struct {
|
||||
srtp_hdr_t header;
|
||||
char body[RTP_MAX_BUF_LEN];
|
||||
} rtp_msg_t;
|
||||
|
||||
typedef struct {
|
||||
rtp_msg_t message;
|
||||
int socket;
|
||||
srtp_ctx_t *srtp_ctx;
|
||||
struct sockaddr_in addr; /* reciever's address */
|
||||
} rtp_sender_t;
|
||||
|
||||
typedef struct {
|
||||
rtp_msg_t message;
|
||||
int socket;
|
||||
srtp_ctx_t *srtp_ctx;
|
||||
struct sockaddr_in addr; /* receiver's address */
|
||||
} rtp_receiver_t;
|
||||
|
||||
|
||||
ssize_t
|
||||
rtp_sendto(rtp_sender_t *sender, const void* msg, int len);
|
||||
|
||||
ssize_t
|
||||
rtp_recvfrom(rtp_receiver_t *receiver, void *msg, int *len);
|
||||
typedef struct rtp_receiver_ctx_t *rtp_receiver_t;
|
||||
|
||||
int
|
||||
rtp_receiver_init(rtp_receiver_t *rcvr, int socket,
|
||||
struct sockaddr_in addr, uint32_t ssrc);
|
||||
rtp_sendto(rtp_sender_t sender, const void* msg, int len);
|
||||
|
||||
int
|
||||
rtp_sender_init(rtp_sender_t *sender, int socket,
|
||||
struct sockaddr_in addr, uint32_t ssrc);
|
||||
rtp_recvfrom(rtp_receiver_t receiver, void *msg, int *len);
|
||||
|
||||
int
|
||||
rtp_receiver_init(rtp_receiver_t rcvr, int sock,
|
||||
struct sockaddr_in addr, unsigned int ssrc);
|
||||
|
||||
int
|
||||
rtp_sender_init(rtp_sender_t sender, int sock,
|
||||
struct sockaddr_in addr, unsigned int ssrc);
|
||||
|
||||
/*
|
||||
* srtp_sender_init(...) initializes an rtp_sender_t
|
||||
*
|
||||
*/
|
||||
|
||||
int
|
||||
srtp_sender_init(rtp_sender_t *rtp_ctx, /* structure to be init'ed */
|
||||
srtp_sender_init(rtp_sender_t rtp_ctx, /* structure to be init'ed */
|
||||
struct sockaddr_in name, /* socket name */
|
||||
sec_serv_t security_services, /* sec. servs. to be used */
|
||||
unsigned char *input_key /* master key/salt in hex */
|
||||
);
|
||||
|
||||
int
|
||||
srtp_receiver_init(rtp_receiver_t *rtp_ctx, /* structure to be init'ed */
|
||||
srtp_receiver_init(rtp_receiver_t rtp_ctx, /* structure to be init'ed */
|
||||
struct sockaddr_in name, /* socket name */
|
||||
sec_serv_t security_services, /* sec. servs. to be used */
|
||||
unsigned char *input_key /* master key/salt in hex */
|
||||
);
|
||||
|
||||
|
||||
int
|
||||
rtp_sender_init_srtp(rtp_sender_t sender, const srtp_policy_t *policy);
|
||||
|
||||
int
|
||||
rtp_sender_deinit_srtp(rtp_sender_t sender);
|
||||
|
||||
int
|
||||
rtp_receiver_init_srtp(rtp_receiver_t sender, const srtp_policy_t *policy);
|
||||
|
||||
int
|
||||
rtp_receiver_deinit_srtp(rtp_receiver_t sender);
|
||||
|
||||
|
||||
rtp_sender_t
|
||||
rtp_sender_alloc(void);
|
||||
|
||||
void
|
||||
rtp_sender_dealloc(rtp_sender_t rtp_ctx);
|
||||
|
||||
rtp_receiver_t
|
||||
rtp_receiver_alloc(void);
|
||||
|
||||
void
|
||||
rtp_receiver_dealloc(rtp_receiver_t rtp_ctx);
|
||||
|
||||
|
||||
/*
|
||||
* RTP_HEADER_LEN indicates the size of an RTP header
|
||||
*/
|
||||
#define RTP_HEADER_LEN 12
|
||||
|
||||
/*
|
||||
* RTP_MAX_BUF_LEN defines the largest RTP packet in the rtp.c implementation
|
||||
*/
|
||||
#define RTP_MAX_BUF_LEN 16384
|
||||
|
||||
|
||||
#endif /* RTP_H */
|
||||
|
|
|
@ -0,0 +1,74 @@
|
|||
/*
|
||||
* rtp_priv.h
|
||||
*
|
||||
* private, internal header file for RTP
|
||||
*
|
||||
* David A. McGrew
|
||||
* Cisco Systems, Inc.
|
||||
*/
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2001-2006 Cisco Systems, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
*
|
||||
* Neither the name of the Cisco Systems, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#ifndef RTP_PRIV_H
|
||||
#define RTP_PRIV_H
|
||||
|
||||
#include "srtp_priv.h"
|
||||
#include "rtp.h"
|
||||
|
||||
typedef srtp_hdr_t rtp_hdr_t;
|
||||
|
||||
typedef struct {
|
||||
srtp_hdr_t header;
|
||||
char body[RTP_MAX_BUF_LEN];
|
||||
} rtp_msg_t;
|
||||
|
||||
typedef struct rtp_sender_ctx_t {
|
||||
rtp_msg_t message;
|
||||
int socket;
|
||||
srtp_ctx_t *srtp_ctx;
|
||||
struct sockaddr_in addr; /* reciever's address */
|
||||
} rtp_sender_ctx_t;
|
||||
|
||||
typedef struct rtp_receiver_ctx_t {
|
||||
rtp_msg_t message;
|
||||
int socket;
|
||||
srtp_ctx_t *srtp_ctx;
|
||||
struct sockaddr_in addr; /* receiver's address */
|
||||
} rtp_receiver_ctx_t;
|
||||
|
||||
|
||||
#endif /* RTP_PRIV_H */
|
|
@ -8,7 +8,7 @@
|
|||
*/
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2001-2005, Cisco Systems, Inc.
|
||||
* Copyright (c) 2001-2006, Cisco Systems, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -50,14 +50,7 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(disable:4214)
|
||||
#endif
|
||||
|
||||
#include "crypto_kernel.h"
|
||||
#include "rdbx.h"
|
||||
#include "rdb.h"
|
||||
#include "integers.h"
|
||||
|
||||
/**
|
||||
* @defgroup SRTP Secure RTP
|
||||
|
@ -171,10 +164,22 @@ typedef enum {
|
|||
|
||||
typedef struct {
|
||||
ssrc_type_t type; /**< The type of this particular SSRC */
|
||||
uint32_t value; /**< The value of this SSRC, if it is not a wildcard */
|
||||
unsigned int value; /**< The value of this SSRC, if it is not a wildcard */
|
||||
} ssrc_t;
|
||||
|
||||
|
||||
/**
|
||||
* @brief points to an EKT policy
|
||||
*/
|
||||
typedef struct ekt_policy_ctx_t *ekt_policy_t;
|
||||
|
||||
|
||||
/**
|
||||
* @brief points to EKT stream data
|
||||
*/
|
||||
typedef struct ekt_stream_ctx_t *ekt_stream_t;
|
||||
|
||||
|
||||
/**
|
||||
* @brief represents the policy for an SRTP session.
|
||||
*
|
||||
|
@ -210,8 +215,18 @@ typedef struct srtp_policy_t {
|
|||
*/
|
||||
crypto_policy_t rtp; /**< SRTP crypto policy. */
|
||||
crypto_policy_t rtcp; /**< SRTCP crypto policy. */
|
||||
uint8_t *key; /**< Pointer to the SRTP master key for
|
||||
unsigned char *key; /**< Pointer to the SRTP master key for
|
||||
* this stream. */
|
||||
ekt_policy_t ekt; /**< Pointer to the EKT policy structure
|
||||
* for this stream (if any) */
|
||||
unsigned long window_size; /**< The window size to use for replay
|
||||
* protection. */
|
||||
int allow_repeat_tx; /**< Whether retransmissions of
|
||||
* packets with the same sequence number
|
||||
* are allowed. (Note that such repeated
|
||||
* transmissions must have the same RTP
|
||||
* payload, or a severe security weakness
|
||||
* is introduced!) */
|
||||
struct srtp_policy_t *next; /**< Pointer to next stream policy. */
|
||||
} srtp_policy_t;
|
||||
|
||||
|
@ -260,6 +275,15 @@ typedef struct srtp_stream_ctx_t *srtp_stream_t;
|
|||
err_status_t
|
||||
srtp_init(void);
|
||||
|
||||
/**
|
||||
* @brief srtp_shutdown() de-initializes the srtp library.
|
||||
*
|
||||
* @warning No srtp functions may be called after calling this function.
|
||||
*/
|
||||
|
||||
err_status_t
|
||||
srtp_shutdown(void);
|
||||
|
||||
/**
|
||||
* @brief srtp_protect() is the Secure RTP sender-side packet processing
|
||||
* function.
|
||||
|
@ -413,14 +437,13 @@ srtp_add_stream(srtp_t session,
|
|||
*/
|
||||
|
||||
err_status_t
|
||||
srtp_remove_stream(srtp_t session, uint32_t ssrc);
|
||||
srtp_remove_stream(srtp_t session, unsigned int ssrc);
|
||||
|
||||
/**
|
||||
* @brief crypto_policy_set_rtp_default() sets a crypto policy
|
||||
* structure to the SRTP default policy for RTP protection.
|
||||
*
|
||||
* @param p is a pointer to the policy strucutre to be set to the
|
||||
* default policy.
|
||||
* @param p is a pointer to the policy structure to be set
|
||||
*
|
||||
* The function call crypto_policy_set_rtp_default(&p) sets the
|
||||
* crypto_policy_t at location p to the SRTP default policy for RTP
|
||||
|
@ -442,8 +465,7 @@ crypto_policy_set_rtp_default(crypto_policy_t *p);
|
|||
* @brief crypto_policy_set_rtcp_default() sets a crypto policy
|
||||
* structure to the SRTP default policy for RTCP protection.
|
||||
*
|
||||
* @param p is a pointer to the policy strucutre to be set to the
|
||||
* default policy.
|
||||
* @param p is a pointer to the policy structure to be set
|
||||
*
|
||||
* The function call crypto_policy_set_rtcp_default(&p) sets the
|
||||
* crypto_policy_t at location p to the SRTP default policy for RTCP
|
||||
|
@ -465,13 +487,12 @@ crypto_policy_set_rtcp_default(crypto_policy_t *p);
|
|||
* @brief crypto_policy_set_aes_cm_128_hmac_sha1_80() sets a crypto
|
||||
* policy structure to the SRTP default policy for RTP protection.
|
||||
*
|
||||
* @param p is a pointer to the policy strucutre to be set to the
|
||||
* default policy.
|
||||
* @param p is a pointer to the policy structure to be set
|
||||
*
|
||||
* The function crypto_policy_set_aes_cm_128_hmac_sha1_80() is a
|
||||
* synonym for crypto_policy_set_rtp_default(). It conforms to the
|
||||
* naming convention used in
|
||||
* http://www.ietf.org/internet-drafts/draft-ietf-mmusic-sdescriptions-12.txt
|
||||
* naming convention used in RFC 4568 (SDP Security Descriptions for
|
||||
* Media Streams).
|
||||
*
|
||||
* @return void.
|
||||
*
|
||||
|
@ -484,13 +505,12 @@ crypto_policy_set_rtcp_default(crypto_policy_t *p);
|
|||
* @brief crypto_policy_set_aes_cm_128_hmac_sha1_32() sets a crypto
|
||||
* policy structure to a short-authentication tag policy
|
||||
*
|
||||
* @param p is a pointer to the policy strucutre to be set to the
|
||||
* default policy.
|
||||
* @param p is a pointer to the policy structure to be set
|
||||
*
|
||||
* The function call crypto_policy_set_aes_cm_128_hmac_sha1_32(&p)
|
||||
* sets the crypto_policy_t at location p to use policy
|
||||
* AES_CM_128_HMAC_SHA1_32 as defined in
|
||||
* draft-ietf-mmusic-sdescriptions-12.txt. This policy uses AES-128
|
||||
* AES_CM_128_HMAC_SHA1_32 as defined in RFC 4568.
|
||||
* This policy uses AES-128
|
||||
* Counter Mode encryption and HMAC-SHA1 authentication, with an
|
||||
* authentication tag that is only 32 bits long. This length is
|
||||
* considered adequate only for protecting audio and video media that
|
||||
|
@ -521,8 +541,7 @@ crypto_policy_set_aes_cm_128_hmac_sha1_32(crypto_policy_t *p);
|
|||
* @brief crypto_policy_set_aes_cm_128_null_auth() sets a crypto
|
||||
* policy structure to an encryption-only policy
|
||||
*
|
||||
* @param p is a pointer to the policy strucutre to be set to the
|
||||
* default policy.
|
||||
* @param p is a pointer to the policy structure to be set
|
||||
*
|
||||
* The function call crypto_policy_set_aes_cm_128_null_auth(&p) sets
|
||||
* the crypto_policy_t at location p to use the SRTP default cipher
|
||||
|
@ -552,8 +571,7 @@ crypto_policy_set_aes_cm_128_null_auth(crypto_policy_t *p);
|
|||
* @brief crypto_policy_set_null_cipher_hmac_sha1_80() sets a crypto
|
||||
* policy structure to an authentication-only policy
|
||||
*
|
||||
* @param p is a pointer to the policy strucutre to be set to the
|
||||
* default policy.
|
||||
* @param p is a pointer to the policy structure to be set
|
||||
*
|
||||
* The function call crypto_policy_set_null_cipher_hmac_sha1_80(&p)
|
||||
* sets the crypto_policy_t at location p to use HMAC-SHA1 with an 80
|
||||
|
@ -577,6 +595,70 @@ crypto_policy_set_aes_cm_128_null_auth(crypto_policy_t *p);
|
|||
void
|
||||
crypto_policy_set_null_cipher_hmac_sha1_80(crypto_policy_t *p);
|
||||
|
||||
|
||||
/**
|
||||
* @brief crypto_policy_set_aes_cm_256_hmac_sha1_80() sets a crypto
|
||||
* policy structure to a encryption and authentication policy using AES-256
|
||||
* for RTP protection.
|
||||
*
|
||||
* @param p is a pointer to the policy structure to be set
|
||||
*
|
||||
* The function call crypto_policy_set_aes_cm_256_hmac_sha1_80(&p)
|
||||
* sets the crypto_policy_t at location p to use policy
|
||||
* AES_CM_256_HMAC_SHA1_80 as defined in
|
||||
* draft-ietf-avt-srtp-big-aes-03.txt. This policy uses AES-256
|
||||
* Counter Mode encryption and HMAC-SHA1 authentication, with an 80 bit
|
||||
* authentication tag.
|
||||
*
|
||||
* This function is a convenience that helps to avoid dealing directly
|
||||
* with the policy data structure. You are encouraged to initialize
|
||||
* policy elements with this function call. Doing so may allow your
|
||||
* code to be forward compatible with later versions of libSRTP that
|
||||
* include more elements in the crypto_policy_t datatype.
|
||||
*
|
||||
* @return void.
|
||||
*
|
||||
*/
|
||||
|
||||
void crypto_policy_set_aes_cm_256_hmac_sha1_80(crypto_policy_t *p);
|
||||
|
||||
|
||||
/**
|
||||
* @brief crypto_policy_set_aes_cm_256_hmac_sha1_32() sets a crypto
|
||||
* policy structure to a short-authentication tag policy using AES-256
|
||||
* encryption.
|
||||
*
|
||||
* @param p is a pointer to the policy structure to be set
|
||||
*
|
||||
* The function call crypto_policy_set_aes_cm_256_hmac_sha1_32(&p)
|
||||
* sets the crypto_policy_t at location p to use policy
|
||||
* AES_CM_256_HMAC_SHA1_32 as defined in
|
||||
* draft-ietf-avt-srtp-big-aes-03.txt. This policy uses AES-256
|
||||
* Counter Mode encryption and HMAC-SHA1 authentication, with an
|
||||
* authentication tag that is only 32 bits long. This length is
|
||||
* considered adequate only for protecting audio and video media that
|
||||
* use a stateless playback function. See Section 7.5 of RFC 3711
|
||||
* (http://www.ietf.org/rfc/rfc3711.txt).
|
||||
*
|
||||
* This function is a convenience that helps to avoid dealing directly
|
||||
* with the policy data structure. You are encouraged to initialize
|
||||
* policy elements with this function call. Doing so may allow your
|
||||
* code to be forward compatible with later versions of libSRTP that
|
||||
* include more elements in the crypto_policy_t datatype.
|
||||
*
|
||||
* @warning This crypto policy is intended for use in SRTP, but not in
|
||||
* SRTCP. It is recommended that a policy that uses longer
|
||||
* authentication tags be used for SRTCP. See Section 7.5 of RFC 3711
|
||||
* (http://www.ietf.org/rfc/rfc3711.txt).
|
||||
*
|
||||
* @return void.
|
||||
*
|
||||
*/
|
||||
|
||||
void
|
||||
crypto_policy_set_aes_cm_256_hmac_sha1_32(crypto_policy_t *p);
|
||||
|
||||
|
||||
/**
|
||||
* @brief srtp_dealloc() deallocates storage for an SRTP session
|
||||
* context.
|
||||
|
@ -597,70 +679,114 @@ err_status_t
|
|||
srtp_dealloc(srtp_t s);
|
||||
|
||||
|
||||
/*
|
||||
* @brief identifies a particular SRTP profile
|
||||
*
|
||||
* An srtp_profile_t enumeration is used to identify a particular SRTP
|
||||
* profile (that is, a set of algorithms and parameters). These
|
||||
* profiles are defined in the DTLS-SRTP draft.
|
||||
*/
|
||||
|
||||
typedef enum {
|
||||
srtp_profile_reserved = 0,
|
||||
srtp_profile_aes128_cm_sha1_80 = 1,
|
||||
srtp_profile_aes128_cm_sha1_32 = 2,
|
||||
srtp_profile_aes256_cm_sha1_80 = 3,
|
||||
srtp_profile_aes256_cm_sha1_32 = 4,
|
||||
srtp_profile_null_sha1_80 = 5,
|
||||
srtp_profile_null_sha1_32 = 6,
|
||||
} srtp_profile_t;
|
||||
|
||||
|
||||
/**
|
||||
* @brief crypto_policy_set_from_profile_for_rtp() sets a crypto policy
|
||||
* structure to the appropriate value for RTP based on an srtp_profile_t
|
||||
*
|
||||
* @param p is a pointer to the policy structure to be set
|
||||
*
|
||||
* The function call crypto_policy_set_rtp_default(&policy, profile)
|
||||
* sets the crypto_policy_t at location policy to the policy for RTP
|
||||
* protection, as defined by the srtp_profile_t profile.
|
||||
*
|
||||
* This function is a convenience that helps to avoid dealing directly
|
||||
* with the policy data structure. You are encouraged to initialize
|
||||
* policy elements with this function call. Doing so may allow your
|
||||
* code to be forward compatible with later versions of libSRTP that
|
||||
* include more elements in the crypto_policy_t datatype.
|
||||
*
|
||||
* @return values
|
||||
* - err_status_ok no problems were encountered
|
||||
* - err_status_bad_param the profile is not supported
|
||||
*
|
||||
*/
|
||||
err_status_t
|
||||
crypto_policy_set_from_profile_for_rtp(crypto_policy_t *policy,
|
||||
srtp_profile_t profile);
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief crypto_policy_set_from_profile_for_rtcp() sets a crypto policy
|
||||
* structure to the appropriate value for RTCP based on an srtp_profile_t
|
||||
*
|
||||
* @param p is a pointer to the policy structure to be set
|
||||
*
|
||||
* The function call crypto_policy_set_rtcp_default(&policy, profile)
|
||||
* sets the crypto_policy_t at location policy to the policy for RTCP
|
||||
* protection, as defined by the srtp_profile_t profile.
|
||||
*
|
||||
* This function is a convenience that helps to avoid dealing directly
|
||||
* with the policy data structure. You are encouraged to initialize
|
||||
* policy elements with this function call. Doing so may allow your
|
||||
* code to be forward compatible with later versions of libSRTP that
|
||||
* include more elements in the crypto_policy_t datatype.
|
||||
*
|
||||
* @return values
|
||||
* - err_status_ok no problems were encountered
|
||||
* - err_status_bad_param the profile is not supported
|
||||
*
|
||||
*/
|
||||
err_status_t
|
||||
crypto_policy_set_from_profile_for_rtcp(crypto_policy_t *policy,
|
||||
srtp_profile_t profile);
|
||||
|
||||
/**
|
||||
* @brief returns the master key length for a given SRTP profile
|
||||
*/
|
||||
unsigned int
|
||||
srtp_profile_get_master_key_length(srtp_profile_t profile);
|
||||
|
||||
|
||||
/**
|
||||
* @brief returns the master salt length for a given SRTP profile
|
||||
*/
|
||||
unsigned int
|
||||
srtp_profile_get_master_salt_length(srtp_profile_t profile);
|
||||
|
||||
/**
|
||||
* @brief appends the salt to the key
|
||||
*
|
||||
* The function call append_salt_to_key(k, klen, s, slen)
|
||||
* copies the string s to the location at klen bytes following
|
||||
* the location k.
|
||||
*
|
||||
* @warning There must be at least bytes_in_salt + bytes_in_key bytes
|
||||
* available at the location pointed to by key.
|
||||
*
|
||||
*/
|
||||
|
||||
void
|
||||
append_salt_to_key(unsigned char *key, unsigned int bytes_in_key,
|
||||
unsigned char *salt, unsigned int bytes_in_salt);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* the following declarations are libSRTP internal functions
|
||||
*/
|
||||
|
||||
/*
|
||||
* srtp_get_stream(ssrc) returns a pointer to the stream corresponding
|
||||
* to ssrc, or NULL if no stream exists for that ssrc
|
||||
*/
|
||||
|
||||
srtp_stream_t
|
||||
srtp_get_stream(srtp_t srtp, uint32_t ssrc);
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* libsrtp internal datatypes
|
||||
*/
|
||||
|
||||
typedef enum direction_t {
|
||||
dir_unknown = 0,
|
||||
dir_srtp_sender = 1,
|
||||
dir_srtp_receiver = 2
|
||||
} direction_t;
|
||||
|
||||
/*
|
||||
* an srtp_stream_t has its own SSRC, encryption key, authentication
|
||||
* key, sequence number, and replay database
|
||||
*
|
||||
* note that the keys might not actually be unique, in which case the
|
||||
* cipher_t and auth_t pointers will point to the same structures
|
||||
*/
|
||||
|
||||
typedef struct srtp_stream_ctx_t {
|
||||
uint32_t ssrc;
|
||||
cipher_t *rtp_cipher;
|
||||
auth_t *rtp_auth;
|
||||
rdbx_t rtp_rdbx;
|
||||
sec_serv_t rtp_services;
|
||||
cipher_t *rtcp_cipher;
|
||||
auth_t *rtcp_auth;
|
||||
rdb_t rtcp_rdb;
|
||||
sec_serv_t rtcp_services;
|
||||
key_limit_ctx_t *limit;
|
||||
direction_t direction;
|
||||
struct srtp_stream_ctx_t *next; /* linked list of streams */
|
||||
} srtp_stream_ctx_t;
|
||||
|
||||
|
||||
/*
|
||||
* an srtp_ctx_t holds a stream list and a service description
|
||||
*/
|
||||
|
||||
typedef struct srtp_ctx_t {
|
||||
srtp_stream_ctx_t *stream_list; /* linked list of streams */
|
||||
srtp_stream_ctx_t *stream_template; /* act as template for other streams */
|
||||
} srtp_ctx_t;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @defgroup SRTCP Secure RTCP
|
||||
|
@ -867,137 +993,12 @@ srtp_install_event_handler(srtp_event_handler_func_t func);
|
|||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/*
|
||||
* srtp_handle_event(srtp, srtm, evnt) calls the event handling
|
||||
* function, if there is one.
|
||||
*
|
||||
* This macro is not included in the documentation as it is
|
||||
* an internal-only function.
|
||||
*/
|
||||
|
||||
#define srtp_handle_event(srtp, strm, evnt) \
|
||||
if(srtp_event_handler) { \
|
||||
srtp_event_data_t data; \
|
||||
data.session = srtp; \
|
||||
data.stream = strm; \
|
||||
data.event = evnt; \
|
||||
srtp_event_handler(&data); \
|
||||
}
|
||||
|
||||
/*
|
||||
* an srtp_hdr_t represents the srtp header
|
||||
*
|
||||
* in this implementation, an srtp_hdr_t is assumed to be 32-bit aligned
|
||||
*
|
||||
* (note that this definition follows that of RFC 1889 Appendix A, but
|
||||
* is not identical)
|
||||
*/
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma pack(push, r1, 1)
|
||||
#endif
|
||||
|
||||
#ifndef WORDS_BIGENDIAN
|
||||
|
||||
typedef struct {
|
||||
unsigned cc:4; /* CSRC count */
|
||||
unsigned x:1; /* header extension flag */
|
||||
unsigned p:1; /* padding flag */
|
||||
unsigned version:2; /* protocol version */
|
||||
unsigned pt:7; /* payload type */
|
||||
unsigned m:1; /* marker bit */
|
||||
unsigned seq:16; /* sequence number */
|
||||
unsigned ts:32; /* timestamp */
|
||||
unsigned ssrc:32; /* synchronization source */
|
||||
} srtp_hdr_t;
|
||||
|
||||
#else /* BIG_ENDIAN */
|
||||
|
||||
typedef struct {
|
||||
unsigned version:2; /* protocol version */
|
||||
unsigned p:1; /* padding flag */
|
||||
unsigned x:1; /* header extension flag */
|
||||
unsigned cc:4; /* CSRC count */
|
||||
unsigned m:1; /* marker bit */
|
||||
unsigned pt:7; /* payload type */
|
||||
unsigned seq:16; /* sequence number */
|
||||
unsigned ts:32; /* timestamp */
|
||||
unsigned ssrc:32; /* synchronization source */
|
||||
} srtp_hdr_t;
|
||||
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
uint16_t profile_specific; /* profile-specific info */
|
||||
uint16_t length; /* number of 32-bit words in extension */
|
||||
} srtp_hdr_xtnd_t;
|
||||
|
||||
|
||||
/*
|
||||
* srtcp_hdr_t represents a secure rtcp header
|
||||
*
|
||||
* in this implementation, an srtcp header is assumed to be 32-bit
|
||||
* alinged
|
||||
*/
|
||||
|
||||
#ifndef WORDS_BIGENDIAN
|
||||
|
||||
typedef struct {
|
||||
unsigned rc:5; /* reception report count */
|
||||
unsigned p:1; /* padding flag */
|
||||
unsigned version:2; /* protocol version */
|
||||
unsigned pt:8; /* payload type */
|
||||
unsigned len:16; /* length */
|
||||
unsigned ssrc:32; /* synchronization source */
|
||||
} srtcp_hdr_t;
|
||||
|
||||
typedef struct {
|
||||
unsigned int index:31; /* srtcp packet index in network order! */
|
||||
unsigned int e:1; /* encrypted? 1=yes */
|
||||
/* optional mikey/etc go here */
|
||||
/* and then the variable-length auth tag */
|
||||
} srtcp_trailer_t;
|
||||
|
||||
|
||||
#else /* BIG_ENDIAN */
|
||||
|
||||
typedef struct {
|
||||
unsigned version:2; /* protocol version */
|
||||
unsigned p:1; /* padding flag */
|
||||
unsigned rc:5; /* reception report count */
|
||||
unsigned pt:8; /* payload type */
|
||||
unsigned len:16; /* length */
|
||||
unsigned ssrc:32; /* synchronization source */
|
||||
} srtcp_hdr_t;
|
||||
|
||||
typedef struct {
|
||||
unsigned int version:2; /* protocol version */
|
||||
unsigned int p:1; /* padding flag */
|
||||
unsigned int count:5; /* varies by packet type */
|
||||
unsigned int pt:8; /* payload type */
|
||||
unsigned length:16; /* len of uint32s of packet less header */
|
||||
} rtcp_common_t;
|
||||
|
||||
typedef struct {
|
||||
unsigned int e:1; /* encrypted? 1=yes */
|
||||
unsigned int index:31; /* srtcp packet index */
|
||||
/* optional mikey/etc go here */
|
||||
/* and then the variable-length auth tag */
|
||||
} srtcp_trailer_t;
|
||||
|
||||
#endif
|
||||
|
||||
/* in host order, so outside the #if */
|
||||
#define SRTCP_E_BIT 0x80000000
|
||||
/* for byte-access */
|
||||
#define SRTCP_E_BYTE_BIT 0x80
|
||||
#define SRTCP_INDEX_MASK 0x7fffffff
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma pack(pop, r1)
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -0,0 +1,256 @@
|
|||
/*
|
||||
* srtp_priv.h
|
||||
*
|
||||
* private internal data structures and functions for libSRTP
|
||||
*
|
||||
* David A. McGrew
|
||||
* Cisco Systems, Inc.
|
||||
*/
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2001-2006 Cisco Systems, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
*
|
||||
* Neither the name of the Cisco Systems, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef SRTP_PRIV_H
|
||||
#define SRTP_PRIV_H
|
||||
|
||||
#include "srtp.h"
|
||||
#include "rdbx.h"
|
||||
#include "rdb.h"
|
||||
#include "integers.h"
|
||||
|
||||
/*
|
||||
* an srtp_hdr_t represents the srtp header
|
||||
*
|
||||
* in this implementation, an srtp_hdr_t is assumed to be 32-bit aligned
|
||||
*
|
||||
* (note that this definition follows that of RFC 1889 Appendix A, but
|
||||
* is not identical)
|
||||
*/
|
||||
|
||||
#ifndef WORDS_BIGENDIAN
|
||||
|
||||
/*
|
||||
* srtp_hdr_t represents an RTP or SRTP header. The bit-fields in
|
||||
* this structure should be declared "unsigned int" instead of
|
||||
* "unsigned char", but doing so causes the MS compiler to not
|
||||
* fully pack the bit fields.
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
unsigned cc:4; /* CSRC count */
|
||||
unsigned x:1; /* header extension flag */
|
||||
unsigned p:1; /* padding flag */
|
||||
unsigned version:2; /* protocol version */
|
||||
unsigned pt:7; /* payload type */
|
||||
unsigned m:1; /* marker bit */
|
||||
unsigned seq:16; /* sequence number */
|
||||
unsigned ts:32; /* timestamp */
|
||||
unsigned ssrc:32; /* synchronization source */
|
||||
} srtp_hdr_t;
|
||||
|
||||
#else /* BIG_ENDIAN */
|
||||
|
||||
typedef struct {
|
||||
unsigned char version:2; /* protocol version */
|
||||
unsigned char p:1; /* padding flag */
|
||||
unsigned char x:1; /* header extension flag */
|
||||
unsigned char cc:4; /* CSRC count */
|
||||
unsigned char m:1; /* marker bit */
|
||||
unsigned pt:7; /* payload type */
|
||||
unsigned seq:16; /* sequence number */
|
||||
unsigned ts:32; /* timestamp */
|
||||
unsigned ssrc:32; /* synchronization source */
|
||||
} srtp_hdr_t;
|
||||
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
uint16_t profile_specific; /* profile-specific info */
|
||||
uint16_t length; /* number of 32-bit words in extension */
|
||||
} srtp_hdr_xtnd_t;
|
||||
|
||||
|
||||
/*
|
||||
* srtcp_hdr_t represents a secure rtcp header
|
||||
*
|
||||
* in this implementation, an srtcp header is assumed to be 32-bit
|
||||
* alinged
|
||||
*/
|
||||
|
||||
#ifndef WORDS_BIGENDIAN
|
||||
|
||||
typedef struct {
|
||||
unsigned rc:5; /* reception report count */
|
||||
unsigned p:1; /* padding flag */
|
||||
unsigned version:2; /* protocol version */
|
||||
unsigned pt:8; /* payload type */
|
||||
unsigned len:16; /* length */
|
||||
unsigned ssrc:32; /* synchronization source */
|
||||
} srtcp_hdr_t;
|
||||
|
||||
typedef struct {
|
||||
unsigned int index:31; /* srtcp packet index in network order! */
|
||||
unsigned int e:1; /* encrypted? 1=yes */
|
||||
/* optional mikey/etc go here */
|
||||
/* and then the variable-length auth tag */
|
||||
} srtcp_trailer_t;
|
||||
|
||||
|
||||
#else /* BIG_ENDIAN */
|
||||
|
||||
typedef struct {
|
||||
unsigned char version:2; /* protocol version */
|
||||
unsigned char p:1; /* padding flag */
|
||||
unsigned char rc:5; /* reception report count */
|
||||
unsigned char pt:8; /* payload type */
|
||||
uint16_t len; /* length */
|
||||
uint32_t ssrc; /* synchronization source */
|
||||
} srtcp_hdr_t;
|
||||
|
||||
typedef struct {
|
||||
unsigned int version:2; /* protocol version */
|
||||
unsigned int p:1; /* padding flag */
|
||||
unsigned int count:5; /* varies by packet type */
|
||||
unsigned int pt:8; /* payload type */
|
||||
uint16_t length; /* len of uint32s of packet less header */
|
||||
} rtcp_common_t;
|
||||
|
||||
typedef struct {
|
||||
unsigned int e:1; /* encrypted? 1=yes */
|
||||
unsigned int index:31; /* srtcp packet index */
|
||||
/* optional mikey/etc go here */
|
||||
/* and then the variable-length auth tag */
|
||||
} srtcp_trailer_t;
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* the following declarations are libSRTP internal functions
|
||||
*/
|
||||
|
||||
/*
|
||||
* srtp_get_stream(ssrc) returns a pointer to the stream corresponding
|
||||
* to ssrc, or NULL if no stream exists for that ssrc
|
||||
*/
|
||||
|
||||
srtp_stream_t
|
||||
srtp_get_stream(srtp_t srtp, uint32_t ssrc);
|
||||
|
||||
|
||||
/*
|
||||
* srtp_stream_init_keys(s, k) (re)initializes the srtp_stream_t s by
|
||||
* deriving all of the needed keys using the KDF and the key k.
|
||||
*/
|
||||
|
||||
|
||||
err_status_t
|
||||
srtp_stream_init_keys(srtp_stream_t srtp, const void *key);
|
||||
|
||||
/*
|
||||
* srtp_stream_init(s, p) initializes the srtp_stream_t s to
|
||||
* use the policy at the location p
|
||||
*/
|
||||
err_status_t
|
||||
srtp_stream_init(srtp_stream_t srtp,
|
||||
const srtp_policy_t *p);
|
||||
|
||||
|
||||
/*
|
||||
* libsrtp internal datatypes
|
||||
*/
|
||||
|
||||
typedef enum direction_t {
|
||||
dir_unknown = 0,
|
||||
dir_srtp_sender = 1,
|
||||
dir_srtp_receiver = 2
|
||||
} direction_t;
|
||||
|
||||
/*
|
||||
* an srtp_stream_t has its own SSRC, encryption key, authentication
|
||||
* key, sequence number, and replay database
|
||||
*
|
||||
* note that the keys might not actually be unique, in which case the
|
||||
* cipher_t and auth_t pointers will point to the same structures
|
||||
*/
|
||||
|
||||
typedef struct srtp_stream_ctx_t {
|
||||
uint32_t ssrc;
|
||||
cipher_t *rtp_cipher;
|
||||
auth_t *rtp_auth;
|
||||
rdbx_t rtp_rdbx;
|
||||
sec_serv_t rtp_services;
|
||||
cipher_t *rtcp_cipher;
|
||||
auth_t *rtcp_auth;
|
||||
rdb_t rtcp_rdb;
|
||||
sec_serv_t rtcp_services;
|
||||
key_limit_ctx_t *limit;
|
||||
direction_t direction;
|
||||
int allow_repeat_tx;
|
||||
ekt_stream_t ekt;
|
||||
struct srtp_stream_ctx_t *next; /* linked list of streams */
|
||||
} srtp_stream_ctx_t;
|
||||
|
||||
|
||||
/*
|
||||
* an srtp_ctx_t holds a stream list and a service description
|
||||
*/
|
||||
|
||||
typedef struct srtp_ctx_t {
|
||||
srtp_stream_ctx_t *stream_list; /* linked list of streams */
|
||||
srtp_stream_ctx_t *stream_template; /* act as template for other streams */
|
||||
} srtp_ctx_t;
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* srtp_handle_event(srtp, srtm, evnt) calls the event handling
|
||||
* function, if there is one.
|
||||
*
|
||||
* This macro is not included in the documentation as it is
|
||||
* an internal-only function.
|
||||
*/
|
||||
|
||||
#define srtp_handle_event(srtp, strm, evnt) \
|
||||
if(srtp_event_handler) { \
|
||||
srtp_event_data_t data; \
|
||||
data.session = srtp; \
|
||||
data.stream = strm; \
|
||||
data.event = evnt; \
|
||||
srtp_event_handler(&data); \
|
||||
}
|
||||
|
||||
|
||||
#endif /* SRTP_PRIV_H */
|
|
@ -10,7 +10,7 @@
|
|||
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2001-2005, Cisco Systems, Inc.
|
||||
* Copyright (c) 2001-2006, Cisco Systems, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
|
|
@ -0,0 +1,278 @@
|
|||
/*
|
||||
* ekt.c
|
||||
*
|
||||
* Encrypted Key Transport for SRTP
|
||||
*
|
||||
* David McGrew
|
||||
* Cisco Systems, Inc.
|
||||
*/
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2001-2006 Cisco Systems, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
*
|
||||
* Neither the name of the Cisco Systems, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include "err.h"
|
||||
#include "srtp_priv.h"
|
||||
#include "ekt.h"
|
||||
|
||||
extern debug_module_t mod_srtp;
|
||||
|
||||
/*
|
||||
* The EKT Authentication Tag format.
|
||||
*
|
||||
* 0 1 2 3
|
||||
* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
* : Base Authentication Tag :
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
* : Encrypted Master Key :
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
* | Rollover Counter |
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
* | Initial Sequence Number | Security Parameter Index |
|
||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
*
|
||||
*/
|
||||
|
||||
#define EKT_OCTETS_AFTER_BASE_TAG 24
|
||||
#define EKT_OCTETS_AFTER_EMK 8
|
||||
#define EKT_OCTETS_AFTER_ROC 4
|
||||
#define EKT_SPI_LEN 2
|
||||
|
||||
unsigned
|
||||
ekt_octets_after_base_tag(ekt_stream_t ekt) {
|
||||
/*
|
||||
* if the pointer ekt is NULL, then EKT is not in effect, so we
|
||||
* indicate this by returning zero
|
||||
*/
|
||||
if (!ekt)
|
||||
return 0;
|
||||
|
||||
switch(ekt->data->ekt_cipher_type) {
|
||||
case EKT_CIPHER_AES_128_ECB:
|
||||
return 16 + EKT_OCTETS_AFTER_EMK;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline ekt_spi_t
|
||||
srtcp_packet_get_ekt_spi(const uint8_t *packet_start, unsigned pkt_octet_len) {
|
||||
const uint8_t *spi_location;
|
||||
|
||||
spi_location = packet_start + (pkt_octet_len - EKT_SPI_LEN);
|
||||
|
||||
return *((const ekt_spi_t *)spi_location);
|
||||
}
|
||||
|
||||
static inline uint32_t
|
||||
srtcp_packet_get_ekt_roc(const uint8_t *packet_start, unsigned pkt_octet_len) {
|
||||
const uint8_t *roc_location;
|
||||
|
||||
roc_location = packet_start + (pkt_octet_len - EKT_OCTETS_AFTER_ROC);
|
||||
|
||||
return *((const uint32_t *)roc_location);
|
||||
}
|
||||
|
||||
static inline const uint8_t *
|
||||
srtcp_packet_get_emk_location(const uint8_t *packet_start,
|
||||
unsigned pkt_octet_len) {
|
||||
const uint8_t *location;
|
||||
|
||||
location = packet_start + (pkt_octet_len - EKT_OCTETS_AFTER_BASE_TAG);
|
||||
|
||||
return location;
|
||||
}
|
||||
|
||||
|
||||
err_status_t
|
||||
ekt_alloc(ekt_stream_t *stream_data, ekt_policy_t policy) {
|
||||
|
||||
/*
|
||||
* if the policy pointer is NULL, then EKT is not in use
|
||||
* so we just set the EKT stream data pointer to NULL
|
||||
*/
|
||||
if (!policy) {
|
||||
*stream_data = NULL;
|
||||
return err_status_ok;
|
||||
}
|
||||
|
||||
/* TODO */
|
||||
*stream_data = NULL;
|
||||
|
||||
return err_status_ok;
|
||||
}
|
||||
|
||||
err_status_t
|
||||
ekt_stream_init_from_policy(ekt_stream_t stream_data, ekt_policy_t policy) {
|
||||
if (!stream_data)
|
||||
return err_status_ok;
|
||||
|
||||
return err_status_ok;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
aes_decrypt_with_raw_key(void *ciphertext, const void *key, int key_len) {
|
||||
aes_expanded_key_t expanded_key;
|
||||
|
||||
aes_expand_decryption_key(key, key_len, &expanded_key);
|
||||
aes_decrypt(ciphertext, &expanded_key);
|
||||
}
|
||||
|
||||
/*
|
||||
* The function srtp_stream_init_from_ekt() initializes a stream using
|
||||
* the EKT data from an SRTCP trailer.
|
||||
*/
|
||||
|
||||
err_status_t
|
||||
srtp_stream_init_from_ekt(srtp_stream_t stream,
|
||||
const void *srtcp_hdr,
|
||||
unsigned pkt_octet_len) {
|
||||
err_status_t err;
|
||||
const uint8_t *master_key;
|
||||
srtp_policy_t srtp_policy;
|
||||
unsigned master_key_len;
|
||||
uint32_t roc;
|
||||
|
||||
/*
|
||||
* NOTE: at present, we only support a single ekt_policy at a time.
|
||||
*/
|
||||
if (stream->ekt->data->spi !=
|
||||
srtcp_packet_get_ekt_spi(srtcp_hdr, pkt_octet_len))
|
||||
return err_status_no_ctx;
|
||||
|
||||
if (stream->ekt->data->ekt_cipher_type != EKT_CIPHER_AES_128_ECB)
|
||||
return err_status_bad_param;
|
||||
master_key_len = 16;
|
||||
|
||||
/* decrypt the Encrypted Master Key field */
|
||||
master_key = srtcp_packet_get_emk_location(srtcp_hdr, pkt_octet_len);
|
||||
/* FIX!? This decrypts the master key in-place, and never uses it */
|
||||
/* FIX!? It's also passing to ekt_dec_key (which is an aes_expanded_key_t)
|
||||
* to a function which expects a raw (unexpanded) key */
|
||||
aes_decrypt_with_raw_key((void*)master_key, &stream->ekt->data->ekt_dec_key, 16);
|
||||
|
||||
/* set the SRTP ROC */
|
||||
roc = srtcp_packet_get_ekt_roc(srtcp_hdr, pkt_octet_len);
|
||||
err = rdbx_set_roc(&stream->rtp_rdbx, roc);
|
||||
if (err) return err;
|
||||
|
||||
err = srtp_stream_init(stream, &srtp_policy);
|
||||
if (err) return err;
|
||||
|
||||
return err_status_ok;
|
||||
}
|
||||
|
||||
void
|
||||
ekt_write_data(ekt_stream_t ekt,
|
||||
uint8_t *base_tag,
|
||||
unsigned base_tag_len,
|
||||
int *packet_len,
|
||||
xtd_seq_num_t pkt_index) {
|
||||
uint32_t roc;
|
||||
uint16_t isn;
|
||||
unsigned emk_len;
|
||||
uint8_t *packet;
|
||||
|
||||
/* if the pointer ekt is NULL, then EKT is not in effect */
|
||||
if (!ekt) {
|
||||
debug_print(mod_srtp, "EKT not in use", NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
/* write zeros into the location of the base tag */
|
||||
octet_string_set_to_zero(base_tag, base_tag_len);
|
||||
packet = base_tag + base_tag_len;
|
||||
|
||||
/* copy encrypted master key into packet */
|
||||
emk_len = ekt_octets_after_base_tag(ekt);
|
||||
memcpy(packet, ekt->encrypted_master_key, emk_len);
|
||||
debug_print(mod_srtp, "writing EKT EMK: %s,",
|
||||
octet_string_hex_string(packet, emk_len));
|
||||
packet += emk_len;
|
||||
|
||||
/* copy ROC into packet */
|
||||
roc = (uint32_t)(pkt_index >> 16);
|
||||
*((uint32_t *)packet) = be32_to_cpu(roc);
|
||||
debug_print(mod_srtp, "writing EKT ROC: %s,",
|
||||
octet_string_hex_string(packet, sizeof(roc)));
|
||||
packet += sizeof(roc);
|
||||
|
||||
/* copy ISN into packet */
|
||||
isn = (uint16_t)pkt_index;
|
||||
*((uint16_t *)packet) = htons(isn);
|
||||
debug_print(mod_srtp, "writing EKT ISN: %s,",
|
||||
octet_string_hex_string(packet, sizeof(isn)));
|
||||
packet += sizeof(isn);
|
||||
|
||||
/* copy SPI into packet */
|
||||
*((uint16_t *)packet) = htons(ekt->data->spi);
|
||||
debug_print(mod_srtp, "writing EKT SPI: %s,",
|
||||
octet_string_hex_string(packet, sizeof(ekt->data->spi)));
|
||||
|
||||
/* increase packet length appropriately */
|
||||
*packet_len += EKT_OCTETS_AFTER_EMK + emk_len;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* The function call srtcp_ekt_trailer(ekt, auth_len, auth_tag )
|
||||
*
|
||||
* If the pointer ekt is NULL, then the other inputs are unaffected.
|
||||
*
|
||||
* auth_tag is a pointer to the pointer to the location of the
|
||||
* authentication tag in the packet. If EKT is in effect, then the
|
||||
* auth_tag pointer is set to the location
|
||||
*/
|
||||
|
||||
void
|
||||
srtcp_ekt_trailer(ekt_stream_t ekt,
|
||||
unsigned *auth_len,
|
||||
void **auth_tag,
|
||||
void *tag_copy) {
|
||||
|
||||
/*
|
||||
* if there is no EKT policy, then the other inputs are unaffected
|
||||
*/
|
||||
if (!ekt)
|
||||
return;
|
||||
|
||||
/* copy auth_tag into temporary location */
|
||||
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
|
@ -8,7 +8,7 @@
|
|||
*/
|
||||
/*
|
||||
*
|
||||
* Copyright(c) 2001-2005 Cisco Systems, Inc.
|
||||
* Copyright(c) 2001-2006 Cisco Systems, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
|
|
@ -0,0 +1,261 @@
|
|||
/*
|
||||
* dtls_srtp_driver.c
|
||||
*
|
||||
* test driver for DTLS-SRTP functions
|
||||
*
|
||||
* David McGrew
|
||||
* Cisco Systems, Inc.
|
||||
*/
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2001-2006 Cisco Systems, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
*
|
||||
* Neither the name of the Cisco Systems, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h> /* for printf() */
|
||||
#include "getopt_s.h" /* for local getopt() */
|
||||
#include "srtp_priv.h"
|
||||
|
||||
err_status_t
|
||||
test_dtls_srtp(void);
|
||||
|
||||
srtp_hdr_t *
|
||||
srtp_create_test_packet(int pkt_octet_len, uint32_t ssrc);
|
||||
|
||||
void
|
||||
usage(char *prog_name) {
|
||||
printf("usage: %s [ -t ][ -c ][ -v ][-d <debug_module> ]* [ -l ]\n"
|
||||
" -d <mod> turn on debugging module <mod>\n"
|
||||
" -l list debugging modules\n", prog_name);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char *argv[]) {
|
||||
unsigned do_list_mods = 0;
|
||||
int q;
|
||||
err_status_t err;
|
||||
|
||||
printf("dtls_srtp_driver\n");
|
||||
|
||||
/* initialize srtp library */
|
||||
err = srtp_init();
|
||||
if (err) {
|
||||
printf("error: srtp init failed with error code %d\n", err);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* process input arguments */
|
||||
while (1) {
|
||||
q = getopt_s(argc, argv, "ld:");
|
||||
if (q == -1)
|
||||
break;
|
||||
switch (q) {
|
||||
case 'l':
|
||||
do_list_mods = 1;
|
||||
break;
|
||||
case 'd':
|
||||
err = crypto_kernel_set_debug_module(optarg_s, 1);
|
||||
if (err) {
|
||||
printf("error: set debug module (%s) failed\n", optarg_s);
|
||||
exit(1);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
usage(argv[0]);
|
||||
}
|
||||
}
|
||||
|
||||
if (do_list_mods) {
|
||||
err = crypto_kernel_list_debug_modules();
|
||||
if (err) {
|
||||
printf("error: list of debug modules failed\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
printf("testing dtls_srtp...");
|
||||
err = test_dtls_srtp();
|
||||
if (err) {
|
||||
printf("\nerror (code %d)\n", err);
|
||||
exit(1);
|
||||
}
|
||||
printf("passed\n");
|
||||
|
||||
/* shut down srtp library */
|
||||
err = srtp_shutdown();
|
||||
if (err) {
|
||||
printf("error: srtp shutdown failed with error code %d\n", err);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
err_status_t
|
||||
test_dtls_srtp(void) {
|
||||
srtp_hdr_t *test_packet;
|
||||
int test_packet_len = 80;
|
||||
srtp_t s;
|
||||
srtp_policy_t policy;
|
||||
uint8_t key[SRTP_MAX_KEY_LEN];
|
||||
uint8_t salt[SRTP_MAX_KEY_LEN];
|
||||
unsigned int key_len, salt_len;
|
||||
srtp_profile_t profile;
|
||||
err_status_t err;
|
||||
|
||||
/* create a 'null' SRTP session */
|
||||
err = srtp_create(&s, NULL);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
/*
|
||||
* verify that packet-processing functions behave properly - we
|
||||
* expect that these functions will return err_status_no_ctx
|
||||
*/
|
||||
test_packet = srtp_create_test_packet(80, 0xa5a5a5a5);
|
||||
if (test_packet == NULL)
|
||||
return err_status_alloc_fail;
|
||||
err = srtp_protect(s, test_packet, &test_packet_len);
|
||||
if (err != err_status_no_ctx) {
|
||||
printf("wrong return value from srtp_protect() (got code %d)\n",
|
||||
err);
|
||||
return err_status_fail;
|
||||
}
|
||||
err = srtp_unprotect(s, test_packet, &test_packet_len);
|
||||
if (err != err_status_no_ctx) {
|
||||
printf("wrong return value from srtp_unprotect() (got code %d)\n",
|
||||
err);
|
||||
return err_status_fail;
|
||||
}
|
||||
err = srtp_protect_rtcp(s, test_packet, &test_packet_len);
|
||||
if (err != err_status_no_ctx) {
|
||||
printf("wrong return value from srtp_protect_rtcp() (got code %d)\n",
|
||||
err);
|
||||
return err_status_fail;
|
||||
}
|
||||
err = srtp_unprotect_rtcp(s, test_packet, &test_packet_len);
|
||||
if (err != err_status_no_ctx) {
|
||||
printf("wrong return value from srtp_unprotect_rtcp() (got code %d)\n",
|
||||
err);
|
||||
return err_status_fail;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* set keys to known values for testing
|
||||
*/
|
||||
profile = srtp_profile_aes128_cm_sha1_80;
|
||||
key_len = srtp_profile_get_master_key_length(profile);
|
||||
salt_len = srtp_profile_get_master_salt_length(profile);
|
||||
memset(key, 0xff, key_len);
|
||||
memset(salt, 0xee, salt_len);
|
||||
append_salt_to_key(key, key_len, salt, salt_len);
|
||||
policy.key = key;
|
||||
|
||||
/* initialize SRTP policy from profile */
|
||||
err = crypto_policy_set_from_profile_for_rtp(&policy.rtp, profile);
|
||||
if (err) return err;
|
||||
err = crypto_policy_set_from_profile_for_rtcp(&policy.rtcp, profile);
|
||||
if (err) return err;
|
||||
policy.ssrc.type = ssrc_any_inbound;
|
||||
policy.ekt = NULL;
|
||||
policy.window_size = 128;
|
||||
policy.allow_repeat_tx = 0;
|
||||
policy.next = NULL;
|
||||
|
||||
err = srtp_add_stream(s, &policy);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = srtp_dealloc(s);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
free(test_packet);
|
||||
|
||||
return err_status_ok;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* srtp_create_test_packet(len, ssrc) returns a pointer to a
|
||||
* (malloced) example RTP packet whose data field has the length given
|
||||
* by pkt_octet_len and the SSRC value ssrc. The total length of the
|
||||
* packet is twelve octets longer, since the header is at the
|
||||
* beginning. There is room at the end of the packet for a trailer,
|
||||
* and the four octets following the packet are filled with 0xff
|
||||
* values to enable testing for overwrites.
|
||||
*
|
||||
* note that the location of the test packet can (and should) be
|
||||
* deallocated with the free() call once it is no longer needed.
|
||||
*/
|
||||
|
||||
srtp_hdr_t *
|
||||
srtp_create_test_packet(int pkt_octet_len, uint32_t ssrc) {
|
||||
int i;
|
||||
uint8_t *buffer;
|
||||
srtp_hdr_t *hdr;
|
||||
int bytes_in_hdr = 12;
|
||||
|
||||
/* allocate memory for test packet */
|
||||
hdr = malloc(pkt_octet_len + bytes_in_hdr
|
||||
+ SRTP_MAX_TRAILER_LEN + 4);
|
||||
if (!hdr)
|
||||
return NULL;
|
||||
|
||||
hdr->version = 2; /* RTP version two */
|
||||
hdr->p = 0; /* no padding needed */
|
||||
hdr->x = 0; /* no header extension */
|
||||
hdr->cc = 0; /* no CSRCs */
|
||||
hdr->m = 0; /* marker bit */
|
||||
hdr->pt = 0xf; /* payload type */
|
||||
hdr->seq = htons(0x1234); /* sequence number */
|
||||
hdr->ts = htonl(0xdecafbad); /* timestamp */
|
||||
hdr->ssrc = htonl(ssrc); /* synch. source */
|
||||
|
||||
buffer = (uint8_t *)hdr;
|
||||
buffer += bytes_in_hdr;
|
||||
|
||||
/* set RTP data to 0xab */
|
||||
for (i=0; i < pkt_octet_len; i++)
|
||||
*buffer++ = 0xab;
|
||||
|
||||
/* set post-data value to 0xffff to enable overrun checking */
|
||||
for (i=0; i < SRTP_MAX_TRAILER_LEN+4; i++)
|
||||
*buffer++ = 0xff;
|
||||
|
||||
return hdr;
|
||||
}
|
|
@ -0,0 +1,112 @@
|
|||
/*
|
||||
* getopt.c
|
||||
*
|
||||
* a minimal implementation of the getopt() function, written so that
|
||||
* test applications that use that function can run on non-POSIX
|
||||
* platforms
|
||||
*
|
||||
*/
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2001-2006 Cisco Systems, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
*
|
||||
* Neither the name of the Cisco Systems, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdlib.h> /* for NULL */
|
||||
|
||||
int optind_s = 0;
|
||||
|
||||
char *optarg_s;
|
||||
|
||||
#define GETOPT_FOUND_WITHOUT_ARGUMENT 2
|
||||
#define GETOPT_FOUND_WITH_ARGUMENT 1
|
||||
#define GETOPT_NOT_FOUND 0
|
||||
|
||||
static int
|
||||
getopt_check_character(char c, const char *string) {
|
||||
unsigned int max_string_len = 128;
|
||||
|
||||
while (*string != 0) {
|
||||
if (max_string_len == 0) {
|
||||
return '?';
|
||||
}
|
||||
if (*string++ == c) {
|
||||
if (*string == ':') {
|
||||
return GETOPT_FOUND_WITH_ARGUMENT;
|
||||
} else {
|
||||
return GETOPT_FOUND_WITHOUT_ARGUMENT;
|
||||
}
|
||||
}
|
||||
}
|
||||
return GETOPT_NOT_FOUND;
|
||||
}
|
||||
|
||||
int
|
||||
getopt_s(int argc,
|
||||
char * const argv[],
|
||||
const char *optstring) {
|
||||
|
||||
|
||||
while (optind_s + 1 < argc) {
|
||||
char *string;
|
||||
|
||||
/* move 'string' on to next argument */
|
||||
optind_s++;
|
||||
string = argv[optind_s];
|
||||
|
||||
if (string == NULL)
|
||||
return '?'; /* NULL argument string */
|
||||
|
||||
if (string[0] != '-')
|
||||
return -1; /* found an unexpected character */
|
||||
|
||||
switch(getopt_check_character(string[1], optstring)) {
|
||||
case GETOPT_FOUND_WITH_ARGUMENT:
|
||||
if (optind_s + 1 < argc) {
|
||||
optind_s++;
|
||||
optarg_s = argv[optind_s];
|
||||
return string[1];
|
||||
} else {
|
||||
return '?'; /* argument missing */
|
||||
}
|
||||
case GETOPT_FOUND_WITHOUT_ARGUMENT:
|
||||
return string[1];
|
||||
case GETOPT_NOT_FOUND:
|
||||
default:
|
||||
return '?'; /* didn't find expected character */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
Binary file not shown.
|
@ -9,7 +9,7 @@
|
|||
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2001-2005, Cisco Systems, Inc.
|
||||
* Copyright (c) 2001-2006, Cisco Systems, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -44,7 +44,7 @@
|
|||
*/
|
||||
|
||||
#include <stdio.h> /* for printf() */
|
||||
#include <unistd.h> /* for getopt() */
|
||||
#include "getopt_s.h" /* for local getopt() */
|
||||
|
||||
#include "rdbx.h"
|
||||
|
||||
|
@ -55,10 +55,10 @@
|
|||
#include "ut_sim.h"
|
||||
|
||||
err_status_t
|
||||
test_replay_dbx(int num_trials);
|
||||
test_replay_dbx(int num_trials, unsigned long ws);
|
||||
|
||||
double
|
||||
rdbx_check_adds_per_second(int num_trials);
|
||||
rdbx_check_adds_per_second(int num_trials, unsigned long ws);
|
||||
|
||||
void
|
||||
usage(char *prog_name) {
|
||||
|
@ -70,13 +70,13 @@ int
|
|||
main (int argc, char *argv[]) {
|
||||
double rate;
|
||||
err_status_t status;
|
||||
char q;
|
||||
int q;
|
||||
unsigned do_timing_test = 0;
|
||||
unsigned do_validation = 0;
|
||||
|
||||
/* process input arguments */
|
||||
while (1) {
|
||||
q = getopt(argc, argv, "tv");
|
||||
q = getopt_s(argc, argv, "tv");
|
||||
if (q == -1)
|
||||
break;
|
||||
switch (q) {
|
||||
|
@ -99,9 +99,18 @@ main (int argc, char *argv[]) {
|
|||
usage(argv[0]);
|
||||
|
||||
if (do_validation) {
|
||||
printf("testing rdbx_t...\n");
|
||||
printf("testing rdbx_t (ws=128)...\n");
|
||||
|
||||
status = test_replay_dbx(1 << 12);
|
||||
status = test_replay_dbx(1 << 12, 128);
|
||||
if (status) {
|
||||
printf("failed\n");
|
||||
exit(1);
|
||||
}
|
||||
printf("passed\n");
|
||||
|
||||
printf("testing rdbx_t (ws=1024)...\n");
|
||||
|
||||
status = test_replay_dbx(1 << 12, 1024);
|
||||
if (status) {
|
||||
printf("failed\n");
|
||||
exit(1);
|
||||
|
@ -110,8 +119,10 @@ main (int argc, char *argv[]) {
|
|||
}
|
||||
|
||||
if (do_timing_test) {
|
||||
rate = rdbx_check_adds_per_second(1 << 18);
|
||||
printf("rdbx_check/replay_adds per second: %e\n", rate);
|
||||
rate = rdbx_check_adds_per_second(1 << 18, 128);
|
||||
printf("rdbx_check/replay_adds per second (ws=128): %e\n", rate);
|
||||
rate = rdbx_check_adds_per_second(1 << 18, 1024);
|
||||
printf("rdbx_check/replay_adds per second (ws=1024): %e\n", rate);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -119,8 +130,11 @@ main (int argc, char *argv[]) {
|
|||
|
||||
void
|
||||
print_rdbx(rdbx_t *rdbx) {
|
||||
char buf[2048];
|
||||
printf("rdbx: {%llu, %s}\n",
|
||||
(unsigned long long)(rdbx->index), v128_bit_string(&rdbx->bitmask));
|
||||
(unsigned long long)(rdbx->index),
|
||||
bitvector_bit_string(&rdbx->bitmask, buf, sizeof(buf))
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
@ -183,28 +197,38 @@ rdbx_check_expect_failure(rdbx_t *rdbx, uint32_t idx) {
|
|||
}
|
||||
|
||||
err_status_t
|
||||
rdbx_check_unordered(rdbx_t *rdbx, uint32_t idx) {
|
||||
rdbx_check_add_unordered(rdbx_t *rdbx, uint32_t idx) {
|
||||
int delta;
|
||||
xtd_seq_num_t est;
|
||||
err_status_t rstat;
|
||||
|
||||
rstat = rdbx_check(rdbx, idx);
|
||||
delta = index_guess(&rdbx->index, &est, idx);
|
||||
|
||||
rstat = rdbx_check(rdbx, delta);
|
||||
if ((rstat != err_status_ok) && (rstat != err_status_replay_old)) {
|
||||
printf("replay_check_unordered failed at index %u\n", idx);
|
||||
printf("replay_check_add_unordered failed at index %u\n", idx);
|
||||
return err_status_algo_fail;
|
||||
}
|
||||
if (rstat == err_status_replay_old) {
|
||||
return err_status_ok;
|
||||
}
|
||||
if (rdbx_add_index(rdbx, delta) != err_status_ok) {
|
||||
printf("rdbx_add_index failed at index %u\n", idx);
|
||||
return err_status_algo_fail;
|
||||
}
|
||||
|
||||
return err_status_ok;
|
||||
}
|
||||
|
||||
#define MAX_IDX 160
|
||||
|
||||
err_status_t
|
||||
test_replay_dbx(int num_trials) {
|
||||
test_replay_dbx(int num_trials, unsigned long ws) {
|
||||
rdbx_t rdbx;
|
||||
uint32_t idx, ircvd;
|
||||
ut_connection utc;
|
||||
err_status_t status;
|
||||
int num_fp_trials;
|
||||
|
||||
status = rdbx_init(&rdbx);
|
||||
status = rdbx_init(&rdbx, ws);
|
||||
if (status) {
|
||||
printf("replay_init failed with error code %d\n", status);
|
||||
exit(1);
|
||||
|
@ -241,7 +265,9 @@ test_replay_dbx(int num_trials) {
|
|||
printf("passed\n");
|
||||
|
||||
/* re-initialize */
|
||||
if (rdbx_init(&rdbx) != err_status_ok) {
|
||||
rdbx_dealloc(&rdbx);
|
||||
|
||||
if (rdbx_init(&rdbx, ws) != err_status_ok) {
|
||||
printf("replay_init failed\n");
|
||||
return err_status_init_fail;
|
||||
}
|
||||
|
@ -257,12 +283,40 @@ test_replay_dbx(int num_trials) {
|
|||
printf("\ttesting non-sequential insertion...");
|
||||
for (idx=0; idx < num_trials; idx++) {
|
||||
ircvd = ut_next_index(&utc);
|
||||
status = rdbx_check_unordered(&rdbx, ircvd);
|
||||
status = rdbx_check_add_unordered(&rdbx, ircvd);
|
||||
if (status)
|
||||
return status;
|
||||
status = rdbx_check_expect_failure(&rdbx, ircvd);
|
||||
if (status)
|
||||
return status;
|
||||
}
|
||||
printf("passed\n");
|
||||
|
||||
/* re-initialize */
|
||||
rdbx_dealloc(&rdbx);
|
||||
|
||||
if (rdbx_init(&rdbx, ws) != err_status_ok) {
|
||||
printf("replay_init failed\n");
|
||||
return err_status_init_fail;
|
||||
}
|
||||
|
||||
/*
|
||||
* test insertion with large gaps.
|
||||
* check for false positives for each insertion.
|
||||
*/
|
||||
printf("\ttesting insertion with large gaps...");
|
||||
for (idx=0, ircvd=0; idx < num_trials; idx++, ircvd += (1 << (rand() % 12))) {
|
||||
status = rdbx_check_add(&rdbx, ircvd);
|
||||
if (status)
|
||||
return status;
|
||||
status = rdbx_check_expect_failure(&rdbx, ircvd);
|
||||
if (status)
|
||||
return status;
|
||||
}
|
||||
printf("passed\n");
|
||||
|
||||
rdbx_dealloc(&rdbx);
|
||||
|
||||
return err_status_ok;
|
||||
}
|
||||
|
||||
|
@ -272,7 +326,7 @@ test_replay_dbx(int num_trials) {
|
|||
#include <stdlib.h> /* for random() */
|
||||
|
||||
double
|
||||
rdbx_check_adds_per_second(int num_trials) {
|
||||
rdbx_check_adds_per_second(int num_trials, unsigned long ws) {
|
||||
uint32_t i;
|
||||
int delta;
|
||||
rdbx_t rdbx;
|
||||
|
@ -280,7 +334,7 @@ rdbx_check_adds_per_second(int num_trials) {
|
|||
clock_t timer;
|
||||
int failures; /* count number of failures */
|
||||
|
||||
if (rdbx_init(&rdbx) != err_status_ok) {
|
||||
if (rdbx_init(&rdbx, ws) != err_status_ok) {
|
||||
printf("replay_init failed\n");
|
||||
exit(1);
|
||||
}
|
||||
|
@ -301,6 +355,8 @@ rdbx_check_adds_per_second(int num_trials) {
|
|||
|
||||
printf("number of failures: %d \n", failures);
|
||||
|
||||
rdbx_dealloc(&rdbx);
|
||||
|
||||
return (double) CLOCKS_PER_SEC * num_trials / timer;
|
||||
}
|
||||
|
||||
|
|
Binary file not shown.
|
@ -9,7 +9,7 @@
|
|||
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2001-2005, Cisco Systems, Inc.
|
||||
* Copyright (c) 2001-2006, Cisco Systems, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -48,7 +48,14 @@
|
|||
#include "rdb.h"
|
||||
#include "ut_sim.h"
|
||||
|
||||
void
|
||||
/*
|
||||
* num_trials defines the number of trials that are used in the
|
||||
* validation functions below
|
||||
*/
|
||||
|
||||
unsigned num_trials = 1 << 16;
|
||||
|
||||
err_status_t
|
||||
test_rdb_db(void);
|
||||
|
||||
double
|
||||
|
@ -56,9 +63,14 @@ rdb_check_adds_per_second(void);
|
|||
|
||||
int
|
||||
main (void) {
|
||||
err_status_t err;
|
||||
|
||||
printf("testing anti-replay database (rdb_t)...\n");
|
||||
test_rdb_db();
|
||||
err = test_rdb_db();
|
||||
if (err) {
|
||||
printf("failed\n");
|
||||
exit(1);
|
||||
}
|
||||
printf("done\n");
|
||||
|
||||
printf("rdb_check/rdb_adds per second: %e\n",
|
||||
|
@ -73,73 +85,138 @@ print_rdb(rdb_t *rdb) {
|
|||
printf("rdb: {%u, %s}\n", rdb->window_start, v128_bit_string(&rdb->bitmask));
|
||||
}
|
||||
|
||||
void
|
||||
err_status_t
|
||||
rdb_check_add(rdb_t *rdb, uint32_t idx) {
|
||||
|
||||
if (rdb_check(rdb, idx) != err_status_ok) {
|
||||
printf("rdb_check failed at index %u\n", idx);
|
||||
return;
|
||||
return err_status_fail;
|
||||
}
|
||||
if (rdb_add_index(rdb, idx) != err_status_ok)
|
||||
if (rdb_add_index(rdb, idx) != err_status_ok) {
|
||||
printf("rdb_add_index failed at index %u\n", idx);
|
||||
return err_status_fail;
|
||||
}
|
||||
|
||||
return err_status_ok;
|
||||
}
|
||||
|
||||
void
|
||||
err_status_t
|
||||
rdb_check_expect_failure(rdb_t *rdb, uint32_t idx) {
|
||||
err_status_t err;
|
||||
|
||||
if (rdb_check(rdb, idx) != err_status_fail)
|
||||
err = rdb_check(rdb, idx);
|
||||
if ((err != err_status_replay_old) && (err != err_status_replay_fail)) {
|
||||
printf("rdb_check failed at index %u (false positive)\n", idx);
|
||||
return err_status_fail;
|
||||
}
|
||||
|
||||
return err_status_ok;
|
||||
}
|
||||
|
||||
void
|
||||
rdb_check_unordered(rdb_t *rdb, uint32_t idx) {
|
||||
err_status_t
|
||||
rdb_check_add_unordered(rdb_t *rdb, uint32_t idx) {
|
||||
err_status_t rstat;
|
||||
|
||||
/* printf("index: %u\n", idx); */
|
||||
rstat = rdb_check(rdb, idx);
|
||||
if ((rstat != err_status_ok) && (rstat != err_status_replay_old))
|
||||
printf("rdb_check_unordered failed at index %u\n", idx);
|
||||
if ((rstat != err_status_ok) && (rstat != err_status_replay_old)) {
|
||||
printf("rdb_check_add_unordered failed at index %u\n", idx);
|
||||
return rstat;
|
||||
}
|
||||
if (rstat == err_status_replay_old) {
|
||||
return err_status_ok;
|
||||
}
|
||||
if (rdb_add_index(rdb, idx) != err_status_ok) {
|
||||
printf("rdb_add_index failed at index %u\n", idx);
|
||||
return err_status_fail;
|
||||
}
|
||||
|
||||
return err_status_ok;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#define MAX_IDX 160
|
||||
|
||||
void
|
||||
err_status_t
|
||||
test_rdb_db() {
|
||||
rdb_t rdb;
|
||||
uint32_t idx, ircvd;
|
||||
ut_connection utc;
|
||||
err_status_t err;
|
||||
|
||||
if (rdb_init(&rdb) != err_status_ok) {
|
||||
printf("rdb_init failed\n");
|
||||
exit(1);
|
||||
return err_status_init_fail;
|
||||
}
|
||||
|
||||
/* test sequential insertion */
|
||||
for (idx=0; idx < MAX_IDX; idx++) {
|
||||
rdb_check_add(&rdb, idx);
|
||||
for (idx=0; idx < num_trials; idx++) {
|
||||
err = rdb_check_add(&rdb, idx);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
|
||||
/* test for false positives */
|
||||
for (idx=0; idx < MAX_IDX; idx++) {
|
||||
rdb_check_expect_failure(&rdb, idx);
|
||||
for (idx=0; idx < num_trials; idx++) {
|
||||
err = rdb_check_expect_failure(&rdb, idx);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
|
||||
/* re-initialize */
|
||||
if (rdb_init(&rdb) != err_status_ok) {
|
||||
printf("rdb_init failed\n");
|
||||
exit(1);
|
||||
return err_status_fail;
|
||||
}
|
||||
|
||||
/* test non-sequential insertion */
|
||||
ut_init(&utc);
|
||||
|
||||
for (idx=0; idx < MAX_IDX; idx++) {
|
||||
for (idx=0; idx < num_trials; idx++) {
|
||||
ircvd = ut_next_index(&utc);
|
||||
rdb_check_unordered(&rdb, ircvd);
|
||||
err = rdb_check_add_unordered(&rdb, ircvd);
|
||||
if (err)
|
||||
return err;
|
||||
err = rdb_check_expect_failure(&rdb, ircvd);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
|
||||
/* re-initialize */
|
||||
if (rdb_init(&rdb) != err_status_ok) {
|
||||
printf("rdb_init failed\n");
|
||||
return err_status_fail;
|
||||
}
|
||||
|
||||
/* test insertion with large gaps */
|
||||
for (idx=0, ircvd=0; idx < num_trials; idx++, ircvd += (1 << (rand() % 10))) {
|
||||
err = rdb_check_add(&rdb, ircvd);
|
||||
if (err)
|
||||
return err;
|
||||
err = rdb_check_expect_failure(&rdb, ircvd);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
|
||||
/* re-initialize */
|
||||
if (rdb_init(&rdb) != err_status_ok) {
|
||||
printf("rdb_init failed\n");
|
||||
return err_status_fail;
|
||||
}
|
||||
|
||||
/* test loss of first 513 packets */
|
||||
for (idx=0; idx < num_trials; idx++) {
|
||||
err = rdb_check_add(&rdb, idx + 513);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
|
||||
/* test for false positives */
|
||||
for (idx=0; idx < num_trials + 513; idx++) {
|
||||
err = rdb_check_expect_failure(&rdb, idx);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
return err_status_ok;
|
||||
}
|
||||
|
||||
#include <time.h> /* for clock() */
|
||||
|
|
Binary file not shown.
|
@ -9,7 +9,7 @@
|
|||
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2001-2005, Cisco Systems, Inc.
|
||||
* Copyright (c) 2001-2006, Cisco Systems, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -138,6 +138,12 @@ roc_test(int num_trials) {
|
|||
ref, local, est, ircvd, delta);
|
||||
#endif
|
||||
|
||||
if (local + delta != est) {
|
||||
printf(" *bad delta*: local %llu + delta %d != est %llu\n",
|
||||
(unsigned long long)local, delta, (unsigned long long)est);
|
||||
return err_status_algo_fail;
|
||||
}
|
||||
|
||||
/* now update local xtd_seq_num_t as necessary */
|
||||
if (delta > 0)
|
||||
index_advance(&local, delta);
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
*/
|
||||
|
||||
|
||||
#include "rtp.h"
|
||||
#include "rtp_priv.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
@ -21,11 +21,11 @@
|
|||
#define PRINT_DEBUG 0 /* set to 1 to print out debugging data */
|
||||
#define VERBOSE_DEBUG 0 /* set to 1 to print out more data */
|
||||
|
||||
ssize_t
|
||||
rtp_sendto(rtp_sender_t *sender, const void* msg, int len) {
|
||||
int
|
||||
rtp_sendto(rtp_sender_t sender, const void* msg, int len) {
|
||||
int octets_sent;
|
||||
err_status_t stat;
|
||||
int pkt_len = len + rtp_header_len;
|
||||
int pkt_len = len + RTP_HEADER_LEN;
|
||||
|
||||
/* marshal data */
|
||||
strncpy(sender->message.body, msg, len);
|
||||
|
@ -61,14 +61,19 @@ rtp_sendto(rtp_sender_t *sender, const void* msg, int len) {
|
|||
return octets_sent;
|
||||
}
|
||||
|
||||
ssize_t
|
||||
rtp_recvfrom(rtp_receiver_t *receiver, void *msg, int *len) {
|
||||
int
|
||||
rtp_recvfrom(rtp_receiver_t receiver, void *msg, int *len) {
|
||||
int octets_recvd;
|
||||
err_status_t stat;
|
||||
|
||||
octets_recvd = recvfrom(receiver->socket, (void *)&receiver->message,
|
||||
*len, 0, (struct sockaddr *) NULL, 0);
|
||||
|
||||
if (octets_recvd == -1) {
|
||||
*len = 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* verify rtp header */
|
||||
if (receiver->message.header.version != 2) {
|
||||
*len = 0;
|
||||
|
@ -99,10 +104,10 @@ rtp_recvfrom(rtp_receiver_t *receiver, void *msg, int *len) {
|
|||
}
|
||||
|
||||
int
|
||||
rtp_sender_init(rtp_sender_t *sender,
|
||||
int socket,
|
||||
rtp_sender_init(rtp_sender_t sender,
|
||||
int sock,
|
||||
struct sockaddr_in addr,
|
||||
uint32_t ssrc) {
|
||||
unsigned int ssrc) {
|
||||
|
||||
/* set header values */
|
||||
sender->message.header.ssrc = htonl(ssrc);
|
||||
|
@ -116,17 +121,17 @@ rtp_sender_init(rtp_sender_t *sender,
|
|||
sender->message.header.cc = 0;
|
||||
|
||||
/* set other stuff */
|
||||
sender->socket = socket;
|
||||
sender->socket = sock;
|
||||
sender->addr = addr;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
rtp_receiver_init(rtp_receiver_t *rcvr,
|
||||
int socket,
|
||||
rtp_receiver_init(rtp_receiver_t rcvr,
|
||||
int sock,
|
||||
struct sockaddr_in addr,
|
||||
uint32_t ssrc) {
|
||||
unsigned int ssrc) {
|
||||
|
||||
/* set header values */
|
||||
rcvr->message.header.ssrc = htonl(ssrc);
|
||||
|
@ -140,11 +145,48 @@ rtp_receiver_init(rtp_receiver_t *rcvr,
|
|||
rcvr->message.header.cc = 0;
|
||||
|
||||
/* set other stuff */
|
||||
rcvr->socket = socket;
|
||||
rcvr->socket = sock;
|
||||
rcvr->addr = addr;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
rtp_sender_init_srtp(rtp_sender_t sender, const srtp_policy_t *policy) {
|
||||
return srtp_create(&sender->srtp_ctx, policy);
|
||||
}
|
||||
|
||||
int
|
||||
rtp_sender_deinit_srtp(rtp_sender_t sender) {
|
||||
return srtp_dealloc(sender->srtp_ctx);
|
||||
}
|
||||
|
||||
int
|
||||
rtp_receiver_init_srtp(rtp_receiver_t sender, const srtp_policy_t *policy) {
|
||||
return srtp_create(&sender->srtp_ctx, policy);
|
||||
}
|
||||
|
||||
int
|
||||
rtp_receiver_deinit_srtp(rtp_receiver_t sender) {
|
||||
return srtp_dealloc(sender->srtp_ctx);
|
||||
}
|
||||
|
||||
rtp_sender_t
|
||||
rtp_sender_alloc(void) {
|
||||
return (rtp_sender_t)malloc(sizeof(rtp_sender_ctx_t));
|
||||
}
|
||||
|
||||
void
|
||||
rtp_sender_dealloc(rtp_sender_t rtp_ctx) {
|
||||
free(rtp_ctx);
|
||||
}
|
||||
|
||||
rtp_receiver_t
|
||||
rtp_receiver_alloc(void) {
|
||||
return (rtp_receiver_t)malloc(sizeof(rtp_receiver_ctx_t));
|
||||
}
|
||||
|
||||
void
|
||||
rtp_receiver_dealloc(rtp_receiver_t rtp_ctx) {
|
||||
return free(rtp_ctx);
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2001-2005, Cisco Systems, Inc.
|
||||
* Copyright (c) 2001-2006, Cisco Systems, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -52,13 +52,19 @@
|
|||
|
||||
|
||||
#include "datatypes.h"
|
||||
#include "getopt_s.h" /* for local getopt() */
|
||||
|
||||
#include <stdio.h> /* for printf, fprintf */
|
||||
#include <stdlib.h> /* for atoi() */
|
||||
#include <errno.h>
|
||||
#include <unistd.h> /* for close() */
|
||||
#include <signal.h> /* for signal() */
|
||||
|
||||
#include <string.h> /* for strncpy() */
|
||||
#include <time.h> /* for usleep() */
|
||||
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h> /* for close() */
|
||||
#endif
|
||||
#ifdef HAVE_SYS_SOCKET_H
|
||||
# include <sys/socket.h>
|
||||
#endif
|
||||
|
@ -113,6 +119,18 @@ void
|
|||
leave_group(int sock, struct ip_mreq mreq, char *name);
|
||||
|
||||
|
||||
/*
|
||||
* setup_signal_handler() sets up a signal handler to trigger
|
||||
* cleanups after an interrupt
|
||||
*/
|
||||
int setup_signal_handler(char* name);
|
||||
|
||||
/*
|
||||
* handle_signal(...) handles interrupt signal to trigger cleanups
|
||||
*/
|
||||
|
||||
volatile int interrupted = 0;
|
||||
|
||||
/*
|
||||
* program_type distinguishes the [s]rtp sender and receiver cases
|
||||
*/
|
||||
|
@ -156,6 +174,10 @@ main (int argc, char *argv[]) {
|
|||
}
|
||||
#endif
|
||||
|
||||
if (setup_signal_handler(argv[0]) != 0) {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* initialize srtp library */
|
||||
status = srtp_init();
|
||||
if (status) {
|
||||
|
@ -165,13 +187,13 @@ main (int argc, char *argv[]) {
|
|||
|
||||
/* check args */
|
||||
while (1) {
|
||||
c = getopt(argc, argv, "k:rsaeld:");
|
||||
c = getopt_s(argc, argv, "k:rsaeld:");
|
||||
if (c == -1) {
|
||||
break;
|
||||
}
|
||||
switch (c) {
|
||||
case 'k':
|
||||
input_key = optarg;
|
||||
input_key = optarg_s;
|
||||
break;
|
||||
case 'e':
|
||||
sec_servs |= sec_serv_conf;
|
||||
|
@ -186,9 +208,9 @@ main (int argc, char *argv[]) {
|
|||
prog_type = sender;
|
||||
break;
|
||||
case 'd':
|
||||
status = crypto_kernel_set_debug_module(optarg, 1);
|
||||
status = crypto_kernel_set_debug_module(optarg_s, 1);
|
||||
if (status) {
|
||||
printf("error: set debug module (%s) failed\n", optarg);
|
||||
printf("error: set debug module (%s) failed\n", optarg_s);
|
||||
exit(1);
|
||||
}
|
||||
break;
|
||||
|
@ -222,16 +244,16 @@ main (int argc, char *argv[]) {
|
|||
usage(argv[0]);
|
||||
}
|
||||
|
||||
if (argc != optind + 2) {
|
||||
if (argc != optind_s + 2) {
|
||||
/* wrong number of arguments */
|
||||
usage(argv[0]);
|
||||
}
|
||||
|
||||
/* get address from arg */
|
||||
address = argv[optind++];
|
||||
address = argv[optind_s++];
|
||||
|
||||
/* get port from arg */
|
||||
port = atoi(argv[optind++]);
|
||||
port = atoi(argv[optind_s++]);
|
||||
|
||||
/* set address */
|
||||
#ifdef HAVE_INET_ATON
|
||||
|
@ -327,7 +349,10 @@ main (int argc, char *argv[]) {
|
|||
policy.ssrc.type = ssrc_specific;
|
||||
policy.ssrc.value = ssrc;
|
||||
policy.key = (uint8_t *) key;
|
||||
policy.ekt = NULL;
|
||||
policy.next = NULL;
|
||||
policy.window_size = 128;
|
||||
policy.allow_repeat_tx = 0;
|
||||
policy.rtp.sec_serv = sec_servs;
|
||||
policy.rtcp.sec_serv = sec_serv_none; /* we don't do RTCP anyway */
|
||||
|
||||
|
@ -380,6 +405,9 @@ main (int argc, char *argv[]) {
|
|||
policy.rtcp.auth_key_len = 0;
|
||||
policy.rtcp.auth_tag_len = 0;
|
||||
policy.rtcp.sec_serv = sec_serv_none;
|
||||
policy.window_size = 0;
|
||||
policy.allow_repeat_tx = 0;
|
||||
policy.ekt = NULL;
|
||||
policy.next = NULL;
|
||||
}
|
||||
|
||||
|
@ -399,8 +427,13 @@ main (int argc, char *argv[]) {
|
|||
#endif /* BEW */
|
||||
|
||||
/* initialize sender's rtp and srtp contexts */
|
||||
rtp_sender_init(&snd, sock, name, ssrc);
|
||||
status = srtp_create(&snd.srtp_ctx, &policy);
|
||||
snd = rtp_sender_alloc();
|
||||
if (snd == NULL) {
|
||||
fprintf(stderr, "error: malloc() failed\n");
|
||||
exit(1);
|
||||
}
|
||||
rtp_sender_init(snd, sock, name, ssrc);
|
||||
status = rtp_sender_init_srtp(snd, &policy);
|
||||
if (status) {
|
||||
fprintf(stderr,
|
||||
"error: srtp_create() failed with code %d\n",
|
||||
|
@ -419,18 +452,22 @@ main (int argc, char *argv[]) {
|
|||
}
|
||||
|
||||
/* read words from dictionary, then send them off */
|
||||
while (fgets(word, MAX_WORD_LEN, dict) != NULL) {
|
||||
while (!interrupted && fgets(word, MAX_WORD_LEN, dict) != NULL) {
|
||||
len = strlen(word) + 1; /* plus one for null */
|
||||
|
||||
if (len > MAX_WORD_LEN)
|
||||
printf("error: word %s too large to send\n", word);
|
||||
else {
|
||||
rtp_sendto(&snd, word, len);
|
||||
rtp_sendto(snd, word, len);
|
||||
printf("sending word: %s", word);
|
||||
}
|
||||
usleep(USEC_RATE);
|
||||
}
|
||||
|
||||
rtp_sender_deinit_srtp(snd);
|
||||
rtp_sender_dealloc(snd);
|
||||
|
||||
fclose(dict);
|
||||
} else { /* prog_type == receiver */
|
||||
rtp_receiver_t rcvr;
|
||||
|
||||
|
@ -444,8 +481,13 @@ main (int argc, char *argv[]) {
|
|||
exit(1);
|
||||
}
|
||||
|
||||
rtp_receiver_init(&rcvr, sock, name, ssrc);
|
||||
status = srtp_create(&rcvr.srtp_ctx, &policy);
|
||||
rcvr = rtp_receiver_alloc();
|
||||
if (rcvr == NULL) {
|
||||
fprintf(stderr, "error: malloc() failed\n");
|
||||
exit(1);
|
||||
}
|
||||
rtp_receiver_init(rcvr, sock, name, ssrc);
|
||||
status = rtp_receiver_init_srtp(rcvr, &policy);
|
||||
if (status) {
|
||||
fprintf(stderr,
|
||||
"error: srtp_create() failed with code %d\n",
|
||||
|
@ -454,18 +496,36 @@ main (int argc, char *argv[]) {
|
|||
}
|
||||
|
||||
/* get next word and loop */
|
||||
while (1) {
|
||||
while (!interrupted) {
|
||||
len = MAX_WORD_LEN;
|
||||
if (rtp_recvfrom(&rcvr, word, &len) > -1)
|
||||
printf("\tword: %s", word);
|
||||
if (rtp_recvfrom(rcvr, word, &len) > -1)
|
||||
printf("\tword: %s\n", word);
|
||||
}
|
||||
|
||||
rtp_receiver_deinit_srtp(rcvr);
|
||||
rtp_receiver_dealloc(rcvr);
|
||||
}
|
||||
|
||||
if (ADDR_IS_MULTICAST(rcvr_addr.s_addr)) {
|
||||
leave_group(sock, mreq, argv[0]);
|
||||
}
|
||||
|
||||
#ifdef RTPW_USE_WINSOCK2
|
||||
ret = closesocket(sock);
|
||||
#else
|
||||
ret = close(sock);
|
||||
#endif
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "%s: Failed to close socket", argv[0]);
|
||||
perror("");
|
||||
}
|
||||
|
||||
status = srtp_shutdown();
|
||||
if (status) {
|
||||
printf("error: srtp shutdown failed with error code %d\n", status);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
#ifdef RTPW_USE_WINSOCK2
|
||||
WSACleanup();
|
||||
#endif
|
||||
|
@ -505,3 +565,41 @@ leave_group(int sock, struct ip_mreq mreq, char *name) {
|
|||
}
|
||||
}
|
||||
|
||||
void handle_signal(int signum)
|
||||
{
|
||||
interrupted = 1;
|
||||
/* Reset handler explicitly, in case we don't have sigaction() (and signal()
|
||||
has BSD semantics), or we don't have SA_RESETHAND */
|
||||
signal(signum, SIG_DFL);
|
||||
}
|
||||
|
||||
int setup_signal_handler(char* name)
|
||||
{
|
||||
#if HAVE_SIGACTION
|
||||
struct sigaction act;
|
||||
memset(&act, 0, sizeof(act));
|
||||
|
||||
act.sa_handler = handle_signal;
|
||||
sigemptyset(&act.sa_mask);
|
||||
#if defined(SA_RESETHAND)
|
||||
act.sa_flags = SA_RESETHAND;
|
||||
#else
|
||||
act.sa_flags = 0;
|
||||
#endif
|
||||
/* Note that we're not setting SA_RESTART; we want recvfrom to return
|
||||
* EINTR when we signal the receiver. */
|
||||
|
||||
if (sigaction(SIGTERM, &act, NULL) != 0) {
|
||||
fprintf(stderr, "%s: error setting up signal handler", name);
|
||||
perror("");
|
||||
return -1;
|
||||
}
|
||||
#else
|
||||
if (signal(SIGTERM, handle_signal) == SIG_ERR) {
|
||||
fprintf(stderr, "%s: error setting up signal handler", name);
|
||||
perror("");
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,80 @@
|
|||
#!/bin/sh
|
||||
#
|
||||
# usage: rtpw_test <rtpw_commands>
|
||||
#
|
||||
# tests the rtpw sender and receiver functions
|
||||
|
||||
RTPW=./rtpw
|
||||
DEST_PORT=9999
|
||||
DURATION=3
|
||||
|
||||
key=2b2edc5034f61a72345ca5986d7bfd0189aa6dc2ecab32fd9af74df6dfc6
|
||||
|
||||
ARGS="-k $key -ae"
|
||||
|
||||
# First, we run "killall" to get rid of all existing rtpw processes.
|
||||
# This step also enables this script to clean up after itself; if this
|
||||
# script is interrupted after the rtpw processes are started but before
|
||||
# they are killed, those processes will linger. Re-running the script
|
||||
# will get rid of them.
|
||||
|
||||
killall rtpw 2>/dev/null
|
||||
|
||||
if test -x $RTPW; then
|
||||
|
||||
echo $0 ": starting rtpw receiver process... "
|
||||
|
||||
$RTPW $* $ARGS -r 0.0.0.0 $DEST_PORT &
|
||||
|
||||
receiver_pid=$!
|
||||
|
||||
echo $0 ": receiver PID = $receiver_pid"
|
||||
|
||||
sleep 1
|
||||
|
||||
# verify that the background job is running
|
||||
ps | grep -q $receiver_pid
|
||||
retval=$?
|
||||
echo $retval
|
||||
if [ $retval != 0 ]; then
|
||||
echo $0 ": error"
|
||||
exit 254
|
||||
fi
|
||||
|
||||
echo $0 ": starting rtpw sender process..."
|
||||
|
||||
$RTPW $* $ARGS -s 127.0.0.1 $DEST_PORT &
|
||||
|
||||
sender_pid=$!
|
||||
|
||||
echo $0 ": sender PID = $sender_pid"
|
||||
|
||||
# verify that the background job is running
|
||||
ps | grep -q $sender_pid
|
||||
retval=$?
|
||||
echo $retval
|
||||
if [ $retval != 0 ]; then
|
||||
echo $0 ": error"
|
||||
exit 255
|
||||
fi
|
||||
|
||||
sleep $DURATION
|
||||
|
||||
kill $receiver_pid
|
||||
kill $sender_pid
|
||||
|
||||
wait $receiver_pid
|
||||
wait $sender_pid
|
||||
|
||||
echo $0 ": done (test passed)"
|
||||
|
||||
else
|
||||
|
||||
echo "error: can't find executable" $RTPW
|
||||
exit 1
|
||||
|
||||
fi
|
||||
|
||||
# EOF
|
||||
|
||||
|
|
@ -8,7 +8,7 @@
|
|||
*/
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2001-2005, Cisco Systems, Inc.
|
||||
* Copyright (c) 2001-2006, Cisco Systems, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -47,9 +47,9 @@
|
|||
#include <time.h> /* for clock() */
|
||||
#include <stdlib.h> /* for malloc(), free() */
|
||||
#include <stdio.h> /* for print(), fflush() */
|
||||
#include <unistd.h> /* for getopt() */
|
||||
#include "getopt_s.h" /* for local getopt() */
|
||||
|
||||
#include "srtp.h"
|
||||
#include "srtp_priv.h"
|
||||
|
||||
#ifdef HAVE_NETINET_IN_H
|
||||
# include <netinet/in.h>
|
||||
|
@ -62,9 +62,15 @@
|
|||
err_status_t
|
||||
srtp_validate(void);
|
||||
|
||||
err_status_t
|
||||
srtp_validate_aes_256(void);
|
||||
|
||||
err_status_t
|
||||
srtp_create_big_policy(srtp_policy_t **list);
|
||||
|
||||
err_status_t
|
||||
srtp_dealloc_big_policy(srtp_policy_t *list);
|
||||
|
||||
err_status_t
|
||||
srtp_test_remove_stream(void);
|
||||
|
||||
|
@ -83,6 +89,9 @@ srtp_do_rejection_timing(const srtp_policy_t *policy);
|
|||
err_status_t
|
||||
srtp_test(const srtp_policy_t *policy);
|
||||
|
||||
err_status_t
|
||||
srtcp_test(const srtp_policy_t *policy);
|
||||
|
||||
err_status_t
|
||||
srtp_session_print_policy(srtp_t srtp);
|
||||
|
||||
|
@ -135,7 +144,7 @@ debug_module_t mod_driver = {
|
|||
|
||||
int
|
||||
main (int argc, char *argv[]) {
|
||||
char q;
|
||||
int q;
|
||||
unsigned do_timing_test = 0;
|
||||
unsigned do_rejection_test = 0;
|
||||
unsigned do_codec_timing = 0;
|
||||
|
@ -148,7 +157,9 @@ main (int argc, char *argv[]) {
|
|||
* structure srtp_hdr_t correctly
|
||||
*/
|
||||
if (sizeof(srtp_hdr_t) != 12) {
|
||||
printf("error: srtp_hdr_t has incorrect size\n");
|
||||
printf("error: srtp_hdr_t has incorrect size"
|
||||
"(size is %ld bytes, expected 12)\n",
|
||||
(long)sizeof(srtp_hdr_t));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
@ -169,7 +180,7 @@ main (int argc, char *argv[]) {
|
|||
|
||||
/* process input arguments */
|
||||
while (1) {
|
||||
q = getopt(argc, argv, "trcvld:");
|
||||
q = getopt_s(argc, argv, "trcvld:");
|
||||
if (q == -1)
|
||||
break;
|
||||
switch (q) {
|
||||
|
@ -189,9 +200,9 @@ main (int argc, char *argv[]) {
|
|||
do_list_mods = 1;
|
||||
break;
|
||||
case 'd':
|
||||
status = crypto_kernel_set_debug_module(optarg, 1);
|
||||
status = crypto_kernel_set_debug_module(optarg_s, 1);
|
||||
if (status) {
|
||||
printf("error: set debug module (%s) failed\n", optarg);
|
||||
printf("error: set debug module (%s) failed\n", optarg_s);
|
||||
exit(1);
|
||||
}
|
||||
break;
|
||||
|
@ -216,7 +227,7 @@ main (int argc, char *argv[]) {
|
|||
const srtp_policy_t **policy = policy_array;
|
||||
srtp_policy_t *big_policy;
|
||||
|
||||
/* loop over policy array, testing srtp for each policy */
|
||||
/* loop over policy array, testing srtp and srtcp for each policy */
|
||||
while (*policy != NULL) {
|
||||
printf("testing srtp_protect and srtp_unprotect\n");
|
||||
if (srtp_test(*policy) == err_status_ok)
|
||||
|
@ -225,6 +236,13 @@ main (int argc, char *argv[]) {
|
|||
printf("failed\n");
|
||||
exit(1);
|
||||
}
|
||||
printf("testing srtp_protect_rtcp and srtp_unprotect_rtcp\n");
|
||||
if (srtcp_test(*policy) == err_status_ok)
|
||||
printf("passed\n\n");
|
||||
else {
|
||||
printf("failed\n");
|
||||
exit(1);
|
||||
}
|
||||
policy++;
|
||||
}
|
||||
|
||||
|
@ -241,6 +259,11 @@ main (int argc, char *argv[]) {
|
|||
printf("failed\n");
|
||||
exit(1);
|
||||
}
|
||||
status = srtp_dealloc_big_policy(big_policy);
|
||||
if (status) {
|
||||
printf("unexpected failure with error code %d\n", status);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* run test on wildcard policy */
|
||||
printf("testing srtp_protect and srtp_unprotect on "
|
||||
|
@ -265,6 +288,19 @@ main (int argc, char *argv[]) {
|
|||
exit(1);
|
||||
}
|
||||
|
||||
/*
|
||||
* run validation test against the reference packets for
|
||||
* AES-256
|
||||
*/
|
||||
printf("testing srtp_protect and srtp_unprotect against "
|
||||
"reference packets (AES-256)\n");
|
||||
if (srtp_validate_aes_256() == err_status_ok)
|
||||
printf("passed\n\n");
|
||||
else {
|
||||
printf("failed\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/*
|
||||
* test the function srtp_remove_stream()
|
||||
*/
|
||||
|
@ -309,6 +345,9 @@ main (int argc, char *argv[]) {
|
|||
policy.ssrc.type = ssrc_specific;
|
||||
policy.ssrc.value = 0xdecafbad;
|
||||
policy.key = test_key;
|
||||
policy.ekt = NULL;
|
||||
policy.window_size = 128;
|
||||
policy.allow_repeat_tx = 0;
|
||||
policy.next = NULL;
|
||||
|
||||
printf("mips estimate: %e\n", mips);
|
||||
|
@ -333,6 +372,18 @@ main (int argc, char *argv[]) {
|
|||
printf("G.729\t\t%d\t\t\t%e\n", 20,
|
||||
(double) mips * (20 * 8) /
|
||||
srtp_bits_per_second(20, &policy) / .02 );
|
||||
printf("Wideband\t%d\t\t\t%e\n", 320,
|
||||
(double) mips * (320 * 8) /
|
||||
srtp_bits_per_second(320, &policy) / .01 );
|
||||
printf("Wideband\t%d\t\t\t%e\n", 640,
|
||||
(double) mips * (640 * 8) /
|
||||
srtp_bits_per_second(640, &policy) / .02 );
|
||||
}
|
||||
|
||||
status = srtp_shutdown();
|
||||
if (status) {
|
||||
printf("error: srtp shutdown failed with error code %d\n", status);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -361,7 +412,7 @@ srtp_create_test_packet(int pkt_octet_len, uint32_t ssrc) {
|
|||
int bytes_in_hdr = 12;
|
||||
|
||||
/* allocate memory for test packet */
|
||||
hdr = malloc(pkt_octet_len + bytes_in_hdr
|
||||
hdr = (srtp_hdr_t*) malloc(pkt_octet_len + bytes_in_hdr
|
||||
+ SRTP_MAX_TRAILER_LEN + 4);
|
||||
if (!hdr)
|
||||
return NULL;
|
||||
|
@ -474,7 +525,6 @@ srtp_bits_per_second(int msg_len_octets, const srtp_policy_t *policy) {
|
|||
|
||||
timer = clock();
|
||||
for (i=0; i < num_trials; i++) {
|
||||
err_status_t status;
|
||||
len = msg_len_octets + 12; /* add in rtp header length */
|
||||
|
||||
/* srtp protect message */
|
||||
|
@ -485,13 +535,22 @@ srtp_bits_per_second(int msg_len_octets, const srtp_policy_t *policy) {
|
|||
}
|
||||
|
||||
/* increment message number */
|
||||
mesg->seq = htons(ntohs(mesg->seq) + 1);
|
||||
|
||||
{
|
||||
/* hack sequence to avoid problems with macros for htons/ntohs on some systems */
|
||||
short new_seq = ntohs(mesg->seq) + 1;
|
||||
mesg->seq = htons(new_seq);
|
||||
}
|
||||
}
|
||||
timer = clock() - timer;
|
||||
|
||||
free(mesg);
|
||||
|
||||
status = srtp_dealloc(srtp);
|
||||
if (status) {
|
||||
printf("error: srtp_dealloc() failed with error code %d\n", status);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
return (double) (msg_len_octets) * 8 *
|
||||
num_trials * CLOCKS_PER_SEC / timer;
|
||||
}
|
||||
|
@ -532,6 +591,12 @@ srtp_rejections_per_second(int msg_len_octets, const srtp_policy_t *policy) {
|
|||
|
||||
free(mesg);
|
||||
|
||||
status = srtp_dealloc(srtp);
|
||||
if (status) {
|
||||
printf("error: srtp_dealloc() failed with error code %d\n", status);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
return (double) num_trials * CLOCKS_PER_SEC / timer;
|
||||
}
|
||||
|
||||
|
@ -659,9 +724,12 @@ srtp_test(const srtp_policy_t *policy) {
|
|||
* we always copy the policy into the rcvr_policy, since otherwise
|
||||
* the compiler would fret about the constness of the policy
|
||||
*/
|
||||
rcvr_policy = malloc(sizeof(srtp_policy_t));
|
||||
if (rcvr_policy == NULL)
|
||||
rcvr_policy = (srtp_policy_t*) malloc(sizeof(srtp_policy_t));
|
||||
if (rcvr_policy == NULL) {
|
||||
free(hdr);
|
||||
free(hdr2);
|
||||
return err_status_alloc_fail;
|
||||
}
|
||||
memcpy(rcvr_policy, policy, sizeof(srtp_policy_t));
|
||||
if (policy->ssrc.type == ssrc_any_outbound) {
|
||||
rcvr_policy->ssrc.type = ssrc_any_inbound;
|
||||
|
@ -683,6 +751,7 @@ srtp_test(const srtp_policy_t *policy) {
|
|||
if (status) {
|
||||
free(hdr);
|
||||
free(hdr2);
|
||||
free(rcvr_policy);
|
||||
return status;
|
||||
}
|
||||
|
||||
|
@ -703,6 +772,7 @@ srtp_test(const srtp_policy_t *policy) {
|
|||
printf("failed with error code %d\n", status);
|
||||
free(hdr);
|
||||
free(hdr2);
|
||||
free(rcvr_policy);
|
||||
return status;
|
||||
} else {
|
||||
printf("passed\n");
|
||||
|
@ -728,6 +798,7 @@ srtp_test(const srtp_policy_t *policy) {
|
|||
printf("failed\n");
|
||||
free(hdr);
|
||||
free(hdr2);
|
||||
free(rcvr_policy);
|
||||
return status;
|
||||
} else {
|
||||
printf("passed\n");
|
||||
|
@ -740,6 +811,210 @@ srtp_test(const srtp_policy_t *policy) {
|
|||
|
||||
free(hdr);
|
||||
free(hdr2);
|
||||
free(rcvr_policy);
|
||||
return err_status_ok;
|
||||
}
|
||||
|
||||
|
||||
err_status_t
|
||||
srtcp_test(const srtp_policy_t *policy) {
|
||||
int i;
|
||||
srtp_t srtcp_sender;
|
||||
srtp_t srtcp_rcvr;
|
||||
err_status_t status = err_status_ok;
|
||||
srtp_hdr_t *hdr, *hdr2;
|
||||
uint8_t hdr_enc[64];
|
||||
uint8_t *pkt_end;
|
||||
int msg_len_octets, msg_len_enc;
|
||||
int len;
|
||||
int tag_length = policy->rtp.auth_tag_len;
|
||||
uint32_t ssrc;
|
||||
srtp_policy_t *rcvr_policy;
|
||||
|
||||
err_check(srtp_create(&srtcp_sender, policy));
|
||||
|
||||
/* print out policy */
|
||||
err_check(srtp_session_print_policy(srtcp_sender));
|
||||
|
||||
/*
|
||||
* initialize data buffer, using the ssrc in the policy unless that
|
||||
* value is a wildcard, in which case we'll just use an arbitrary
|
||||
* one
|
||||
*/
|
||||
if (policy->ssrc.type != ssrc_specific)
|
||||
ssrc = 0xdecafbad;
|
||||
else
|
||||
ssrc = policy->ssrc.value;
|
||||
msg_len_octets = 28;
|
||||
hdr = srtp_create_test_packet(msg_len_octets, ssrc);
|
||||
|
||||
if (hdr == NULL)
|
||||
return err_status_alloc_fail;
|
||||
hdr2 = srtp_create_test_packet(msg_len_octets, ssrc);
|
||||
if (hdr2 == NULL) {
|
||||
free(hdr);
|
||||
return err_status_alloc_fail;
|
||||
}
|
||||
|
||||
/* set message length */
|
||||
len = msg_len_octets;
|
||||
|
||||
debug_print(mod_driver, "before protection:\n%s",
|
||||
srtp_packet_to_string(hdr, len));
|
||||
|
||||
#if PRINT_REFERENCE_PACKET
|
||||
debug_print(mod_driver, "reference packet before protection:\n%s",
|
||||
octet_string_hex_string((uint8_t *)hdr, len));
|
||||
#endif
|
||||
err_check(srtp_protect_rtcp(srtcp_sender, hdr, &len));
|
||||
|
||||
debug_print(mod_driver, "after protection:\n%s",
|
||||
srtp_packet_to_string(hdr, len));
|
||||
#if PRINT_REFERENCE_PACKET
|
||||
debug_print(mod_driver, "after protection:\n%s",
|
||||
octet_string_hex_string((uint8_t *)hdr, len));
|
||||
#endif
|
||||
|
||||
/* save protected message and length */
|
||||
memcpy(hdr_enc, hdr, len);
|
||||
msg_len_enc = len;
|
||||
|
||||
/*
|
||||
* check for overrun of the srtp_protect() function
|
||||
*
|
||||
* The packet is followed by a value of 0xfffff; if the value of the
|
||||
* data following the packet is different, then we know that the
|
||||
* protect function is overwriting the end of the packet.
|
||||
*/
|
||||
pkt_end = (uint8_t *)hdr + sizeof(srtp_hdr_t)
|
||||
+ msg_len_octets + tag_length;
|
||||
for (i = 0; i < 4; i++)
|
||||
if (pkt_end[i] != 0xff) {
|
||||
fprintf(stdout, "overwrite in srtp_protect_rtcp() function "
|
||||
"(expected %x, found %x in trailing octet %d)\n",
|
||||
0xff, ((uint8_t *)hdr)[i], i);
|
||||
free(hdr);
|
||||
free(hdr2);
|
||||
return err_status_algo_fail;
|
||||
}
|
||||
|
||||
/*
|
||||
* if the policy includes confidentiality, check that ciphertext is
|
||||
* different than plaintext
|
||||
*
|
||||
* Note that this check will give false negatives, with some small
|
||||
* probability, especially if the packets are short. For that
|
||||
* reason, we skip this check if the plaintext is less than four
|
||||
* octets long.
|
||||
*/
|
||||
if ((policy->rtp.sec_serv & sec_serv_conf) && (msg_len_octets >= 4)) {
|
||||
printf("testing that ciphertext is distinct from plaintext...");
|
||||
status = err_status_algo_fail;
|
||||
for (i=12; i < msg_len_octets+12; i++)
|
||||
if (((uint8_t *)hdr)[i] != ((uint8_t *)hdr2)[i]) {
|
||||
status = err_status_ok;
|
||||
}
|
||||
if (status) {
|
||||
printf("failed\n");
|
||||
free(hdr);
|
||||
free(hdr2);
|
||||
return status;
|
||||
}
|
||||
printf("passed\n");
|
||||
}
|
||||
|
||||
/*
|
||||
* if the policy uses a 'wildcard' ssrc, then we need to make a copy
|
||||
* of the policy that changes the direction to inbound
|
||||
*
|
||||
* we always copy the policy into the rcvr_policy, since otherwise
|
||||
* the compiler would fret about the constness of the policy
|
||||
*/
|
||||
rcvr_policy = (srtp_policy_t*) malloc(sizeof(srtp_policy_t));
|
||||
if (rcvr_policy == NULL)
|
||||
return err_status_alloc_fail;
|
||||
memcpy(rcvr_policy, policy, sizeof(srtp_policy_t));
|
||||
if (policy->ssrc.type == ssrc_any_outbound) {
|
||||
rcvr_policy->ssrc.type = ssrc_any_inbound;
|
||||
}
|
||||
|
||||
err_check(srtp_create(&srtcp_rcvr, rcvr_policy));
|
||||
|
||||
err_check(srtp_unprotect_rtcp(srtcp_rcvr, hdr, &len));
|
||||
|
||||
debug_print(mod_driver, "after unprotection:\n%s",
|
||||
srtp_packet_to_string(hdr, len));
|
||||
|
||||
/* verify that the unprotected packet matches the origial one */
|
||||
for (i=0; i < msg_len_octets; i++)
|
||||
if (((uint8_t *)hdr)[i] != ((uint8_t *)hdr2)[i]) {
|
||||
fprintf(stdout, "mismatch at octet %d\n", i);
|
||||
status = err_status_algo_fail;
|
||||
}
|
||||
if (status) {
|
||||
free(hdr);
|
||||
free(hdr2);
|
||||
free(rcvr_policy);
|
||||
return status;
|
||||
}
|
||||
|
||||
/*
|
||||
* if the policy includes authentication, then test for false positives
|
||||
*/
|
||||
if (policy->rtp.sec_serv & sec_serv_auth) {
|
||||
char *data = ((char *)hdr) + 12;
|
||||
|
||||
printf("testing for false positives in replay check...");
|
||||
|
||||
/* set message length */
|
||||
len = msg_len_enc;
|
||||
|
||||
/* unprotect a second time - should fail with a replay error */
|
||||
status = srtp_unprotect_rtcp(srtcp_rcvr, hdr_enc, &len);
|
||||
if (status != err_status_replay_fail) {
|
||||
printf("failed with error code %d\n", status);
|
||||
free(hdr);
|
||||
free(hdr2);
|
||||
free(rcvr_policy);
|
||||
return status;
|
||||
} else {
|
||||
printf("passed\n");
|
||||
}
|
||||
|
||||
printf("testing for false positives in auth check...");
|
||||
|
||||
/* increment sequence number in header */
|
||||
hdr->seq++;
|
||||
|
||||
/* set message length */
|
||||
len = msg_len_octets;
|
||||
|
||||
/* apply protection */
|
||||
err_check(srtp_protect_rtcp(srtcp_sender, hdr, &len));
|
||||
|
||||
/* flip bits in packet */
|
||||
data[0] ^= 0xff;
|
||||
|
||||
/* unprotect, and check for authentication failure */
|
||||
status = srtp_unprotect_rtcp(srtcp_rcvr, hdr, &len);
|
||||
if (status != err_status_auth_fail) {
|
||||
printf("failed\n");
|
||||
free(hdr);
|
||||
free(hdr2);
|
||||
free(rcvr_policy);
|
||||
return status;
|
||||
} else {
|
||||
printf("passed\n");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
err_check(srtp_dealloc(srtcp_sender));
|
||||
err_check(srtp_dealloc(srtcp_rcvr));
|
||||
|
||||
free(hdr);
|
||||
free(hdr2);
|
||||
free(rcvr_policy);
|
||||
return err_status_ok;
|
||||
}
|
||||
|
||||
|
@ -772,14 +1047,18 @@ srtp_session_print_policy(srtp_t srtp) {
|
|||
"# rtp services: %s\r\n"
|
||||
"# rtcp cipher: %s\r\n"
|
||||
"# rtcp auth: %s\r\n"
|
||||
"# rtcp services: %s\r\n",
|
||||
"# rtcp services: %s\r\n"
|
||||
"# window size: %lu\r\n"
|
||||
"# tx rtx allowed:%s\r\n",
|
||||
direction[stream->direction],
|
||||
stream->rtp_cipher->type->description,
|
||||
stream->rtp_auth->type->description,
|
||||
serv_descr[stream->rtp_services],
|
||||
stream->rtcp_cipher->type->description,
|
||||
stream->rtcp_auth->type->description,
|
||||
serv_descr[stream->rtcp_services]);
|
||||
serv_descr[stream->rtcp_services],
|
||||
rdbx_get_window_size(&stream->rtp_rdbx),
|
||||
stream->allow_repeat_tx ? "true" : "false");
|
||||
}
|
||||
|
||||
/* loop over streams in session, printing the policy of each */
|
||||
|
@ -794,14 +1073,18 @@ srtp_session_print_policy(srtp_t srtp) {
|
|||
"# rtp services: %s\r\n"
|
||||
"# rtcp cipher: %s\r\n"
|
||||
"# rtcp auth: %s\r\n"
|
||||
"# rtcp services: %s\r\n",
|
||||
"# rtcp services: %s\r\n"
|
||||
"# window size: %lu\r\n"
|
||||
"# tx rtx allowed:%s\r\n",
|
||||
stream->ssrc,
|
||||
stream->rtp_cipher->type->description,
|
||||
stream->rtp_auth->type->description,
|
||||
serv_descr[stream->rtp_services],
|
||||
stream->rtcp_cipher->type->description,
|
||||
stream->rtcp_auth->type->description,
|
||||
serv_descr[stream->rtcp_services]);
|
||||
serv_descr[stream->rtcp_services],
|
||||
rdbx_get_window_size(&stream->rtp_rdbx),
|
||||
stream->allow_repeat_tx ? "true" : "false");
|
||||
|
||||
/* advance to next stream in the list */
|
||||
stream = stream->next;
|
||||
|
@ -891,7 +1174,7 @@ srtp_packet_to_string(srtp_hdr_t *hdr, int pkt_octet_len) {
|
|||
double
|
||||
mips_estimate(int num_trials, int *ignore) {
|
||||
clock_t t;
|
||||
int i, sum;
|
||||
volatile int i, sum;
|
||||
|
||||
sum = 0;
|
||||
t = clock();
|
||||
|
@ -915,12 +1198,6 @@ mips_estimate(int num_trials, int *ignore) {
|
|||
|
||||
err_status_t
|
||||
srtp_validate() {
|
||||
unsigned char test_key[30] = {
|
||||
0xe1, 0xf9, 0x7a, 0x0d, 0x3e, 0x01, 0x8b, 0xe0,
|
||||
0xd6, 0x4f, 0xa3, 0x2c, 0x06, 0xde, 0x41, 0x39,
|
||||
0x0e, 0xc6, 0x75, 0xad, 0x49, 0x8a, 0xfe, 0xeb,
|
||||
0xb6, 0x96, 0x0b, 0x3a, 0xab, 0xe6
|
||||
};
|
||||
uint8_t srtp_plaintext_ref[28] = {
|
||||
0x80, 0x0f, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad,
|
||||
0xca, 0xfe, 0xba, 0xbe, 0xab, 0xab, 0xab, 0xab,
|
||||
|
@ -955,6 +1232,9 @@ srtp_validate() {
|
|||
policy.ssrc.type = ssrc_specific;
|
||||
policy.ssrc.value = 0xcafebabe;
|
||||
policy.key = test_key;
|
||||
policy.ekt = NULL;
|
||||
policy.window_size = 128;
|
||||
policy.allow_repeat_tx = 0;
|
||||
policy.next = NULL;
|
||||
|
||||
status = srtp_create(&srtp_snd, &policy);
|
||||
|
@ -996,6 +1276,122 @@ srtp_validate() {
|
|||
if (octet_string_is_eq(srtp_ciphertext, srtp_plaintext_ref, len))
|
||||
return err_status_fail;
|
||||
|
||||
status = srtp_dealloc(srtp_snd);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
status = srtp_dealloc(srtp_recv);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
return err_status_ok;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* srtp_validate_aes_256() verifies the correctness of libsrtp by comparing
|
||||
* some computed packets against some pre-computed reference values.
|
||||
* These packets were made with the AES-CM-256/HMAC-SHA-1-80 policy.
|
||||
*/
|
||||
|
||||
|
||||
err_status_t
|
||||
srtp_validate_aes_256() {
|
||||
unsigned char aes_256_test_key[46] = {
|
||||
0xf0, 0xf0, 0x49, 0x14, 0xb5, 0x13, 0xf2, 0x76,
|
||||
0x3a, 0x1b, 0x1f, 0xa1, 0x30, 0xf1, 0x0e, 0x29,
|
||||
0x98, 0xf6, 0xf6, 0xe4, 0x3e, 0x43, 0x09, 0xd1,
|
||||
0xe6, 0x22, 0xa0, 0xe3, 0x32, 0xb9, 0xf1, 0xb6,
|
||||
|
||||
0x3b, 0x04, 0x80, 0x3d, 0xe5, 0x1e, 0xe7, 0xc9,
|
||||
0x64, 0x23, 0xab, 0x5b, 0x78, 0xd2
|
||||
};
|
||||
uint8_t srtp_plaintext_ref[28] = {
|
||||
0x80, 0x0f, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad,
|
||||
0xca, 0xfe, 0xba, 0xbe, 0xab, 0xab, 0xab, 0xab,
|
||||
0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
|
||||
0xab, 0xab, 0xab, 0xab
|
||||
};
|
||||
uint8_t srtp_plaintext[38] = {
|
||||
0x80, 0x0f, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad,
|
||||
0xca, 0xfe, 0xba, 0xbe, 0xab, 0xab, 0xab, 0xab,
|
||||
0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
|
||||
0xab, 0xab, 0xab, 0xab, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
uint8_t srtp_ciphertext[38] = {
|
||||
0x80, 0x0f, 0x12, 0x34, 0xde, 0xca, 0xfb, 0xad,
|
||||
0xca, 0xfe, 0xba, 0xbe, 0xf1, 0xd9, 0xde, 0x17,
|
||||
0xff, 0x25, 0x1f, 0xf1, 0xaa, 0x00, 0x77, 0x74,
|
||||
0xb0, 0xb4, 0xb4, 0x0d, 0xa0, 0x8d, 0x9d, 0x9a,
|
||||
0x5b, 0x3a, 0x55, 0xd8, 0x87, 0x3b
|
||||
};
|
||||
srtp_t srtp_snd, srtp_recv;
|
||||
err_status_t status;
|
||||
int len;
|
||||
srtp_policy_t policy;
|
||||
|
||||
/*
|
||||
* create a session with a single stream using the default srtp
|
||||
* policy and with the SSRC value 0xcafebabe
|
||||
*/
|
||||
crypto_policy_set_aes_cm_256_hmac_sha1_80(&policy.rtp);
|
||||
crypto_policy_set_aes_cm_256_hmac_sha1_80(&policy.rtcp);
|
||||
policy.ssrc.type = ssrc_specific;
|
||||
policy.ssrc.value = 0xcafebabe;
|
||||
policy.key = aes_256_test_key;
|
||||
policy.ekt = NULL;
|
||||
policy.window_size = 128;
|
||||
policy.allow_repeat_tx = 0;
|
||||
policy.next = NULL;
|
||||
|
||||
status = srtp_create(&srtp_snd, &policy);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
/*
|
||||
* protect plaintext, then compare with ciphertext
|
||||
*/
|
||||
len = 28;
|
||||
status = srtp_protect(srtp_snd, srtp_plaintext, &len);
|
||||
if (status || (len != 38))
|
||||
return err_status_fail;
|
||||
|
||||
debug_print(mod_driver, "ciphertext:\n %s",
|
||||
octet_string_hex_string(srtp_plaintext, len));
|
||||
debug_print(mod_driver, "ciphertext reference:\n %s",
|
||||
octet_string_hex_string(srtp_ciphertext, len));
|
||||
|
||||
if (octet_string_is_eq(srtp_plaintext, srtp_ciphertext, len))
|
||||
return err_status_fail;
|
||||
|
||||
/*
|
||||
* create a receiver session context comparable to the one created
|
||||
* above - we need to do this so that the replay checking doesn't
|
||||
* complain
|
||||
*/
|
||||
status = srtp_create(&srtp_recv, &policy);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
/*
|
||||
* unprotect ciphertext, then compare with plaintext
|
||||
*/
|
||||
status = srtp_unprotect(srtp_recv, srtp_ciphertext, &len);
|
||||
if (status || (len != 28))
|
||||
return status;
|
||||
|
||||
if (octet_string_is_eq(srtp_ciphertext, srtp_plaintext_ref, len))
|
||||
return err_status_fail;
|
||||
|
||||
status = srtp_dealloc(srtp_snd);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
status = srtp_dealloc(srtp_recv);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
return err_status_ok;
|
||||
}
|
||||
|
||||
|
@ -1017,7 +1413,7 @@ srtp_create_big_policy(srtp_policy_t **list) {
|
|||
*/
|
||||
tmp = NULL;
|
||||
while (policy_array[i] != NULL) {
|
||||
p = malloc(sizeof(srtp_policy_t));
|
||||
p = (srtp_policy_t*) malloc(sizeof(srtp_policy_t));
|
||||
if (p == NULL)
|
||||
return err_status_bad_param;
|
||||
memcpy(p, policy_array[i], sizeof(srtp_policy_t));
|
||||
|
@ -1032,10 +1428,23 @@ srtp_create_big_policy(srtp_policy_t **list) {
|
|||
return err_status_ok;
|
||||
}
|
||||
|
||||
err_status_t
|
||||
srtp_dealloc_big_policy(srtp_policy_t *list) {
|
||||
srtp_policy_t *p, *next;
|
||||
|
||||
for (p = list; p != NULL; p = next) {
|
||||
next = p->next;
|
||||
free(p);
|
||||
}
|
||||
|
||||
return err_status_ok;
|
||||
}
|
||||
|
||||
|
||||
err_status_t
|
||||
srtp_test_remove_stream() {
|
||||
err_status_t status;
|
||||
srtp_policy_t *policy_list;
|
||||
srtp_policy_t *policy_list, policy;
|
||||
srtp_t session;
|
||||
srtp_stream_t stream;
|
||||
/*
|
||||
|
@ -1076,6 +1485,41 @@ srtp_test_remove_stream() {
|
|||
if (stream == NULL)
|
||||
return err_status_fail;
|
||||
|
||||
status = srtp_dealloc(session);
|
||||
if (status != err_status_ok)
|
||||
return status;
|
||||
|
||||
status = srtp_dealloc_big_policy(policy_list);
|
||||
if (status != err_status_ok)
|
||||
return status;
|
||||
|
||||
/* Now test adding and removing a single stream */
|
||||
crypto_policy_set_rtp_default(&policy.rtp);
|
||||
crypto_policy_set_rtcp_default(&policy.rtcp);
|
||||
policy.ssrc.type = ssrc_specific;
|
||||
policy.ssrc.value = 0xcafebabe;
|
||||
policy.key = test_key;
|
||||
policy.ekt = NULL;
|
||||
policy.window_size = 128;
|
||||
policy.allow_repeat_tx = 0;
|
||||
policy.next = NULL;
|
||||
|
||||
status = srtp_create(&session, NULL);
|
||||
if (status != err_status_ok)
|
||||
return status;
|
||||
|
||||
status = srtp_add_stream(session, &policy);
|
||||
if (status != err_status_ok)
|
||||
return status;
|
||||
|
||||
status = srtp_remove_stream(session, htonl(0xcafebabe));
|
||||
if (status != err_status_ok)
|
||||
return status;
|
||||
|
||||
status = srtp_dealloc(session);
|
||||
if (status != err_status_ok)
|
||||
return status;
|
||||
|
||||
return err_status_ok;
|
||||
}
|
||||
|
||||
|
@ -1110,6 +1554,9 @@ const srtp_policy_t default_policy = {
|
|||
sec_serv_conf_and_auth /* security services flag */
|
||||
},
|
||||
test_key,
|
||||
NULL, /* indicates that EKT is not in use */
|
||||
128, /* replay window size */
|
||||
0, /* retransmission not allowed */
|
||||
NULL
|
||||
};
|
||||
|
||||
|
@ -1132,6 +1579,9 @@ const srtp_policy_t aes_tmmh_policy = {
|
|||
sec_serv_conf_and_auth /* security services flag */
|
||||
},
|
||||
test_key,
|
||||
NULL, /* indicates that EKT is not in use */
|
||||
128, /* replay window size */
|
||||
0, /* retransmission not allowed */
|
||||
NULL
|
||||
};
|
||||
|
||||
|
@ -1154,6 +1604,9 @@ const srtp_policy_t tmmh_only_policy = {
|
|||
sec_serv_auth /* security services flag */
|
||||
},
|
||||
test_key,
|
||||
NULL, /* indicates that EKT is not in use */
|
||||
128, /* replay window size */
|
||||
0, /* retransmission not allowed */
|
||||
NULL
|
||||
};
|
||||
|
||||
|
@ -1176,6 +1629,9 @@ const srtp_policy_t aes_only_policy = {
|
|||
sec_serv_conf /* security services flag */
|
||||
},
|
||||
test_key,
|
||||
NULL, /* indicates that EKT is not in use */
|
||||
128, /* replay window size */
|
||||
0, /* retransmission not allowed */
|
||||
NULL
|
||||
};
|
||||
|
||||
|
@ -1198,6 +1654,9 @@ const srtp_policy_t hmac_only_policy = {
|
|||
sec_serv_auth /* security services flag */
|
||||
},
|
||||
test_key,
|
||||
NULL, /* indicates that EKT is not in use */
|
||||
128, /* replay window size */
|
||||
0, /* retransmission not allowed */
|
||||
NULL
|
||||
};
|
||||
|
||||
|
@ -1220,6 +1679,83 @@ const srtp_policy_t null_policy = {
|
|||
sec_serv_none /* security services flag */
|
||||
},
|
||||
test_key,
|
||||
NULL, /* indicates that EKT is not in use */
|
||||
128, /* replay window size */
|
||||
0, /* retransmission not allowed */
|
||||
NULL
|
||||
};
|
||||
|
||||
unsigned char test_256_key[46] = {
|
||||
0xf0, 0xf0, 0x49, 0x14, 0xb5, 0x13, 0xf2, 0x76,
|
||||
0x3a, 0x1b, 0x1f, 0xa1, 0x30, 0xf1, 0x0e, 0x29,
|
||||
0x98, 0xf6, 0xf6, 0xe4, 0x3e, 0x43, 0x09, 0xd1,
|
||||
0xe6, 0x22, 0xa0, 0xe3, 0x32, 0xb9, 0xf1, 0xb6,
|
||||
|
||||
0x3b, 0x04, 0x80, 0x3d, 0xe5, 0x1e, 0xe7, 0xc9,
|
||||
0x64, 0x23, 0xab, 0x5b, 0x78, 0xd2
|
||||
};
|
||||
|
||||
const srtp_policy_t aes_256_hmac_policy = {
|
||||
{ ssrc_any_outbound, 0 }, /* SSRC */
|
||||
{ /* SRTP policy */
|
||||
AES_ICM, /* cipher type */
|
||||
46, /* cipher key length in octets */
|
||||
HMAC_SHA1, /* authentication func type */
|
||||
20, /* auth key length in octets */
|
||||
10, /* auth tag length in octets */
|
||||
sec_serv_conf_and_auth /* security services flag */
|
||||
},
|
||||
{ /* SRTCP policy */
|
||||
AES_ICM, /* cipher type */
|
||||
46, /* cipher key length in octets */
|
||||
HMAC_SHA1, /* authentication func type */
|
||||
20, /* auth key length in octets */
|
||||
10, /* auth tag length in octets */
|
||||
sec_serv_conf_and_auth /* security services flag */
|
||||
},
|
||||
test_256_key,
|
||||
NULL, /* indicates that EKT is not in use */
|
||||
128, /* replay window size */
|
||||
0, /* retransmission not allowed */
|
||||
NULL
|
||||
};
|
||||
|
||||
uint8_t ekt_test_key[16] = {
|
||||
0x77, 0x26, 0x9d, 0xac, 0x16, 0xa3, 0x28, 0xca,
|
||||
0x8e, 0xc9, 0x68, 0x4b, 0xcc, 0xc4, 0xd2, 0x1b
|
||||
};
|
||||
|
||||
#include "ekt.h"
|
||||
|
||||
ekt_policy_ctx_t ekt_test_policy = {
|
||||
0xa5a5, /* SPI */
|
||||
EKT_CIPHER_AES_128_ECB,
|
||||
ekt_test_key,
|
||||
NULL
|
||||
};
|
||||
|
||||
const srtp_policy_t hmac_only_with_ekt_policy = {
|
||||
{ ssrc_any_outbound, 0 }, /* SSRC */
|
||||
{
|
||||
NULL_CIPHER, /* cipher type */
|
||||
0, /* cipher key length in octets */
|
||||
HMAC_SHA1, /* authentication func type */
|
||||
20, /* auth key length in octets */
|
||||
4, /* auth tag length in octets */
|
||||
sec_serv_auth /* security services flag */
|
||||
},
|
||||
{
|
||||
NULL_CIPHER, /* cipher type */
|
||||
0, /* cipher key length in octets */
|
||||
HMAC_SHA1, /* authentication func type */
|
||||
20, /* auth key length in octets */
|
||||
4, /* auth tag length in octets */
|
||||
sec_serv_auth /* security services flag */
|
||||
},
|
||||
test_key,
|
||||
&ekt_test_policy, /* indicates that EKT is not in use */
|
||||
128, /* replay window size */
|
||||
0, /* retransmission not allowed */
|
||||
NULL
|
||||
};
|
||||
|
||||
|
@ -1248,6 +1784,8 @@ policy_array[] = {
|
|||
#endif
|
||||
&default_policy,
|
||||
&null_policy,
|
||||
&aes_256_hmac_policy,
|
||||
&hmac_only_with_ekt_policy,
|
||||
NULL
|
||||
};
|
||||
|
||||
|
@ -1270,5 +1808,8 @@ const srtp_policy_t wildcard_policy = {
|
|||
sec_serv_conf_and_auth /* security services flag */
|
||||
},
|
||||
test_key,
|
||||
NULL,
|
||||
128, /* replay window size */
|
||||
0, /* retransmission not allowed */
|
||||
NULL
|
||||
};
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
a=`find . -name "*.[ch]"`
|
||||
for x in $a; do
|
||||
sed 's/(c) 2001-2004/(c) 2001-2005/' $x > $x.tmp;
|
||||
sed 's/(c) 2001-2005/(c) 2001-2006/' $x > $x.tmp;
|
||||
mv $x.tmp $x;
|
||||
done
|
||||
|
||||
|
|
|
@ -47,6 +47,7 @@
|
|||
#undef inline
|
||||
#include <datatypes.h>
|
||||
#include <srtp.h>
|
||||
#include <srtp_priv.h>
|
||||
#include <switch_version.h>
|
||||
|
||||
#define READ_INC(rtp_session) switch_mutex_lock(rtp_session->read_mutex); rtp_session->reading++
|
||||
|
|
Loading…
Reference in New Issue