- migrate to the latest libsrtp version
This commit is contained in:
parent
6f55c91c7a
commit
48f6bf21d9
|
|
@ -137,7 +137,7 @@ add_subdirectory(${rtphone_libs}/libgsm)
|
|||
add_subdirectory(${rtphone_libs}/gsmhr)
|
||||
add_subdirectory(${rtphone_libs}/g722)
|
||||
add_subdirectory(${rtphone_libs}/speexdsp)
|
||||
add_subdirectory(${rtphone_libs}/srtp)
|
||||
add_subdirectory(${rtphone_libs}/libsrtp)
|
||||
add_subdirectory(${rtphone_libs}/webrtc)
|
||||
add_subdirectory(${rtphone_engine}/helper)
|
||||
add_subdirectory(${rtphone_engine}/audio)
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
#include "../engine_config.h"
|
||||
#include "jrtplib/src/rtpexternaltransmitter.h"
|
||||
#include "srtp/include/srtp.h"
|
||||
#include "libsrtp/include/srtp.h"
|
||||
#include "../helper/HL_NetworkSocket.h"
|
||||
#include "../helper/HL_InternetAddress.h"
|
||||
#include "../helper/HL_Rtp.h"
|
||||
|
|
|
|||
|
|
@ -1,30 +1,32 @@
|
|||
/* Copyright(C) 2007-2016 VoIP objects (voipobjects.com)
|
||||
/* Copyright(C) 2007-2025 VoIP objects (voipobjects.com)
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "../engine_config.h"
|
||||
#include "MT_SrtpHelper.h"
|
||||
#include "../helper/HL_Log.h"
|
||||
#include "../helper/HL_Exception.h"
|
||||
#include "../helper/HL_Rtp.h"
|
||||
#include <openssl/rand.h>
|
||||
#include <assert.h>
|
||||
|
||||
// --- SrtpStream ---
|
||||
void initSrtpStream(SrtpStream& s, unsigned ssrc, SrtpSuite suite)
|
||||
static void configureSrtpStream(SrtpStream& s, uint16_t ssrc, SrtpSuite suite)
|
||||
{
|
||||
s.second.ssrc.type = ssrc_specific;
|
||||
s.second.ssrc.value = ntohl(ssrc);
|
||||
s.second.next = NULL;
|
||||
s.second.next = nullptr;
|
||||
switch (suite)
|
||||
{
|
||||
case SRTP_AES_128_AUTH_80:
|
||||
crypto_policy_set_aes_cm_128_hmac_sha1_80(&s.second.rtp);
|
||||
crypto_policy_set_aes_cm_128_hmac_sha1_80(&s.second.rtcp);
|
||||
srtp_crypto_policy_set_aes_cm_128_hmac_sha1_80(&s.second.rtp);
|
||||
srtp_crypto_policy_set_aes_cm_128_hmac_sha1_80(&s.second.rtcp);
|
||||
break;
|
||||
|
||||
case SRTP_AES_256_AUTH_80:
|
||||
crypto_policy_set_aes_cm_256_hmac_sha1_80(&s.second.rtp);
|
||||
crypto_policy_set_aes_cm_256_hmac_sha1_80(&s.second.rtcp);
|
||||
srtp_crypto_policy_set_aes_cm_256_hmac_sha1_80(&s.second.rtp);
|
||||
srtp_crypto_policy_set_aes_cm_256_hmac_sha1_80(&s.second.rtcp);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
|
@ -33,10 +35,8 @@ void initSrtpStream(SrtpStream& s, unsigned ssrc, SrtpSuite suite)
|
|||
}
|
||||
|
||||
SrtpSession::SrtpSession()
|
||||
:mInboundSession(NULL), mOutboundSession(NULL)
|
||||
:mInboundSession(nullptr), mOutboundSession(nullptr)
|
||||
{
|
||||
mInboundSession = NULL;
|
||||
mOutboundSession = NULL;
|
||||
mSuite = SRTP_NONE;
|
||||
|
||||
memset(&mInboundPolicy, 0, sizeof mInboundPolicy);
|
||||
|
|
@ -46,22 +46,20 @@ SrtpSession::SrtpSession()
|
|||
mOutboundPolicy.ssrc.type = ssrc_specific;
|
||||
|
||||
// Generate outgoing keys
|
||||
|
||||
mOutgoingKey[SRTP_AES_128_AUTH_80-1].first = PByteBuffer(new ByteBuffer());
|
||||
mOutgoingKey[SRTP_AES_128_AUTH_80-1].first = std::make_shared<ByteBuffer>();
|
||||
mOutgoingKey[SRTP_AES_128_AUTH_80-1].first->resize(30);
|
||||
crypto_get_random((unsigned char*)mOutgoingKey[SRTP_AES_128_AUTH_80-1].first->mutableData(), 30);
|
||||
RAND_bytes((unsigned char*)mOutgoingKey[SRTP_AES_128_AUTH_80-1].first->mutableData(), 30);
|
||||
|
||||
mOutgoingKey[SRTP_AES_256_AUTH_80-1].first = PByteBuffer(new ByteBuffer());
|
||||
mOutgoingKey[SRTP_AES_256_AUTH_80-1].first = std::make_shared<ByteBuffer>();
|
||||
mOutgoingKey[SRTP_AES_256_AUTH_80-1].first->resize(46);
|
||||
crypto_get_random((unsigned char*)mOutgoingKey[SRTP_AES_256_AUTH_80-1].first->mutableData(), 46);
|
||||
|
||||
RAND_bytes((unsigned char*)mOutgoingKey[SRTP_AES_256_AUTH_80-1].first->mutableData(), 46);
|
||||
}
|
||||
|
||||
SrtpSession::~SrtpSession()
|
||||
{
|
||||
}
|
||||
|
||||
void SrtpSession::addSsrc(unsigned ssrc, SsrcDirection d)
|
||||
/*void SrtpSession::addSsrc(unsigned ssrc, SsrcDirection d)
|
||||
{
|
||||
Lock l(mGuard);
|
||||
assert(mSuite != SRTP_NONE);
|
||||
|
|
@ -76,7 +74,7 @@ void SrtpSession::addSsrc(unsigned ssrc, SsrcDirection d)
|
|||
if (streamIter != mIncomingMap.end())
|
||||
return;
|
||||
|
||||
initSrtpStream(s, ssrc, mSuite);
|
||||
configureSrtpStream(s, ssrc, mSuite);
|
||||
s.second.key = (unsigned char*)mIncomingKey.first->mutableData();
|
||||
mIncomingMap[ssrc] = s;
|
||||
srtp_add_stream(mInboundSession, &s.second);
|
||||
|
|
@ -86,13 +84,13 @@ void SrtpSession::addSsrc(unsigned ssrc, SsrcDirection d)
|
|||
streamIter = mOutgoingMap.find(ssrc);
|
||||
if (streamIter != mOutgoingMap.end())
|
||||
return;
|
||||
initSrtpStream(s, ssrc, mSuite);
|
||||
configureSrtpStream(s, ssrc, mSuite);
|
||||
s.second.key = (unsigned char*)mOutgoingKey[int(mSuite)-1].first->mutableData();
|
||||
mOutgoingMap[ssrc] = s;
|
||||
srtp_add_stream(mOutboundSession, &s.second);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
void SrtpSession::open(ByteBuffer& incomingKey, SrtpSuite suite)
|
||||
{
|
||||
|
|
@ -106,23 +104,23 @@ void SrtpSession::open(ByteBuffer& incomingKey, SrtpSuite suite)
|
|||
mSuite = suite;
|
||||
|
||||
// Save key
|
||||
mIncomingKey.first = PByteBuffer(new ByteBuffer(incomingKey));
|
||||
mIncomingKey.first = std::make_shared<ByteBuffer>(incomingKey);
|
||||
|
||||
// Update policy
|
||||
switch (suite)
|
||||
{
|
||||
case SRTP_AES_128_AUTH_80:
|
||||
crypto_policy_set_aes_cm_128_hmac_sha1_80(&mInboundPolicy.rtp);
|
||||
crypto_policy_set_aes_cm_128_hmac_sha1_80(&mInboundPolicy.rtcp);
|
||||
crypto_policy_set_aes_cm_128_hmac_sha1_80(&mOutboundPolicy.rtp);
|
||||
crypto_policy_set_aes_cm_128_hmac_sha1_80(&mOutboundPolicy.rtcp);
|
||||
srtp_crypto_policy_set_aes_cm_128_hmac_sha1_80(&mInboundPolicy.rtp);
|
||||
srtp_crypto_policy_set_aes_cm_128_hmac_sha1_80(&mInboundPolicy.rtcp);
|
||||
srtp_crypto_policy_set_aes_cm_128_hmac_sha1_80(&mOutboundPolicy.rtp);
|
||||
srtp_crypto_policy_set_aes_cm_128_hmac_sha1_80(&mOutboundPolicy.rtcp);
|
||||
break;
|
||||
|
||||
case SRTP_AES_256_AUTH_80:
|
||||
crypto_policy_set_aes_cm_256_hmac_sha1_80(&mInboundPolicy.rtp);
|
||||
crypto_policy_set_aes_cm_256_hmac_sha1_80(&mInboundPolicy.rtcp);
|
||||
crypto_policy_set_aes_cm_256_hmac_sha1_80(&mOutboundPolicy.rtp);
|
||||
crypto_policy_set_aes_cm_256_hmac_sha1_80(&mOutboundPolicy.rtcp);
|
||||
srtp_crypto_policy_set_aes_cm_256_hmac_sha1_80(&mInboundPolicy.rtp);
|
||||
srtp_crypto_policy_set_aes_cm_256_hmac_sha1_80(&mInboundPolicy.rtcp);
|
||||
srtp_crypto_policy_set_aes_cm_256_hmac_sha1_80(&mOutboundPolicy.rtp);
|
||||
srtp_crypto_policy_set_aes_cm_256_hmac_sha1_80(&mOutboundPolicy.rtcp);
|
||||
break;
|
||||
|
||||
case SRTP_NONE:
|
||||
|
|
@ -132,7 +130,7 @@ void SrtpSession::open(ByteBuffer& incomingKey, SrtpSuite suite)
|
|||
mInboundPolicy.key = (unsigned char*)mIncomingKey.first->mutableData();
|
||||
|
||||
// Create SRTP session
|
||||
err_status_t err;
|
||||
srtp_err_status_t err;
|
||||
|
||||
err = srtp_create(&mOutboundSession, &mOutboundPolicy);
|
||||
if (err)
|
||||
|
|
@ -175,44 +173,74 @@ SrtpKeySalt& SrtpSession::outgoingKey(SrtpSuite suite)
|
|||
|
||||
bool SrtpSession::protectRtp(void* buffer, int* length)
|
||||
{
|
||||
addSsrc(RtpHelper::findSsrc(buffer, *length), sdOutgoing);
|
||||
// addSsrc(RtpHelper::findSsrc(buffer, *length), sdOutgoing);
|
||||
|
||||
Lock l(mGuard);
|
||||
if (mOutboundSession)
|
||||
return srtp_protect(mOutboundSession, buffer, length) == 0;
|
||||
{
|
||||
size_t srtp_len = MAX_VALID_UDPPACKET_SIZE;
|
||||
auto code = srtp_protect(mOutboundSession,
|
||||
(const uint8_t*)buffer, (size_t)*length,
|
||||
(uint8_t*)buffer, &srtp_len,
|
||||
0 /* mki_index, non-used */);
|
||||
*length = srtp_len;
|
||||
return code == 0;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SrtpSession::protectRtcp(void* buffer, int* length)
|
||||
{
|
||||
addSsrc(RtpHelper::findSsrc(buffer, *length), sdOutgoing);
|
||||
//addSsrc(RtpHelper::findSsrc(buffer, *length), sdOutgoing);
|
||||
|
||||
Lock l(mGuard);
|
||||
if (mOutboundSession)
|
||||
return srtp_protect_rtcp(mOutboundSession, buffer, length) == 0;
|
||||
{
|
||||
size_t srtp_len = MAX_VALID_UDPPACKET_SIZE;
|
||||
auto code = srtp_protect_rtcp(mOutboundSession,
|
||||
(const uint8_t*)buffer, (size_t)*length,
|
||||
(uint8_t*)buffer, &srtp_len,
|
||||
0 /* mki_index, non-used */);
|
||||
*length = srtp_len;
|
||||
return code == 0;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SrtpSession::unprotectRtp(void* buffer, int* length)
|
||||
{
|
||||
addSsrc(RtpHelper::findSsrc(buffer, *length), sdIncoming);
|
||||
//addSsrc(RtpHelper::findSsrc(buffer, *length), sdIncoming);
|
||||
|
||||
Lock l(mGuard);
|
||||
if (mInboundSession)
|
||||
return srtp_unprotect(mInboundSession, buffer, length) == 0;
|
||||
{
|
||||
size_t rtp_len = MAX_VALID_UDPPACKET_SIZE;
|
||||
auto code = srtp_unprotect(mInboundSession,
|
||||
(const uint8_t*)buffer, (size_t)*length,
|
||||
(uint8_t*)buffer, &rtp_len);
|
||||
*length = rtp_len;
|
||||
return code == 0;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SrtpSession::unprotectRtcp(void* buffer, int* length)
|
||||
{
|
||||
addSsrc(RtpHelper::findSsrc(buffer, *length), sdIncoming);
|
||||
//addSsrc(RtpHelper::findSsrc(buffer, *length), sdIncoming);
|
||||
|
||||
Lock l(mGuard);
|
||||
if (mInboundSession)
|
||||
return srtp_unprotect_rtcp(mInboundSession, buffer, (int*)length) == 0;
|
||||
{
|
||||
size_t rtp_len = MAX_VALID_UDPPACKET_SIZE;
|
||||
auto code = srtp_unprotect_rtcp(mInboundSession,
|
||||
(const uint8_t*)buffer, (size_t)*length,
|
||||
(uint8_t*)buffer, (size_t*)rtp_len);
|
||||
*length = rtp_len;
|
||||
return code == 0;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
|
@ -223,9 +251,9 @@ void SrtpSession::initSrtp()
|
|||
if (GSrtpInitialized)
|
||||
return;
|
||||
|
||||
err_status_t err = srtp_init();
|
||||
auto err = srtp_init();
|
||||
|
||||
if (err != err_status_ok)
|
||||
if (err != srtp_err_status_ok)
|
||||
throw Exception(ERR_SRTP, err);
|
||||
GSrtpInitialized = true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@
|
|||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
#include "srtp/include/srtp.h"
|
||||
#include "libsrtp/include/srtp.h"
|
||||
#include "../helper/HL_Sync.h"
|
||||
#include "../helper/HL_ByteBuffer.h"
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1 @@
|
|||
Subproject commit 50d80624525fac023704ce4a2333beab6bb11aa8
|
||||
|
|
@ -1,223 +0,0 @@
|
|||
Changelog
|
||||
|
||||
1.3.20
|
||||
|
||||
Lots of changes. Thanks to Jeff Chan for catching a memory leak and
|
||||
helping track down the endian issues with the SSRCs.
|
||||
|
||||
1.3.8
|
||||
|
||||
This is an interim release. Several little-endian bugs were identified
|
||||
and fixed; this means that we can use intel/linux for development again.
|
||||
|
||||
Cleaned up sha1 and hmac code significantly, got rid of some excess
|
||||
functions and properly documented the fuctions in the .h files.
|
||||
|
||||
Eliminated some vestigial files.
|
||||
|
||||
There is a SIGBUS error in the AES encrypt function on sparc
|
||||
(observed on both solaris and openbsd) with gcc 2.95. Was unable to
|
||||
find bad pointer anywhere, so I'm wondering if it isn't a compiler
|
||||
problem (there's a known problem whose profile it fits). It doesn't
|
||||
appear on any other platform, even in the cipher_driver stress
|
||||
tests.
|
||||
|
||||
Planned changes
|
||||
|
||||
Change interface to nonces (xtd_seq_num_t) so that it uses
|
||||
network byte ordering, and is consistent with other arguments.
|
||||
|
||||
|
||||
1.3.6
|
||||
|
||||
Changed /dev/random (in configure.in and crypto/rng/rand_source.c) to
|
||||
/dev/urandom; the latter is non-blocking on all known platforms (which
|
||||
corrects some programs that seem to hang) and is actually present on
|
||||
Open BSD (unlike /dev/random, which only works in the presence of
|
||||
hardware supported random number generation).
|
||||
|
||||
Added machine/types.h case in include/integers.h.
|
||||
|
||||
1.3.5
|
||||
|
||||
Removing srtp_t::template and stream_clone().
|
||||
|
||||
Adding a new policy structure, which will reflect a complete SRTP
|
||||
policy (including SRTCP).
|
||||
|
||||
This version is *incomplete* and will undergo more changes. It is
|
||||
provided only as a basis for discussion.
|
||||
|
||||
1.3.4
|
||||
|
||||
Removed tmmh.c and tmmh.h, which implemented version one of TMMH.
|
||||
|
||||
Changed srtp_get_trailer_length() to act on streams rather than
|
||||
sessions, and documented the macro SRTP_MAX_TRAILER_LEN, which should
|
||||
usually be used rather than that function.
|
||||
|
||||
Removed 'salt' from cipher input.
|
||||
|
||||
Changed rdbx to use err.h error codes.
|
||||
|
||||
Changed malloc() and free() to xalloc() and xfree; these functions
|
||||
are defined in crypto/kernel/alloc.c and declared in
|
||||
include/alloc.h.
|
||||
|
||||
Added 'output' functions to cipher, in addition to 'encrypt'
|
||||
functions. It is no longer necessary to zeroize a buffer before
|
||||
encrypting in order to get keystream.
|
||||
|
||||
Changed octet_string_hex_string() so that "times two" isn't needed
|
||||
in its input.
|
||||
|
||||
Added crypto_kernel_init() prior to command-line parsing, so that
|
||||
kernel can be passed command-line arguments, such as "-d
|
||||
debug_module". This was done to for the applications
|
||||
test/srtp-driver, test/kernel-driver, and test/ust-driver.
|
||||
|
||||
Improved srtp_init_aes_128_prf - wrote key derivation function
|
||||
(srtp_kdf_t).
|
||||
|
||||
Add the tag_len as an argument to the auth_compute() function, but
|
||||
not the corresponding macro. This change allows the tag length for
|
||||
a given auth func to be set to different values at initialization
|
||||
time. Previously, the structure auth_t contained the
|
||||
output_length, but that value was inaccessible from hmac_compute()
|
||||
and other functions.
|
||||
|
||||
Re-named files from a-b.c to a_b.c. in order to help portability.
|
||||
|
||||
Re-named rijndael to aes (or aes_128 as appropriate).
|
||||
|
||||
|
||||
1.2.1
|
||||
|
||||
Changes so that 1.2.0 compiles on cygwin-win2k.
|
||||
|
||||
Added better error reporting system. If syslog is present on the
|
||||
OS, then it is used.
|
||||
|
||||
|
||||
1.2.0 Many improvements and additions, and a fex fixes
|
||||
|
||||
Fixed endian issues in RTP header construction in the function
|
||||
rtp_sendto() in srtp/rtp.c.
|
||||
|
||||
Implemented RIJNDAEL decryption operation, adding the functions
|
||||
rijndael_decrypt() and rijndael_expand_decryption_key(). Also
|
||||
re-named rijndael_expand_key() to rijndael_expand_encryption_key()
|
||||
for consistency.
|
||||
|
||||
Implemented random number source using /dev/random, in the files
|
||||
crypto/rng/rand_source.c and include/rand_source.h.
|
||||
|
||||
Added index check to SEAL cipher (only values less than 2^32 are
|
||||
allowed)
|
||||
|
||||
Added test case for null_auth authentication function.
|
||||
|
||||
Added a timing test which tests the effect of CPU cache thrash on
|
||||
cipher throughput. The test is done by the function
|
||||
cipher_test_throughput_array(); the function
|
||||
cipher_array_alloc_init() creates an array of ciphers for use in
|
||||
this test. This test can be accessed by using the -a flag to
|
||||
the application cipher-driver in the test subdirectory.
|
||||
|
||||
Added argument processing to ust-driver.c, and added that app to
|
||||
the 'runtest' target in Makefile.in.
|
||||
|
||||
A minor auth_t API change: last argument of auth_init() eliminated.
|
||||
|
||||
|
||||
1.0.6 A small but important fix
|
||||
|
||||
Fixed srtp_init_aes_128_prf() by adding octet_string_set_to_zero()
|
||||
after buffer allocation.
|
||||
|
||||
Eliminated references to no-longer-existing variables in debugging
|
||||
code in srtp/srtp.c. This fixes the compilation failure that
|
||||
occured when using PRINT_DEBUG in that file.
|
||||
|
||||
Corrected spelling of Richard Priestley's name in credits. Sorry
|
||||
Richard!
|
||||
|
||||
|
||||
1.0.5 Many little fixes
|
||||
|
||||
Fixed octet_string_set_to_zero(), which was writing one
|
||||
more zero octet than it should. This bug caused srtp_protect()
|
||||
and srtp_unprotect() to overwrite the byte that followed the
|
||||
srtp packet.
|
||||
|
||||
Changed sizeof(uint32_t) to srtp_get_trailer_length() in
|
||||
srtp-driver.c. This is just defensive coding.
|
||||
|
||||
Added NULL check to malloc in srtp_alloc().
|
||||
|
||||
|
||||
1.0.4 Many minor fixes and two big ones (thanks for the bug reports!)
|
||||
|
||||
Removed 'ssrc' from the srtp_init_aes_128_prf() function argument
|
||||
list. This is so that applications which do not a priori know the
|
||||
ssrc which they will be receiving can still use libsrtp. Now the
|
||||
SSRC value is gleaned from the rtp header and exored into the
|
||||
counter mode offset in the srtp_protect() and srtp_unprotect()
|
||||
functions, if that cipher is used. This change cascaed through
|
||||
many other functions, including srtp_init_from_hex(),
|
||||
srtp_sender_init() and srtp_receiver_init() in rtp.c, and also
|
||||
changing the CLI to test/rtpw. In the future, another function
|
||||
call will be added to the library that enables multiple ssrc/key
|
||||
pairs to be installed into the same srtp session, so that libsrtp
|
||||
works with multiple srtp senders. For now, this functionality is
|
||||
lacking.
|
||||
|
||||
Removed the GDOI interface to the rtpw demo program. This will be
|
||||
added again at a later date, after the SRTP and GDOI distributions
|
||||
stabilize. For now, I've left in the GDOI #defines and autoconf
|
||||
definitions so that they'll be in place when needed.
|
||||
|
||||
Updated tmmhv2_compute() so that it didn't assume any particular
|
||||
alginment of the output tag.
|
||||
|
||||
Changed bit field variables in srtp.h to unsigned char from
|
||||
unsigned int in order to avoid a potential endianness issue.
|
||||
|
||||
Fixed rdbx_estimate_index() to handle all input cases. This solves
|
||||
the now notorious "abaft" bug in the rtpw demo app on linux/intel,
|
||||
in which spurious replay protection failures happen after that word
|
||||
is received.
|
||||
|
||||
Added ntohs(hdr->seq) to srtp_protect and srtp_unprotect, removed
|
||||
from rijndael_icm_set_segment().
|
||||
|
||||
Added error checking and handling to srtp_sender_init() and
|
||||
srtp_receiver_init().
|
||||
|
||||
Changed srtp_alloc() so that it does what you'd expect: allocate an
|
||||
srtp_ctx_t structure. This hides the library internals.
|
||||
|
||||
|
||||
1.0.1 Many minor fixes
|
||||
|
||||
Added cipher_driver_buffer_test(...) to test/cipher-driver.c. This
|
||||
function checks that the byte-buffering functions used by a cipher
|
||||
are correct.
|
||||
|
||||
Fixed SunOS/Solaris build problems: added HAVE_SYS_INT_TYPES_H and
|
||||
changed index_t to xtd_seq_num_t (see include/rdbx.h).
|
||||
|
||||
Fixed SEAL3.0 output byte buffering, added byte-buffering test to
|
||||
cipher/cipher-driver.c.
|
||||
|
||||
Fixed roc-driver so that the non-sequential insertion test
|
||||
automatically recovers from bad estimates. This was required to
|
||||
prevent spurious failures.
|
||||
|
||||
Made rdbx_estimate_index(...) function smarter, so that initial RTP
|
||||
sequence numbers greater than 32,768 don't cause it to estimate the
|
||||
rollover counter of 0xffffffff.
|
||||
|
||||
|
||||
1.0.0 Initial release
|
||||
|
||||
|
|
@ -1,60 +0,0 @@
|
|||
project (srtp)
|
||||
|
||||
# Rely on C++ 11
|
||||
set (CMAKE_CXX_STANDARD 20)
|
||||
set (CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
|
||||
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
|
||||
|
||||
set (SRTP_SOURCES
|
||||
srtp/srtp.c
|
||||
srtp/ekt.c
|
||||
crypto/rng/rand_source.c
|
||||
crypto/rng/prng.c
|
||||
crypto/rng/ctr_prng.c
|
||||
crypto/replay/ut_sim.c
|
||||
crypto/replay/rdbx.c
|
||||
crypto/replay/rdb.c
|
||||
crypto/math/stat.c
|
||||
crypto/math/gf2_8.c
|
||||
crypto/kernel/key.c
|
||||
crypto/kernel/err.c
|
||||
crypto/kernel/crypto_kernel.c
|
||||
crypto/kernel/alloc.c
|
||||
crypto/hash/sha1.c
|
||||
crypto/hash/null_auth.c
|
||||
crypto/hash/hmac.c
|
||||
crypto/cipher/null_cipher.c
|
||||
crypto/cipher/cipher.c
|
||||
crypto/cipher/aes.c
|
||||
crypto/cipher/aes_icm.c
|
||||
crypto/cipher/aes_cbc.c
|
||||
crypto/ae_xfm/xfm.c
|
||||
crypto/hash/srtp_auth.c
|
||||
crypto/math/datatypes.c
|
||||
)
|
||||
|
||||
add_library(srtp ${SRTP_SOURCES})
|
||||
target_include_directories(srtp PUBLIC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/include
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/crypto/include
|
||||
)
|
||||
|
||||
if (CMAKE_SYSTEM MATCHES "Linux*" OR CMAKE_SYSTEM MATCHES "Darwin*" OR ANDROID_ABI)
|
||||
set (PLATFORM_DEFINES HAVE_NETINET_IN_H)
|
||||
else()
|
||||
set (PLATFORM_DEFINES HAVE_WINSOCK2_H)
|
||||
endif()
|
||||
|
||||
if (ANDROID_ABI)
|
||||
if (CMAKE_ANDROID_ARCH_ABI MATCHES "arm.*")
|
||||
message ("ARM based processor found, defining CPU_RISC")
|
||||
set (PLATFORM_DEFINES ${PLATFORM_DEFINES} -DCPU_RISC)
|
||||
else()
|
||||
set (PLATFORM_DEFINES ${PLATFORM_DEFINES} -DCPU_CISC)
|
||||
endif()
|
||||
else()
|
||||
set (PLATFORM_DEFINES ${PLATFORM_DEFINES} CPU_CISC)
|
||||
endif()
|
||||
|
||||
target_compile_definitions(srtp PUBLIC -DHAVE_INTTYPES_H ${PLATFORM_DEFINES})
|
||||
|
|
@ -1,35 +0,0 @@
|
|||
/*
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
|
@ -1,237 +0,0 @@
|
|||
# Makefile for secure rtp
|
||||
#
|
||||
# David A. McGrew
|
||||
# Cisco Systems, Inc.
|
||||
|
||||
# targets:
|
||||
#
|
||||
# runtest runs test applications
|
||||
# test builds test applications
|
||||
# libcrypt.a static library implementing crypto engine
|
||||
# libsrtp.a static library implementing srtp
|
||||
# clean removes objects, libs, and executables
|
||||
# distribution cleans and builds a .tgz
|
||||
# tags builds etags file from all .c and .h files
|
||||
|
||||
.PHONY: all test build_table_apps
|
||||
|
||||
all: test
|
||||
|
||||
runtest: build_table_apps test
|
||||
@echo "running libsrtp test applications..."
|
||||
crypto/test/cipher_driver$(EXE) -v >/dev/null
|
||||
crypto/test/kernel_driver$(EXE) -v >/dev/null
|
||||
test/rdbx_driver$(EXE) -v >/dev/null
|
||||
test/srtp_driver$(EXE) -v >/dev/null
|
||||
test/roc_driver$(EXE) -v >/dev/null
|
||||
test/replay_driver$(EXE) -v >/dev/null
|
||||
test/dtls_srtp_driver$(EXE) >/dev/null
|
||||
cd test; $(abspath $(srcdir))/test/rtpw_test.sh >/dev/null
|
||||
@echo "libsrtp test applications passed."
|
||||
$(MAKE) -C crypto runtest
|
||||
|
||||
# makefile variables
|
||||
|
||||
CC = @CC@
|
||||
INCDIR = -Icrypto/include -I$(srcdir)/include -I$(srcdir)/crypto/include
|
||||
DEFS = @DEFS@
|
||||
CPPFLAGS= @CPPFLAGS@
|
||||
CFLAGS = @CFLAGS@
|
||||
LIBS = @LIBS@
|
||||
LDFLAGS = @LDFLAGS@ -L.
|
||||
COMPILE = $(CC) $(DEFS) $(INCDIR) $(CPPFLAGS) $(CFLAGS)
|
||||
SRTPLIB = -lsrtp
|
||||
|
||||
RANLIB = @RANLIB@
|
||||
INSTALL = @INSTALL@
|
||||
|
||||
# EXE defines the suffix on executables - it's .exe for Windows, and
|
||||
# null on linux, bsd, and OS X and other OSes.
|
||||
EXE = @EXE@
|
||||
# gdoi is the group domain of interpretation for isakmp, a group key
|
||||
# management system which can provide keys for srtp
|
||||
gdoi = @GDOI_OBJS@
|
||||
# Random source.
|
||||
RNG_OBJS = @RNG_OBJS@
|
||||
|
||||
srcdir = @srcdir@
|
||||
top_srcdir = @top_srcdir@
|
||||
top_builddir = @top_builddir@
|
||||
VPATH = @srcdir@
|
||||
prefix = @prefix@
|
||||
exec_prefix = @exec_prefix@
|
||||
includedir = @includedir@
|
||||
libdir = @libdir@
|
||||
|
||||
|
||||
# implicit rules for object files and test apps
|
||||
|
||||
%.o: %.c
|
||||
$(COMPILE) -c $< -o $@
|
||||
|
||||
%$(EXE): %.c
|
||||
$(COMPILE) $(LDFLAGS) $< -o $@ $(SRTPLIB) $(LIBS)
|
||||
|
||||
|
||||
# libcrypt.a (the crypto engine)
|
||||
ciphers = crypto/cipher/cipher.o crypto/cipher/null_cipher.o \
|
||||
crypto/cipher/aes.o crypto/cipher/aes_icm.o \
|
||||
crypto/cipher/aes_cbc.o
|
||||
|
||||
hashes = crypto/hash/null_auth.o crypto/hash/sha1.o \
|
||||
crypto/hash/hmac.o crypto/hash/auth.o # crypto/hash/tmmhv2.o
|
||||
|
||||
replay = crypto/replay/rdb.o crypto/replay/rdbx.o \
|
||||
crypto/replay/ut_sim.o
|
||||
|
||||
math = crypto/math/datatypes.o crypto/math/stat.o
|
||||
|
||||
ust = crypto/ust/ust.o
|
||||
|
||||
rng = crypto/rng/$(RNG_OBJS) crypto/rng/prng.o crypto/rng/ctr_prng.o
|
||||
|
||||
err = crypto/kernel/err.o
|
||||
|
||||
kernel = crypto/kernel/crypto_kernel.o crypto/kernel/alloc.o \
|
||||
crypto/kernel/key.o $(rng) $(err) # $(ust)
|
||||
|
||||
cryptobj = $(ciphers) $(hashes) $(math) $(stat) $(kernel) $(replay)
|
||||
|
||||
# libsrtp.a (implements srtp processing)
|
||||
|
||||
srtpobj = srtp/srtp.o srtp/ekt.o
|
||||
|
||||
libsrtp.a: $(srtpobj) $(cryptobj) $(gdoi)
|
||||
ar cr libsrtp.a $^
|
||||
$(RANLIB) libsrtp.a
|
||||
|
||||
# libcryptomath.a contains general-purpose routines that are used to
|
||||
# generate tables and verify cryptoalgorithm implementations - this
|
||||
# library is not meant to be included in production code
|
||||
|
||||
cryptomath = crypto/math/math.o crypto/math/gf2_8.o
|
||||
|
||||
libcryptomath.a: $(cryptomath)
|
||||
ar cr libcryptomath.a $(cryptomath)
|
||||
$(RANLIB) libcryptomath.a
|
||||
|
||||
|
||||
# test applications
|
||||
|
||||
crypto_testapp = crypto/test/aes_calc$(EXE) crypto/test/cipher_driver$(EXE) \
|
||||
crypto/test/datatypes_driver$(EXE) crypto/test/kernel_driver$(EXE) \
|
||||
crypto/test/rand_gen$(EXE) crypto/test/sha1_driver$(EXE) \
|
||||
crypto/test/stat_driver$(EXE)
|
||||
|
||||
testapp = $(crypto_testapp) test/srtp_driver$(EXE) test/replay_driver$(EXE) \
|
||||
test/roc_driver$(EXE) test/rdbx_driver$(EXE) test/rtpw$(EXE) \
|
||||
test/dtls_srtp_driver$(EXE)
|
||||
|
||||
$(testapp): libsrtp.a
|
||||
|
||||
test/rtpw$(EXE): test/rtpw.c test/rtp.c test/getopt_s.c
|
||||
$(COMPILE) $(LDFLAGS) -o $@ $^ $(LIBS) $(SRTPLIB)
|
||||
|
||||
test/srtp_driver$(EXE): test/srtp_driver.c test/getopt_s.c
|
||||
$(COMPILE) $(LDFLAGS) -o $@ $^ $(LIBS) $(SRTPLIB)
|
||||
|
||||
test/rdbx_driver$(EXE): test/rdbx_driver.c test/getopt_s.c
|
||||
$(COMPILE) $(LDFLAGS) -o $@ $^ $(LIBS) $(SRTPLIB)
|
||||
|
||||
test/dtls_srtp_driver$(EXE): test/dtls_srtp_driver.c test/getopt_s.c
|
||||
$(COMPILE) $(LDFLAGS) -o $@ $^ $(LIBS) $(SRTPLIB)
|
||||
|
||||
test: $(testapp)
|
||||
@echo "Build done. Please run '$(MAKE) runtest' to run self tests."
|
||||
|
||||
memtest: test/srtp_driver
|
||||
@test/srtp_driver -v -d "alloc" > tmp
|
||||
@grep freed tmp | wc -l > freed
|
||||
@grep allocated tmp | wc -l > allocated
|
||||
@echo "checking for memory leaks (only works with --enable-stdout)"
|
||||
cmp -s allocated freed
|
||||
@echo "passed (same number of alloc() and dealloc() calls found)"
|
||||
@rm freed allocated tmp
|
||||
|
||||
# tables_apps are used to generate the tables used in the crypto
|
||||
# implementations; these need only be generated during porting, not
|
||||
# for building libsrtp or the test applications
|
||||
|
||||
table_apps = tables/aes_tables
|
||||
|
||||
build_table_apps: $(table_apps)
|
||||
|
||||
# in the tables/ subdirectory, we use libcryptomath instead of libsrtp
|
||||
|
||||
tables/%: tables/%.c libcryptomath.a
|
||||
$(COMPILE) $(LDFLAGS) $< -o $@ $(LIBS) libcryptomath.a
|
||||
|
||||
# the target 'plot' runs the timing test (test/srtp_driver -t) then
|
||||
# uses gnuplot to produce plots of the results - see the script file
|
||||
# 'timing'
|
||||
|
||||
plot: test/srtp_driver
|
||||
test/srtp_driver -t > timing.dat
|
||||
|
||||
|
||||
# bookkeeping: tags, clean, and distribution
|
||||
|
||||
tags:
|
||||
etags */*.[ch] */*/*.[ch]
|
||||
|
||||
|
||||
# documentation - the target libsrtpdoc builds a PDF file documenting
|
||||
# libsrtp
|
||||
|
||||
libsrtpdoc:
|
||||
$(MAKE) -C doc
|
||||
|
||||
.PHONY: clean superclean distclean install
|
||||
|
||||
install:
|
||||
@if [ -r $(DESTDIR)$(includedir)/srtp/srtp.h ]; then \
|
||||
echo "you should run 'make uninstall' first"; exit 1; \
|
||||
fi
|
||||
$(INSTALL) -d $(DESTDIR)$(includedir)/srtp
|
||||
$(INSTALL) -d $(DESTDIR)$(libdir)
|
||||
cp $(srcdir)/include/*.h $(DESTDIR)$(includedir)/srtp
|
||||
cp $(srcdir)/crypto/include/*.h $(DESTDIR)$(includedir)/srtp
|
||||
if [ "$(srcdir)" != "." ]; then cp crypto/include/*.h $(DESTDIR)$(includedir)/srtp; fi
|
||||
if [ -f libsrtp.a ]; then cp libsrtp.a $(DESTDIR)$(libdir)/; fi
|
||||
|
||||
uninstall:
|
||||
rm -f $(DESTDIR)$(includedir)/srtp/*.h
|
||||
rm -f $(DESTDIR)$(libdir)/libsrtp.a
|
||||
-rmdir $(DESTDIR)$(includedir)/srtp
|
||||
|
||||
clean:
|
||||
rm -rf $(cryptobj) $(srtpobj) $(cryptomath) TAGS \
|
||||
libcryptomath.a libsrtp.a core *.core test/core
|
||||
for a in * */* */*/*; do \
|
||||
if [ -f "$$a~" ] ; then rm -f $$a~; fi; \
|
||||
done;
|
||||
for a in $(testapp) $(table_apps); do rm -rf $$a$(EXE); done
|
||||
rm -rf *.pict *.jpg *.dat
|
||||
rm -rf freed allocated tmp
|
||||
$(MAKE) -C doc clean
|
||||
$(MAKE) -C crypto clean
|
||||
|
||||
|
||||
superclean: clean
|
||||
rm -rf crypto/include/config.h config.log config.cache config.status \
|
||||
Makefile crypto/Makefile doc/Makefile \
|
||||
.gdb_history test/.gdb_history .DS_Store
|
||||
rm -rf autom4te.cache
|
||||
|
||||
distclean: superclean
|
||||
|
||||
distname = srtp-$(shell cat VERSION)
|
||||
|
||||
distribution: runtest superclean
|
||||
if ! [ -f VERSION ]; then exit 1; fi
|
||||
if [ -f ../$(distname).tgz ]; then \
|
||||
mv ../$(distname).tgz ../$(distname).tgz.bak; \
|
||||
fi
|
||||
cd ..; tar cvzf $(distname).tgz srtp
|
||||
|
||||
# EOF
|
||||
|
|
@ -1,174 +0,0 @@
|
|||
Secure RTP (SRTP) Reference Implementation
|
||||
David A. McGrew
|
||||
Cisco Systems, Inc.
|
||||
mcgrew@cisco.com
|
||||
|
||||
|
||||
This package provides an implementation of the Secure Real-time
|
||||
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). An overview and reference manual is available in
|
||||
doc/libsrtp.pdf. The PDF documentation is more up to date than this
|
||||
file.
|
||||
|
||||
|
||||
Installation:
|
||||
|
||||
./configure [ options ] # GNU autoconf script
|
||||
make # or gmake if needed; use GNU make
|
||||
|
||||
The configure script accepts the following options:
|
||||
|
||||
--help provides a usage summary
|
||||
--disable-debug compile without the runtime debugging system
|
||||
--enable-syslog use syslog for error reporting
|
||||
--disable-stdout use stdout for error reporting
|
||||
--enable-console use /dev/console for error reporting
|
||||
--gdoi use GDOI key management (disabled at present)
|
||||
|
||||
By default, debbuging is enabled and stdout is used for debugging.
|
||||
You can use the above configure options to have the debugging output
|
||||
sent to syslog or the system console. Alternatively, you can define
|
||||
ERR_REPORTING_FILE in include/conf.h to be any other file that can be
|
||||
opened by libSRTP, and debug messages will be sent to it.
|
||||
|
||||
This package has been tested on Mac OS X (powerpc-apple-darwin1.4),
|
||||
Cygwin (i686-pc-cygwin), and Sparc (sparc-sun-solaris2.6). Previous
|
||||
versions have been tested on Linux and OpenBSD on both x86 and sparc
|
||||
platforms.
|
||||
|
||||
A quick tour of this package:
|
||||
|
||||
Makefile targets: all, clean, ...
|
||||
README this file
|
||||
CHANGES change log
|
||||
VERSION version number of this package
|
||||
LICENSE legal details (it's a BSD-like license)
|
||||
crypto/ciphers/ ciphers (null, aes_icm, ...)
|
||||
crypto/math/ crypto math routines
|
||||
crypto/hash/ crypto hashing (hmac, tmmhv2, ...)
|
||||
crypto/replay/ replay protection
|
||||
doc/ documentation: rfcs, apis, and suchlike
|
||||
include/ include files for all code in distribution
|
||||
srtp/ secure real-time transport protocol implementation
|
||||
tables/ apps for generating tables (useful in porting)
|
||||
test/ test drivers
|
||||
|
||||
|
||||
Applications
|
||||
|
||||
Several test drivers and a simple and portable srtp application
|
||||
are included in the test/ subdirectory.
|
||||
|
||||
test driver function tested
|
||||
-------------------------------------------------------------
|
||||
kernel_driver crypto kernel (ciphers, auth funcs, rng)
|
||||
srtp_driver srtp in-memory tests (does not use the network)
|
||||
rdbx_driver rdbx (extended replay database)
|
||||
roc_driver extended sequence number functions
|
||||
replay_driver replay database (n.b. not used in libsrtp)
|
||||
cipher_driver ciphers
|
||||
auth_driver hash functions
|
||||
|
||||
The app rtpw is a simple rtp application which reads words from
|
||||
/usr/dict/words and then sends them out one at a time using [s]rtp.
|
||||
Manual srtp keying uses the -k option; automated key management
|
||||
using gdoi will be added later.
|
||||
|
||||
usage: rtpw [-d <debug>]* [-k <key> [-a][-e]] [-s | -r] dest_ip dest_port
|
||||
or rtpw -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 the dictionary will be sent, respectively.
|
||||
|
||||
options:
|
||||
|
||||
-s (s)rtp sender - causes app to send words
|
||||
|
||||
-r (s)rtp receive - causes app to receve words
|
||||
|
||||
-k <key> use srtp master key <key>, where the
|
||||
key is a hexadecimal value (without the
|
||||
leading "0x")
|
||||
|
||||
-e encrypt/decrypt (for data confidentiality)
|
||||
(requires use of -k option as well)
|
||||
|
||||
-a message authentication
|
||||
(requires use of -k option as well)
|
||||
|
||||
-l list debug modules
|
||||
|
||||
-d <debug> turn on debugging for module <debug>
|
||||
|
||||
|
||||
In order to get random 30-byte values for use as key/salt pairs , you
|
||||
can use the following bash function to format the output of
|
||||
/dev/random (where that device is available).
|
||||
|
||||
function randhex() {
|
||||
cat /dev/random | od --read-bytes=32 --width=32 -x | awk '{ print $2 $3 $4 $5 $6 $7 $8 $9 $10 $11 $12 $13 $14 $15 $16 }'
|
||||
}
|
||||
|
||||
|
||||
An example of an SRTP session using two rtpw programs follows:
|
||||
|
||||
set k=c1eec3717da76195bb878578790af71c4ee9f859e197a414a78d5abc7451
|
||||
|
||||
[sh1]$ test/rtpw -s -k $k -ea 0.0.0.0 9999
|
||||
Security services: confidentiality message authentication
|
||||
set master key/salt to C1EEC3717DA76195BB878578790AF71C/4EE9F859E197A414A78D5ABC7451
|
||||
setting SSRC to 2078917053
|
||||
sending word: A
|
||||
sending word: a
|
||||
sending word: aa
|
||||
sending word: aal
|
||||
...
|
||||
|
||||
[sh2]$ test/rtpw -r -k $k -ea 0.0.0.0 9999
|
||||
security services: confidentiality message authentication
|
||||
set master key/salt to C1EEC3717DA76195BB878578790AF71C/4EE9F859E197A414A78D5ABC7451
|
||||
19 octets received from SSRC 2078917053 word: A
|
||||
19 octets received from SSRC 2078917053 word: a
|
||||
20 octets received from SSRC 2078917053 word: aa
|
||||
21 octets received from SSRC 2078917053 word: aal
|
||||
...
|
||||
|
||||
Implementation Notes
|
||||
|
||||
* The srtp_protect() function assumes that the buffer holding the
|
||||
rtp packet has enough storage allocated that the authentication
|
||||
tag can be written to the end of that packet. If this assumption
|
||||
is not valid, memory corruption will ensue.
|
||||
|
||||
* Automated tests for the crypto functions are provided through
|
||||
the cipher_type_self_test() and auth_type_self_test() functions.
|
||||
These functions should be used to test each port of this code
|
||||
to a new platform.
|
||||
|
||||
* Replay protection is contained in the crypto engine, and
|
||||
tests for it are provided.
|
||||
|
||||
* This implementation provides calls to initialize, protect, and
|
||||
unprotect RTP packets, and makes as few as possible assumptions
|
||||
about how these functions will be called. For example, the
|
||||
caller is not expected to provide packets in order (though if
|
||||
they're called more than 65k out of sequence, synchronization
|
||||
will be lost).
|
||||
|
||||
* The sequence number in the rtp packet is used as the low 16 bits
|
||||
of the sender's local packet index. Note that RTP will start its
|
||||
sequence number in a random place, and the SRTP layer just jumps
|
||||
forward to that number at its first invocation. An earlier
|
||||
version of this library used initial sequence numbers that are
|
||||
less than 32,768; this trick is no longer required as the
|
||||
rdbx_estimate_index(...) function has been made smarter.
|
||||
|
||||
* The replay window is 128 bits in length, and is hard-coded to this
|
||||
value for now.
|
||||
|
||||
|
||||
|
|
@ -1,22 +0,0 @@
|
|||
========================================================================
|
||||
STATIC LIBRARY : srtp Project Overview
|
||||
========================================================================
|
||||
|
||||
AppWizard has created this srtp library project for you.
|
||||
|
||||
No source files were created as part of your project.
|
||||
|
||||
|
||||
srtp.vcproj
|
||||
This is the main project file for VC++ projects generated using an Application Wizard.
|
||||
It contains information about the version of Visual C++ that generated the file, and
|
||||
information about the platforms, configurations, and project features selected with the
|
||||
Application Wizard.
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
Other notes:
|
||||
|
||||
AppWizard uses "TODO:" comments to indicate parts of the source code you
|
||||
should add to or customize.
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -1,66 +0,0 @@
|
|||
TODO List
|
||||
|
||||
1.4.1
|
||||
|
||||
- document which fields are in NBO/HBO, and check for consistency.
|
||||
|
||||
- move HAVE_U_LONG_LONG inside of datatypes.c, or some other
|
||||
separate file
|
||||
|
||||
- re-write configure.in to make cross-compilation easier
|
||||
|
||||
- eliminate GENERIC_AESICM by generalizing the code a bit
|
||||
|
||||
Older comments
|
||||
|
||||
- add tests for key_limit_t datatype
|
||||
|
||||
- move octet_get_weight() from datatypes.c to math.c (any other
|
||||
funcs?)
|
||||
|
||||
Changes and additions planned
|
||||
|
||||
Make cipher and auth dealloc() functions zeroize the key-storage
|
||||
areas before calling free().
|
||||
|
||||
Eliminate key_len from auth_init()
|
||||
|
||||
Doucument internal APIs (cipher, auth, srtp_protect, ...)
|
||||
|
||||
|
||||
SRTP options not (yet) included in this libaray:
|
||||
|
||||
- the aes-f8-mode cipher
|
||||
- the Master Key Index
|
||||
- re-keying using the key derivation function (only the initial
|
||||
use of the PRF has been implemented, as it's sufficient
|
||||
for most uses)
|
||||
|
||||
|
||||
(OLD) PLANNED CHANGES
|
||||
|
||||
strip out test/lfsr.c
|
||||
|
||||
Write new documentation!!!
|
||||
|
||||
Fix the x86 assembly code in aes.c.
|
||||
|
||||
Eliminate /* DAM */ - there's one in srtp.c
|
||||
|
||||
Change debugging so that it can print more than one line. Or perhaps
|
||||
just change it so that a single check of the debug-enabled flag is
|
||||
needed.
|
||||
|
||||
Improve interface between cipher and rdbx - perhaps generalize rdbx
|
||||
into 'nonce' datatype.
|
||||
|
||||
Make rijndael_icm accept variable sized keys.
|
||||
|
||||
Add rdbx functions that allow different-sized explicit sequence
|
||||
numbers to be used.
|
||||
|
||||
Write uniform byte-buffering code for PRFs, preferably as macros.
|
||||
|
||||
Consider eliminating low-level alloc functions in favor of len()
|
||||
functions, so that there need not be multiple allocations within a
|
||||
particular alloc() function.
|
||||
|
|
@ -1 +0,0 @@
|
|||
1.4.4
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -1,174 +0,0 @@
|
|||
/* Hacked config.h for Windows XP 32-bit & VC7 */
|
||||
|
||||
#ifdef (_MSC_VER >= 1400)
|
||||
# define HAVE_RAND_S 1
|
||||
#endif
|
||||
|
||||
/* Define if building for a CISC machine (e.g. Intel). */
|
||||
#define CPU_CISC 1
|
||||
|
||||
/* Define if building for a RISC machine (assume slow byte access). */
|
||||
#undef CPU_RISC
|
||||
|
||||
/* Path to random device */
|
||||
#undef DEV_URANDOM
|
||||
|
||||
/* Define to compile in dynamic debugging system. */
|
||||
#undef ENABLE_DEBUGGING
|
||||
|
||||
/* Report errors to this file. */
|
||||
#undef ERR_REPORTING_FILE
|
||||
|
||||
/* Define to use logging to stdout. */
|
||||
#undef ERR_REPORTING_STDOUT
|
||||
|
||||
/* Define this to use ISMAcryp code. */
|
||||
#undef GENERIC_AESICM
|
||||
|
||||
/* Define to 1 if you have the <arpa/inet.h> header file. */
|
||||
#undef HAVE_ARPA_INET_H
|
||||
|
||||
/* Define to 1 if you have the <byteswap.h> header file. */
|
||||
#undef HAVE_BYTESWAP_H
|
||||
|
||||
/* Define to 1 if you have the `inet_aton' function. */
|
||||
#define HAVE_INET_ATON 1
|
||||
|
||||
/* Define to 1 if the system has the type `int16_t'. */
|
||||
#undef HAVE_INT16_T
|
||||
|
||||
/* Define to 1 if the system has the type `int32_t'. */
|
||||
#undef HAVE_INT32_T
|
||||
|
||||
/* Define to 1 if the system has the type `int8_t'. */
|
||||
#undef HAVE_INT8_T
|
||||
|
||||
/* Define to 1 if you have the <inttypes.h> header file. */
|
||||
#undef HAVE_INTTYPES_H
|
||||
|
||||
/* Define to 1 if you have the `socket' library (-lsocket). */
|
||||
#undef HAVE_LIBSOCKET
|
||||
|
||||
/* Define to 1 if you have the <machine/types.h> header file. */
|
||||
#undef HAVE_MACHINE_TYPES_H
|
||||
|
||||
/* Define to 1 if you have the <memory.h> header file. */
|
||||
#define HAVE_MEMORY_H 1
|
||||
|
||||
/* Define to 1 if you have the <netinet/in.h> header file. */
|
||||
#undef HAVE_NETINET_IN_H
|
||||
|
||||
/* Define to 1 if you have the `socket' function. */
|
||||
#define HAVE_SOCKET 1
|
||||
|
||||
/* Define to 1 if you have the <stdint.h> header file. */
|
||||
#undef HAVE_STDINT_H
|
||||
|
||||
/* Define to 1 if you have the <stdlib.h> header file. */
|
||||
#define HAVE_STDLIB_H 1
|
||||
|
||||
/* Define to 1 if you have the <strings.h> header file. */
|
||||
#define HAVE_STRINGS_H 1
|
||||
|
||||
/* Define to 1 if you have the <string.h> header file. */
|
||||
#define HAVE_STRING_H 1
|
||||
|
||||
/* Define to 1 if you have the <syslog.h> header file. */
|
||||
#undef HAVE_SYSLOG_H
|
||||
|
||||
/* Define to 1 if you have the <sys/int_types.h> header file. */
|
||||
#undef HAVE_SYS_INT_TYPES_H
|
||||
|
||||
/* Define to 1 if you have the <sys/socket.h> header file. */
|
||||
#undef HAVE_SYS_SOCKET_H
|
||||
|
||||
/* Define to 1 if you have the <sys/stat.h> header file. */
|
||||
#undef HAVE_SYS_STAT_H
|
||||
|
||||
/* Define to 1 if you have the <sys/types.h> header file. */
|
||||
#undef HAVE_SYS_TYPES_H
|
||||
|
||||
/* Define to 1 if you have the <sys/uio.h> header file. */
|
||||
#undef HAVE_SYS_UIO_H
|
||||
|
||||
/* Define to 1 if the system has the type `uint16_t'. */
|
||||
#undef HAVE_UINT16_T
|
||||
|
||||
/* Define to 1 if the system has the type `uint32_t'. */
|
||||
#undef HAVE_UINT32_T
|
||||
|
||||
/* Define to 1 if the system has the type `uint64_t'. */
|
||||
#undef HAVE_UINT64_T
|
||||
|
||||
/* Define to 1 if the system has the type `uint8_t'. */
|
||||
#undef HAVE_UINT8_T
|
||||
|
||||
/* Define to 1 if you have the <unistd.h> header file. */
|
||||
#define HAVE_UNISTD_H 1
|
||||
|
||||
/* Define to 1 if you have the `usleep' function. */
|
||||
#define HAVE_USLEEP 1
|
||||
|
||||
/* Define to 1 if you have the <windows.h> header file. */
|
||||
#define HAVE_WINDOWS_H 1
|
||||
|
||||
/* Define to 1 if you have the <winsock2.h> header file. */
|
||||
#define HAVE_WINSOCK2_H 1
|
||||
|
||||
/* Define to use X86 inlined assembly code */
|
||||
#undef HAVE_X86
|
||||
|
||||
/* Define to the address where bug reports for this package should be sent. */
|
||||
#undef PACKAGE_BUGREPORT
|
||||
|
||||
/* Define to the full name of this package. */
|
||||
#undef PACKAGE_NAME
|
||||
|
||||
/* Define to the full name and version of this package. */
|
||||
#undef PACKAGE_STRING
|
||||
|
||||
/* Define to the one symbol short name of this package. */
|
||||
#undef PACKAGE_TARNAME
|
||||
|
||||
/* Define to the version of this package. */
|
||||
#undef PACKAGE_VERSION
|
||||
|
||||
/* The size of a `unsigned long', as computed by sizeof. */
|
||||
#define SIZEOF_UNSIGNED_LONG 4
|
||||
|
||||
/* The size of a `unsigned long long', as computed by sizeof. */
|
||||
#define SIZEOF_UNSIGNED_LONG_LONG 8
|
||||
|
||||
/* Define to use GDOI. */
|
||||
#undef SRTP_GDOI
|
||||
|
||||
/* Define to compile for kernel contexts. */
|
||||
#undef SRTP_KERNEL
|
||||
|
||||
/* Define to compile for Linux kernel context. */
|
||||
#undef SRTP_KERNEL_LINUX
|
||||
|
||||
/* Define to 1 if you have the ANSI C header files. */
|
||||
#undef STDC_HEADERS
|
||||
|
||||
/* Write errors to this file */
|
||||
#undef USE_ERR_REPORTING_FILE
|
||||
|
||||
/* Define to use syslog logging. */
|
||||
#undef USE_SYSLOG
|
||||
|
||||
/* Define to 1 if your processor stores words with the most significant byte
|
||||
first (like Motorola and SPARC, unlike Intel and VAX). */
|
||||
#undef WORDS_BIGENDIAN
|
||||
|
||||
/* 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
|
||||
//#undef inline
|
||||
//#endif
|
||||
#define inline __inline
|
||||
|
||||
/* Define to `unsigned' if <sys/types.h> does not define. */
|
||||
//#undef size_t
|
||||
|
|
@ -1,196 +0,0 @@
|
|||
/* 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
|
||||
|
||||
/* Define if building for a RISC machine (assume slow byte access). */
|
||||
/* #undef CPU_RISC */
|
||||
|
||||
/* Path to random device */
|
||||
/* #define DEV_URANDOM "/dev/urandom" */
|
||||
|
||||
/* Define to compile in dynamic debugging system. */
|
||||
#define ENABLE_DEBUGGING 1
|
||||
|
||||
/* Report errors to this file. */
|
||||
/* #undef ERR_REPORTING_FILE */
|
||||
|
||||
/* Define to use logging to stdout. */
|
||||
#define ERR_REPORTING_STDOUT 1
|
||||
|
||||
/* Define this to use ISMAcryp code. */
|
||||
/* #undef GENERIC_AESICM */
|
||||
|
||||
/* Define to 1 if you have the <arpa/inet.h> header file. */
|
||||
/* #undef HAVE_ARPA_INET_H */
|
||||
|
||||
/* Define to 1 if you have the <byteswap.h> header file. */
|
||||
/* #undef HAVE_BYTESWAP_H */
|
||||
|
||||
/* Define to 1 if you have the `inet_aton' function. */
|
||||
/* #undef HAVE_INET_ATON */
|
||||
|
||||
/* Define to 1 if the system has the type `int16_t'. */
|
||||
#define HAVE_INT16_T 1
|
||||
|
||||
/* Define to 1 if the system has the type `int32_t'. */
|
||||
#define HAVE_INT32_T 1
|
||||
|
||||
/* Define to 1 if the system has the type `int8_t'. */
|
||||
#define HAVE_INT8_T 1
|
||||
|
||||
/* Define to 1 if you have the <inttypes.h> header file. */
|
||||
/* #undef HAVE_INTTYPES_H */
|
||||
|
||||
/* Define to 1 if you have the `socket' library (-lsocket). */
|
||||
/* #undef HAVE_LIBSOCKET */
|
||||
|
||||
/* Define to 1 if you have the <machine/types.h> header file. */
|
||||
/* #undef HAVE_MACHINE_TYPES_H */
|
||||
|
||||
/* Define to 1 if you have the <memory.h> header file. */
|
||||
#define HAVE_MEMORY_H 1
|
||||
|
||||
/* Define to 1 if you have the <netinet/in.h> header file. */
|
||||
/* #undef HAVE_NETINET_IN_H */
|
||||
|
||||
/* Define to 1 if you have the `socket' function. */
|
||||
/* #undef HAVE_SOCKET */
|
||||
|
||||
/* Define to 1 if you have the <stdint.h> header file. */
|
||||
/* #undef HAVE_STDINT_H */
|
||||
|
||||
/* Define to 1 if you have the <stdlib.h> header file. */
|
||||
#define HAVE_STDLIB_H 1
|
||||
|
||||
/* Define to 1 if you have the <strings.h> header file. */
|
||||
#define HAVE_STRINGS_H 1
|
||||
|
||||
/* Define to 1 if you have the <string.h> header file. */
|
||||
#define HAVE_STRING_H 1
|
||||
|
||||
/* Define to 1 if you have the <syslog.h> header file. */
|
||||
/* #undef HAVE_SYSLOG_H */
|
||||
|
||||
/* Define to 1 if you have the <sys/int_types.h> header file. */
|
||||
/* #undef HAVE_SYS_INT_TYPES_H */
|
||||
|
||||
/* Define to 1 if you have the <sys/socket.h> header file. */
|
||||
/* #undef HAVE_SYS_SOCKET_H */
|
||||
|
||||
/* Define to 1 if you have the <sys/stat.h> header file. */
|
||||
#define HAVE_SYS_STAT_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/types.h> header file. */
|
||||
#define HAVE_SYS_TYPES_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/uio.h> header file. */
|
||||
/* #undef HAVE_SYS_UIO_H */
|
||||
|
||||
/* Define to 1 if the system has the type `uint16_t'. */
|
||||
#define HAVE_UINT16_T 1
|
||||
|
||||
/* Define to 1 if the system has the type `uint32_t'. */
|
||||
#define HAVE_UINT32_T 1
|
||||
|
||||
/* Define to 1 if the system has the type `uint64_t'. */
|
||||
#define HAVE_UINT64_T 1
|
||||
|
||||
/* Define to 1 if the system has the type `uint8_t'. */
|
||||
#define HAVE_UINT8_T 1
|
||||
|
||||
/* Define to 1 if you have the <unistd.h> header file. */
|
||||
/* #undef HAVE_UNISTD_H */
|
||||
|
||||
/* Define to 1 if you have the `usleep' function. */
|
||||
/* #undef HAVE_USLEEP */
|
||||
|
||||
/* Define to 1 if you have the <windows.h> header file. */
|
||||
#define HAVE_WINDOWS_H 1
|
||||
|
||||
/* Define to 1 if you have the <winsock2.h> header file. */
|
||||
#define HAVE_WINSOCK2_H 1
|
||||
|
||||
/* Define to use X86 inlined assembly code */
|
||||
/* #undef HAVE_X86 */
|
||||
|
||||
/* Define to the address where bug reports for this package should be sent. */
|
||||
#define PACKAGE_BUGREPORT ""
|
||||
|
||||
/* Define to the full name of this package. */
|
||||
#define PACKAGE_NAME ""
|
||||
|
||||
/* Define to the full name and version of this package. */
|
||||
#define PACKAGE_STRING ""
|
||||
|
||||
/* Define to the one symbol short name of this package. */
|
||||
#define PACKAGE_TARNAME ""
|
||||
|
||||
/* Define to the version of this package. */
|
||||
#define PACKAGE_VERSION ""
|
||||
|
||||
/* The size of a `unsigned long', as computed by sizeof. */
|
||||
#define SIZEOF_UNSIGNED_LONG 4
|
||||
|
||||
/* The size of a `unsigned long long', as computed by sizeof. */
|
||||
#define SIZEOF_UNSIGNED_LONG_LONG 8
|
||||
|
||||
/* Define to use GDOI. */
|
||||
/* #undef SRTP_GDOI */
|
||||
|
||||
/* Define to compile for kernel contexts. */
|
||||
/* #undef SRTP_KERNEL */
|
||||
|
||||
/* Define to compile for Linux kernel context. */
|
||||
/* #undef SRTP_KERNEL_LINUX */
|
||||
|
||||
/* Define to 1 if you have the ANSI C header files. */
|
||||
#define STDC_HEADERS 1
|
||||
|
||||
/* Write errors to this file */
|
||||
/* #undef USE_ERR_REPORTING_FILE */
|
||||
|
||||
/* Define to use syslog logging. */
|
||||
/* #undef USE_SYSLOG */
|
||||
|
||||
/* Define to 1 if your processor stores words with the most significant byte
|
||||
first (like Motorola and SPARC, unlike Intel and VAX). */
|
||||
/* #undef WORDS_BIGENDIAN */
|
||||
|
||||
/* Define to empty if `const' does not conform to ANSI C. */
|
||||
/* #undef const */
|
||||
|
||||
/* 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 */
|
||||
|
||||
#if (_MSC_VER >= 1400) // VC8+
|
||||
#ifndef _CRT_SECURE_NO_DEPRECATE
|
||||
#define _CRT_SECURE_NO_DEPRECATE
|
||||
#endif
|
||||
#ifndef _CRT_NONSTDC_NO_DEPRECATE
|
||||
#define _CRT_NONSTDC_NO_DEPRECATE
|
||||
#endif
|
||||
#endif // VC8+
|
||||
|
||||
#ifndef uint32_t
|
||||
typedef unsigned __int8 uint8_t;
|
||||
typedef unsigned __int16 uint16_t;
|
||||
typedef unsigned __int32 uint32_t;
|
||||
typedef unsigned __int64 uint64_t;
|
||||
typedef __int8 int8_t;
|
||||
typedef __int16 int16_t;
|
||||
typedef __int32 int32_t;
|
||||
typedef __int64 int64_t;
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(disable:4311)
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -1,173 +0,0 @@
|
|||
/* config_in.h. Generated from configure.in by autoheader. */
|
||||
|
||||
/* Define if building for a CISC machine (e.g. Intel). */
|
||||
#undef CPU_CISC
|
||||
|
||||
/* Define if building for a RISC machine (assume slow byte access). */
|
||||
#undef CPU_RISC
|
||||
|
||||
/* Path to random device */
|
||||
#undef DEV_URANDOM
|
||||
|
||||
/* Define to compile in dynamic debugging system. */
|
||||
#undef ENABLE_DEBUGGING
|
||||
|
||||
/* Report errors to this file. */
|
||||
#undef ERR_REPORTING_FILE
|
||||
|
||||
/* Define to use logging to stdout. */
|
||||
#undef ERR_REPORTING_STDOUT
|
||||
|
||||
/* Define this to use ISMAcryp code. */
|
||||
#undef GENERIC_AESICM
|
||||
|
||||
/* Define to 1 if you have the <arpa/inet.h> header file. */
|
||||
#undef HAVE_ARPA_INET_H
|
||||
|
||||
/* Define to 1 if you have the <byteswap.h> header file. */
|
||||
#undef HAVE_BYTESWAP_H
|
||||
|
||||
/* Define to 1 if you have the `inet_aton' function. */
|
||||
#undef HAVE_INET_ATON
|
||||
|
||||
/* Define to 1 if the system has the type `int16_t'. */
|
||||
#undef HAVE_INT16_T
|
||||
|
||||
/* Define to 1 if the system has the type `int32_t'. */
|
||||
#undef HAVE_INT32_T
|
||||
|
||||
/* Define to 1 if the system has the type `int8_t'. */
|
||||
#undef HAVE_INT8_T
|
||||
|
||||
/* Define to 1 if you have the <inttypes.h> header file. */
|
||||
#undef HAVE_INTTYPES_H
|
||||
|
||||
/* Define to 1 if you have the `socket' library (-lsocket). */
|
||||
#undef HAVE_LIBSOCKET
|
||||
|
||||
/* Define to 1 if you have the <machine/types.h> header file. */
|
||||
#undef HAVE_MACHINE_TYPES_H
|
||||
|
||||
/* Define to 1 if you have the <memory.h> header file. */
|
||||
#undef HAVE_MEMORY_H
|
||||
|
||||
/* Define to 1 if you have the <netinet/in.h> header file. */
|
||||
#undef HAVE_NETINET_IN_H
|
||||
|
||||
/* Define to 1 if you have the `sigaction' function. */
|
||||
#undef HAVE_SIGACTION
|
||||
|
||||
/* Define to 1 if you have the `socket' function. */
|
||||
#undef HAVE_SOCKET
|
||||
|
||||
/* Define to 1 if you have the <stdint.h> header file. */
|
||||
#undef HAVE_STDINT_H
|
||||
|
||||
/* Define to 1 if you have the <stdlib.h> header file. */
|
||||
#undef HAVE_STDLIB_H
|
||||
|
||||
/* Define to 1 if you have the <strings.h> header file. */
|
||||
#undef HAVE_STRINGS_H
|
||||
|
||||
/* Define to 1 if you have the <string.h> header file. */
|
||||
#undef HAVE_STRING_H
|
||||
|
||||
/* Define to 1 if you have the <syslog.h> header file. */
|
||||
#undef HAVE_SYSLOG_H
|
||||
|
||||
/* Define to 1 if you have the <sys/int_types.h> header file. */
|
||||
#undef HAVE_SYS_INT_TYPES_H
|
||||
|
||||
/* Define to 1 if you have the <sys/socket.h> header file. */
|
||||
#undef HAVE_SYS_SOCKET_H
|
||||
|
||||
/* Define to 1 if you have the <sys/stat.h> header file. */
|
||||
#undef HAVE_SYS_STAT_H
|
||||
|
||||
/* Define to 1 if you have the <sys/types.h> header file. */
|
||||
#undef HAVE_SYS_TYPES_H
|
||||
|
||||
/* Define to 1 if you have the <sys/uio.h> header file. */
|
||||
#undef HAVE_SYS_UIO_H
|
||||
|
||||
/* Define to 1 if the system has the type `uint16_t'. */
|
||||
#undef HAVE_UINT16_T
|
||||
|
||||
/* Define to 1 if the system has the type `uint32_t'. */
|
||||
#undef HAVE_UINT32_T
|
||||
|
||||
/* Define to 1 if the system has the type `uint64_t'. */
|
||||
#undef HAVE_UINT64_T
|
||||
|
||||
/* Define to 1 if the system has the type `uint8_t'. */
|
||||
#undef HAVE_UINT8_T
|
||||
|
||||
/* Define to 1 if you have the <unistd.h> header file. */
|
||||
#undef HAVE_UNISTD_H
|
||||
|
||||
/* Define to 1 if you have the `usleep' function. */
|
||||
#undef HAVE_USLEEP
|
||||
|
||||
/* Define to 1 if you have the <windows.h> header file. */
|
||||
#undef HAVE_WINDOWS_H
|
||||
|
||||
/* Define to 1 if you have the <winsock2.h> header file. */
|
||||
#undef HAVE_WINSOCK2_H
|
||||
|
||||
/* Define to use X86 inlined assembly code */
|
||||
#undef HAVE_X86
|
||||
|
||||
/* Define to the address where bug reports for this package should be sent. */
|
||||
#undef PACKAGE_BUGREPORT
|
||||
|
||||
/* Define to the full name of this package. */
|
||||
#undef PACKAGE_NAME
|
||||
|
||||
/* Define to the full name and version of this package. */
|
||||
#undef PACKAGE_STRING
|
||||
|
||||
/* Define to the one symbol short name of this package. */
|
||||
#undef PACKAGE_TARNAME
|
||||
|
||||
/* Define to the version of this package. */
|
||||
#undef PACKAGE_VERSION
|
||||
|
||||
/* The size of a `unsigned long', as computed by sizeof. */
|
||||
#undef SIZEOF_UNSIGNED_LONG
|
||||
|
||||
/* The size of a `unsigned long long', as computed by sizeof. */
|
||||
#undef SIZEOF_UNSIGNED_LONG_LONG
|
||||
|
||||
/* Define to use GDOI. */
|
||||
#undef SRTP_GDOI
|
||||
|
||||
/* Define to compile for kernel contexts. */
|
||||
#undef SRTP_KERNEL
|
||||
|
||||
/* Define to compile for Linux kernel context. */
|
||||
#undef SRTP_KERNEL_LINUX
|
||||
|
||||
/* Define to 1 if you have the ANSI C header files. */
|
||||
#undef STDC_HEADERS
|
||||
|
||||
/* Write errors to this file */
|
||||
#undef USE_ERR_REPORTING_FILE
|
||||
|
||||
/* Define to use syslog logging. */
|
||||
#undef USE_SYSLOG
|
||||
|
||||
/* Define to 1 if your processor stores words with the most significant byte
|
||||
first (like Motorola and SPARC, unlike Intel and VAX). */
|
||||
#undef WORDS_BIGENDIAN
|
||||
|
||||
/* 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
|
||||
#undef inline
|
||||
#endif
|
||||
|
||||
/* Define to `unsigned' if <sys/types.h> does not define. */
|
||||
#undef size_t
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -1,209 +0,0 @@
|
|||
dnl Process this file with autoconf to produce a configure script.
|
||||
AC_INIT(srtp)
|
||||
|
||||
dnl Must come before AC_PROG_CC
|
||||
if test -z "$CFLAGS"; then
|
||||
dnl Default value for CFLAGS if not specified.
|
||||
CFLAGS="-Wall -O4 -fexpensive-optimizations -funroll-loops"
|
||||
fi
|
||||
|
||||
dnl Checks for programs.
|
||||
AC_PROG_RANLIB
|
||||
AC_PROG_CC
|
||||
AC_PROG_INSTALL
|
||||
|
||||
dnl Check the byte order
|
||||
AC_C_BIGENDIAN
|
||||
|
||||
AC_CANONICAL_HOST
|
||||
|
||||
dnl check host_cpu type, set defines appropriately
|
||||
case $host_cpu in
|
||||
i*86 )
|
||||
AC_DEFINE(CPU_CISC, 1,
|
||||
[Define if building for a CISC machine (e.g. Intel).])
|
||||
AC_DEFINE(HAVE_X86, 1,
|
||||
[Define to use X86 inlined assembly code]);;
|
||||
* )
|
||||
# CPU_RISC is only supported for big endian machines.
|
||||
if test "$ac_cv_c_bigendian" = "yes"; then
|
||||
AC_DEFINE(CPU_RISC, 1,
|
||||
[Define if building for a RISC machine (assume slow byte access).])
|
||||
else
|
||||
AC_DEFINE(CPU_CISC, 1)
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
dnl Check if we are on a Windows platform.
|
||||
case $host_os in
|
||||
*cygwin*|*mingw* )
|
||||
EXE=.exe
|
||||
HOST_IS_WINDOWS=yes
|
||||
;;
|
||||
* )
|
||||
EXE=""
|
||||
;;
|
||||
esac
|
||||
AC_SUBST(EXE) # define executable suffix; this is needed for `make clean'
|
||||
|
||||
|
||||
AC_ARG_ENABLE(kernel-linux,
|
||||
[AS_HELP_STRING([--enable-kernel-linux],
|
||||
[build library to run in Linux kernel context])],
|
||||
[], enable_kernel_linux=no)
|
||||
AC_MSG_CHECKING(whether to build for Linux kernel context)
|
||||
if test "$enable_kernel_linux" = "yes"; then
|
||||
AC_DEFINE(SRTP_KERNEL, 1,
|
||||
[Define to compile for kernel contexts.])
|
||||
AC_DEFINE(SRTP_KERNEL_LINUX, 1,
|
||||
[Define to compile for Linux kernel context.])
|
||||
fi
|
||||
AC_MSG_RESULT($enable_kernel_linux)
|
||||
|
||||
if test "$cross_compiling" != yes -a "$HOST_IS_WINDOWS" != yes; then
|
||||
dnl Check for /dev/urandom
|
||||
AC_CHECK_FILE(/dev/urandom, DEV_URANDOM=/dev/urandom,
|
||||
[AC_CHECK_FILE(/dev/random, DEV_URANDOM=/dev/random)])
|
||||
fi
|
||||
|
||||
AC_MSG_CHECKING(which random device to use)
|
||||
if test "$enable_kernel_linux" = "yes"; then
|
||||
RNG_OBJS=rand_linux_kernel.o
|
||||
AC_MSG_RESULT([Linux kernel builtin])
|
||||
else
|
||||
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])
|
||||
else
|
||||
AC_MSG_RESULT([standard rand() function...])
|
||||
fi
|
||||
fi
|
||||
AC_SUBST(RNG_OBJS)
|
||||
|
||||
|
||||
dnl Checks for header files.
|
||||
AC_HEADER_STDC
|
||||
AC_CHECK_HEADERS(stdlib.h)
|
||||
AC_CHECK_HEADERS(unistd.h)
|
||||
AC_CHECK_HEADERS(byteswap.h)
|
||||
AC_CHECK_HEADERS(stdint.h)
|
||||
AC_CHECK_HEADERS(sys/uio.h)
|
||||
AC_CHECK_HEADERS(inttypes.h)
|
||||
AC_CHECK_HEADERS(sys/types.h)
|
||||
AC_CHECK_HEADERS(machine/types.h)
|
||||
AC_CHECK_HEADERS(sys/int_types.h)
|
||||
|
||||
dnl socket() and friends
|
||||
AC_CHECK_HEADERS(sys/socket.h netinet/in.h arpa/inet.h)
|
||||
AC_CHECK_HEADERS(windows.h, [AC_CHECK_HEADERS(winsock2.h)])
|
||||
|
||||
AC_CHECK_HEADERS(syslog.h)
|
||||
|
||||
AC_CHECK_TYPES([int8_t,uint8_t,int16_t,uint16_t,int32_t,uint32_t,uint64_t])
|
||||
AC_CHECK_SIZEOF(unsigned long)
|
||||
AC_CHECK_SIZEOF(unsigned long long)
|
||||
|
||||
dnl Checks for typedefs, structures, and compiler characteristics.
|
||||
AC_C_CONST
|
||||
AC_C_INLINE
|
||||
AC_TYPE_SIZE_T
|
||||
|
||||
dnl Checks for library functions.
|
||||
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
|
||||
AC_CHECK_LIB(socket, socket)
|
||||
AC_MSG_CHECKING([for socket in -lwsock32])
|
||||
SAVELIBS="$LIBS"
|
||||
LIBS="$LIBS -lwsock32"
|
||||
AC_TRY_LINK([
|
||||
#include <winsock2.h>
|
||||
],[
|
||||
socket(0, 0, 0);
|
||||
],
|
||||
ac_cv_func_socket=yes
|
||||
AC_MSG_RESULT(yes),
|
||||
LIBS="$SAVELIBS"
|
||||
AC_MSG_RESULT(no))
|
||||
fi
|
||||
|
||||
AC_MSG_CHECKING(whether to compile in debugging)
|
||||
AC_ARG_ENABLE(debug,
|
||||
[AS_HELP_STRING([--disable-debug],
|
||||
[do not compile in dynamic debugging system])],
|
||||
[], enable_debug=yes)
|
||||
if test "$enable_debug" = "yes"; then
|
||||
AC_DEFINE(ENABLE_DEBUGGING, 1,
|
||||
[Define to compile in dynamic debugging system.])
|
||||
fi
|
||||
AC_MSG_RESULT($enable_debug)
|
||||
|
||||
AC_MSG_CHECKING(whether to use ISMAcryp code)
|
||||
AC_ARG_ENABLE(generic-aesicm,
|
||||
[AS_HELP_STRING([--enable-generic-aesicm],
|
||||
[compile in changes for ISMAcryp])],
|
||||
[], enable_generic_aesicm=no)
|
||||
if test "$enable_generic_aesicm" = "yes"; then
|
||||
AC_DEFINE(GENERIC_AESICM, 1, [Define this to use ISMAcryp code.])
|
||||
fi
|
||||
AC_MSG_RESULT($enable_generic_aesicm)
|
||||
|
||||
AC_MSG_CHECKING(whether to use syslog for error reporting)
|
||||
AC_ARG_ENABLE(syslog,
|
||||
[AS_HELP_STRING([--enable-syslog], [use syslog for error reporting])],
|
||||
[], enable_syslog=no)
|
||||
if test "$enable_syslog" = "yes"; then
|
||||
AC_DEFINE(USE_SYSLOG, 1, [Define to use syslog logging.])
|
||||
fi
|
||||
AC_MSG_RESULT($enable_syslog)
|
||||
|
||||
AC_MSG_CHECKING(whether to use stdout for error reporting)
|
||||
AC_ARG_ENABLE(stdout,
|
||||
[AS_HELP_STRING([--disable-stdout], [don't use stdout for error reporting])],
|
||||
[], enable_stdout=yes)
|
||||
if test "$enable_stdout" = "yes"; then
|
||||
AC_DEFINE(ERR_REPORTING_STDOUT, 1, [Define to use logging to stdout.])
|
||||
fi
|
||||
AC_MSG_RESULT($enable_stdout)
|
||||
|
||||
AC_MSG_CHECKING(whether to use /dev/console for error reporting)
|
||||
AC_ARG_ENABLE(console,
|
||||
[AS_HELP_STRING([--enable-console], [use /dev/console for error reporting])],
|
||||
[], enable_console=no)
|
||||
if test "$enable_console" = "yes"; then
|
||||
AC_DEFINE(USE_ERR_REPORTING_FILE, 1, [Write errors to this file])
|
||||
AC_DEFINE(ERR_REPORTING_FILE, "/dev/console", [Report errors to this file.])
|
||||
fi
|
||||
AC_MSG_RESULT($enable_console)
|
||||
|
||||
AC_MSG_CHECKING(whether to use GDOI key management)
|
||||
AC_ARG_ENABLE(gdoi,
|
||||
[AS_HELP_STRING([--enable-gdoi], [enable GDOI key management])],
|
||||
[], enable_gdoi=no)
|
||||
if test "$enable_gdoi" = "yes"; then
|
||||
AC_DEFINE(SRTP_GDOI, 1, [Define to use GDOI.])
|
||||
GDOI_OBJS=gdoi/srtp+gdoi.o
|
||||
AC_SUBST(GDOI_OBJS)
|
||||
fi
|
||||
AC_MSG_RESULT($enable_gdoi)
|
||||
|
||||
AC_CONFIG_HEADER(crypto/include/config.h:config_in.h)
|
||||
|
||||
AC_OUTPUT(Makefile crypto/Makefile doc/Makefile)
|
||||
|
||||
# This is needed when building outside the source dir.
|
||||
AS_MKDIR_P(crypto/ae_xfm)
|
||||
AS_MKDIR_P(crypto/cipher)
|
||||
AS_MKDIR_P(crypto/hash)
|
||||
AS_MKDIR_P(crypto/kernel)
|
||||
AS_MKDIR_P(crypto/math)
|
||||
AS_MKDIR_P(crypto/replay)
|
||||
AS_MKDIR_P(crypto/rng)
|
||||
AS_MKDIR_P(crypto/test)
|
||||
AS_MKDIR_P(doc)
|
||||
AS_MKDIR_P(srtp)
|
||||
AS_MKDIR_P(tables)
|
||||
AS_MKDIR_P(test)
|
||||
|
|
@ -1,130 +0,0 @@
|
|||
# Makefile for libcryptomodule.a
|
||||
#
|
||||
# David A. McGrew
|
||||
# Cisco Systems, Inc.
|
||||
|
||||
srcdir = .
|
||||
top_srcdir = ..
|
||||
top_builddir = ../
|
||||
|
||||
|
||||
CC = gcc
|
||||
INCDIR = -Iinclude -I$(srcdir)/include
|
||||
DEFS = -DHAVE_CONFIG_H
|
||||
CPPFLAGS=
|
||||
CFLAGS = -Wall -O4 -fexpensive-optimizations -funroll-loops
|
||||
LIBS =
|
||||
LDFLAGS = -L.
|
||||
COMPILE = $(CC) $(DEFS) $(INCDIR) $(CPPFLAGS) $(CFLAGS)
|
||||
CRYPTOLIB = -lcryptomodule
|
||||
|
||||
RANLIB = ranlib
|
||||
|
||||
# EXE defines the suffix on executables - it's .exe for cygwin, and
|
||||
# null on linux, bsd, and OS X and other OSes. we define this so that
|
||||
# `make clean` will work on the cygwin platform
|
||||
EXE =
|
||||
# Random source.
|
||||
RNG_OBJS = rand_source.o
|
||||
|
||||
ifdef ARCH
|
||||
DEFS += -D$(ARCH)=1
|
||||
endif
|
||||
|
||||
ifdef sysname
|
||||
DEFS += -D$(sysname)=1
|
||||
endif
|
||||
|
||||
.PHONY: dummy all runtest clean superclean
|
||||
|
||||
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)
|
||||
|
||||
# data values used to test the aes_calc application
|
||||
|
||||
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/cipher_driver$(EXE) -v >/dev/null
|
||||
test/datatypes_driver$(EXE) -v >/dev/null
|
||||
test/stat_driver$(EXE) >/dev/null
|
||||
test/sha1_driver$(EXE) -v >/dev/null
|
||||
test/kernel_driver$(EXE) -v >/dev/null
|
||||
test/rand_gen$(EXE) -n 256 >/dev/null
|
||||
@echo "libcryptomodule test applications passed."
|
||||
|
||||
# libcryptomodule.a (the crypto engine)
|
||||
|
||||
ciphers = cipher/cipher.o cipher/null_cipher.o \
|
||||
cipher/aes.o cipher/aes_icm.o \
|
||||
cipher/aes_cbc.o
|
||||
|
||||
hashes = hash/null_auth.o hash/sha1.o \
|
||||
hash/hmac.o hash/auth.o
|
||||
|
||||
math = math/datatypes.o math/stat.o
|
||||
|
||||
rng = rng/$(RNG_OBJS) rng/rand_source.o rng/prng.o rng/ctr_prng.o
|
||||
|
||||
err = kernel/err.o
|
||||
|
||||
kernel = kernel/crypto_kernel.o kernel/alloc.o \
|
||||
kernel/key.o $(rng) $(err)
|
||||
|
||||
xfm = ae_xfm/xfm.o
|
||||
|
||||
cryptobj = $(ciphers) $(hashes) $(math) $(stat) $(kernel) $(xfm)
|
||||
|
||||
# the rule for making object files and test apps
|
||||
|
||||
%.o: %.c
|
||||
$(COMPILE) -c $< -o $@
|
||||
|
||||
%$(EXE): %.c libcryptomodule.a
|
||||
$(COMPILE) $(LDFLAGS) $< -o $@ $(CRYPTOLIB) $(LIBS)
|
||||
|
||||
ifndef AR
|
||||
AR=ar
|
||||
endif
|
||||
|
||||
# and the crypto module library itself
|
||||
|
||||
libcryptomodule.a: $(cryptobj)
|
||||
$(AR) cr libcryptomodule.a $(cryptobj)
|
||||
$(RANLIB) libcryptomodule.a
|
||||
|
||||
all: libcryptomodule.a $(testapp)
|
||||
|
||||
# housekeeping functions
|
||||
|
||||
clean:
|
||||
rm -f libcryptomodule.a
|
||||
rm -f $(testapp) *.o */*.o
|
||||
for a in * .* */*; do if [ -f "$$a~" ] ; then rm $$a~; fi; done;
|
||||
rm -f `find . -name "*.[ch]~*~"`
|
||||
rm -rf latex
|
||||
|
||||
superclean: clean
|
||||
rm -f *core TAGS ktrace.out
|
||||
|
||||
|
||||
# the target 'package' builds a compressed tar archive of the source code
|
||||
|
||||
distname = crypto-$(shell cat VERSION)
|
||||
|
||||
package: superclean
|
||||
cd ..; tar cvzf $(distname).tgz crypto/
|
||||
|
||||
|
||||
# EOF
|
||||
|
|
@ -1,137 +0,0 @@
|
|||
# Makefile for libcryptomodule.a
|
||||
#
|
||||
# David A. McGrew
|
||||
# Cisco Systems, Inc.
|
||||
|
||||
srcdir = @srcdir@
|
||||
top_srcdir = @top_srcdir@
|
||||
top_builddir = @top_builddir@
|
||||
VPATH = @srcdir@
|
||||
|
||||
CC = @CC@
|
||||
INCDIR = -Iinclude -I$(srcdir)/include
|
||||
DEFS = @DEFS@
|
||||
CPPFLAGS= @CPPFLAGS@
|
||||
CFLAGS = @CFLAGS@
|
||||
LIBS = @LIBS@
|
||||
LDFLAGS = @LDFLAGS@ -L.
|
||||
COMPILE = $(CC) $(DEFS) $(INCDIR) $(CPPFLAGS) $(CFLAGS)
|
||||
CRYPTOLIB = -lcryptomodule
|
||||
|
||||
RANLIB = @RANLIB@
|
||||
|
||||
# EXE defines the suffix on executables - it's .exe for cygwin, and
|
||||
# null on linux, bsd, and OS X and other OSes. we define this so that
|
||||
# `make clean` will work on the cygwin platform
|
||||
EXE = @EXE@
|
||||
# Random source.
|
||||
RNG_OBJS = @RNG_OBJS@
|
||||
|
||||
ifdef ARCH
|
||||
DEFS += -D$(ARCH)=1
|
||||
endif
|
||||
|
||||
ifdef sysname
|
||||
DEFS += -D$(sysname)=1
|
||||
endif
|
||||
|
||||
.PHONY: dummy all runtest clean superclean
|
||||
|
||||
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)
|
||||
|
||||
# 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
|
||||
|
||||
|
||||
runtest: libcryptomodule.a $(testapp)
|
||||
test/env$(EXE) # print out information on the build environment
|
||||
@echo "running libcryptomodule test applications..."
|
||||
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
|
||||
test/sha1_driver$(EXE) -v >/dev/null
|
||||
test/kernel_driver$(EXE) -v >/dev/null
|
||||
test/rand_gen$(EXE) -n 256 >/dev/null
|
||||
@echo "libcryptomodule test applications passed."
|
||||
|
||||
# libcryptomodule.a (the crypto engine)
|
||||
|
||||
ciphers = cipher/cipher.o cipher/null_cipher.o \
|
||||
cipher/aes.o cipher/aes_icm.o \
|
||||
cipher/aes_cbc.o
|
||||
|
||||
hashes = hash/null_auth.o hash/sha1.o \
|
||||
hash/hmac.o hash/auth.o
|
||||
|
||||
math = math/datatypes.o math/stat.o
|
||||
|
||||
rng = rng/$(RNG_OBJS) rng/rand_source.o rng/prng.o rng/ctr_prng.o
|
||||
|
||||
err = kernel/err.o
|
||||
|
||||
kernel = kernel/crypto_kernel.o kernel/alloc.o \
|
||||
kernel/key.o $(rng) $(err)
|
||||
|
||||
xfm = ae_xfm/xfm.o
|
||||
|
||||
cryptobj = $(ciphers) $(hashes) $(math) $(stat) $(kernel) $(xfm)
|
||||
|
||||
# the rule for making object files and test apps
|
||||
|
||||
%.o: %.c
|
||||
$(COMPILE) -c $< -o $@
|
||||
|
||||
%$(EXE): %.c libcryptomodule.a
|
||||
$(COMPILE) $(LDFLAGS) $< -o $@ $(CRYPTOLIB) $(LIBS)
|
||||
|
||||
ifndef AR
|
||||
AR=ar
|
||||
endif
|
||||
|
||||
# and the crypto module library itself
|
||||
|
||||
libcryptomodule.a: $(cryptobj)
|
||||
$(AR) cr libcryptomodule.a $(cryptobj)
|
||||
$(RANLIB) libcryptomodule.a
|
||||
|
||||
all: libcryptomodule.a $(testapp)
|
||||
|
||||
# housekeeping functions
|
||||
|
||||
clean:
|
||||
rm -f libcryptomodule.a
|
||||
rm -f $(testapp) *.o */*.o
|
||||
for a in * .* */*; do if [ -f "$$a~" ] ; then rm $$a~; fi; done;
|
||||
rm -f `find . -name "*.[ch]~*~"`
|
||||
rm -rf latex
|
||||
|
||||
superclean: clean
|
||||
rm -f *core TAGS ktrace.out
|
||||
|
||||
|
||||
# the target 'package' builds a compressed tar archive of the source code
|
||||
|
||||
distname = crypto-$(shell cat VERSION)
|
||||
|
||||
package: superclean
|
||||
cd ..; tar cvzf $(distname).tgz crypto/
|
||||
|
||||
|
||||
# EOF
|
||||
|
|
@ -1 +0,0 @@
|
|||
1.0.0
|
||||
|
|
@ -1,570 +0,0 @@
|
|||
/*
|
||||
* xfm.c
|
||||
*
|
||||
* Crypto transform implementation
|
||||
*
|
||||
* David A. McGrew
|
||||
* Cisco Systems, Inc.
|
||||
*/
|
||||
|
||||
#include "cryptoalg.h"
|
||||
#include "aes_cbc.h"
|
||||
#include "hmac.h"
|
||||
#include "crypto_kernel.h" /* for crypto_get_random() */
|
||||
|
||||
#define KEY_LEN 16
|
||||
#define ENC_KEY_LEN 16
|
||||
#define MAC_KEY_LEN 16
|
||||
#define IV_LEN 16
|
||||
#define TAG_LEN 12
|
||||
#define MAX_EXPAND 27
|
||||
|
||||
err_status_t
|
||||
aes_128_cbc_hmac_sha1_96_func(void *key,
|
||||
void *clear,
|
||||
unsigned clear_len,
|
||||
void *iv,
|
||||
void *opaque,
|
||||
unsigned *opaque_len,
|
||||
void *auth_tag) {
|
||||
aes_cbc_ctx_t aes_ctx;
|
||||
hmac_ctx_t hmac_ctx;
|
||||
unsigned char enc_key[ENC_KEY_LEN];
|
||||
unsigned char mac_key[MAC_KEY_LEN];
|
||||
err_status_t status;
|
||||
|
||||
/* check if we're doing authentication only */
|
||||
if ((iv == NULL) && (opaque == NULL) && (opaque_len == NULL)) {
|
||||
|
||||
/* perform authentication only */
|
||||
|
||||
} else if ((iv == NULL) || (opaque == NULL) || (opaque_len == NULL)) {
|
||||
|
||||
/*
|
||||
* bad parameter - we expect either all three pointers to be NULL,
|
||||
* or none of those pointers to be NULL
|
||||
*/
|
||||
return err_status_fail;
|
||||
|
||||
} else {
|
||||
|
||||
/* derive encryption and authentication keys from the input key */
|
||||
status = hmac_init(&hmac_ctx, key, KEY_LEN);
|
||||
if (status) return status;
|
||||
status = hmac_compute(&hmac_ctx, "ENC", 3, ENC_KEY_LEN, enc_key);
|
||||
if (status) return status;
|
||||
|
||||
status = hmac_init(&hmac_ctx, key, KEY_LEN);
|
||||
if (status) return status;
|
||||
status = hmac_compute(&hmac_ctx, "MAC", 3, MAC_KEY_LEN, mac_key);
|
||||
if (status) return status;
|
||||
|
||||
|
||||
/* perform encryption and authentication */
|
||||
|
||||
/* set aes key */
|
||||
status = aes_cbc_context_init(&aes_ctx, key, ENC_KEY_LEN, direction_encrypt);
|
||||
if (status) return status;
|
||||
|
||||
/* set iv */
|
||||
status = crypto_get_random(iv, IV_LEN);
|
||||
if (status) return status;
|
||||
status = aes_cbc_set_iv(&aes_ctx, iv);
|
||||
|
||||
/* encrypt the opaque data */
|
||||
status = aes_cbc_nist_encrypt(&aes_ctx, opaque, opaque_len);
|
||||
if (status) return status;
|
||||
|
||||
/* authenticate clear and opaque data */
|
||||
status = hmac_init(&hmac_ctx, mac_key, MAC_KEY_LEN);
|
||||
if (status) return status;
|
||||
|
||||
status = hmac_start(&hmac_ctx);
|
||||
if (status) return status;
|
||||
|
||||
status = hmac_update(&hmac_ctx, clear, clear_len);
|
||||
if (status) return status;
|
||||
|
||||
status = hmac_compute(&hmac_ctx, opaque, *opaque_len, TAG_LEN, auth_tag);
|
||||
if (status) return status;
|
||||
|
||||
}
|
||||
|
||||
return err_status_ok;
|
||||
}
|
||||
|
||||
err_status_t
|
||||
aes_128_cbc_hmac_sha1_96_inv(void *key,
|
||||
void *clear,
|
||||
unsigned clear_len,
|
||||
void *iv,
|
||||
void *opaque,
|
||||
unsigned *opaque_len,
|
||||
void *auth_tag) {
|
||||
aes_cbc_ctx_t aes_ctx;
|
||||
hmac_ctx_t hmac_ctx;
|
||||
unsigned char enc_key[ENC_KEY_LEN];
|
||||
unsigned char mac_key[MAC_KEY_LEN];
|
||||
unsigned char tmp_tag[TAG_LEN];
|
||||
unsigned char *tag = auth_tag;
|
||||
err_status_t status;
|
||||
int i;
|
||||
|
||||
/* check if we're doing authentication only */
|
||||
if ((iv == NULL) && (opaque == NULL) && (opaque_len == NULL)) {
|
||||
|
||||
/* perform authentication only */
|
||||
|
||||
} else if ((iv == NULL) || (opaque == NULL) || (opaque_len == NULL)) {
|
||||
|
||||
/*
|
||||
* bad parameter - we expect either all three pointers to be NULL,
|
||||
* or none of those pointers to be NULL
|
||||
*/
|
||||
return err_status_fail;
|
||||
|
||||
} else {
|
||||
|
||||
/* derive encryption and authentication keys from the input key */
|
||||
status = hmac_init(&hmac_ctx, key, KEY_LEN);
|
||||
if (status) return status;
|
||||
status = hmac_compute(&hmac_ctx, "ENC", 3, ENC_KEY_LEN, enc_key);
|
||||
if (status) return status;
|
||||
|
||||
status = hmac_init(&hmac_ctx, key, KEY_LEN);
|
||||
if (status) return status;
|
||||
status = hmac_compute(&hmac_ctx, "MAC", 3, MAC_KEY_LEN, mac_key);
|
||||
if (status) return status;
|
||||
|
||||
/* perform encryption and authentication */
|
||||
|
||||
/* set aes key */
|
||||
status = aes_cbc_context_init(&aes_ctx, key, ENC_KEY_LEN, direction_decrypt);
|
||||
if (status) return status;
|
||||
|
||||
/* set iv */
|
||||
status = rand_source_get_octet_string(iv, IV_LEN);
|
||||
if (status) return status;
|
||||
status = aes_cbc_set_iv(&aes_ctx, iv);
|
||||
|
||||
/* encrypt the opaque data */
|
||||
status = aes_cbc_nist_decrypt(&aes_ctx, opaque, opaque_len);
|
||||
if (status) return status;
|
||||
|
||||
/* authenticate clear and opaque data */
|
||||
status = hmac_init(&hmac_ctx, mac_key, MAC_KEY_LEN);
|
||||
if (status) return status;
|
||||
|
||||
status = hmac_start(&hmac_ctx);
|
||||
if (status) return status;
|
||||
|
||||
status = hmac_update(&hmac_ctx, clear, clear_len);
|
||||
if (status) return status;
|
||||
|
||||
status = hmac_compute(&hmac_ctx, opaque, *opaque_len, TAG_LEN, tmp_tag);
|
||||
if (status) return status;
|
||||
|
||||
/* compare the computed tag with the one provided as input */
|
||||
for (i=0; i < TAG_LEN; i++)
|
||||
if (tmp_tag[i] != tag[i])
|
||||
return err_status_auth_fail;
|
||||
|
||||
}
|
||||
|
||||
return err_status_ok;
|
||||
}
|
||||
|
||||
|
||||
#define ENC 1
|
||||
|
||||
#define DEBUG 0
|
||||
|
||||
err_status_t
|
||||
aes_128_cbc_hmac_sha1_96_enc(void *key,
|
||||
const void *clear,
|
||||
unsigned clear_len,
|
||||
void *iv,
|
||||
void *opaque,
|
||||
unsigned *opaque_len) {
|
||||
aes_cbc_ctx_t aes_ctx;
|
||||
hmac_ctx_t hmac_ctx;
|
||||
unsigned char enc_key[ENC_KEY_LEN];
|
||||
unsigned char mac_key[MAC_KEY_LEN];
|
||||
unsigned char *auth_tag;
|
||||
err_status_t status;
|
||||
|
||||
/* check if we're doing authentication only */
|
||||
if ((iv == NULL) && (opaque == NULL) && (opaque_len == NULL)) {
|
||||
|
||||
/* perform authentication only */
|
||||
|
||||
} else if ((iv == NULL) || (opaque == NULL) || (opaque_len == NULL)) {
|
||||
|
||||
/*
|
||||
* bad parameter - we expect either all three pointers to be NULL,
|
||||
* or none of those pointers to be NULL
|
||||
*/
|
||||
return err_status_fail;
|
||||
|
||||
} else {
|
||||
|
||||
#if DEBUG
|
||||
printf("ENC using key %s\n", octet_string_hex_string(key, KEY_LEN));
|
||||
#endif
|
||||
|
||||
/* derive encryption and authentication keys from the input key */
|
||||
status = hmac_init(&hmac_ctx, key, KEY_LEN);
|
||||
if (status) return status;
|
||||
status = hmac_compute(&hmac_ctx, "ENC", 3, ENC_KEY_LEN, enc_key);
|
||||
if (status) return status;
|
||||
|
||||
status = hmac_init(&hmac_ctx, key, KEY_LEN);
|
||||
if (status) return status;
|
||||
status = hmac_compute(&hmac_ctx, "MAC", 3, MAC_KEY_LEN, mac_key);
|
||||
if (status) return status;
|
||||
|
||||
|
||||
/* perform encryption and authentication */
|
||||
|
||||
/* set aes key */
|
||||
status = aes_cbc_context_init(&aes_ctx, key, ENC_KEY_LEN, direction_encrypt);
|
||||
if (status) return status;
|
||||
|
||||
/* set iv */
|
||||
status = rand_source_get_octet_string(iv, IV_LEN);
|
||||
if (status) return status;
|
||||
status = aes_cbc_set_iv(&aes_ctx, iv);
|
||||
if (status) return status;
|
||||
|
||||
#if DEBUG
|
||||
printf("plaintext len: %d\n", *opaque_len);
|
||||
printf("iv: %s\n", octet_string_hex_string(iv, IV_LEN));
|
||||
printf("plaintext: %s\n", octet_string_hex_string(opaque, *opaque_len));
|
||||
#endif
|
||||
|
||||
#if ENC
|
||||
/* encrypt the opaque data */
|
||||
status = aes_cbc_nist_encrypt(&aes_ctx, opaque, opaque_len);
|
||||
if (status) return status;
|
||||
#endif
|
||||
|
||||
#if DEBUG
|
||||
printf("ciphertext len: %d\n", *opaque_len);
|
||||
printf("ciphertext: %s\n", octet_string_hex_string(opaque, *opaque_len));
|
||||
#endif
|
||||
|
||||
/*
|
||||
* authenticate clear and opaque data, then write the
|
||||
* authentication tag to the location immediately following the
|
||||
* ciphertext
|
||||
*/
|
||||
status = hmac_init(&hmac_ctx, mac_key, MAC_KEY_LEN);
|
||||
if (status) return status;
|
||||
|
||||
status = hmac_start(&hmac_ctx);
|
||||
if (status) return status;
|
||||
|
||||
status = hmac_update(&hmac_ctx, clear, clear_len);
|
||||
if (status) return status;
|
||||
#if DEBUG
|
||||
printf("hmac input: %s\n",
|
||||
octet_string_hex_string(clear, clear_len));
|
||||
#endif
|
||||
auth_tag = (unsigned char *)opaque;
|
||||
auth_tag += *opaque_len;
|
||||
status = hmac_compute(&hmac_ctx, opaque, *opaque_len, TAG_LEN, auth_tag);
|
||||
if (status) return status;
|
||||
#if DEBUG
|
||||
printf("hmac input: %s\n",
|
||||
octet_string_hex_string(opaque, *opaque_len));
|
||||
#endif
|
||||
/* bump up the opaque_len to reflect the authentication tag */
|
||||
*opaque_len += TAG_LEN;
|
||||
|
||||
#if DEBUG
|
||||
printf("prot data len: %d\n", *opaque_len);
|
||||
printf("prot data: %s\n", octet_string_hex_string(opaque, *opaque_len));
|
||||
#endif
|
||||
}
|
||||
|
||||
return err_status_ok;
|
||||
}
|
||||
|
||||
err_status_t
|
||||
aes_128_cbc_hmac_sha1_96_dec(void *key,
|
||||
const void *clear,
|
||||
unsigned clear_len,
|
||||
void *iv,
|
||||
void *opaque,
|
||||
unsigned *opaque_len) {
|
||||
aes_cbc_ctx_t aes_ctx;
|
||||
hmac_ctx_t hmac_ctx;
|
||||
unsigned char enc_key[ENC_KEY_LEN];
|
||||
unsigned char mac_key[MAC_KEY_LEN];
|
||||
unsigned char tmp_tag[TAG_LEN];
|
||||
unsigned char *auth_tag;
|
||||
unsigned ciphertext_len;
|
||||
err_status_t status;
|
||||
int i;
|
||||
|
||||
/* check if we're doing authentication only */
|
||||
if ((iv == NULL) && (opaque == NULL) && (opaque_len == NULL)) {
|
||||
|
||||
/* perform authentication only */
|
||||
|
||||
} else if ((iv == NULL) || (opaque == NULL) || (opaque_len == NULL)) {
|
||||
|
||||
/*
|
||||
* bad parameter - we expect either all three pointers to be NULL,
|
||||
* or none of those pointers to be NULL
|
||||
*/
|
||||
return err_status_fail;
|
||||
|
||||
} else {
|
||||
#if DEBUG
|
||||
printf("DEC using key %s\n", octet_string_hex_string(key, KEY_LEN));
|
||||
#endif
|
||||
|
||||
/* derive encryption and authentication keys from the input key */
|
||||
status = hmac_init(&hmac_ctx, key, KEY_LEN);
|
||||
if (status) return status;
|
||||
status = hmac_compute(&hmac_ctx, "ENC", 3, ENC_KEY_LEN, enc_key);
|
||||
if (status) return status;
|
||||
|
||||
status = hmac_init(&hmac_ctx, key, KEY_LEN);
|
||||
if (status) return status;
|
||||
status = hmac_compute(&hmac_ctx, "MAC", 3, MAC_KEY_LEN, mac_key);
|
||||
if (status) return status;
|
||||
|
||||
#if DEBUG
|
||||
printf("prot data len: %d\n", *opaque_len);
|
||||
printf("prot data: %s\n", octet_string_hex_string(opaque, *opaque_len));
|
||||
#endif
|
||||
|
||||
/*
|
||||
* set the protected data length to that of the ciphertext, by
|
||||
* subtracting out the length of the authentication tag
|
||||
*/
|
||||
ciphertext_len = *opaque_len - TAG_LEN;
|
||||
|
||||
#if DEBUG
|
||||
printf("ciphertext len: %d\n", ciphertext_len);
|
||||
#endif
|
||||
/* verify the authentication tag */
|
||||
|
||||
/*
|
||||
* compute the authentication tag for the clear and opaque data,
|
||||
* and write it to a temporary location
|
||||
*/
|
||||
status = hmac_init(&hmac_ctx, mac_key, MAC_KEY_LEN);
|
||||
if (status) return status;
|
||||
|
||||
status = hmac_start(&hmac_ctx);
|
||||
if (status) return status;
|
||||
|
||||
status = hmac_update(&hmac_ctx, clear, clear_len);
|
||||
if (status) return status;
|
||||
|
||||
#if DEBUG
|
||||
printf("hmac input: %s\n",
|
||||
octet_string_hex_string(clear, clear_len));
|
||||
#endif
|
||||
|
||||
status = hmac_compute(&hmac_ctx, opaque, ciphertext_len, TAG_LEN, tmp_tag);
|
||||
if (status) return status;
|
||||
|
||||
#if DEBUG
|
||||
printf("hmac input: %s\n",
|
||||
octet_string_hex_string(opaque, ciphertext_len));
|
||||
#endif
|
||||
|
||||
/*
|
||||
* compare the computed tag with the one provided as input (which
|
||||
* immediately follows the ciphertext)
|
||||
*/
|
||||
auth_tag = (unsigned char *)opaque;
|
||||
auth_tag += ciphertext_len;
|
||||
#if DEBUG
|
||||
printf("auth_tag: %s\n", octet_string_hex_string(auth_tag, TAG_LEN));
|
||||
printf("tmp_tag: %s\n", octet_string_hex_string(tmp_tag, TAG_LEN));
|
||||
#endif
|
||||
for (i=0; i < TAG_LEN; i++) {
|
||||
if (tmp_tag[i] != auth_tag[i])
|
||||
return err_status_auth_fail;
|
||||
}
|
||||
|
||||
/* bump down the opaque_len to reflect the authentication tag */
|
||||
*opaque_len -= TAG_LEN;
|
||||
|
||||
/* decrypt the confidential data */
|
||||
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;
|
||||
|
||||
#if DEBUG
|
||||
printf("ciphertext: %s\n", octet_string_hex_string(opaque, *opaque_len));
|
||||
printf("iv: %s\n", octet_string_hex_string(iv, IV_LEN));
|
||||
#endif
|
||||
|
||||
#if ENC
|
||||
status = aes_cbc_nist_decrypt(&aes_ctx, opaque, &ciphertext_len);
|
||||
if (status) return status;
|
||||
#endif
|
||||
|
||||
#if DEBUG
|
||||
printf("plaintext len: %d\n", ciphertext_len);
|
||||
printf("plaintext: %s\n",
|
||||
octet_string_hex_string(opaque, ciphertext_len));
|
||||
#endif
|
||||
|
||||
/* indicate the length of the plaintext */
|
||||
*opaque_len = ciphertext_len;
|
||||
}
|
||||
|
||||
return err_status_ok;
|
||||
}
|
||||
|
||||
cryptoalg_ctx_t cryptoalg_ctx = {
|
||||
aes_128_cbc_hmac_sha1_96_enc,
|
||||
aes_128_cbc_hmac_sha1_96_dec,
|
||||
KEY_LEN,
|
||||
IV_LEN,
|
||||
TAG_LEN,
|
||||
MAX_EXPAND,
|
||||
};
|
||||
|
||||
cryptoalg_t cryptoalg = &cryptoalg_ctx;
|
||||
|
||||
#define NULL_TAG_LEN 12
|
||||
|
||||
err_status_t
|
||||
null_enc(void *key,
|
||||
const void *clear,
|
||||
unsigned clear_len,
|
||||
void *iv,
|
||||
void *opaque,
|
||||
unsigned *opaque_len) {
|
||||
int i;
|
||||
unsigned char *auth_tag;
|
||||
unsigned char *init_vec = iv;
|
||||
|
||||
/* check if we're doing authentication only */
|
||||
if ((iv == NULL) && (opaque == NULL) && (opaque_len == NULL)) {
|
||||
|
||||
/* perform authentication only */
|
||||
|
||||
} else if ((iv == NULL) || (opaque == NULL) || (opaque_len == NULL)) {
|
||||
|
||||
/*
|
||||
* bad parameter - we expect either all three pointers to be NULL,
|
||||
* or none of those pointers to be NULL
|
||||
*/
|
||||
return err_status_fail;
|
||||
|
||||
} else {
|
||||
|
||||
#if DEBUG
|
||||
printf("NULL ENC using key %s\n", octet_string_hex_string(key, KEY_LEN));
|
||||
printf("NULL_TAG_LEN: %d\n", NULL_TAG_LEN);
|
||||
printf("plaintext len: %d\n", *opaque_len);
|
||||
#endif
|
||||
for (i=0; i < IV_LEN; i++)
|
||||
init_vec[i] = i + (i * 16);
|
||||
#if DEBUG
|
||||
printf("iv: %s\n",
|
||||
octet_string_hex_string(iv, IV_LEN));
|
||||
printf("plaintext: %s\n",
|
||||
octet_string_hex_string(opaque, *opaque_len));
|
||||
#endif
|
||||
auth_tag = opaque;
|
||||
auth_tag += *opaque_len;
|
||||
for (i=0; i < NULL_TAG_LEN; i++)
|
||||
auth_tag[i] = i + (i * 16);
|
||||
*opaque_len += NULL_TAG_LEN;
|
||||
#if DEBUG
|
||||
printf("protected data len: %d\n", *opaque_len);
|
||||
printf("protected data: %s\n",
|
||||
octet_string_hex_string(opaque, *opaque_len));
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
return err_status_ok;
|
||||
}
|
||||
|
||||
err_status_t
|
||||
null_dec(void *key,
|
||||
const void *clear,
|
||||
unsigned clear_len,
|
||||
void *iv,
|
||||
void *opaque,
|
||||
unsigned *opaque_len) {
|
||||
unsigned char *auth_tag;
|
||||
|
||||
/* check if we're doing authentication only */
|
||||
if ((iv == NULL) && (opaque == NULL) && (opaque_len == NULL)) {
|
||||
|
||||
/* perform authentication only */
|
||||
|
||||
} else if ((iv == NULL) || (opaque == NULL) || (opaque_len == NULL)) {
|
||||
|
||||
/*
|
||||
* bad parameter - we expect either all three pointers to be NULL,
|
||||
* or none of those pointers to be NULL
|
||||
*/
|
||||
return err_status_fail;
|
||||
|
||||
} else {
|
||||
|
||||
#if DEBUG
|
||||
printf("NULL DEC using key %s\n", octet_string_hex_string(key, KEY_LEN));
|
||||
|
||||
printf("protected data len: %d\n", *opaque_len);
|
||||
printf("protected data: %s\n",
|
||||
octet_string_hex_string(opaque, *opaque_len));
|
||||
#endif
|
||||
auth_tag = opaque;
|
||||
auth_tag += (*opaque_len - NULL_TAG_LEN);
|
||||
#if DEBUG
|
||||
printf("iv: %s\n", octet_string_hex_string(iv, IV_LEN));
|
||||
#endif
|
||||
*opaque_len -= NULL_TAG_LEN;
|
||||
#if DEBUG
|
||||
printf("plaintext len: %d\n", *opaque_len);
|
||||
printf("plaintext: %s\n",
|
||||
octet_string_hex_string(opaque, *opaque_len));
|
||||
#endif
|
||||
}
|
||||
|
||||
return err_status_ok;
|
||||
}
|
||||
|
||||
cryptoalg_ctx_t null_cryptoalg_ctx = {
|
||||
null_enc,
|
||||
null_dec,
|
||||
KEY_LEN,
|
||||
IV_LEN,
|
||||
NULL_TAG_LEN,
|
||||
MAX_EXPAND,
|
||||
};
|
||||
|
||||
cryptoalg_t null_cryptoalg = &null_cryptoalg_ctx;
|
||||
|
||||
int
|
||||
cryptoalg_get_id(cryptoalg_t c) {
|
||||
if (c == cryptoalg)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
cryptoalg_t
|
||||
cryptoalg_find_by_id(int id) {
|
||||
switch(id) {
|
||||
case 1:
|
||||
return cryptoalg;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -1,540 +0,0 @@
|
|||
/*
|
||||
* aes_cbc.c
|
||||
*
|
||||
* AES Cipher Block Chaining Mode
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include "aes_cbc.h"
|
||||
#include "alloc.h"
|
||||
|
||||
debug_module_t mod_aes_cbc = {
|
||||
0, /* debugging is off by default */
|
||||
"aes cbc" /* printable module name */
|
||||
};
|
||||
|
||||
|
||||
|
||||
err_status_t
|
||||
aes_cbc_alloc(cipher_t **c, int key_len) {
|
||||
extern cipher_type_t aes_cbc;
|
||||
uint8_t *pointer;
|
||||
int tmp;
|
||||
|
||||
debug_print(mod_aes_cbc,
|
||||
"allocating cipher with key length %d", key_len);
|
||||
|
||||
if (key_len != 16 && key_len != 24 && key_len != 32)
|
||||
return err_status_bad_param;
|
||||
|
||||
/* allocate memory a cipher of type aes_cbc */
|
||||
tmp = (sizeof(aes_cbc_ctx_t) + sizeof(cipher_t));
|
||||
pointer = (uint8_t*)crypto_alloc(tmp);
|
||||
if (pointer == NULL)
|
||||
return err_status_alloc_fail;
|
||||
|
||||
/* set pointers */
|
||||
*c = (cipher_t *)pointer;
|
||||
(*c)->type = &aes_cbc;
|
||||
(*c)->state = pointer + sizeof(cipher_t);
|
||||
|
||||
/* increment ref_count */
|
||||
aes_cbc.ref_count++;
|
||||
|
||||
/* set key size */
|
||||
(*c)->key_len = key_len;
|
||||
|
||||
return err_status_ok;
|
||||
}
|
||||
|
||||
err_status_t
|
||||
aes_cbc_dealloc(cipher_t *c) {
|
||||
extern cipher_type_t aes_cbc;
|
||||
|
||||
/* zeroize entire state*/
|
||||
octet_string_set_to_zero((uint8_t *)c,
|
||||
sizeof(aes_cbc_ctx_t) + sizeof(cipher_t));
|
||||
|
||||
/* free memory */
|
||||
crypto_free(c);
|
||||
|
||||
/* decrement ref_count */
|
||||
aes_cbc.ref_count--;
|
||||
|
||||
return err_status_ok;
|
||||
}
|
||||
|
||||
err_status_t
|
||||
aes_cbc_context_init(aes_cbc_ctx_t *c, const uint8_t *key, int key_len,
|
||||
cipher_direction_t dir) {
|
||||
err_status_t status;
|
||||
|
||||
debug_print(mod_aes_cbc,
|
||||
"key: %s", octet_string_hex_string(key, key_len));
|
||||
|
||||
/* expand key for the appropriate direction */
|
||||
switch (dir) {
|
||||
case (direction_encrypt):
|
||||
status = aes_expand_encryption_key(key, key_len, &c->expanded_key);
|
||||
if (status)
|
||||
return status;
|
||||
break;
|
||||
case (direction_decrypt):
|
||||
status = aes_expand_decryption_key(key, key_len, &c->expanded_key);
|
||||
if (status)
|
||||
return status;
|
||||
break;
|
||||
default:
|
||||
return err_status_bad_param;
|
||||
}
|
||||
|
||||
|
||||
return err_status_ok;
|
||||
}
|
||||
|
||||
|
||||
err_status_t
|
||||
aes_cbc_set_iv(aes_cbc_ctx_t *c, void *iv) {
|
||||
int i;
|
||||
/* v128_t *input = iv; */
|
||||
uint8_t *input = (uint8_t*) iv;
|
||||
|
||||
/* set state and 'previous' block to iv */
|
||||
for (i=0; i < 16; i++)
|
||||
c->previous.v8[i] = c->state.v8[i] = input[i];
|
||||
|
||||
debug_print(mod_aes_cbc, "setting iv: %s", v128_hex_string(&c->state));
|
||||
|
||||
return err_status_ok;
|
||||
}
|
||||
|
||||
err_status_t
|
||||
aes_cbc_encrypt(aes_cbc_ctx_t *c,
|
||||
unsigned char *data,
|
||||
unsigned int *bytes_in_data) {
|
||||
int i;
|
||||
unsigned char *input = data; /* pointer to data being read */
|
||||
unsigned char *output = data; /* pointer to data being written */
|
||||
int bytes_to_encr = *bytes_in_data;
|
||||
|
||||
/*
|
||||
* verify that we're 16-octet aligned
|
||||
*/
|
||||
if (*bytes_in_data & 0xf)
|
||||
return err_status_bad_param;
|
||||
|
||||
/*
|
||||
* note that we assume that the initialization vector has already
|
||||
* been set, e.g. by calling aes_cbc_set_iv()
|
||||
*/
|
||||
debug_print(mod_aes_cbc, "iv: %s",
|
||||
v128_hex_string(&c->state));
|
||||
|
||||
/*
|
||||
* loop over plaintext blocks, exoring state into plaintext then
|
||||
* encrypting and writing to output
|
||||
*/
|
||||
while (bytes_to_encr > 0) {
|
||||
|
||||
/* exor plaintext into state */
|
||||
for (i=0; i < 16; i++)
|
||||
c->state.v8[i] ^= *input++;
|
||||
|
||||
debug_print(mod_aes_cbc, "inblock: %s",
|
||||
v128_hex_string(&c->state));
|
||||
|
||||
aes_encrypt(&c->state, &c->expanded_key);
|
||||
|
||||
debug_print(mod_aes_cbc, "outblock: %s",
|
||||
v128_hex_string(&c->state));
|
||||
|
||||
/* copy ciphertext to output */
|
||||
for (i=0; i < 16; i++)
|
||||
*output++ = c->state.v8[i];
|
||||
|
||||
bytes_to_encr -= 16;
|
||||
}
|
||||
|
||||
return err_status_ok;
|
||||
}
|
||||
|
||||
err_status_t
|
||||
aes_cbc_decrypt(aes_cbc_ctx_t *c,
|
||||
unsigned char *data,
|
||||
unsigned int *bytes_in_data) {
|
||||
int i;
|
||||
v128_t state, previous;
|
||||
unsigned char *input = data; /* pointer to data being read */
|
||||
unsigned char *output = data; /* pointer to data being written */
|
||||
int bytes_to_encr = *bytes_in_data;
|
||||
uint8_t tmp;
|
||||
|
||||
/*
|
||||
* verify that we're 16-octet aligned
|
||||
*/
|
||||
if (*bytes_in_data & 0x0f)
|
||||
return err_status_bad_param;
|
||||
|
||||
/* set 'previous' block to iv*/
|
||||
for (i=0; i < 16; i++) {
|
||||
previous.v8[i] = c->previous.v8[i];
|
||||
}
|
||||
|
||||
debug_print(mod_aes_cbc, "iv: %s",
|
||||
v128_hex_string(&previous));
|
||||
|
||||
/*
|
||||
* loop over ciphertext blocks, decrypting then exoring with state
|
||||
* then writing plaintext to output
|
||||
*/
|
||||
while (bytes_to_encr > 0) {
|
||||
|
||||
/* set state to ciphertext input block */
|
||||
for (i=0; i < 16; i++) {
|
||||
state.v8[i] = *input++;
|
||||
}
|
||||
|
||||
debug_print(mod_aes_cbc, "inblock: %s",
|
||||
v128_hex_string(&state));
|
||||
|
||||
/* decrypt state */
|
||||
aes_decrypt(&state, &c->expanded_key);
|
||||
|
||||
debug_print(mod_aes_cbc, "outblock: %s",
|
||||
v128_hex_string(&state));
|
||||
|
||||
/*
|
||||
* exor previous ciphertext block out of plaintext, and write new
|
||||
* plaintext block to output, while copying old ciphertext block
|
||||
* to the 'previous' block
|
||||
*/
|
||||
for (i=0; i < 16; i++) {
|
||||
tmp = *output;
|
||||
*output++ = state.v8[i] ^ previous.v8[i];
|
||||
previous.v8[i] = tmp;
|
||||
}
|
||||
|
||||
bytes_to_encr -= 16;
|
||||
}
|
||||
|
||||
return err_status_ok;
|
||||
}
|
||||
|
||||
|
||||
err_status_t
|
||||
aes_cbc_nist_encrypt(aes_cbc_ctx_t *c,
|
||||
unsigned char *data,
|
||||
unsigned int *bytes_in_data) {
|
||||
int i;
|
||||
unsigned char *pad_start;
|
||||
int num_pad_bytes;
|
||||
err_status_t status;
|
||||
|
||||
/*
|
||||
* determine the number of padding bytes that we need to add -
|
||||
* this value is always between 1 and 16, inclusive.
|
||||
*/
|
||||
num_pad_bytes = 16 - (*bytes_in_data & 0xf);
|
||||
pad_start = data;
|
||||
pad_start += *bytes_in_data;
|
||||
*pad_start++ = 0xa0;
|
||||
for (i=0; i < num_pad_bytes; i++)
|
||||
*pad_start++ = 0x00;
|
||||
|
||||
/*
|
||||
* increment the data size
|
||||
*/
|
||||
*bytes_in_data += num_pad_bytes;
|
||||
|
||||
/*
|
||||
* now cbc encrypt the padded data
|
||||
*/
|
||||
status = aes_cbc_encrypt(c, data, bytes_in_data);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
return err_status_ok;
|
||||
}
|
||||
|
||||
|
||||
err_status_t
|
||||
aes_cbc_nist_decrypt(aes_cbc_ctx_t *c,
|
||||
unsigned char *data,
|
||||
unsigned int *bytes_in_data) {
|
||||
unsigned char *pad_end;
|
||||
int num_pad_bytes;
|
||||
err_status_t status;
|
||||
|
||||
/*
|
||||
* cbc decrypt the padded data
|
||||
*/
|
||||
status = aes_cbc_decrypt(c, data, bytes_in_data);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
/*
|
||||
* determine the number of padding bytes in the decrypted plaintext
|
||||
* - this value is always between 1 and 16, inclusive.
|
||||
*/
|
||||
num_pad_bytes = 1;
|
||||
pad_end = data + (*bytes_in_data - 1);
|
||||
while (*pad_end != 0xa0) { /* note: should check padding correctness */
|
||||
pad_end--;
|
||||
num_pad_bytes++;
|
||||
}
|
||||
|
||||
/* decrement data size */
|
||||
*bytes_in_data -= num_pad_bytes;
|
||||
|
||||
return err_status_ok;
|
||||
}
|
||||
|
||||
|
||||
char
|
||||
aes_cbc_description[] = "aes cipher block chaining (cbc) mode";
|
||||
|
||||
/*
|
||||
* 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
|
||||
* particular platform, then you should print out AES intermediate
|
||||
* data and compare with the detailed info provided in that appendix.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
uint8_t aes_cbc_test_case_0_key[16] = {
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
||||
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f
|
||||
};
|
||||
|
||||
uint8_t aes_cbc_test_case_0_plaintext[64] = {
|
||||
0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
|
||||
0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff
|
||||
};
|
||||
|
||||
uint8_t aes_cbc_test_case_0_ciphertext[80] = {
|
||||
0x69, 0xc4, 0xe0, 0xd8, 0x6a, 0x7b, 0x04, 0x30,
|
||||
0xd8, 0xcd, 0xb7, 0x80, 0x70, 0xb4, 0xc5, 0x5a,
|
||||
0x03, 0x35, 0xed, 0x27, 0x67, 0xf2, 0x6d, 0xf1,
|
||||
0x64, 0x83, 0x2e, 0x23, 0x44, 0x38, 0x70, 0x8b
|
||||
|
||||
};
|
||||
|
||||
uint8_t aes_cbc_test_case_0_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_0 = {
|
||||
16, /* octets in key */
|
||||
aes_cbc_test_case_0_key, /* key */
|
||||
aes_cbc_test_case_0_iv, /* initialization vector */
|
||||
16, /* octets in plaintext */
|
||||
aes_cbc_test_case_0_plaintext, /* plaintext */
|
||||
32, /* octets in ciphertext */
|
||||
aes_cbc_test_case_0_ciphertext, /* ciphertext */
|
||||
NULL /* 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_1_key[16] = {
|
||||
0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
|
||||
0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c,
|
||||
};
|
||||
|
||||
uint8_t aes_cbc_test_case_1_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_1_ciphertext[80] = {
|
||||
0x76, 0x49, 0xab, 0xac, 0x81, 0x19, 0xb2, 0x46,
|
||||
0xce, 0xe9, 0x8e, 0x9b, 0x12, 0xe9, 0x19, 0x7d,
|
||||
0x50, 0x86, 0xcb, 0x9b, 0x50, 0x72, 0x19, 0xee,
|
||||
0x95, 0xdb, 0x11, 0x3a, 0x91, 0x76, 0x78, 0xb2,
|
||||
0x73, 0xbe, 0xd6, 0xb8, 0xe3, 0xc1, 0x74, 0x3b,
|
||||
0x71, 0x16, 0xe6, 0x9e, 0x22, 0x22, 0x95, 0x16,
|
||||
0x3f, 0xf1, 0xca, 0xa1, 0x68, 0x1f, 0xac, 0x09,
|
||||
0x12, 0x0e, 0xca, 0x30, 0x75, 0x86, 0xe1, 0xa7,
|
||||
0x39, 0x34, 0x07, 0x03, 0x36, 0xd0, 0x77, 0x99,
|
||||
0xe0, 0xc4, 0x2f, 0xdd, 0xa8, 0xdf, 0x4c, 0xa3
|
||||
};
|
||||
|
||||
uint8_t aes_cbc_test_case_1_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_1 = {
|
||||
16, /* octets in key */
|
||||
aes_cbc_test_case_1_key, /* key */
|
||||
aes_cbc_test_case_1_iv, /* initialization vector */
|
||||
64, /* octets in plaintext */
|
||||
aes_cbc_test_case_1_plaintext, /* plaintext */
|
||||
80, /* octets in ciphertext */
|
||||
aes_cbc_test_case_1_ciphertext, /* ciphertext */
|
||||
&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,
|
||||
(cipher_init_func_t) aes_cbc_context_init,
|
||||
(cipher_encrypt_func_t) aes_cbc_nist_encrypt,
|
||||
(cipher_decrypt_func_t) aes_cbc_nist_decrypt,
|
||||
(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_3,
|
||||
(debug_module_t *) &mod_aes_cbc,
|
||||
(cipher_type_id_t) AES_CBC
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -1,561 +0,0 @@
|
|||
/*
|
||||
* aes_icm.c
|
||||
*
|
||||
* AES Integer Counter Mode
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#define ALIGN_32 0
|
||||
|
||||
#include "aes_icm.h"
|
||||
#include "alloc.h"
|
||||
|
||||
|
||||
debug_module_t mod_aes_icm = {
|
||||
0, /* debugging is off by default */
|
||||
"aes icm" /* printable module name */
|
||||
};
|
||||
|
||||
/*
|
||||
* integer counter mode works as follows:
|
||||
*
|
||||
* 16 bits
|
||||
* <----->
|
||||
* +------+------+------+------+------+------+------+------+
|
||||
* | nonce | pakcet index | ctr |---+
|
||||
* +------+------+------+------+------+------+------+------+ |
|
||||
* |
|
||||
* +------+------+------+------+------+------+------+------+ v
|
||||
* | salt |000000|->(+)
|
||||
* +------+------+------+------+------+------+------+------+ |
|
||||
* |
|
||||
* +---------+
|
||||
* | encrypt |
|
||||
* +---------+
|
||||
* |
|
||||
* +------+------+------+------+------+------+------+------+ |
|
||||
* | keystream block |<--+
|
||||
* +------+------+------+------+------+------+------+------+
|
||||
*
|
||||
* All fields are big-endian
|
||||
*
|
||||
* ctr is the block counter, which increments from zero for
|
||||
* each packet (16 bits wide)
|
||||
*
|
||||
* packet index is distinct for each packet (48 bits wide)
|
||||
*
|
||||
* nonce can be distinct across many uses of the same key, or
|
||||
* can be a fixed value per key, or can be per-packet randomness
|
||||
* (64 bits)
|
||||
*
|
||||
*/
|
||||
|
||||
err_status_t
|
||||
aes_icm_alloc_ismacryp(cipher_t **c, int key_len, int forIsmacryp) {
|
||||
extern cipher_type_t aes_icm;
|
||||
uint8_t *pointer;
|
||||
int tmp;
|
||||
|
||||
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/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 > 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 = (uint8_t*)crypto_alloc(tmp);
|
||||
if (pointer == NULL)
|
||||
return err_status_alloc_fail;
|
||||
|
||||
/* set pointers */
|
||||
*c = (cipher_t *)pointer;
|
||||
(*c)->type = &aes_icm;
|
||||
(*c)->state = pointer + sizeof(cipher_t);
|
||||
|
||||
/* increment ref_count */
|
||||
aes_icm.ref_count++;
|
||||
|
||||
/* set key size */
|
||||
(*c)->key_len = key_len;
|
||||
|
||||
return err_status_ok;
|
||||
}
|
||||
|
||||
err_status_t aes_icm_alloc(cipher_t **c, int key_len, int forIsmacryp) {
|
||||
return aes_icm_alloc_ismacryp(c, key_len, 0);
|
||||
}
|
||||
|
||||
err_status_t
|
||||
aes_icm_dealloc(cipher_t *c) {
|
||||
extern cipher_type_t aes_icm;
|
||||
|
||||
/* zeroize entire state*/
|
||||
octet_string_set_to_zero((uint8_t *)c,
|
||||
sizeof(aes_icm_ctx_t) + sizeof(cipher_t));
|
||||
|
||||
/* free memory */
|
||||
crypto_free(c);
|
||||
|
||||
/* decrement ref_count */
|
||||
aes_icm.ref_count--;
|
||||
|
||||
return err_status_ok;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* aes_icm_context_init(...) initializes the aes_icm_context
|
||||
* using the value in key[].
|
||||
*
|
||||
* the key is the secret key
|
||||
*
|
||||
* the salt is unpredictable (but not necessarily secret) data which
|
||||
* randomizes the starting point in the keystream
|
||||
*/
|
||||
|
||||
err_status_t
|
||||
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 */
|
||||
/* 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;
|
||||
|
||||
debug_print(mod_aes_icm,
|
||||
"key: %s", octet_string_hex_string(key, base_key_len));
|
||||
debug_print(mod_aes_icm,
|
||||
"offset: %s", v128_hex_string(&c->offset));
|
||||
|
||||
/* expand 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;
|
||||
|
||||
return err_status_ok;
|
||||
}
|
||||
|
||||
/*
|
||||
* aes_icm_set_octet(c, i) sets the counter of the context which it is
|
||||
* passed so that the next octet of keystream that will be generated
|
||||
* is the ith octet
|
||||
*/
|
||||
|
||||
err_status_t
|
||||
aes_icm_set_octet(aes_icm_ctx_t *c,
|
||||
uint64_t octet_num) {
|
||||
|
||||
#ifdef NO_64BIT_MATH
|
||||
int tail_num = low32(octet_num) & 0x0f;
|
||||
/* 64-bit right-shift 4 */
|
||||
uint64_t block_num = make64(high32(octet_num) >> 4,
|
||||
((high32(octet_num) & 0x0f)<<(32-4)) |
|
||||
(low32(octet_num) >> 4));
|
||||
#else
|
||||
int tail_num = (int)(octet_num % 16);
|
||||
uint64_t block_num = octet_num / 16;
|
||||
#endif
|
||||
|
||||
|
||||
/* set counter value */
|
||||
/* FIX - There's no way this is correct */
|
||||
c->counter.v64[0] = c->offset.v64[0];
|
||||
#ifdef NO_64BIT_MATH
|
||||
c->counter.v64[0] = make64(high32(c->offset.v64[0]) ^ high32(block_num),
|
||||
low32(c->offset.v64[0]) ^ low32(block_num));
|
||||
#else
|
||||
c->counter.v64[0] = c->offset.v64[0] ^ block_num;
|
||||
#endif
|
||||
|
||||
debug_print(mod_aes_icm,
|
||||
"set_octet: %s", v128_hex_string(&c->counter));
|
||||
|
||||
/* fill keystream buffer, if needed */
|
||||
if (tail_num) {
|
||||
v128_copy(&c->keystream_buffer, &c->counter);
|
||||
aes_encrypt(&c->keystream_buffer, &c->expanded_key);
|
||||
c->bytes_in_buffer = sizeof(v128_t);
|
||||
|
||||
debug_print(mod_aes_icm, "counter: %s",
|
||||
v128_hex_string(&c->counter));
|
||||
debug_print(mod_aes_icm, "ciphertext: %s",
|
||||
v128_hex_string(&c->keystream_buffer));
|
||||
|
||||
/* indicate number of bytes in keystream_buffer */
|
||||
c->bytes_in_buffer = sizeof(v128_t) - tail_num;
|
||||
|
||||
} else {
|
||||
|
||||
/* indicate that keystream_buffer is empty */
|
||||
c->bytes_in_buffer = 0;
|
||||
}
|
||||
|
||||
return err_status_ok;
|
||||
}
|
||||
|
||||
/*
|
||||
* aes_icm_set_iv(c, iv) sets the counter value to the exor of iv with
|
||||
* the offset
|
||||
*/
|
||||
|
||||
err_status_t
|
||||
aes_icm_set_iv(aes_icm_ctx_t *c, void *iv) {
|
||||
v128_t *nonce = (v128_t *) iv;
|
||||
|
||||
debug_print(mod_aes_icm,
|
||||
"setting iv: %s", v128_hex_string(nonce));
|
||||
|
||||
v128_xor(&c->counter, &c->offset, nonce);
|
||||
|
||||
debug_print(mod_aes_icm,
|
||||
"set_counter: %s", v128_hex_string(&c->counter));
|
||||
|
||||
/* indicate that the keystream_buffer is empty */
|
||||
c->bytes_in_buffer = 0;
|
||||
|
||||
return err_status_ok;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* aes_icm_advance(...) refills the keystream_buffer and
|
||||
* advances the block index of the sicm_context forward by one
|
||||
*
|
||||
* this is an internal, hopefully inlined function
|
||||
*/
|
||||
|
||||
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);
|
||||
c->bytes_in_buffer = sizeof(v128_t);
|
||||
|
||||
debug_print(mod_aes_icm, "counter: %s",
|
||||
v128_hex_string(&c->counter));
|
||||
debug_print(mod_aes_icm, "ciphertext: %s",
|
||||
v128_hex_string(&c->keystream_buffer));
|
||||
|
||||
/* clock counter forward */
|
||||
|
||||
if (forIsmacryp) {
|
||||
uint32_t temp;
|
||||
//alex's clock counter forward
|
||||
temp = ntohl(c->counter.v32[3]);
|
||||
c->counter.v32[3] = htonl(++temp);
|
||||
} else {
|
||||
if (!++(c->counter.v8[15]))
|
||||
++(c->counter.v8[14]);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void aes_icm_advance(aes_icm_ctx_t *c) {
|
||||
aes_icm_advance_ismacryp(c, 0);
|
||||
}
|
||||
|
||||
|
||||
/*e
|
||||
* icm_encrypt deals with the following cases:
|
||||
*
|
||||
* bytes_to_encr < bytes_in_buffer
|
||||
* - add keystream into data
|
||||
*
|
||||
* bytes_to_encr > bytes_in_buffer
|
||||
* - add keystream into data until keystream_buffer is depleted
|
||||
* - loop over blocks, filling keystream_buffer and then
|
||||
* adding keystream into data
|
||||
* - fill buffer then add in remaining (< 16) bytes of keystream
|
||||
*/
|
||||
|
||||
err_status_t
|
||||
aes_icm_encrypt_ismacryp(aes_icm_ctx_t *c,
|
||||
unsigned char *buf, unsigned int *enc_len,
|
||||
int forIsmacryp) {
|
||||
unsigned int bytes_to_encr = *enc_len;
|
||||
unsigned int i;
|
||||
uint32_t *b;
|
||||
|
||||
/* check that there's enough segment left but not for ismacryp*/
|
||||
if (!forIsmacryp && (bytes_to_encr + htons(c->counter.v16[7])) > 0xffff)
|
||||
return err_status_terminus;
|
||||
|
||||
debug_print(mod_aes_icm, "block index: %d",
|
||||
htons(c->counter.v16[7]));
|
||||
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);
|
||||
i < (sizeof(v128_t) - c->bytes_in_buffer + bytes_to_encr); i++)
|
||||
{
|
||||
*buf++ ^= c->keystream_buffer.v8[i];
|
||||
}
|
||||
|
||||
c->bytes_in_buffer -= bytes_to_encr;
|
||||
|
||||
/* return now to avoid the main loop */
|
||||
return err_status_ok;
|
||||
|
||||
} else {
|
||||
|
||||
/* encrypt bytes until the remaining data is 16-byte aligned */
|
||||
for (i=(sizeof(v128_t) - c->bytes_in_buffer); i < sizeof(v128_t); i++)
|
||||
*buf++ ^= c->keystream_buffer.v8[i];
|
||||
|
||||
bytes_to_encr -= c->bytes_in_buffer;
|
||||
c->bytes_in_buffer = 0;
|
||||
|
||||
}
|
||||
|
||||
/* now loop over entire 16-byte blocks of keystream */
|
||||
for (i=0; i < (bytes_to_encr/sizeof(v128_t)); i++) {
|
||||
|
||||
/* fill buffer with new keystream */
|
||||
aes_icm_advance_ismacryp(c, forIsmacryp);
|
||||
|
||||
/*
|
||||
* add keystream into the data buffer (this would be a lot faster
|
||||
* if we could assume 32-bit alignment!)
|
||||
*/
|
||||
|
||||
#if ALIGN_32
|
||||
b = (uint32_t *)buf;
|
||||
*b++ ^= c->keystream_buffer.v32[0];
|
||||
*b++ ^= c->keystream_buffer.v32[1];
|
||||
*b++ ^= c->keystream_buffer.v32[2];
|
||||
*b++ ^= c->keystream_buffer.v32[3];
|
||||
buf = (uint8_t *)b;
|
||||
#else
|
||||
if ((((unsigned long) buf) & 0x03) != 0) {
|
||||
*buf++ ^= c->keystream_buffer.v8[0];
|
||||
*buf++ ^= c->keystream_buffer.v8[1];
|
||||
*buf++ ^= c->keystream_buffer.v8[2];
|
||||
*buf++ ^= c->keystream_buffer.v8[3];
|
||||
*buf++ ^= c->keystream_buffer.v8[4];
|
||||
*buf++ ^= c->keystream_buffer.v8[5];
|
||||
*buf++ ^= c->keystream_buffer.v8[6];
|
||||
*buf++ ^= c->keystream_buffer.v8[7];
|
||||
*buf++ ^= c->keystream_buffer.v8[8];
|
||||
*buf++ ^= c->keystream_buffer.v8[9];
|
||||
*buf++ ^= c->keystream_buffer.v8[10];
|
||||
*buf++ ^= c->keystream_buffer.v8[11];
|
||||
*buf++ ^= c->keystream_buffer.v8[12];
|
||||
*buf++ ^= c->keystream_buffer.v8[13];
|
||||
*buf++ ^= c->keystream_buffer.v8[14];
|
||||
*buf++ ^= c->keystream_buffer.v8[15];
|
||||
} else {
|
||||
b = (uint32_t *)buf;
|
||||
*b++ ^= c->keystream_buffer.v32[0];
|
||||
*b++ ^= c->keystream_buffer.v32[1];
|
||||
*b++ ^= c->keystream_buffer.v32[2];
|
||||
*b++ ^= c->keystream_buffer.v32[3];
|
||||
buf = (uint8_t *)b;
|
||||
}
|
||||
#endif /* #if ALIGN_32 */
|
||||
|
||||
}
|
||||
|
||||
/* if there is a tail end of the data, process it */
|
||||
if ((bytes_to_encr & 0xf) != 0) {
|
||||
|
||||
/* fill buffer with new keystream */
|
||||
aes_icm_advance_ismacryp(c, forIsmacryp);
|
||||
|
||||
for (i=0; i < (bytes_to_encr & 0xf); i++)
|
||||
*buf++ ^= c->keystream_buffer.v8[i];
|
||||
|
||||
/* reset the keystream buffer size to right value */
|
||||
c->bytes_in_buffer = sizeof(v128_t) - i;
|
||||
} else {
|
||||
|
||||
/* no tail, so just reset the keystream buffer size to zero */
|
||||
c->bytes_in_buffer = 0;
|
||||
|
||||
}
|
||||
|
||||
return err_status_ok;
|
||||
}
|
||||
|
||||
err_status_t
|
||||
aes_icm_encrypt(aes_icm_ctx_t *c, unsigned char *buf, unsigned int *enc_len) {
|
||||
return aes_icm_encrypt_ismacryp(c, buf, enc_len, 0);
|
||||
}
|
||||
|
||||
err_status_t
|
||||
aes_icm_output(aes_icm_ctx_t *c, uint8_t *buffer, int num_octets_to_output) {
|
||||
unsigned int len = num_octets_to_output;
|
||||
|
||||
/* zeroize the buffer */
|
||||
octet_string_set_to_zero(buffer, num_octets_to_output);
|
||||
|
||||
/* exor keystream into buffer */
|
||||
return aes_icm_encrypt(c, buffer, &len);
|
||||
}
|
||||
|
||||
|
||||
char
|
||||
aes_icm_description[] = "aes integer counter mode";
|
||||
|
||||
uint8_t aes_icm_test_case_0_key[30] = {
|
||||
0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
|
||||
0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c,
|
||||
0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
|
||||
0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd
|
||||
};
|
||||
|
||||
uint8_t aes_icm_test_case_0_nonce[16] = {
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
|
||||
uint8_t aes_icm_test_case_0_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_0_ciphertext[32] = {
|
||||
0xe0, 0x3e, 0xad, 0x09, 0x35, 0xc9, 0x5e, 0x80,
|
||||
0xe1, 0x66, 0xb1, 0x6d, 0xd9, 0x2b, 0x4e, 0xb4,
|
||||
0xd2, 0x35, 0x13, 0x16, 0x2b, 0x02, 0xd0, 0xf7,
|
||||
0x2a, 0x43, 0xa2, 0xfe, 0x4a, 0x5f, 0x97, 0xab
|
||||
};
|
||||
|
||||
cipher_test_case_t aes_icm_test_case_0 = {
|
||||
30, /* octets in key */
|
||||
aes_icm_test_case_0_key, /* key */
|
||||
aes_icm_test_case_0_nonce, /* packet index */
|
||||
32, /* octets in plaintext */
|
||||
aes_icm_test_case_0_plaintext, /* plaintext */
|
||||
32, /* octets in ciphertext */
|
||||
aes_icm_test_case_0_ciphertext, /* ciphertext */
|
||||
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
|
||||
*/
|
||||
|
||||
cipher_type_t aes_icm = {
|
||||
(cipher_alloc_func_t) aes_icm_alloc,
|
||||
(cipher_dealloc_func_t) aes_icm_dealloc,
|
||||
(cipher_init_func_t) aes_icm_context_init,
|
||||
(cipher_encrypt_func_t) aes_icm_encrypt,
|
||||
(cipher_decrypt_func_t) aes_icm_encrypt,
|
||||
(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_1,
|
||||
(debug_module_t *) &mod_aes_icm,
|
||||
(cipher_type_id_t) AES_ICM
|
||||
};
|
||||
|
||||
|
|
@ -1,421 +0,0 @@
|
|||
/*
|
||||
* cipher.c
|
||||
*
|
||||
* cipher meta-functions
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "cipher.h"
|
||||
#include "rand_source.h" /* used in invertibiltiy tests */
|
||||
#include "alloc.h" /* for crypto_alloc(), crypto_free() */
|
||||
|
||||
debug_module_t mod_cipher = {
|
||||
0, /* debugging is off by default */
|
||||
"cipher" /* printable module name */
|
||||
};
|
||||
|
||||
err_status_t
|
||||
cipher_output(cipher_t *c, uint8_t *buffer, int num_octets_to_output) {
|
||||
|
||||
/* zeroize the buffer */
|
||||
octet_string_set_to_zero(buffer, num_octets_to_output);
|
||||
|
||||
/* exor keystream into buffer */
|
||||
return cipher_encrypt(c, buffer, (unsigned int *) &num_octets_to_output);
|
||||
}
|
||||
|
||||
/* some bookkeeping functions */
|
||||
|
||||
int
|
||||
cipher_get_key_length(const cipher_t *c) {
|
||||
return c->key_len;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#define SELF_TEST_BUF_OCTETS 128
|
||||
#define NUM_RAND_TESTS 128
|
||||
#define MAX_KEY_LEN 64
|
||||
|
||||
err_status_t
|
||||
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];
|
||||
uint8_t buffer2[SELF_TEST_BUF_OCTETS];
|
||||
unsigned int len;
|
||||
int i, j, case_num = 0;
|
||||
|
||||
debug_print(mod_cipher, "running self-test for cipher %s",
|
||||
ct->description);
|
||||
|
||||
/*
|
||||
* check to make sure that we have at least one test case, and
|
||||
* return an error if we don't - we need to be paranoid here
|
||||
*/
|
||||
if (test_case == NULL)
|
||||
return err_status_cant_check;
|
||||
|
||||
/*
|
||||
* loop over all test cases, perform known-answer tests of both the
|
||||
* encryption and decryption functions
|
||||
*/
|
||||
while (test_case != NULL) {
|
||||
|
||||
/* allocate cipher */
|
||||
status = cipher_type_alloc(ct, &c, test_case->key_length_octets);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
/*
|
||||
* test the encrypt function
|
||||
*/
|
||||
debug_print(mod_cipher, "testing encryption", NULL);
|
||||
|
||||
/* initialize cipher */
|
||||
status = cipher_init(c, test_case->key, direction_encrypt);
|
||||
if (status) {
|
||||
cipher_dealloc(c);
|
||||
return status;
|
||||
}
|
||||
|
||||
/* copy plaintext into test buffer */
|
||||
if (test_case->ciphertext_length_octets > SELF_TEST_BUF_OCTETS) {
|
||||
cipher_dealloc(c);
|
||||
return err_status_bad_param;
|
||||
}
|
||||
for (i=0; i < test_case->plaintext_length_octets; i++)
|
||||
buffer[i] = test_case->plaintext[i];
|
||||
|
||||
debug_print(mod_cipher, "plaintext: %s",
|
||||
octet_string_hex_string(buffer,
|
||||
test_case->plaintext_length_octets));
|
||||
|
||||
/* set the initialization vector */
|
||||
status = cipher_set_iv(c, test_case->idx);
|
||||
if (status) {
|
||||
cipher_dealloc(c);
|
||||
return status;
|
||||
}
|
||||
|
||||
/* encrypt */
|
||||
len = test_case->plaintext_length_octets;
|
||||
status = cipher_encrypt(c, buffer, &len);
|
||||
if (status) {
|
||||
cipher_dealloc(c);
|
||||
return status;
|
||||
}
|
||||
|
||||
debug_print(mod_cipher, "ciphertext: %s",
|
||||
octet_string_hex_string(buffer,
|
||||
test_case->ciphertext_length_octets));
|
||||
|
||||
/* compare the resulting ciphertext with that in the test case */
|
||||
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++)
|
||||
if (buffer[i] != test_case->ciphertext[i]) {
|
||||
status = err_status_algo_fail;
|
||||
debug_print(mod_cipher, "test case %d failed", case_num);
|
||||
debug_print(mod_cipher, "(failure at byte %d)", i);
|
||||
break;
|
||||
}
|
||||
if (status) {
|
||||
|
||||
debug_print(mod_cipher, "c computed: %s",
|
||||
octet_string_hex_string(buffer,
|
||||
2*test_case->plaintext_length_octets));
|
||||
debug_print(mod_cipher, "c expected: %s",
|
||||
octet_string_hex_string(test_case->ciphertext,
|
||||
2*test_case->plaintext_length_octets));
|
||||
|
||||
cipher_dealloc(c);
|
||||
return err_status_algo_fail;
|
||||
}
|
||||
|
||||
/*
|
||||
* test the decrypt function
|
||||
*/
|
||||
debug_print(mod_cipher, "testing decryption", NULL);
|
||||
|
||||
/* re-initialize cipher for decryption */
|
||||
status = cipher_init(c, test_case->key, direction_decrypt);
|
||||
if (status) {
|
||||
cipher_dealloc(c);
|
||||
return status;
|
||||
}
|
||||
|
||||
/* copy ciphertext into test buffer */
|
||||
if (test_case->ciphertext_length_octets > SELF_TEST_BUF_OCTETS) {
|
||||
cipher_dealloc(c);
|
||||
return err_status_bad_param;
|
||||
}
|
||||
for (i=0; i < test_case->ciphertext_length_octets; i++)
|
||||
buffer[i] = test_case->ciphertext[i];
|
||||
|
||||
debug_print(mod_cipher, "ciphertext: %s",
|
||||
octet_string_hex_string(buffer,
|
||||
test_case->plaintext_length_octets));
|
||||
|
||||
/* set the initialization vector */
|
||||
status = cipher_set_iv(c, test_case->idx);
|
||||
if (status) {
|
||||
cipher_dealloc(c);
|
||||
return status;
|
||||
}
|
||||
|
||||
/* decrypt */
|
||||
len = test_case->ciphertext_length_octets;
|
||||
status = cipher_decrypt(c, buffer, &len);
|
||||
if (status) {
|
||||
cipher_dealloc(c);
|
||||
return status;
|
||||
}
|
||||
|
||||
debug_print(mod_cipher, "plaintext: %s",
|
||||
octet_string_hex_string(buffer,
|
||||
test_case->plaintext_length_octets));
|
||||
|
||||
/* compare the resulting plaintext with that in the test case */
|
||||
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++)
|
||||
if (buffer[i] != test_case->plaintext[i]) {
|
||||
status = err_status_algo_fail;
|
||||
debug_print(mod_cipher, "test case %d failed", case_num);
|
||||
debug_print(mod_cipher, "(failure at byte %d)", i);
|
||||
}
|
||||
if (status) {
|
||||
|
||||
debug_print(mod_cipher, "p computed: %s",
|
||||
octet_string_hex_string(buffer,
|
||||
2*test_case->plaintext_length_octets));
|
||||
debug_print(mod_cipher, "p expected: %s",
|
||||
octet_string_hex_string(test_case->plaintext,
|
||||
2*test_case->plaintext_length_octets));
|
||||
|
||||
cipher_dealloc(c);
|
||||
return err_status_algo_fail;
|
||||
}
|
||||
|
||||
/* deallocate the cipher */
|
||||
status = cipher_dealloc(c);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
/*
|
||||
* the cipher passed the test case, so move on to the next test
|
||||
* case in the list; if NULL, we'l proceed to the next test
|
||||
*/
|
||||
test_case = test_case->next_test_case;
|
||||
++case_num;
|
||||
}
|
||||
|
||||
/* now run some random invertibility tests */
|
||||
|
||||
/* allocate cipher, using paramaters from the first test case */
|
||||
test_case = test_data;
|
||||
status = cipher_type_alloc(ct, &c, test_case->key_length_octets);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
rand_source_init();
|
||||
|
||||
for (j=0; j < NUM_RAND_TESTS; j++) {
|
||||
unsigned length;
|
||||
int plaintext_len;
|
||||
uint8_t key[MAX_KEY_LEN];
|
||||
uint8_t iv[MAX_KEY_LEN];
|
||||
|
||||
/* choose a length at random (leaving room for IV and padding) */
|
||||
length = rand() % (SELF_TEST_BUF_OCTETS - 64);
|
||||
debug_print(mod_cipher, "random plaintext length %d\n", length);
|
||||
status = rand_source_get_octet_string(buffer, length);
|
||||
if (status) return status;
|
||||
|
||||
debug_print(mod_cipher, "plaintext: %s",
|
||||
octet_string_hex_string(buffer, length));
|
||||
|
||||
/* copy plaintext into second buffer */
|
||||
for (i=0; (unsigned int)i < length; i++)
|
||||
buffer2[i] = buffer[i];
|
||||
|
||||
/* choose a key at random */
|
||||
if (test_case->key_length_octets > MAX_KEY_LEN)
|
||||
return err_status_cant_check;
|
||||
status = rand_source_get_octet_string(key, test_case->key_length_octets);
|
||||
if (status) return status;
|
||||
|
||||
/* chose a random initialization vector */
|
||||
status = rand_source_get_octet_string(iv, MAX_KEY_LEN);
|
||||
if (status) return status;
|
||||
|
||||
/* initialize cipher */
|
||||
status = cipher_init(c, key, direction_encrypt);
|
||||
if (status) {
|
||||
cipher_dealloc(c);
|
||||
return status;
|
||||
}
|
||||
|
||||
/* set initialization vector */
|
||||
status = cipher_set_iv(c, test_case->idx);
|
||||
if (status) {
|
||||
cipher_dealloc(c);
|
||||
return status;
|
||||
}
|
||||
|
||||
/* encrypt buffer with cipher */
|
||||
plaintext_len = length;
|
||||
status = cipher_encrypt(c, buffer, &length);
|
||||
if (status) {
|
||||
cipher_dealloc(c);
|
||||
return status;
|
||||
}
|
||||
debug_print(mod_cipher, "ciphertext: %s",
|
||||
octet_string_hex_string(buffer, length));
|
||||
|
||||
/*
|
||||
* re-initialize cipher for decryption, re-set the iv, then
|
||||
* decrypt the ciphertext
|
||||
*/
|
||||
status = cipher_init(c, key, direction_decrypt);
|
||||
if (status) {
|
||||
cipher_dealloc(c);
|
||||
return status;
|
||||
}
|
||||
status = cipher_set_iv(c, test_case->idx);
|
||||
if (status) {
|
||||
cipher_dealloc(c);
|
||||
return status;
|
||||
}
|
||||
status = cipher_decrypt(c, buffer, &length);
|
||||
if (status) {
|
||||
cipher_dealloc(c);
|
||||
return status;
|
||||
}
|
||||
|
||||
debug_print(mod_cipher, "plaintext[2]: %s",
|
||||
octet_string_hex_string(buffer, length));
|
||||
|
||||
/* compare the resulting plaintext with the original one */
|
||||
if (length != plaintext_len)
|
||||
return err_status_algo_fail;
|
||||
status = err_status_ok;
|
||||
for (i=0; i < plaintext_len; i++)
|
||||
if (buffer[i] != buffer2[i]) {
|
||||
status = err_status_algo_fail;
|
||||
debug_print(mod_cipher, "random test case %d failed", case_num);
|
||||
debug_print(mod_cipher, "(failure at byte %d)", i);
|
||||
}
|
||||
if (status) {
|
||||
cipher_dealloc(c);
|
||||
return err_status_algo_fail;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
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
|
||||
*
|
||||
* c is a cipher (which MUST be allocated and initialized already), l
|
||||
* is the length in octets of the test data to be encrypted, and t is
|
||||
* the number of trials
|
||||
*
|
||||
* if an error is encountered, the value 0 is returned
|
||||
*/
|
||||
|
||||
uint64_t
|
||||
cipher_bits_per_second(cipher_t *c, int octets_in_buffer, int num_trials) {
|
||||
int i;
|
||||
v128_t nonce;
|
||||
clock_t timer;
|
||||
unsigned char *enc_buf;
|
||||
unsigned int len = octets_in_buffer;
|
||||
|
||||
enc_buf = (unsigned char*) crypto_alloc(octets_in_buffer);
|
||||
if (enc_buf == NULL)
|
||||
return 0; /* indicate bad parameters by returning null */
|
||||
|
||||
/* time repeated trials */
|
||||
v128_set_to_zero(&nonce);
|
||||
timer = clock();
|
||||
for(i=0; i < num_trials; i++, nonce.v32[3] = i) {
|
||||
cipher_set_iv(c, &nonce);
|
||||
cipher_encrypt(c, enc_buf, &len);
|
||||
}
|
||||
timer = clock() - timer;
|
||||
|
||||
crypto_free(enc_buf);
|
||||
|
||||
if (timer == 0) {
|
||||
/* Too fast! */
|
||||
return 0;
|
||||
}
|
||||
|
||||
return (uint64_t)CLOCKS_PER_SEC * num_trials * 8 * octets_in_buffer / timer;
|
||||
}
|
||||
|
|
@ -1,153 +0,0 @@
|
|||
/*
|
||||
* null_cipher.c
|
||||
*
|
||||
* A null cipher implementation. This cipher leaves the plaintext
|
||||
* unchanged.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "datatypes.h"
|
||||
#include "null_cipher.h"
|
||||
#include "alloc.h"
|
||||
|
||||
/* the null_cipher uses the cipher debug module */
|
||||
|
||||
extern debug_module_t mod_cipher;
|
||||
|
||||
err_status_t
|
||||
null_cipher_alloc(cipher_t **c, int key_len) {
|
||||
extern cipher_type_t null_cipher;
|
||||
uint8_t *pointer;
|
||||
|
||||
debug_print(mod_cipher,
|
||||
"allocating cipher with key length %d", key_len);
|
||||
|
||||
/* allocate memory a cipher of type null_cipher */
|
||||
pointer = (uint8_t*)crypto_alloc(sizeof(null_cipher_ctx_t) + sizeof(cipher_t));
|
||||
if (pointer == NULL)
|
||||
return err_status_alloc_fail;
|
||||
|
||||
/* set pointers */
|
||||
*c = (cipher_t *)pointer;
|
||||
(*c)->type = &null_cipher;
|
||||
(*c)->state = pointer + sizeof(cipher_t);
|
||||
|
||||
/* set key size */
|
||||
(*c)->key_len = key_len;
|
||||
|
||||
/* increment ref_count */
|
||||
null_cipher.ref_count++;
|
||||
|
||||
return err_status_ok;
|
||||
|
||||
}
|
||||
|
||||
err_status_t
|
||||
null_cipher_dealloc(cipher_t *c) {
|
||||
extern cipher_type_t null_cipher;
|
||||
|
||||
/* zeroize entire state*/
|
||||
octet_string_set_to_zero((uint8_t *)c,
|
||||
sizeof(null_cipher_ctx_t) + sizeof(cipher_t));
|
||||
|
||||
/* free memory of type null_cipher */
|
||||
crypto_free(c);
|
||||
|
||||
/* decrement reference count */
|
||||
null_cipher.ref_count--;
|
||||
|
||||
return err_status_ok;
|
||||
|
||||
}
|
||||
|
||||
err_status_t
|
||||
null_cipher_init(null_cipher_ctx_t *ctx, const uint8_t *key, int key_len) {
|
||||
|
||||
debug_print(mod_cipher, "initializing null cipher", NULL);
|
||||
|
||||
return err_status_ok;
|
||||
}
|
||||
|
||||
err_status_t
|
||||
null_cipher_set_iv(null_cipher_ctx_t *c, void *iv) {
|
||||
return err_status_ok;
|
||||
}
|
||||
|
||||
err_status_t
|
||||
null_cipher_encrypt(null_cipher_ctx_t *c,
|
||||
unsigned char *buf, unsigned int *bytes_to_encr) {
|
||||
return err_status_ok;
|
||||
}
|
||||
|
||||
char
|
||||
null_cipher_description[] = "null cipher";
|
||||
|
||||
cipher_test_case_t
|
||||
null_cipher_test_0 = {
|
||||
0, /* octets in key */
|
||||
NULL, /* key */
|
||||
0, /* packet index */
|
||||
0, /* octets in plaintext */
|
||||
NULL, /* plaintext */
|
||||
0, /* octets in plaintext */
|
||||
NULL, /* ciphertext */
|
||||
NULL /* pointer to next testcase */
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* note: the decrypt function is idential to the encrypt function
|
||||
*/
|
||||
|
||||
cipher_type_t null_cipher = {
|
||||
(cipher_alloc_func_t) null_cipher_alloc,
|
||||
(cipher_dealloc_func_t) null_cipher_dealloc,
|
||||
(cipher_init_func_t) null_cipher_init,
|
||||
(cipher_encrypt_func_t) null_cipher_encrypt,
|
||||
(cipher_decrypt_func_t) null_cipher_encrypt,
|
||||
(cipher_set_iv_func_t) null_cipher_set_iv,
|
||||
(char *) null_cipher_description,
|
||||
(int) 0,
|
||||
(cipher_test_case_t *) &null_cipher_test_0,
|
||||
(debug_module_t *) NULL,
|
||||
(cipher_type_id_t) NULL_CIPHER
|
||||
};
|
||||
|
||||
|
|
@ -1,268 +0,0 @@
|
|||
/*
|
||||
* hmac.c
|
||||
*
|
||||
* implementation of hmac auth_type_t
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "hmac.h"
|
||||
#include "alloc.h"
|
||||
|
||||
/* the debug module for authentiation */
|
||||
|
||||
debug_module_t mod_hmac = {
|
||||
0, /* debugging is off by default */
|
||||
"hmac sha-1" /* printable name for module */
|
||||
};
|
||||
|
||||
|
||||
err_status_t
|
||||
hmac_alloc(auth_t **a, int key_len, int out_len) {
|
||||
extern auth_type_t hmac;
|
||||
uint8_t *pointer;
|
||||
|
||||
debug_print(mod_hmac, "allocating auth func with key length %d", key_len);
|
||||
debug_print(mod_hmac, " tag length %d", out_len);
|
||||
|
||||
/*
|
||||
* check key length - note that we don't support keys larger
|
||||
* than 20 bytes yet
|
||||
*/
|
||||
if (key_len > 20)
|
||||
return err_status_bad_param;
|
||||
|
||||
/* check output length - should be less than 20 bytes */
|
||||
if (out_len > 20)
|
||||
return err_status_bad_param;
|
||||
|
||||
/* allocate memory for auth and hmac_ctx_t structures */
|
||||
pointer = (uint8_t*)crypto_alloc(sizeof(hmac_ctx_t) + sizeof(auth_t));
|
||||
if (pointer == NULL)
|
||||
return err_status_alloc_fail;
|
||||
|
||||
/* set pointers */
|
||||
*a = (auth_t *)pointer;
|
||||
(*a)->type = &hmac;
|
||||
(*a)->state = pointer + sizeof(auth_t);
|
||||
(*a)->out_len = out_len;
|
||||
(*a)->key_len = key_len;
|
||||
(*a)->prefix_len = 0;
|
||||
|
||||
/* increment global count of all hmac uses */
|
||||
hmac.ref_count++;
|
||||
|
||||
return err_status_ok;
|
||||
}
|
||||
|
||||
err_status_t
|
||||
hmac_dealloc(auth_t *a) {
|
||||
extern auth_type_t hmac;
|
||||
|
||||
/* zeroize entire state*/
|
||||
octet_string_set_to_zero((uint8_t *)a,
|
||||
sizeof(hmac_ctx_t) + sizeof(auth_t));
|
||||
|
||||
/* free memory */
|
||||
crypto_free(a);
|
||||
|
||||
/* decrement global count of all hmac uses */
|
||||
hmac.ref_count--;
|
||||
|
||||
return err_status_ok;
|
||||
}
|
||||
|
||||
err_status_t
|
||||
hmac_init(hmac_ctx_t *state, const uint8_t *key, int key_len) {
|
||||
int i;
|
||||
uint8_t ipad[64];
|
||||
|
||||
/*
|
||||
* check key length - note that we don't support keys larger
|
||||
* than 20 bytes yet
|
||||
*/
|
||||
if (key_len > 20)
|
||||
return err_status_bad_param;
|
||||
|
||||
/*
|
||||
* set values of ipad and opad by exoring the key into the
|
||||
* appropriate constant values
|
||||
*/
|
||||
for (i=0; i < key_len; i++) {
|
||||
ipad[i] = key[i] ^ 0x36;
|
||||
state->opad[i] = key[i] ^ 0x5c;
|
||||
}
|
||||
/* set the rest of ipad, opad to constant values */
|
||||
for ( ; i < 64; i++) {
|
||||
ipad[i] = 0x36;
|
||||
((uint8_t *)state->opad)[i] = 0x5c;
|
||||
}
|
||||
|
||||
debug_print(mod_hmac, "ipad: %s", octet_string_hex_string(ipad, 64));
|
||||
|
||||
/* initialize sha1 context */
|
||||
srtp_sha1_init(&state->init_ctx);
|
||||
|
||||
/* hash ipad ^ key */
|
||||
srtp_sha1_update(&state->init_ctx, ipad, 64);
|
||||
memcpy(&state->ctx, &state->init_ctx, sizeof(sha1_ctx_t));
|
||||
|
||||
return err_status_ok;
|
||||
}
|
||||
|
||||
err_status_t
|
||||
hmac_start(hmac_ctx_t *state) {
|
||||
|
||||
memcpy(&state->ctx, &state->init_ctx, sizeof(sha1_ctx_t));
|
||||
|
||||
return err_status_ok;
|
||||
}
|
||||
|
||||
err_status_t
|
||||
hmac_update(hmac_ctx_t *state, const uint8_t *message, int msg_octets) {
|
||||
|
||||
debug_print(mod_hmac, "input: %s",
|
||||
octet_string_hex_string(message, msg_octets));
|
||||
|
||||
/* hash message into sha1 context */
|
||||
srtp_sha1_update(&state->ctx, message, msg_octets);
|
||||
|
||||
return err_status_ok;
|
||||
}
|
||||
|
||||
err_status_t
|
||||
hmac_compute(hmac_ctx_t *state, const void *message,
|
||||
int msg_octets, int tag_len, uint8_t *result) {
|
||||
uint32_t hash_value[5];
|
||||
uint32_t H[5];
|
||||
int i;
|
||||
|
||||
/* check tag length, return error if we can't provide the value expected */
|
||||
if (tag_len > 20)
|
||||
return err_status_bad_param;
|
||||
|
||||
/* hash message, copy output into H */
|
||||
hmac_update(state, (const uint8_t*)message, msg_octets);
|
||||
srtp_sha1_final(&state->ctx, H);
|
||||
|
||||
/*
|
||||
* note that we don't need to debug_print() the input, since the
|
||||
* function hmac_update() already did that for us
|
||||
*/
|
||||
debug_print(mod_hmac, "intermediate state: %s",
|
||||
octet_string_hex_string((uint8_t *)H, 20));
|
||||
|
||||
/* re-initialize hash context */
|
||||
srtp_sha1_init(&state->ctx);
|
||||
|
||||
/* hash opad ^ key */
|
||||
srtp_sha1_update(&state->ctx, (uint8_t *)state->opad, 64);
|
||||
|
||||
/* hash the result of the inner hash */
|
||||
srtp_sha1_update(&state->ctx, (uint8_t *)H, 20);
|
||||
|
||||
/* the result is returned in the array hash_value[] */
|
||||
srtp_sha1_final(&state->ctx, hash_value);
|
||||
|
||||
/* copy hash_value to *result */
|
||||
for (i=0; i < tag_len; i++)
|
||||
result[i] = ((uint8_t *)hash_value)[i];
|
||||
|
||||
debug_print(mod_hmac, "output: %s",
|
||||
octet_string_hex_string((uint8_t *)hash_value, tag_len));
|
||||
|
||||
return err_status_ok;
|
||||
}
|
||||
|
||||
|
||||
/* begin test case 0 */
|
||||
|
||||
uint8_t
|
||||
hmac_test_case_0_key[20] = {
|
||||
0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
|
||||
0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
|
||||
0x0b, 0x0b, 0x0b, 0x0b
|
||||
};
|
||||
|
||||
uint8_t
|
||||
hmac_test_case_0_data[8] = {
|
||||
0x48, 0x69, 0x20, 0x54, 0x68, 0x65, 0x72, 0x65 /* "Hi There" */
|
||||
};
|
||||
|
||||
uint8_t
|
||||
hmac_test_case_0_tag[20] = {
|
||||
0xb6, 0x17, 0x31, 0x86, 0x55, 0x05, 0x72, 0x64,
|
||||
0xe2, 0x8b, 0xc0, 0xb6, 0xfb, 0x37, 0x8c, 0x8e,
|
||||
0xf1, 0x46, 0xbe, 0x00
|
||||
};
|
||||
|
||||
auth_test_case_t
|
||||
hmac_test_case_0 = {
|
||||
20, /* octets in key */
|
||||
hmac_test_case_0_key, /* key */
|
||||
8, /* octets in data */
|
||||
hmac_test_case_0_data, /* data */
|
||||
20, /* octets in tag */
|
||||
hmac_test_case_0_tag, /* tag */
|
||||
NULL /* pointer to next testcase */
|
||||
};
|
||||
|
||||
/* end test case 0 */
|
||||
|
||||
char hmac_description[] = "hmac sha-1 authentication function";
|
||||
|
||||
/*
|
||||
* auth_type_t hmac is the hmac metaobject
|
||||
*/
|
||||
|
||||
auth_type_t
|
||||
hmac = {
|
||||
(auth_alloc_func) hmac_alloc,
|
||||
(auth_dealloc_func) hmac_dealloc,
|
||||
(auth_init_func) hmac_init,
|
||||
(auth_compute_func) hmac_compute,
|
||||
(auth_update_func) hmac_update,
|
||||
(auth_start_func) hmac_start,
|
||||
(char *) hmac_description,
|
||||
(int) 0, /* instance count */
|
||||
(auth_test_case_t *) &hmac_test_case_0,
|
||||
(debug_module_t *) &mod_hmac,
|
||||
(auth_type_id_t) HMAC_SHA1
|
||||
};
|
||||
|
||||
|
|
@ -1,162 +0,0 @@
|
|||
/*
|
||||
* null_auth.c
|
||||
*
|
||||
* implements the do-nothing auth algorithm
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include "null_auth.h"
|
||||
#include "alloc.h"
|
||||
|
||||
/* null_auth uses the auth debug module */
|
||||
|
||||
extern debug_module_t mod_auth;
|
||||
|
||||
err_status_t
|
||||
null_auth_alloc(auth_t **a, int key_len, int out_len) {
|
||||
extern auth_type_t null_auth;
|
||||
uint8_t *pointer;
|
||||
|
||||
debug_print(mod_auth, "allocating auth func with key length %d", key_len);
|
||||
debug_print(mod_auth, " tag length %d", out_len);
|
||||
|
||||
/* allocate memory for auth and null_auth_ctx_t structures */
|
||||
pointer = (uint8_t*)crypto_alloc(sizeof(null_auth_ctx_t) + sizeof(auth_t));
|
||||
if (pointer == NULL)
|
||||
return err_status_alloc_fail;
|
||||
|
||||
/* set pointers */
|
||||
*a = (auth_t *)pointer;
|
||||
(*a)->type = &null_auth;
|
||||
(*a)->state = pointer + sizeof (auth_t);
|
||||
(*a)->out_len = out_len;
|
||||
(*a)->prefix_len = out_len;
|
||||
(*a)->key_len = key_len;
|
||||
|
||||
/* increment global count of all null_auth uses */
|
||||
null_auth.ref_count++;
|
||||
|
||||
return err_status_ok;
|
||||
}
|
||||
|
||||
err_status_t
|
||||
null_auth_dealloc(auth_t *a) {
|
||||
extern auth_type_t null_auth;
|
||||
|
||||
/* zeroize entire state*/
|
||||
octet_string_set_to_zero((uint8_t *)a,
|
||||
sizeof(null_auth_ctx_t) + sizeof(auth_t));
|
||||
|
||||
/* free memory */
|
||||
crypto_free(a);
|
||||
|
||||
/* decrement global count of all null_auth uses */
|
||||
null_auth.ref_count--;
|
||||
|
||||
return err_status_ok;
|
||||
}
|
||||
|
||||
err_status_t
|
||||
null_auth_init(null_auth_ctx_t *state, const uint8_t *key, int key_len) {
|
||||
|
||||
/* accept any length of key, and do nothing */
|
||||
|
||||
return err_status_ok;
|
||||
}
|
||||
|
||||
err_status_t
|
||||
null_auth_compute(null_auth_ctx_t *state, uint8_t *message,
|
||||
int msg_octets, int tag_len, uint8_t *result) {
|
||||
|
||||
return err_status_ok;
|
||||
}
|
||||
|
||||
err_status_t
|
||||
null_auth_update(null_auth_ctx_t *state, uint8_t *message,
|
||||
int msg_octets) {
|
||||
|
||||
return err_status_ok;
|
||||
}
|
||||
|
||||
err_status_t
|
||||
null_auth_start(null_auth_ctx_t *state) {
|
||||
return err_status_ok;
|
||||
}
|
||||
|
||||
/*
|
||||
* auth_type_t - defines description, test case, and null_auth
|
||||
* metaobject
|
||||
*/
|
||||
|
||||
/* begin test case 0 */
|
||||
|
||||
auth_test_case_t
|
||||
null_auth_test_case_0 = {
|
||||
0, /* octets in key */
|
||||
NULL, /* key */
|
||||
0, /* octets in data */
|
||||
NULL, /* data */
|
||||
0, /* octets in tag */
|
||||
NULL, /* tag */
|
||||
NULL /* pointer to next testcase */
|
||||
};
|
||||
|
||||
/* end test case 0 */
|
||||
|
||||
char null_auth_description[] = "null authentication function";
|
||||
|
||||
auth_type_t
|
||||
null_auth = {
|
||||
(auth_alloc_func) null_auth_alloc,
|
||||
(auth_dealloc_func) null_auth_dealloc,
|
||||
(auth_init_func) null_auth_init,
|
||||
(auth_compute_func) null_auth_compute,
|
||||
(auth_update_func) null_auth_update,
|
||||
(auth_start_func) null_auth_start,
|
||||
(char *) null_auth_description,
|
||||
(int) 0, /* instance count */
|
||||
(auth_test_case_t *) &null_auth_test_case_0,
|
||||
(debug_module_t *) NULL,
|
||||
(auth_type_id_t) NULL_AUTH
|
||||
};
|
||||
|
||||
|
|
@ -1,405 +0,0 @@
|
|||
/*
|
||||
* sha1.c
|
||||
*
|
||||
* an implementation of the Secure Hash Algorithm v.1 (SHA-1),
|
||||
* specified in FIPS 180-1
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include "sha1.h"
|
||||
|
||||
debug_module_t mod_sha1 = {
|
||||
0, /* debugging is off by default */
|
||||
"sha-1" /* printable module name */
|
||||
};
|
||||
|
||||
/* SN == Rotate left N bits */
|
||||
#define S1(X) ((X << 1) | (X >> 31))
|
||||
#define S5(X) ((X << 5) | (X >> 27))
|
||||
#define S30(X) ((X << 30) | (X >> 2))
|
||||
|
||||
#define f0(B,C,D) ((B & C) | (~B & D))
|
||||
#define f1(B,C,D) (B ^ C ^ D)
|
||||
#define f2(B,C,D) ((B & C) | (B & D) | (C & D))
|
||||
#define f3(B,C,D) (B ^ C ^ D)
|
||||
|
||||
/*
|
||||
* nota bene: the variable K0 appears in the curses library, so we
|
||||
* give longer names to these variables to avoid spurious warnings
|
||||
* on systems that uses curses
|
||||
*/
|
||||
|
||||
uint32_t SHA_K0 = 0x5A827999; /* Kt for 0 <= t <= 19 */
|
||||
uint32_t SHA_K1 = 0x6ED9EBA1; /* Kt for 20 <= t <= 39 */
|
||||
uint32_t SHA_K2 = 0x8F1BBCDC; /* Kt for 40 <= t <= 59 */
|
||||
uint32_t SHA_K3 = 0xCA62C1D6; /* Kt for 60 <= t <= 79 */
|
||||
|
||||
void
|
||||
sha1(const uint8_t *msg, int octets_in_msg, uint32_t hash_value[5]) {
|
||||
sha1_ctx_t ctx;
|
||||
|
||||
srtp_sha1_init(&ctx);
|
||||
srtp_sha1_update(&ctx, msg, octets_in_msg);
|
||||
srtp_sha1_final(&ctx, hash_value);
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* sha1_core(M, H) computes the core compression function, where M is
|
||||
* the next part of the message (in network byte order) and H is the
|
||||
* intermediate state { H0, H1, ...} (in host byte order)
|
||||
*
|
||||
* this function does not do any of the padding required in the
|
||||
* complete SHA1 function
|
||||
*
|
||||
* this function is used in the SEAL 3.0 key setup routines
|
||||
* (crypto/cipher/seal.c)
|
||||
*/
|
||||
|
||||
void
|
||||
sha1_core(const uint32_t M[16], uint32_t hash_value[5]) {
|
||||
uint32_t H0;
|
||||
uint32_t H1;
|
||||
uint32_t H2;
|
||||
uint32_t H3;
|
||||
uint32_t H4;
|
||||
uint32_t W[80];
|
||||
uint32_t A, B, C, D, E, TEMP;
|
||||
int t;
|
||||
|
||||
/* copy hash_value into H0, H1, H2, H3, H4 */
|
||||
H0 = hash_value[0];
|
||||
H1 = hash_value[1];
|
||||
H2 = hash_value[2];
|
||||
H3 = hash_value[3];
|
||||
H4 = hash_value[4];
|
||||
|
||||
/* copy/xor message into array */
|
||||
|
||||
W[0] = be32_to_cpu(M[0]);
|
||||
W[1] = be32_to_cpu(M[1]);
|
||||
W[2] = be32_to_cpu(M[2]);
|
||||
W[3] = be32_to_cpu(M[3]);
|
||||
W[4] = be32_to_cpu(M[4]);
|
||||
W[5] = be32_to_cpu(M[5]);
|
||||
W[6] = be32_to_cpu(M[6]);
|
||||
W[7] = be32_to_cpu(M[7]);
|
||||
W[8] = be32_to_cpu(M[8]);
|
||||
W[9] = be32_to_cpu(M[9]);
|
||||
W[10] = be32_to_cpu(M[10]);
|
||||
W[11] = be32_to_cpu(M[11]);
|
||||
W[12] = be32_to_cpu(M[12]);
|
||||
W[13] = be32_to_cpu(M[13]);
|
||||
W[14] = be32_to_cpu(M[14]);
|
||||
W[15] = be32_to_cpu(M[15]);
|
||||
TEMP = W[13] ^ W[8] ^ W[2] ^ W[0]; W[16] = S1(TEMP);
|
||||
TEMP = W[14] ^ W[9] ^ W[3] ^ W[1]; W[17] = S1(TEMP);
|
||||
TEMP = W[15] ^ W[10] ^ W[4] ^ W[2]; W[18] = S1(TEMP);
|
||||
TEMP = W[16] ^ W[11] ^ W[5] ^ W[3]; W[19] = S1(TEMP);
|
||||
TEMP = W[17] ^ W[12] ^ W[6] ^ W[4]; W[20] = S1(TEMP);
|
||||
TEMP = W[18] ^ W[13] ^ W[7] ^ W[5]; W[21] = S1(TEMP);
|
||||
TEMP = W[19] ^ W[14] ^ W[8] ^ W[6]; W[22] = S1(TEMP);
|
||||
TEMP = W[20] ^ W[15] ^ W[9] ^ W[7]; W[23] = S1(TEMP);
|
||||
TEMP = W[21] ^ W[16] ^ W[10] ^ W[8]; W[24] = S1(TEMP);
|
||||
TEMP = W[22] ^ W[17] ^ W[11] ^ W[9]; W[25] = S1(TEMP);
|
||||
TEMP = W[23] ^ W[18] ^ W[12] ^ W[10]; W[26] = S1(TEMP);
|
||||
TEMP = W[24] ^ W[19] ^ W[13] ^ W[11]; W[27] = S1(TEMP);
|
||||
TEMP = W[25] ^ W[20] ^ W[14] ^ W[12]; W[28] = S1(TEMP);
|
||||
TEMP = W[26] ^ W[21] ^ W[15] ^ W[13]; W[29] = S1(TEMP);
|
||||
TEMP = W[27] ^ W[22] ^ W[16] ^ W[14]; W[30] = S1(TEMP);
|
||||
TEMP = W[28] ^ W[23] ^ W[17] ^ W[15]; W[31] = S1(TEMP);
|
||||
|
||||
/* process the remainder of the array */
|
||||
for (t=32; t < 80; t++) {
|
||||
TEMP = W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16];
|
||||
W[t] = S1(TEMP);
|
||||
}
|
||||
|
||||
A = H0; B = H1; C = H2; D = H3; E = H4;
|
||||
|
||||
for (t=0; t < 20; t++) {
|
||||
TEMP = S5(A) + f0(B,C,D) + E + W[t] + SHA_K0;
|
||||
E = D; D = C; C = S30(B); B = A; A = TEMP;
|
||||
}
|
||||
for ( ; t < 40; t++) {
|
||||
TEMP = S5(A) + f1(B,C,D) + E + W[t] + SHA_K1;
|
||||
E = D; D = C; C = S30(B); B = A; A = TEMP;
|
||||
}
|
||||
for ( ; t < 60; t++) {
|
||||
TEMP = S5(A) + f2(B,C,D) + E + W[t] + SHA_K2;
|
||||
E = D; D = C; C = S30(B); B = A; A = TEMP;
|
||||
}
|
||||
for ( ; t < 80; t++) {
|
||||
TEMP = S5(A) + f3(B,C,D) + E + W[t] + SHA_K3;
|
||||
E = D; D = C; C = S30(B); B = A; A = TEMP;
|
||||
}
|
||||
|
||||
hash_value[0] = H0 + A;
|
||||
hash_value[1] = H1 + B;
|
||||
hash_value[2] = H2 + C;
|
||||
hash_value[3] = H3 + D;
|
||||
hash_value[4] = H4 + E;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
srtp_sha1_init(sha1_ctx_t *ctx) {
|
||||
|
||||
/* initialize state vector */
|
||||
ctx->H[0] = 0x67452301;
|
||||
ctx->H[1] = 0xefcdab89;
|
||||
ctx->H[2] = 0x98badcfe;
|
||||
ctx->H[3] = 0x10325476;
|
||||
ctx->H[4] = 0xc3d2e1f0;
|
||||
|
||||
/* indicate that message buffer is empty */
|
||||
ctx->octets_in_buffer = 0;
|
||||
|
||||
/* reset message bit-count to zero */
|
||||
ctx->num_bits_in_msg = 0;
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
srtp_sha1_update(sha1_ctx_t *ctx, const uint8_t *msg, int octets_in_msg) {
|
||||
int i;
|
||||
uint8_t *buf = (uint8_t *)ctx->M;
|
||||
|
||||
/* update message bit-count */
|
||||
ctx->num_bits_in_msg += octets_in_msg * 8;
|
||||
|
||||
/* loop over 16-word blocks of M */
|
||||
while (octets_in_msg > 0) {
|
||||
|
||||
if (octets_in_msg + ctx->octets_in_buffer >= 64) {
|
||||
|
||||
/*
|
||||
* copy words of M into msg buffer until that buffer is full,
|
||||
* converting them into host byte order as needed
|
||||
*/
|
||||
octets_in_msg -= (64 - ctx->octets_in_buffer);
|
||||
for (i=ctx->octets_in_buffer; i < 64; i++)
|
||||
buf[i] = *msg++;
|
||||
ctx->octets_in_buffer = 0;
|
||||
|
||||
/* process a whole block */
|
||||
|
||||
debug_print(mod_sha1, "(update) running sha1_core()", NULL);
|
||||
|
||||
sha1_core(ctx->M, ctx->H);
|
||||
|
||||
} else {
|
||||
|
||||
debug_print(mod_sha1, "(update) not running sha1_core()", NULL);
|
||||
|
||||
for (i=ctx->octets_in_buffer;
|
||||
i < (ctx->octets_in_buffer + octets_in_msg); i++)
|
||||
buf[i] = *msg++;
|
||||
ctx->octets_in_buffer += octets_in_msg;
|
||||
octets_in_msg = 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* sha1_final(ctx, output) computes the result for ctx and copies it
|
||||
* into the twenty octets located at *output
|
||||
*/
|
||||
|
||||
void
|
||||
srtp_sha1_final(sha1_ctx_t *ctx, uint32_t *output) {
|
||||
uint32_t A, B, C, D, E, TEMP;
|
||||
uint32_t W[80];
|
||||
int i, t;
|
||||
|
||||
/*
|
||||
* process the remaining octets_in_buffer, padding and terminating as
|
||||
* necessary
|
||||
*/
|
||||
{
|
||||
int tail = ctx->octets_in_buffer % 4;
|
||||
|
||||
/* copy/xor message into array */
|
||||
for (i=0; i < (ctx->octets_in_buffer+3)/4; i++)
|
||||
W[i] = be32_to_cpu(ctx->M[i]);
|
||||
|
||||
/* set the high bit of the octet immediately following the message */
|
||||
switch (tail) {
|
||||
case (3):
|
||||
W[i-1] = (be32_to_cpu(ctx->M[i-1]) & 0xffffff00) | 0x80;
|
||||
W[i] = 0x0;
|
||||
break;
|
||||
case (2):
|
||||
W[i-1] = (be32_to_cpu(ctx->M[i-1]) & 0xffff0000) | 0x8000;
|
||||
W[i] = 0x0;
|
||||
break;
|
||||
case (1):
|
||||
W[i-1] = (be32_to_cpu(ctx->M[i-1]) & 0xff000000) | 0x800000;
|
||||
W[i] = 0x0;
|
||||
break;
|
||||
case (0):
|
||||
W[i] = 0x80000000;
|
||||
break;
|
||||
}
|
||||
|
||||
/* zeroize remaining words */
|
||||
for (i++ ; i < 15; i++)
|
||||
W[i] = 0x0;
|
||||
|
||||
/*
|
||||
* if there is room at the end of the word array, then set the
|
||||
* last word to the bit-length of the message; otherwise, set that
|
||||
* word to zero and then we need to do one more run of the
|
||||
* compression algo.
|
||||
*/
|
||||
if (ctx->octets_in_buffer < 56)
|
||||
W[15] = ctx->num_bits_in_msg;
|
||||
else if (ctx->octets_in_buffer < 60)
|
||||
W[15] = 0x0;
|
||||
|
||||
/* 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);
|
||||
}
|
||||
|
||||
A = ctx->H[0];
|
||||
B = ctx->H[1];
|
||||
C = ctx->H[2];
|
||||
D = ctx->H[3];
|
||||
E = ctx->H[4];
|
||||
|
||||
for (t=0; t < 20; t++) {
|
||||
TEMP = S5(A) + f0(B,C,D) + E + W[t] + SHA_K0;
|
||||
E = D; D = C; C = S30(B); B = A; A = TEMP;
|
||||
}
|
||||
for ( ; t < 40; t++) {
|
||||
TEMP = S5(A) + f1(B,C,D) + E + W[t] + SHA_K1;
|
||||
E = D; D = C; C = S30(B); B = A; A = TEMP;
|
||||
}
|
||||
for ( ; t < 60; t++) {
|
||||
TEMP = S5(A) + f2(B,C,D) + E + W[t] + SHA_K2;
|
||||
E = D; D = C; C = S30(B); B = A; A = TEMP;
|
||||
}
|
||||
for ( ; t < 80; t++) {
|
||||
TEMP = S5(A) + f3(B,C,D) + E + W[t] + SHA_K3;
|
||||
E = D; D = C; C = S30(B); B = A; A = TEMP;
|
||||
}
|
||||
|
||||
ctx->H[0] += A;
|
||||
ctx->H[1] += B;
|
||||
ctx->H[2] += C;
|
||||
ctx->H[3] += D;
|
||||
ctx->H[4] += E;
|
||||
|
||||
}
|
||||
|
||||
debug_print(mod_sha1, "(final) running sha1_core()", NULL);
|
||||
|
||||
if (ctx->octets_in_buffer >= 56) {
|
||||
|
||||
debug_print(mod_sha1, "(final) running sha1_core() again", NULL);
|
||||
|
||||
/* we need to do one final run of the compression algo */
|
||||
|
||||
/*
|
||||
* set initial part of word array to zeros, and set the
|
||||
* final part to the number of bits in the message
|
||||
*/
|
||||
for (i=0; i < 15; i++)
|
||||
W[i] = 0x0;
|
||||
W[15] = ctx->num_bits_in_msg;
|
||||
|
||||
/* 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);
|
||||
}
|
||||
|
||||
A = ctx->H[0];
|
||||
B = ctx->H[1];
|
||||
C = ctx->H[2];
|
||||
D = ctx->H[3];
|
||||
E = ctx->H[4];
|
||||
|
||||
for (t=0; t < 20; t++) {
|
||||
TEMP = S5(A) + f0(B,C,D) + E + W[t] + SHA_K0;
|
||||
E = D; D = C; C = S30(B); B = A; A = TEMP;
|
||||
}
|
||||
for ( ; t < 40; t++) {
|
||||
TEMP = S5(A) + f1(B,C,D) + E + W[t] + SHA_K1;
|
||||
E = D; D = C; C = S30(B); B = A; A = TEMP;
|
||||
}
|
||||
for ( ; t < 60; t++) {
|
||||
TEMP = S5(A) + f2(B,C,D) + E + W[t] + SHA_K2;
|
||||
E = D; D = C; C = S30(B); B = A; A = TEMP;
|
||||
}
|
||||
for ( ; t < 80; t++) {
|
||||
TEMP = S5(A) + f3(B,C,D) + E + W[t] + SHA_K3;
|
||||
E = D; D = C; C = S30(B); B = A; A = TEMP;
|
||||
}
|
||||
|
||||
ctx->H[0] += A;
|
||||
ctx->H[1] += B;
|
||||
ctx->H[2] += C;
|
||||
ctx->H[3] += D;
|
||||
ctx->H[4] += E;
|
||||
}
|
||||
|
||||
/* copy result into output buffer */
|
||||
output[0] = be32_to_cpu(ctx->H[0]);
|
||||
output[1] = be32_to_cpu(ctx->H[1]);
|
||||
output[2] = be32_to_cpu(ctx->H[2]);
|
||||
output[3] = be32_to_cpu(ctx->H[3]);
|
||||
output[4] = be32_to_cpu(ctx->H[4]);
|
||||
|
||||
/* indicate that message buffer in context is empty */
|
||||
ctx->octets_in_buffer = 0;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
@ -1,183 +0,0 @@
|
|||
/*
|
||||
* auth.c
|
||||
*
|
||||
* some bookkeeping functions for authentication functions
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "auth.h"
|
||||
|
||||
/* the debug module for authentiation */
|
||||
|
||||
debug_module_t mod_auth = {
|
||||
0, /* debugging is off by default */
|
||||
"auth func" /* printable name for module */
|
||||
};
|
||||
|
||||
|
||||
int
|
||||
auth_get_key_length(const auth_t *a) {
|
||||
return a->key_len;
|
||||
}
|
||||
|
||||
int
|
||||
auth_get_tag_length(const auth_t *a) {
|
||||
return a->out_len;
|
||||
}
|
||||
|
||||
int
|
||||
auth_get_prefix_length(const auth_t *a) {
|
||||
return a->prefix_len;
|
||||
}
|
||||
|
||||
int
|
||||
auth_type_get_ref_count(const auth_type_t *at) {
|
||||
return at->ref_count;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
/* should be big enough for most occasions */
|
||||
#define SELF_TEST_TAG_BUF_OCTETS 32
|
||||
|
||||
err_status_t
|
||||
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];
|
||||
int i, case_num = 0;
|
||||
|
||||
debug_print(mod_auth, "running self-test for auth function %s",
|
||||
at->description);
|
||||
|
||||
/*
|
||||
* check to make sure that we have at least one test case, and
|
||||
* return an error if we don't - we need to be paranoid here
|
||||
*/
|
||||
if (test_case == NULL)
|
||||
return err_status_cant_check;
|
||||
|
||||
/* loop over all test cases */
|
||||
while (test_case != NULL) {
|
||||
|
||||
/* check test case parameters */
|
||||
if (test_case->tag_length_octets > SELF_TEST_TAG_BUF_OCTETS)
|
||||
return err_status_bad_param;
|
||||
|
||||
/* allocate auth */
|
||||
status = auth_type_alloc(at, &a, test_case->key_length_octets,
|
||||
test_case->tag_length_octets);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
/* initialize auth */
|
||||
status = auth_init(a, test_case->key);
|
||||
if (status) {
|
||||
auth_dealloc(a);
|
||||
return status;
|
||||
}
|
||||
|
||||
/* zeroize tag then compute */
|
||||
octet_string_set_to_zero(tag, test_case->tag_length_octets);
|
||||
status = auth_compute(a, test_case->data,
|
||||
test_case->data_length_octets, tag);
|
||||
if (status) {
|
||||
auth_dealloc(a);
|
||||
return status;
|
||||
}
|
||||
|
||||
debug_print(mod_auth, "key: %s",
|
||||
octet_string_hex_string(test_case->key,
|
||||
test_case->key_length_octets));
|
||||
debug_print(mod_auth, "data: %s",
|
||||
octet_string_hex_string(test_case->data,
|
||||
test_case->data_length_octets));
|
||||
debug_print(mod_auth, "tag computed: %s",
|
||||
octet_string_hex_string(tag, test_case->tag_length_octets));
|
||||
debug_print(mod_auth, "tag expected: %s",
|
||||
octet_string_hex_string(test_case->tag,
|
||||
test_case->tag_length_octets));
|
||||
|
||||
/* check the result */
|
||||
status = err_status_ok;
|
||||
for (i=0; i < test_case->tag_length_octets; i++)
|
||||
if (tag[i] != test_case->tag[i]) {
|
||||
status = err_status_algo_fail;
|
||||
debug_print(mod_auth, "test case %d failed", case_num);
|
||||
debug_print(mod_auth, " (mismatch at octet %d)", i);
|
||||
}
|
||||
if (status) {
|
||||
auth_dealloc(a);
|
||||
return err_status_algo_fail;
|
||||
}
|
||||
|
||||
/* deallocate the auth function */
|
||||
status = auth_dealloc(a);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
/*
|
||||
* the auth function passed the test case, so move on to the next test
|
||||
* case in the list; if NULL, we'll quit and return an OK
|
||||
*/
|
||||
test_case = test_case->next_test_case;
|
||||
++case_num;
|
||||
}
|
||||
|
||||
return err_status_ok;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* 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);
|
||||
}
|
||||
|
||||
|
|
@ -1,90 +0,0 @@
|
|||
/*
|
||||
* aes.h
|
||||
*
|
||||
* header file for the AES block cipher
|
||||
*
|
||||
* 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 _AES_H
|
||||
#define _AES_H
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "datatypes.h"
|
||||
#include "gf2_8.h"
|
||||
#include "err.h"
|
||||
|
||||
/* aes internals */
|
||||
|
||||
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_encrypt(v128_t *plaintext, const aes_expanded_key_t *exp_key);
|
||||
|
||||
void
|
||||
aes_decrypt(v128_t *plaintext, const aes_expanded_key_t *exp_key);
|
||||
|
||||
#if 0
|
||||
/*
|
||||
* internal functions
|
||||
*/
|
||||
|
||||
void
|
||||
aes_init_sbox(void);
|
||||
|
||||
void
|
||||
aes_compute_tables(void);
|
||||
#endif
|
||||
|
||||
#endif /* _AES_H */
|
||||
|
|
@ -1,50 +0,0 @@
|
|||
/*
|
||||
* aes_cbc.h
|
||||
*
|
||||
* Header for AES Cipher Blobk Chaining Mode.
|
||||
*
|
||||
* David A. McGrew
|
||||
* Cisco Systems, Inc.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef AES_CBC_H
|
||||
#define AES_CBC_H
|
||||
|
||||
#include "aes.h"
|
||||
#include "cipher.h"
|
||||
|
||||
typedef struct {
|
||||
v128_t state; /* cipher chaining state */
|
||||
v128_t previous; /* previous ciphertext block */
|
||||
aes_expanded_key_t expanded_key; /* the cipher key */
|
||||
} aes_cbc_ctx_t;
|
||||
|
||||
err_status_t
|
||||
aes_cbc_set_key(aes_cbc_ctx_t *c,
|
||||
const unsigned char *key);
|
||||
|
||||
err_status_t
|
||||
aes_cbc_encrypt(aes_cbc_ctx_t *c,
|
||||
unsigned char *buf,
|
||||
unsigned int *bytes_in_data);
|
||||
|
||||
err_status_t
|
||||
aes_cbc_context_init(aes_cbc_ctx_t *c, const uint8_t *key,
|
||||
int key_len, cipher_direction_t dir);
|
||||
|
||||
err_status_t
|
||||
aes_cbc_set_iv(aes_cbc_ctx_t *c, void *iv);
|
||||
|
||||
err_status_t
|
||||
aes_cbc_nist_encrypt(aes_cbc_ctx_t *c,
|
||||
unsigned char *data,
|
||||
unsigned int *bytes_in_data);
|
||||
|
||||
err_status_t
|
||||
aes_cbc_nist_decrypt(aes_cbc_ctx_t *c,
|
||||
unsigned char *data,
|
||||
unsigned int *bytes_in_data);
|
||||
|
||||
#endif /* AES_CBC_H */
|
||||
|
||||
|
|
@ -1,57 +0,0 @@
|
|||
/*
|
||||
* aes_icm.h
|
||||
*
|
||||
* Header for AES Integer Counter Mode.
|
||||
*
|
||||
* David A. McGrew
|
||||
* Cisco Systems, Inc.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef AES_ICM_H
|
||||
#define AES_ICM_H
|
||||
|
||||
#include "aes.h"
|
||||
#include "cipher.h"
|
||||
|
||||
typedef struct {
|
||||
v128_t counter; /* holds the counter value */
|
||||
v128_t offset; /* initial offset value */
|
||||
v128_t keystream_buffer; /* buffers bytes of keystream */
|
||||
aes_expanded_key_t expanded_key; /* the cipher key */
|
||||
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,
|
||||
int key_len);
|
||||
|
||||
err_status_t
|
||||
aes_icm_set_iv(aes_icm_ctx_t *c, void *iv);
|
||||
|
||||
err_status_t
|
||||
aes_icm_encrypt(aes_icm_ctx_t *c,
|
||||
unsigned char *buf, unsigned int *bytes_to_encr);
|
||||
|
||||
err_status_t
|
||||
aes_icm_output(aes_icm_ctx_t *c,
|
||||
unsigned char *buf, int bytes_to_output);
|
||||
|
||||
err_status_t
|
||||
aes_icm_dealloc(cipher_t *c);
|
||||
|
||||
err_status_t
|
||||
aes_icm_encrypt_ismacryp(aes_icm_ctx_t *c,
|
||||
unsigned char *buf,
|
||||
unsigned int *enc_len,
|
||||
int forIsmacryp);
|
||||
|
||||
err_status_t
|
||||
aes_icm_alloc_ismacryp(cipher_t **c,
|
||||
int key_len,
|
||||
int forIsmacryp);
|
||||
|
||||
#endif /* AES_ICM_H */
|
||||
|
||||
|
|
@ -1,57 +0,0 @@
|
|||
/*
|
||||
* alloc.h
|
||||
*
|
||||
* interface to memory allocation and deallocation, with optional debugging
|
||||
*
|
||||
* 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 CRYPTO_ALLOC_H
|
||||
#define CRYPTO_ALLOC_H
|
||||
|
||||
#include "datatypes.h"
|
||||
|
||||
void *
|
||||
crypto_alloc(size_t size);
|
||||
|
||||
void
|
||||
crypto_free(void *ptr);
|
||||
|
||||
#endif /* CRYPTO_ALLOC_H */
|
||||
|
|
@ -1,171 +0,0 @@
|
|||
/*
|
||||
* auth.h
|
||||
*
|
||||
* common interface to authentication functions
|
||||
*
|
||||
* 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 AUTH_H
|
||||
#define AUTH_H
|
||||
|
||||
#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;
|
||||
|
||||
typedef err_status_t (*auth_alloc_func)
|
||||
(auth_pointer_t *ap, int key_len, int out_len);
|
||||
|
||||
typedef err_status_t (*auth_init_func)
|
||||
(void *state, const uint8_t *key, int key_len);
|
||||
|
||||
typedef err_status_t (*auth_dealloc_func)(auth_pointer_t ap);
|
||||
|
||||
typedef err_status_t (*auth_compute_func)
|
||||
(void *state, uint8_t *buffer, int octets_to_auth,
|
||||
int tag_len, uint8_t *tag);
|
||||
|
||||
typedef err_status_t (*auth_update_func)
|
||||
(void *state, uint8_t *buffer, int octets_to_auth);
|
||||
|
||||
typedef err_status_t (*auth_start_func)(void *state);
|
||||
|
||||
/* some syntactic sugar on these function types */
|
||||
|
||||
#define auth_type_alloc(at, a, klen, outlen) \
|
||||
((at)->alloc((a), (klen), (outlen)))
|
||||
|
||||
#define auth_init(a, key) \
|
||||
(((a)->type)->init((a)->state, (key), ((a)->key_len)))
|
||||
|
||||
#define auth_compute(a, buf, len, res) \
|
||||
(((a)->type)->compute((a)->state, (buf), (len), (a)->out_len, (res)))
|
||||
|
||||
#define auth_update(a, buf, len) \
|
||||
(((a)->type)->update((a)->state, (buf), (len)))
|
||||
|
||||
#define auth_start(a)(((a)->type)->start((a)->state))
|
||||
|
||||
#define auth_dealloc(c) (((c)->type)->dealloc(c))
|
||||
|
||||
/* functions to get information about a particular auth_t */
|
||||
|
||||
int
|
||||
auth_get_key_length(const struct auth_t *a);
|
||||
|
||||
int
|
||||
auth_get_tag_length(const struct auth_t *a);
|
||||
|
||||
int
|
||||
auth_get_prefix_length(const struct auth_t *a);
|
||||
|
||||
/*
|
||||
* auth_test_case_t is a (list of) key/message/tag values that are
|
||||
* known to be correct for a particular cipher. this data can be used
|
||||
* to test an implementation in an on-the-fly self test of the
|
||||
* correcness of the implementation. (see the auth_type_self_test()
|
||||
* function below)
|
||||
*/
|
||||
|
||||
typedef struct auth_test_case_t {
|
||||
int key_length_octets; /* octets in key */
|
||||
uint8_t *key; /* key */
|
||||
int data_length_octets; /* octets in data */
|
||||
uint8_t *data; /* data */
|
||||
int tag_length_octets; /* octets in tag */
|
||||
uint8_t *tag; /* tag */
|
||||
struct auth_test_case_t *next_test_case; /* pointer to next testcase */
|
||||
} auth_test_case_t;
|
||||
|
||||
/* auth_type_t */
|
||||
|
||||
typedef struct auth_type_t {
|
||||
auth_alloc_func alloc;
|
||||
auth_dealloc_func dealloc;
|
||||
auth_init_func init;
|
||||
auth_compute_func compute;
|
||||
auth_update_func update;
|
||||
auth_start_func start;
|
||||
char *description;
|
||||
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 {
|
||||
auth_type_t *type;
|
||||
void *state;
|
||||
int out_len; /* length of output tag in octets */
|
||||
int key_len; /* length of key in octets */
|
||||
int prefix_len; /* length of keystream prefix */
|
||||
} auth_t;
|
||||
|
||||
/*
|
||||
* auth_type_self_test() tests an auth_type against test cases
|
||||
* provided in an array of values of key/message/tag that is known to
|
||||
* be good
|
||||
*/
|
||||
|
||||
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
|
||||
*/
|
||||
|
||||
int
|
||||
auth_type_get_ref_count(const auth_type_t *at);
|
||||
|
||||
#endif /* AUTH_H */
|
||||
|
|
@ -1,230 +0,0 @@
|
|||
/*
|
||||
* cipher.h
|
||||
*
|
||||
* common interface to ciphers
|
||||
*
|
||||
* 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 CIPHER_H
|
||||
#define CIPHER_H
|
||||
|
||||
#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 */
|
||||
|
||||
|
||||
/**
|
||||
* @brief cipher_direction_t defines a particular cipher operation.
|
||||
*
|
||||
* A cipher_direction_t is an enum that describes a particular cipher
|
||||
* operation, i.e. encryption or decryption. For some ciphers, this
|
||||
* distinction does not matter, but for others, it is essential.
|
||||
*/
|
||||
|
||||
typedef enum {
|
||||
direction_encrypt, /**< encryption (convert plaintext to ciphertext) */
|
||||
direction_decrypt, /**< decryption (convert ciphertext to plaintext) */
|
||||
direction_any /**< encryption or decryption */
|
||||
} cipher_direction_t;
|
||||
|
||||
/*
|
||||
* the cipher_pointer and cipher_type_pointer definitions are needed
|
||||
* as cipher_t and cipher_type_t are not yet defined
|
||||
*/
|
||||
|
||||
typedef struct cipher_type_t *cipher_type_pointer_t;
|
||||
typedef struct cipher_t *cipher_pointer_t;
|
||||
|
||||
/*
|
||||
* a cipher_alloc_func_t allocates (but does not initialize) a cipher_t
|
||||
*/
|
||||
|
||||
typedef err_status_t (*cipher_alloc_func_t)
|
||||
(cipher_pointer_t *cp, int key_len);
|
||||
|
||||
/*
|
||||
* a cipher_init_func_t [re-]initializes a cipher_t with a given key
|
||||
* and direction (i.e., encrypt or decrypt)
|
||||
*/
|
||||
|
||||
typedef err_status_t (*cipher_init_func_t)
|
||||
(void *state, const uint8_t *key, int key_len, cipher_direction_t dir);
|
||||
|
||||
/* a cipher_dealloc_func_t de-allocates a cipher_t */
|
||||
|
||||
typedef err_status_t (*cipher_dealloc_func_t)(cipher_pointer_t cp);
|
||||
|
||||
/* a cipher_set_segment_func_t sets the segment index of a cipher_t */
|
||||
|
||||
typedef err_status_t (*cipher_set_segment_func_t)
|
||||
(void *state, xtd_seq_num_t idx);
|
||||
|
||||
/* a cipher_encrypt_func_t encrypts data in-place */
|
||||
|
||||
typedef err_status_t (*cipher_encrypt_func_t)
|
||||
(void *state, uint8_t *buffer, unsigned int *octets_to_encrypt);
|
||||
|
||||
/* a cipher_decrypt_func_t decrypts data in-place */
|
||||
|
||||
typedef err_status_t (*cipher_decrypt_func_t)
|
||||
(void *state, uint8_t *buffer, unsigned int *octets_to_decrypt);
|
||||
|
||||
/*
|
||||
* a cipher_set_iv_func_t function sets the current initialization vector
|
||||
*/
|
||||
|
||||
typedef err_status_t (*cipher_set_iv_func_t)
|
||||
(cipher_pointer_t cp, void *iv);
|
||||
|
||||
/*
|
||||
* cipher_test_case_t is a (list of) key, salt, xtd_seq_num_t,
|
||||
* plaintext, and ciphertext values that are known to be correct for a
|
||||
* particular cipher. this data can be used to test an implementation
|
||||
* in an on-the-fly self test of the correcness of the implementation.
|
||||
* (see the cipher_type_self_test() function below)
|
||||
*/
|
||||
|
||||
typedef struct cipher_test_case_t {
|
||||
int key_length_octets; /* octets in key */
|
||||
uint8_t *key; /* key */
|
||||
uint8_t *idx; /* packet index */
|
||||
int plaintext_length_octets; /* octets in plaintext */
|
||||
uint8_t *plaintext; /* plaintext */
|
||||
int ciphertext_length_octets; /* octets in plaintext */
|
||||
uint8_t *ciphertext; /* ciphertext */
|
||||
struct cipher_test_case_t *next_test_case; /* pointer to next testcase */
|
||||
} cipher_test_case_t;
|
||||
|
||||
/* cipher_type_t defines the 'metadata' for a particular cipher type */
|
||||
|
||||
typedef struct cipher_type_t {
|
||||
cipher_alloc_func_t alloc;
|
||||
cipher_dealloc_func_t dealloc;
|
||||
cipher_init_func_t init;
|
||||
cipher_encrypt_func_t encrypt;
|
||||
cipher_encrypt_func_t decrypt;
|
||||
cipher_set_iv_func_t set_iv;
|
||||
char *description;
|
||||
int ref_count;
|
||||
cipher_test_case_t *test_data;
|
||||
debug_module_t *debug;
|
||||
cipher_type_id_t id;
|
||||
} cipher_type_t;
|
||||
|
||||
/*
|
||||
* cipher_t defines an instantiation of a particular cipher, with fixed
|
||||
* key length, key and salt values
|
||||
*/
|
||||
|
||||
typedef struct cipher_t {
|
||||
cipher_type_t *type;
|
||||
void *state;
|
||||
int key_len;
|
||||
#ifdef FORCE_64BIT_ALIGN
|
||||
int pad;
|
||||
#endif
|
||||
} cipher_t;
|
||||
|
||||
/* some syntactic sugar on these function types */
|
||||
|
||||
#define cipher_type_alloc(ct, c, klen) ((ct)->alloc((c), (klen)))
|
||||
|
||||
#define cipher_dealloc(c) (((c)->type)->dealloc(c))
|
||||
|
||||
#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)))
|
||||
|
||||
#define cipher_decrypt(c, buf, len) \
|
||||
(((c)->type)->decrypt(((c)->state), (buf), (len)))
|
||||
|
||||
#define cipher_set_iv(c, n) \
|
||||
((c) ? (((c)->type)->set_iv(((cipher_pointer_t)(c)->state), (n))) : \
|
||||
err_status_no_such_op)
|
||||
|
||||
err_status_t
|
||||
cipher_output(cipher_t *c, uint8_t *buffer, int num_octets_to_output);
|
||||
|
||||
|
||||
/* some bookkeeping functions */
|
||||
|
||||
int
|
||||
cipher_get_key_length(const cipher_t *c);
|
||||
|
||||
|
||||
/*
|
||||
* cipher_type_self_test() tests a cipher against 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_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
|
||||
*
|
||||
* c is a cipher (which MUST be allocated and initialized already), l
|
||||
* is the length in octets of the test data to be encrypted, and t is
|
||||
* the number of trials
|
||||
*
|
||||
* if an error is encountered, then the value 0 is returned
|
||||
*/
|
||||
|
||||
uint64_t
|
||||
cipher_bits_per_second(cipher_t *c, int octets_in_buffer, int num_trials);
|
||||
|
||||
#endif /* CIPHER_H */
|
||||
|
|
@ -1,12 +0,0 @@
|
|||
#ifndef SRTP_CONFIG_H
|
||||
#define SRTP_CONFIG_H
|
||||
|
||||
#define HAVE_STDLIB_H
|
||||
|
||||
#ifdef WIN32
|
||||
#define HAVE_WINSOCK2_H 1
|
||||
#define CPU_CISC 1
|
||||
#else
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
@ -1,43 +0,0 @@
|
|||
/*
|
||||
* crypto.h
|
||||
*
|
||||
* API for libcrypto
|
||||
*
|
||||
* David A. McGrew
|
||||
* Cisco Systems, Inc.
|
||||
*/
|
||||
|
||||
#ifndef CRYPTO_H
|
||||
#define CRYPTO_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 */
|
||||
|
||||
|
||||
|
|
@ -1,280 +0,0 @@
|
|||
/*
|
||||
* crypto_kernel.h
|
||||
*
|
||||
* header for the cryptographic kernel
|
||||
*
|
||||
* 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 CRYPTO_KERNEL
|
||||
#define CRYPTO_KERNEL
|
||||
|
||||
#include "rand_source.h"
|
||||
#include "prng.h"
|
||||
#include "cipher.h"
|
||||
#include "auth.h"
|
||||
#include "cryptoalg.h"
|
||||
#include "stat.h"
|
||||
#include "err.h"
|
||||
#include "crypto_types.h"
|
||||
#include "key.h"
|
||||
#include "crypto.h"
|
||||
|
||||
/*
|
||||
* crypto_kernel_state_t defines the possible states:
|
||||
*
|
||||
* insecure - not yet initialized
|
||||
* secure - initialized and passed self-tests
|
||||
*/
|
||||
|
||||
typedef enum {
|
||||
crypto_kernel_state_insecure,
|
||||
crypto_kernel_state_secure
|
||||
} crypto_kernel_state_t;
|
||||
|
||||
/*
|
||||
* linked list of cipher types
|
||||
*/
|
||||
|
||||
typedef struct kernel_cipher_type {
|
||||
cipher_type_id_t id;
|
||||
cipher_type_t *cipher_type;
|
||||
struct kernel_cipher_type *next;
|
||||
} kernel_cipher_type_t;
|
||||
|
||||
/*
|
||||
* linked list of auth types
|
||||
*/
|
||||
|
||||
typedef struct kernel_auth_type {
|
||||
auth_type_id_t id;
|
||||
auth_type_t *auth_type;
|
||||
struct kernel_auth_type *next;
|
||||
} kernel_auth_type_t;
|
||||
|
||||
/*
|
||||
* linked list of debug modules
|
||||
*/
|
||||
|
||||
typedef struct kernel_debug_module {
|
||||
debug_module_t *mod;
|
||||
struct kernel_debug_module *next;
|
||||
} kernel_debug_module_t;
|
||||
|
||||
|
||||
/*
|
||||
* crypto_kernel_t is the data structure for the crypto kernel
|
||||
*
|
||||
* note that there is *exactly one* instance of this data type,
|
||||
* a global variable defined in crypto_kernel.c
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
crypto_kernel_state_t state; /* current state of kernel */
|
||||
kernel_cipher_type_t *cipher_type_list; /* list of all cipher types */
|
||||
kernel_auth_type_t *auth_type_list; /* list of all auth func types */
|
||||
kernel_debug_module_t *debug_module_list; /* list of all debug modules */
|
||||
} crypto_kernel_t;
|
||||
|
||||
|
||||
/*
|
||||
* crypto_kernel_t external api
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* The function crypto_kernel_init() initialized the crypto kernel and
|
||||
* runs the self-test operations on the random number generators and
|
||||
* crypto algorithms. Possible return values are:
|
||||
*
|
||||
* err_status_ok initialization successful
|
||||
* <other> init failure
|
||||
*
|
||||
* If any value other than err_status_ok is returned, the
|
||||
* crypto_kernel MUST NOT be used.
|
||||
*/
|
||||
|
||||
err_status_t
|
||||
crypto_kernel_init(void);
|
||||
|
||||
|
||||
/*
|
||||
* The function crypto_kernel_shutdown() de-initializes the
|
||||
* crypto_kernel, zeroizes keys and other cryptographic material, and
|
||||
* deallocates any dynamically allocated memory. Possible return
|
||||
* values are:
|
||||
*
|
||||
* err_status_ok shutdown successful
|
||||
* <other> shutdown failure
|
||||
*
|
||||
*/
|
||||
|
||||
err_status_t
|
||||
crypto_kernel_shutdown(void);
|
||||
|
||||
/*
|
||||
* The function crypto_kernel_stats() checks the the crypto_kernel,
|
||||
* running tests on the ciphers, auth funcs, and rng, and prints out a
|
||||
* status report. Possible return values are:
|
||||
*
|
||||
* err_status_ok all tests were passed
|
||||
* <other> a test failed
|
||||
*
|
||||
*/
|
||||
|
||||
err_status_t
|
||||
crypto_kernel_status(void);
|
||||
|
||||
|
||||
/*
|
||||
* crypto_kernel_list_debug_modules() outputs a list of debugging modules
|
||||
*
|
||||
*/
|
||||
|
||||
err_status_t
|
||||
crypto_kernel_list_debug_modules(void);
|
||||
|
||||
/*
|
||||
* crypto_kernel_load_cipher_type()
|
||||
*
|
||||
*/
|
||||
|
||||
err_status_t
|
||||
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);
|
||||
|
||||
/*
|
||||
* crypto_kernel_alloc_cipher(id, cp, key_len);
|
||||
*
|
||||
* allocates a cipher of type id at location *cp, with key length
|
||||
* key_len octets. Return values are:
|
||||
*
|
||||
* err_status_ok no problems
|
||||
* err_status_alloc_fail an allocation failure occured
|
||||
* err_status_fail couldn't find cipher with identifier 'id'
|
||||
*/
|
||||
|
||||
err_status_t
|
||||
crypto_kernel_alloc_cipher(cipher_type_id_t id,
|
||||
cipher_pointer_t *cp,
|
||||
int key_len);
|
||||
|
||||
/*
|
||||
* crypto_kernel_alloc_auth(id, ap, key_len, tag_len);
|
||||
*
|
||||
* allocates an auth function of type id at location *ap, with key
|
||||
* length key_len octets and output tag length of tag_len. Return
|
||||
* values are:
|
||||
*
|
||||
* err_status_ok no problems
|
||||
* err_status_alloc_fail an allocation failure occured
|
||||
* err_status_fail couldn't find auth with identifier 'id'
|
||||
*/
|
||||
|
||||
err_status_t
|
||||
crypto_kernel_alloc_auth(auth_type_id_t id,
|
||||
auth_pointer_t *ap,
|
||||
int key_len,
|
||||
int tag_len);
|
||||
|
||||
|
||||
/*
|
||||
* crypto_kernel_set_debug_module(mod_name, v)
|
||||
*
|
||||
* sets dynamic debugging to the value v (0 for off, 1 for on) for the
|
||||
* debug module with the name mod_name
|
||||
*
|
||||
* returns err_status_ok on success, err_status_fail otherwise
|
||||
*/
|
||||
|
||||
err_status_t
|
||||
crypto_kernel_set_debug_module(char *mod_name, int v);
|
||||
|
||||
/**
|
||||
* @brief writes a random octet string.
|
||||
*
|
||||
* The function call crypto_get_random(dest, len) writes len octets of
|
||||
* random data to the location to which dest points, and returns an
|
||||
* error code. This error code @b must be checked, and if a failure is
|
||||
* reported, the data in the buffer @b must @b not be used.
|
||||
*
|
||||
* @warning If the return code is not checked, then non-random
|
||||
* data may be in the buffer. This function will fail
|
||||
* unless it is called after crypto_kernel_init().
|
||||
*
|
||||
* @return
|
||||
* - err_status_ok if no problems occured.
|
||||
* - [other] a problem occured, and no assumptions should
|
||||
* be made about the contents of the destination
|
||||
* buffer.
|
||||
*
|
||||
* @ingroup SRTP
|
||||
*/
|
||||
err_status_t
|
||||
crypto_get_random(unsigned char *buffer, unsigned int length);
|
||||
|
||||
#endif /* CRYPTO_KERNEL */
|
||||
|
|
@ -1,239 +0,0 @@
|
|||
/*
|
||||
* math.h
|
||||
*
|
||||
* crypto math operations and data types
|
||||
*
|
||||
* 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 MATH_H
|
||||
#define MATH_H
|
||||
|
||||
#include "datatypes.h"
|
||||
|
||||
unsigned char
|
||||
v32_weight(v32_t a);
|
||||
|
||||
unsigned char
|
||||
v32_distance(v32_t x, v32_t y);
|
||||
|
||||
unsigned int
|
||||
v32_dot_product(v32_t a, v32_t b);
|
||||
|
||||
char *
|
||||
v16_bit_string(v16_t x);
|
||||
|
||||
char *
|
||||
v32_bit_string(v32_t x);
|
||||
|
||||
char *
|
||||
v64_bit_string(const v64_t *x);
|
||||
|
||||
char *
|
||||
octet_hex_string(uint8_t x);
|
||||
|
||||
char *
|
||||
v16_hex_string(v16_t x);
|
||||
|
||||
char *
|
||||
v32_hex_string(v32_t x);
|
||||
|
||||
char *
|
||||
v64_hex_string(const v64_t *x);
|
||||
|
||||
int
|
||||
hex_char_to_nibble(uint8_t c);
|
||||
|
||||
int
|
||||
is_hex_string(char *s);
|
||||
|
||||
v16_t
|
||||
hex_string_to_v16(char *s);
|
||||
|
||||
v32_t
|
||||
hex_string_to_v32(char *s);
|
||||
|
||||
v64_t
|
||||
hex_string_to_v64(char *s);
|
||||
|
||||
/* the matrix A[] is stored in column format, i.e., A[i] is
|
||||
the ith column of the matrix */
|
||||
|
||||
uint8_t
|
||||
A_times_x_plus_b(uint8_t A[8], uint8_t x, uint8_t b);
|
||||
|
||||
void
|
||||
v16_copy_octet_string(v16_t *x, const uint8_t s[2]);
|
||||
|
||||
void
|
||||
v32_copy_octet_string(v32_t *x, const uint8_t s[4]);
|
||||
|
||||
void
|
||||
v64_copy_octet_string(v64_t *x, const uint8_t s[8]);
|
||||
|
||||
void
|
||||
v128_add(v128_t *z, v128_t *x, v128_t *y);
|
||||
|
||||
int
|
||||
octet_string_is_eq(uint8_t *a, uint8_t *b, int len);
|
||||
|
||||
void
|
||||
octet_string_set_to_zero(uint8_t *s, int len);
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* the matrix A[] is stored in column format, i.e., A[i] is the ith
|
||||
* column of the matrix
|
||||
*/
|
||||
uint8_t
|
||||
A_times_x_plus_b(uint8_t A[8], uint8_t x, uint8_t b);
|
||||
|
||||
|
||||
#if 0
|
||||
#if WORDS_BIGENDIAN
|
||||
|
||||
#define _v128_add(z, x, y) { \
|
||||
uint64_t tmp; \
|
||||
\
|
||||
tmp = x->v32[3] + y->v32[3]; \
|
||||
z->v32[3] = (uint32_t) tmp; \
|
||||
\
|
||||
tmp = x->v32[2] + y->v32[2] + (tmp >> 32); \
|
||||
z->v32[2] = (uint32_t) tmp; \
|
||||
\
|
||||
tmp = x->v32[1] + y->v32[1] + (tmp >> 32); \
|
||||
z->v32[1] = (uint32_t) tmp; \
|
||||
\
|
||||
tmp = x->v32[0] + y->v32[0] + (tmp >> 32); \
|
||||
z->v32[0] = (uint32_t) tmp; \
|
||||
}
|
||||
|
||||
#else /* assume little endian architecture */
|
||||
|
||||
#define _v128_add(z, x, y) { \
|
||||
uint64_t tmp; \
|
||||
\
|
||||
tmp = htonl(x->v32[3]) + htonl(y->v32[3]); \
|
||||
z->v32[3] = ntohl((uint32_t) tmp); \
|
||||
\
|
||||
tmp = htonl(x->v32[2]) + htonl(y->v32[2]) \
|
||||
+ htonl(tmp >> 32); \
|
||||
z->v32[2] = ntohl((uint32_t) tmp); \
|
||||
\
|
||||
tmp = htonl(x->v32[1]) + htonl(y->v32[1]) \
|
||||
+ htonl(tmp >> 32); \
|
||||
z->v32[1] = ntohl((uint32_t) tmp); \
|
||||
\
|
||||
tmp = htonl(x->v32[0]) + htonl(y->v32[0]) \
|
||||
+ htonl(tmp >> 32); \
|
||||
z->v32[0] = ntohl((uint32_t) tmp); \
|
||||
}
|
||||
|
||||
#endif /* WORDS_BIGENDIAN */
|
||||
#endif
|
||||
|
||||
#ifdef DATATYPES_USE_MACROS /* little functions are really macros */
|
||||
|
||||
#define v128_set_to_zero(z) _v128_set_to_zero(z)
|
||||
#define v128_copy(z, x) _v128_copy(z, x)
|
||||
#define v128_xor(z, x, y) _v128_xor(z, x, y)
|
||||
#define v128_and(z, x, y) _v128_and(z, x, y)
|
||||
#define v128_or(z, x, y) _v128_or(z, x, y)
|
||||
#define v128_complement(x) _v128_complement(x)
|
||||
#define v128_is_eq(x, y) _v128_is_eq(x, y)
|
||||
#define v128_xor_eq(x, y) _v128_xor_eq(x, y)
|
||||
#define v128_get_bit(x, i) _v128_get_bit(x, i)
|
||||
#define v128_set_bit(x, i) _v128_set_bit(x, i)
|
||||
#define v128_clear_bit(x, i) _v128_clear_bit(x, i)
|
||||
#define v128_set_bit_to(x, i, y) _v128_set_bit_to(x, i, y)
|
||||
|
||||
#else
|
||||
|
||||
void
|
||||
v128_set_to_zero(v128_t *x);
|
||||
|
||||
int
|
||||
v128_is_eq(const v128_t *x, const v128_t *y);
|
||||
|
||||
void
|
||||
v128_copy(v128_t *x, const v128_t *y);
|
||||
|
||||
void
|
||||
v128_xor(v128_t *z, v128_t *x, v128_t *y);
|
||||
|
||||
void
|
||||
v128_and(v128_t *z, v128_t *x, v128_t *y);
|
||||
|
||||
void
|
||||
v128_or(v128_t *z, v128_t *x, v128_t *y);
|
||||
|
||||
void
|
||||
v128_complement(v128_t *x);
|
||||
|
||||
int
|
||||
v128_get_bit(const v128_t *x, int i);
|
||||
|
||||
void
|
||||
v128_set_bit(v128_t *x, int i) ;
|
||||
|
||||
void
|
||||
v128_clear_bit(v128_t *x, int i);
|
||||
|
||||
void
|
||||
v128_set_bit_to(v128_t *x, int i, int y);
|
||||
|
||||
#endif /* DATATYPES_USE_MACROS */
|
||||
|
||||
/*
|
||||
* octet_string_is_eq(a,b, len) returns 1 if the length len strings a
|
||||
* and b are not equal, returns 0 otherwise
|
||||
*/
|
||||
|
||||
int
|
||||
octet_string_is_eq(uint8_t *a, uint8_t *b, int len);
|
||||
|
||||
void
|
||||
octet_string_set_to_zero(uint8_t *s, int len);
|
||||
|
||||
|
||||
#endif /* MATH_H */
|
||||
|
||||
|
||||
|
||||
|
|
@ -1,220 +0,0 @@
|
|||
/*
|
||||
* crypto_types.h
|
||||
*
|
||||
* constants for cipher types and auth func types
|
||||
*
|
||||
* 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 CRYPTO_TYPES_H
|
||||
#define CRYPTO_TYPES_H
|
||||
|
||||
/**
|
||||
* @defgroup Algos Cryptographic Algorithms
|
||||
*
|
||||
*
|
||||
* This library provides several different cryptographic algorithms,
|
||||
* each of which can be selected by using the cipher_type_id_t and
|
||||
* auth_type_id_t. These algorithms are documented below.
|
||||
*
|
||||
* Authentication functions that use the Universal Security Transform
|
||||
* (UST) must be used in conjunction with a cipher other than the null
|
||||
* cipher. These functions require a per-message pseudorandom input
|
||||
* that is generated by the cipher.
|
||||
*
|
||||
* The identifiers STRONGHOLD_AUTH and STRONGHOLD_CIPHER identify the
|
||||
* strongest available authentication function and cipher,
|
||||
* respectively. They are resolved at compile time to the strongest
|
||||
* available algorithm. The stronghold algorithms can serve as did
|
||||
* the keep of a medieval fortification; they provide the strongest
|
||||
* defense (or the last refuge).
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup Ciphers Cipher Types
|
||||
*
|
||||
* @brief Each cipher type is identified by an unsigned integer. The
|
||||
* cipher types available in this edition of libSRTP are given
|
||||
* by the #defines below.
|
||||
*
|
||||
* A cipher_type_id_t is an identifier for a cipher_type; only values
|
||||
* given by the #defines above (or those present in the file
|
||||
* crypto_types.h) should be used.
|
||||
*
|
||||
* The identifier STRONGHOLD_CIPHER indicates the strongest available
|
||||
* cipher, allowing an application to choose the strongest available
|
||||
* algorithm without any advance knowledge about the avaliable
|
||||
* algorithms.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief The null cipher performs no encryption.
|
||||
*
|
||||
* The NULL_CIPHER leaves its inputs unaltered, during both the
|
||||
* encryption and decryption operations. This cipher can be chosen
|
||||
* to indicate that no encryption is to be performed.
|
||||
*/
|
||||
#define NULL_CIPHER 0
|
||||
|
||||
/**
|
||||
* @brief AES Integer Counter Mode (AES ICM)
|
||||
*
|
||||
* 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_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
|
||||
*
|
||||
* SEAL is the Software-Optimized Encryption Algorithm of Coppersmith
|
||||
* and Rogaway. Nota bene: this cipher is IBM proprietary.
|
||||
*/
|
||||
#define SEAL 2
|
||||
|
||||
/**
|
||||
* @brief AES Cipher Block Chaining mode (AES CBC)
|
||||
*
|
||||
* AES CBC is the AES Cipher Block Chaining mode.
|
||||
* This cipher uses a 16-, 24-, or 32-octet key.
|
||||
*/
|
||||
#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_ICM
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @defgroup Authentication Authentication Function Types
|
||||
*
|
||||
* @brief Each authentication function type is identified by an
|
||||
* unsigned integer. The authentication function types available in
|
||||
* this edition of libSRTP are given by the #defines below.
|
||||
*
|
||||
* An auth_type_id_t is an identifier for an authentication function type;
|
||||
* only values given by the #defines above (or those present in the
|
||||
* file crypto_types.h) should be used.
|
||||
*
|
||||
* The identifier STRONGHOLD_AUTH indicates the strongest available
|
||||
* authentication function, allowing an application to choose the
|
||||
* strongest available algorithm without any advance knowledge about
|
||||
* the avaliable algorithms. The stronghold algorithms can serve as
|
||||
* did the keep of a medieval fortification; they provide the
|
||||
* strongest defense (or the last refuge).
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief The null authentication function performs no authentication.
|
||||
*
|
||||
* The NULL_AUTH function does nothing, and can be selected to indicate
|
||||
* that authentication should not be performed.
|
||||
*/
|
||||
#define NULL_AUTH 0
|
||||
|
||||
/**
|
||||
* @brief UST with TMMH Version 2
|
||||
*
|
||||
* UST_TMMHv2 implements the Truncated Multi-Modular Hash using
|
||||
* UST. This function must be used in conjunction with a cipher other
|
||||
* than the null cipher.
|
||||
* with a cipher.
|
||||
*/
|
||||
#define UST_TMMHv2 1
|
||||
|
||||
/**
|
||||
* @brief (UST) AES-128 XORMAC
|
||||
*
|
||||
* UST_AES_128_XMAC implements AES-128 XORMAC, using UST. Nota bene:
|
||||
* the XORMAC algorithm is IBM proprietary.
|
||||
*/
|
||||
#define UST_AES_128_XMAC 2
|
||||
|
||||
/**
|
||||
* @brief HMAC-SHA1
|
||||
*
|
||||
* HMAC_SHA1 implements the Hash-based MAC using the NIST Secure
|
||||
* Hash Algorithm version 1 (SHA1).
|
||||
*/
|
||||
#define HMAC_SHA1 3
|
||||
|
||||
/**
|
||||
* @brief Strongest available authentication function.
|
||||
*
|
||||
* This identifier resolves to the strongest available authentication
|
||||
* function.
|
||||
*/
|
||||
#define STRONGHOLD_AUTH HMAC_SHA1
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* CRYPTO_TYPES_H */
|
||||
|
|
@ -1,133 +0,0 @@
|
|||
/*
|
||||
* cryptoalg.h
|
||||
*
|
||||
* API for authenticated encryption crypto algorithms
|
||||
*
|
||||
* 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 CRYPTOALG_H
|
||||
#define CRYPTOALG_H
|
||||
|
||||
#include "err.h"
|
||||
|
||||
/**
|
||||
* @defgroup Crypto Cryptography
|
||||
*
|
||||
* Zed uses a simple interface to a cryptographic transform.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief applies a crypto algorithm
|
||||
*
|
||||
* The function pointer cryptoalg_func_t points to a function that
|
||||
* implements a crypto transform, and provides a uniform API for
|
||||
* accessing crypto mechanisms.
|
||||
*
|
||||
* @param key location of secret key
|
||||
*
|
||||
* @param clear data to be authenticated but not encrypted
|
||||
*
|
||||
* @param clear_len length of data to be authenticated but not encrypted
|
||||
*
|
||||
* @param iv location to write the Initialization Vector (IV)
|
||||
*
|
||||
* @param protect location of the data to be encrypted and
|
||||
* authenticated (before the function call), and the ciphertext
|
||||
* and authentication tag (after the call)
|
||||
*
|
||||
* @param protected_len location of the length of the data to be
|
||||
* encrypted and authenticated (before the function call), and the
|
||||
* length of the ciphertext (after the call)
|
||||
*
|
||||
*/
|
||||
|
||||
typedef err_status_t (*cryptoalg_func_t)
|
||||
(void *key,
|
||||
const void *clear,
|
||||
unsigned clear_len,
|
||||
void *iv,
|
||||
void *protect,
|
||||
unsigned *protected_len);
|
||||
|
||||
typedef
|
||||
err_status_t (*cryptoalg_inv_t)
|
||||
(void *key, /* location of secret key */
|
||||
const void *clear, /* data to be authenticated only */
|
||||
unsigned clear_len, /* length of data to be authenticated only */
|
||||
void *iv, /* location of iv */
|
||||
void *opaque, /* data to be decrypted and authenticated */
|
||||
unsigned *opaque_len /* location of the length of data to be
|
||||
* decrypted and authd (before and after)
|
||||
*/
|
||||
);
|
||||
|
||||
typedef struct cryptoalg_ctx_t {
|
||||
cryptoalg_func_t enc;
|
||||
cryptoalg_inv_t dec;
|
||||
unsigned key_len;
|
||||
unsigned iv_len;
|
||||
unsigned auth_tag_len;
|
||||
unsigned max_expansion;
|
||||
} cryptoalg_ctx_t;
|
||||
|
||||
typedef cryptoalg_ctx_t *cryptoalg_t;
|
||||
|
||||
#define cryptoalg_get_key_len(cryptoalg) ((cryptoalg)->key_len)
|
||||
|
||||
#define cryptoalg_get_iv_len(cryptoalg) ((cryptoalg)->iv_len)
|
||||
|
||||
#define cryptoalg_get_auth_tag_len(cryptoalg) ((cryptoalg)->auth_tag_len)
|
||||
|
||||
int
|
||||
cryptoalg_get_id(cryptoalg_t c);
|
||||
|
||||
cryptoalg_t
|
||||
cryptoalg_find_by_id(int id);
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* CRYPTOALG_H */
|
||||
|
||||
|
||||
|
|
@ -1,510 +0,0 @@
|
|||
/*
|
||||
* datatypes.h
|
||||
*
|
||||
* data types for bit vectors and finite fields
|
||||
*
|
||||
* 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 _DATATYPES_H
|
||||
#define _DATATYPES_H
|
||||
|
||||
#include "integers.h" /* definitions of uint32_t, et cetera */
|
||||
#include "alloc.h"
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
#ifndef SRTP_KERNEL
|
||||
# include <stdio.h>
|
||||
# include <string.h>
|
||||
# include <time.h>
|
||||
# ifdef HAVE_NETINET_IN_H
|
||||
# include <netinet/in.h>
|
||||
# elif defined HAVE_WINSOCK2_H
|
||||
# include <winsock2.h>
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
||||
/* if DATATYPES_USE_MACROS is defined, then little functions are macros */
|
||||
#define DATATYPES_USE_MACROS
|
||||
|
||||
typedef union {
|
||||
uint8_t v8[2];
|
||||
uint16_t value;
|
||||
} v16_t;
|
||||
|
||||
typedef union {
|
||||
uint8_t v8[4];
|
||||
uint16_t v16[2];
|
||||
uint32_t value;
|
||||
} v32_t;
|
||||
|
||||
typedef union {
|
||||
uint8_t v8[8];
|
||||
uint16_t v16[4];
|
||||
uint32_t v32[2];
|
||||
uint64_t value;
|
||||
} v64_t;
|
||||
|
||||
typedef union {
|
||||
uint8_t v8[16];
|
||||
uint16_t v16[8];
|
||||
uint32_t v32[4];
|
||||
uint64_t v64[2];
|
||||
} v128_t;
|
||||
|
||||
|
||||
|
||||
/* some useful and simple math functions */
|
||||
|
||||
#define pow_2(X) ( (unsigned int)1 << (X) ) /* 2^X */
|
||||
|
||||
#define pow_minus_one(X) ( (X) ? -1 : 1 ) /* (-1)^X */
|
||||
|
||||
|
||||
/*
|
||||
* octet_get_weight(x) returns the hamming weight (number of bits equal to
|
||||
* one) in the octet x
|
||||
*/
|
||||
|
||||
int
|
||||
octet_get_weight(uint8_t octet);
|
||||
|
||||
char *
|
||||
octet_bit_string(uint8_t x);
|
||||
|
||||
#define MAX_PRINT_STRING_LEN 1024
|
||||
|
||||
char *
|
||||
octet_string_hex_string(const void *str, int length);
|
||||
|
||||
char *
|
||||
v128_bit_string(v128_t *x);
|
||||
|
||||
char *
|
||||
v128_hex_string(v128_t *x);
|
||||
|
||||
uint8_t
|
||||
nibble_to_hex_char(uint8_t nibble);
|
||||
|
||||
char *
|
||||
char_to_hex_string(char *x, int num_char);
|
||||
|
||||
uint8_t
|
||||
hex_string_to_octet(char *s);
|
||||
|
||||
/*
|
||||
* hex_string_to_octet_string(raw, hex, len) converts the hexadecimal
|
||||
* string at *hex (of length len octets) to the equivalent raw data
|
||||
* and writes it to *raw.
|
||||
*
|
||||
* if a character in the hex string that is not a hexadeciaml digit
|
||||
* (0123456789abcdefABCDEF) is encountered, the function stops writing
|
||||
* data to *raw
|
||||
*
|
||||
* the number of hex digits copied (which is two times the number of
|
||||
* octets in *raw) is returned
|
||||
*/
|
||||
|
||||
int
|
||||
hex_string_to_octet_string(char *raw, char *hex, int len);
|
||||
|
||||
v128_t
|
||||
hex_string_to_v128(char *s);
|
||||
|
||||
void
|
||||
v128_copy_octet_string(v128_t *x, const uint8_t s[16]);
|
||||
|
||||
void
|
||||
v128_left_shift(v128_t *x, int shift_index);
|
||||
|
||||
void
|
||||
v128_right_shift(v128_t *x, int shift_index);
|
||||
|
||||
/*
|
||||
* the following macros define the data manipulation functions
|
||||
*
|
||||
* If DATATYPES_USE_MACROS is defined, then these macros are used
|
||||
* directly (and function call overhead is avoided). Otherwise,
|
||||
* the macros are used through the functions defined in datatypes.c
|
||||
* (and the compiler provides better warnings).
|
||||
*/
|
||||
|
||||
#define _v128_set_to_zero(x) \
|
||||
( \
|
||||
(x)->v32[0] = 0, \
|
||||
(x)->v32[1] = 0, \
|
||||
(x)->v32[2] = 0, \
|
||||
(x)->v32[3] = 0 \
|
||||
)
|
||||
|
||||
#define _v128_copy(x, y) \
|
||||
( \
|
||||
(x)->v32[0] = (y)->v32[0], \
|
||||
(x)->v32[1] = (y)->v32[1], \
|
||||
(x)->v32[2] = (y)->v32[2], \
|
||||
(x)->v32[3] = (y)->v32[3] \
|
||||
)
|
||||
|
||||
#define _v128_xor(z, x, y) \
|
||||
( \
|
||||
(z)->v32[0] = (x)->v32[0] ^ (y)->v32[0], \
|
||||
(z)->v32[1] = (x)->v32[1] ^ (y)->v32[1], \
|
||||
(z)->v32[2] = (x)->v32[2] ^ (y)->v32[2], \
|
||||
(z)->v32[3] = (x)->v32[3] ^ (y)->v32[3] \
|
||||
)
|
||||
|
||||
#define _v128_and(z, x, y) \
|
||||
( \
|
||||
(z)->v32[0] = (x)->v32[0] & (y)->v32[0], \
|
||||
(z)->v32[1] = (x)->v32[1] & (y)->v32[1], \
|
||||
(z)->v32[2] = (x)->v32[2] & (y)->v32[2], \
|
||||
(z)->v32[3] = (x)->v32[3] & (y)->v32[3] \
|
||||
)
|
||||
|
||||
#define _v128_or(z, x, y) \
|
||||
( \
|
||||
(z)->v32[0] = (x)->v32[0] | (y)->v32[0], \
|
||||
(z)->v32[1] = (x)->v32[1] | (y)->v32[1], \
|
||||
(z)->v32[2] = (x)->v32[2] | (y)->v32[2], \
|
||||
(z)->v32[3] = (x)->v32[3] | (y)->v32[3] \
|
||||
)
|
||||
|
||||
#define _v128_complement(x) \
|
||||
( \
|
||||
(x)->v32[0] = ~(x)->v32[0], \
|
||||
(x)->v32[1] = ~(x)->v32[1], \
|
||||
(x)->v32[2] = ~(x)->v32[2], \
|
||||
(x)->v32[3] = ~(x)->v32[3] \
|
||||
)
|
||||
|
||||
/* ok for NO_64BIT_MATH if it can compare uint64_t's (even as structures) */
|
||||
#define _v128_is_eq(x, y) \
|
||||
(((x)->v64[0] == (y)->v64[0]) && ((x)->v64[1] == (y)->v64[1]))
|
||||
|
||||
|
||||
#ifdef NO_64BIT_MATH
|
||||
#define _v128_xor_eq(z, x) \
|
||||
( \
|
||||
(z)->v32[0] ^= (x)->v32[0], \
|
||||
(z)->v32[1] ^= (x)->v32[1], \
|
||||
(z)->v32[2] ^= (x)->v32[2], \
|
||||
(z)->v32[3] ^= (x)->v32[3] \
|
||||
)
|
||||
#else
|
||||
#define _v128_xor_eq(z, x) \
|
||||
( \
|
||||
(z)->v64[0] ^= (x)->v64[0], \
|
||||
(z)->v64[1] ^= (x)->v64[1] \
|
||||
)
|
||||
#endif
|
||||
|
||||
/* NOTE! This assumes an odd ordering! */
|
||||
/* This will not be compatible directly with math on some processors */
|
||||
/* bit 0 is first 32-bit word, low order bit. in little-endian, that's
|
||||
the first byte of the first 32-bit word. In big-endian, that's
|
||||
the 3rd byte of the first 32-bit word */
|
||||
/* The get/set bit code is used by the replay code ONLY, and it doesn't
|
||||
really care which bit is which. AES does care which bit is which, but
|
||||
doesn't use the 128-bit get/set or 128-bit shifts */
|
||||
|
||||
#define _v128_get_bit(x, bit) \
|
||||
( \
|
||||
((((x)->v32[(bit) >> 5]) >> ((bit) & 31)) & 1) \
|
||||
)
|
||||
|
||||
#define _v128_set_bit(x, bit) \
|
||||
( \
|
||||
(((x)->v32[(bit) >> 5]) |= ((uint32_t)1 << ((bit) & 31))) \
|
||||
)
|
||||
|
||||
#define _v128_clear_bit(x, bit) \
|
||||
( \
|
||||
(((x)->v32[(bit) >> 5]) &= ~((uint32_t)1 << ((bit) & 31))) \
|
||||
)
|
||||
|
||||
#define _v128_set_bit_to(x, bit, value) \
|
||||
( \
|
||||
(value) ? _v128_set_bit(x, bit) : \
|
||||
_v128_clear_bit(x, bit) \
|
||||
)
|
||||
|
||||
|
||||
#if 0
|
||||
/* nothing uses this */
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
|
||||
#define _v128_add(z, x, y) { \
|
||||
uint64_t tmp; \
|
||||
\
|
||||
tmp = x->v32[3] + y->v32[3]; \
|
||||
z->v32[3] = (uint32_t) tmp; \
|
||||
\
|
||||
tmp = x->v32[2] + y->v32[2] + (tmp >> 32); \
|
||||
z->v32[2] = (uint32_t) tmp; \
|
||||
\
|
||||
tmp = x->v32[1] + y->v32[1] + (tmp >> 32); \
|
||||
z->v32[1] = (uint32_t) tmp; \
|
||||
\
|
||||
tmp = x->v32[0] + y->v32[0] + (tmp >> 32); \
|
||||
z->v32[0] = (uint32_t) tmp; \
|
||||
}
|
||||
|
||||
#else /* assume little endian architecture */
|
||||
|
||||
#define _v128_add(z, x, y) { \
|
||||
uint64_t tmp; \
|
||||
\
|
||||
tmp = htonl(x->v32[3]) + htonl(y->v32[3]); \
|
||||
z->v32[3] = ntohl((uint32_t) tmp); \
|
||||
\
|
||||
tmp = htonl(x->v32[2]) + htonl(y->v32[2]) \
|
||||
+ htonl(tmp >> 32); \
|
||||
z->v32[2] = ntohl((uint32_t) tmp); \
|
||||
\
|
||||
tmp = htonl(x->v32[1]) + htonl(y->v32[1]) \
|
||||
+ htonl(tmp >> 32); \
|
||||
z->v32[1] = ntohl((uint32_t) tmp); \
|
||||
\
|
||||
tmp = htonl(x->v32[0]) + htonl(y->v32[0]) \
|
||||
+ htonl(tmp >> 32); \
|
||||
z->v32[0] = ntohl((uint32_t) tmp); \
|
||||
}
|
||||
#endif /* WORDS_BIGENDIAN */
|
||||
#endif /* 0 */
|
||||
|
||||
|
||||
#ifdef DATATYPES_USE_MACROS /* little functions are really macros */
|
||||
|
||||
#define v128_set_to_zero(z) _v128_set_to_zero(z)
|
||||
#define v128_copy(z, x) _v128_copy(z, x)
|
||||
#define v128_xor(z, x, y) _v128_xor(z, x, y)
|
||||
#define v128_and(z, x, y) _v128_and(z, x, y)
|
||||
#define v128_or(z, x, y) _v128_or(z, x, y)
|
||||
#define v128_complement(x) _v128_complement(x)
|
||||
#define v128_is_eq(x, y) _v128_is_eq(x, y)
|
||||
#define v128_xor_eq(x, y) _v128_xor_eq(x, y)
|
||||
#define v128_get_bit(x, i) _v128_get_bit(x, i)
|
||||
#define v128_set_bit(x, i) _v128_set_bit(x, i)
|
||||
#define v128_clear_bit(x, i) _v128_clear_bit(x, i)
|
||||
#define v128_set_bit_to(x, i, y) _v128_set_bit_to(x, i, y)
|
||||
|
||||
#else
|
||||
|
||||
void
|
||||
v128_set_to_zero(v128_t *x);
|
||||
|
||||
int
|
||||
v128_is_eq(const v128_t *x, const v128_t *y);
|
||||
|
||||
void
|
||||
v128_copy(v128_t *x, const v128_t *y);
|
||||
|
||||
void
|
||||
v128_xor(v128_t *z, v128_t *x, v128_t *y);
|
||||
|
||||
void
|
||||
v128_and(v128_t *z, v128_t *x, v128_t *y);
|
||||
|
||||
void
|
||||
v128_or(v128_t *z, v128_t *x, v128_t *y);
|
||||
|
||||
void
|
||||
v128_complement(v128_t *x);
|
||||
|
||||
int
|
||||
v128_get_bit(const v128_t *x, int i);
|
||||
|
||||
void
|
||||
v128_set_bit(v128_t *x, int i) ;
|
||||
|
||||
void
|
||||
v128_clear_bit(v128_t *x, int i);
|
||||
|
||||
void
|
||||
v128_set_bit_to(v128_t *x, int i, int y);
|
||||
|
||||
#endif /* DATATYPES_USE_MACROS */
|
||||
|
||||
/*
|
||||
* octet_string_is_eq(a,b, len) returns 1 if the length len strings a
|
||||
* and b are not equal, returns 0 otherwise
|
||||
*/
|
||||
|
||||
int
|
||||
octet_string_is_eq(uint8_t *a, uint8_t *b, int len);
|
||||
|
||||
void
|
||||
octet_string_set_to_zero(uint8_t *s, int len);
|
||||
|
||||
|
||||
#ifndef SRTP_KERNEL_LINUX
|
||||
|
||||
/*
|
||||
* Convert big endian integers to CPU byte order.
|
||||
*/
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
/* Nothing to do. */
|
||||
# define be32_to_cpu(x) (x)
|
||||
# define be64_to_cpu(x) (x)
|
||||
#elif defined(HAVE_BYTESWAP_H)
|
||||
/* We have (hopefully) optimized versions in byteswap.h */
|
||||
# include <byteswap.h>
|
||||
# define be32_to_cpu(x) bswap_32((x))
|
||||
# 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>
|
||||
# include <arpa/inet.h>
|
||||
# if defined(TARGET_ANDROID)
|
||||
# include <sys/endian.h>
|
||||
# endif
|
||||
# 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 */
|
||||
v = make64(htonl(low32(v)),htonl(high32(v)));
|
||||
# else
|
||||
/* 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 */
|
||||
|
|
@ -1,174 +0,0 @@
|
|||
/*
|
||||
* err.h
|
||||
*
|
||||
* error status codes
|
||||
*
|
||||
* 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 ERR_H
|
||||
#define ERR_H
|
||||
|
||||
#include "datatypes.h"
|
||||
|
||||
/**
|
||||
* @defgroup Error Error Codes
|
||||
*
|
||||
* Error status codes are represented by the enumeration err_status_t.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* @brief err_status_t defines error codes.
|
||||
*
|
||||
* The enumeration err_status_t defines error codes. Note that the
|
||||
* value of err_status_ok is equal to zero, which can simplify error
|
||||
* checking somewhat.
|
||||
*
|
||||
*/
|
||||
typedef enum {
|
||||
err_status_ok = 0, /**< nothing to report */
|
||||
err_status_fail = 1, /**< unspecified failure */
|
||||
err_status_bad_param = 2, /**< unsupported parameter */
|
||||
err_status_alloc_fail = 3, /**< couldn't allocate memory */
|
||||
err_status_dealloc_fail = 4, /**< couldn't deallocate properly */
|
||||
err_status_init_fail = 5, /**< couldn't initialize */
|
||||
err_status_terminus = 6, /**< can't process as much data as requested */
|
||||
err_status_auth_fail = 7, /**< authentication failure */
|
||||
err_status_cipher_fail = 8, /**< cipher failure */
|
||||
err_status_replay_fail = 9, /**< replay check failed (bad index) */
|
||||
err_status_replay_old = 10, /**< replay check failed (index too old) */
|
||||
err_status_algo_fail = 11, /**< algorithm failed test routine */
|
||||
err_status_no_such_op = 12, /**< unsupported operation */
|
||||
err_status_no_ctx = 13, /**< no appropriate context found */
|
||||
err_status_cant_check = 14, /**< unable to perform desired validation */
|
||||
err_status_key_expired = 15, /**< can't use key any more */
|
||||
err_status_socket_err = 16, /**< error in use of socket */
|
||||
err_status_signal_err = 17, /**< error in use POSIX signals */
|
||||
err_status_nonce_bad = 18, /**< nonce check failed */
|
||||
err_status_read_fail = 19, /**< couldn't read data */
|
||||
err_status_write_fail = 20, /**< couldn't write data */
|
||||
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_t;
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
typedef enum {
|
||||
err_level_emergency = 0,
|
||||
err_level_alert,
|
||||
err_level_critical,
|
||||
err_level_error,
|
||||
err_level_warning,
|
||||
err_level_notice,
|
||||
err_level_info,
|
||||
err_level_debug,
|
||||
err_level_none
|
||||
} err_reporting_level_t;
|
||||
|
||||
/*
|
||||
* err_reporting_init prepares the error system. If
|
||||
* ERR_REPORTING_SYSLOG is defined, it will open syslog.
|
||||
*
|
||||
* The ident argument is a string that will be prepended to
|
||||
* all syslog messages. It is conventionally argv[0].
|
||||
*/
|
||||
|
||||
err_status_t
|
||||
err_reporting_init(char *ident);
|
||||
|
||||
#ifdef SRTP_KERNEL_LINUX
|
||||
extern err_reporting_level_t err_level;
|
||||
#else
|
||||
|
||||
/*
|
||||
* keydaemon_report_error reports a 'printf' formatted error
|
||||
* string, followed by a an arg list. The priority argument
|
||||
* is equivalent to that defined for syslog.
|
||||
*
|
||||
* Errors will be reported to ERR_REPORTING_FILE, if defined, and to
|
||||
* syslog, if ERR_REPORTING_SYSLOG is defined.
|
||||
*
|
||||
*/
|
||||
|
||||
void
|
||||
err_report(int priority, char *format, ...);
|
||||
#endif /* ! SRTP_KERNEL_LINUX */
|
||||
|
||||
|
||||
/*
|
||||
* debug_module_t defines a debug module
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
int on; /* 1 if debugging is on, 0 if it is off */
|
||||
char *name; /* printable name for debug module */
|
||||
} debug_module_t;
|
||||
|
||||
#ifdef ENABLE_DEBUGGING
|
||||
|
||||
#define debug_on(mod) (mod).on = 1
|
||||
|
||||
#define debug_off(mod) (mod).on = 0
|
||||
|
||||
/* use err_report() to report debug message */
|
||||
#define debug_print(mod, format, arg) \
|
||||
if (mod.on) err_report(err_level_debug, ("%s: " format "\n"), mod.name, arg)
|
||||
#define debug_print2(mod, format, arg1,arg2) \
|
||||
if (mod.on) err_report(err_level_debug, ("%s: " format "\n"), mod.name, arg1,arg2)
|
||||
|
||||
#else
|
||||
|
||||
/* define macros to do nothing */
|
||||
#define debug_print(mod, format, arg)
|
||||
|
||||
#define debug_on(mod)
|
||||
|
||||
#define debug_off(mod)
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* ERR_H */
|
||||
|
|
@ -1,79 +0,0 @@
|
|||
/*
|
||||
* gf2_8.h
|
||||
*
|
||||
* GF(256) implementation
|
||||
*
|
||||
* 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 GF2_8_H
|
||||
#define GF2_8_H
|
||||
|
||||
#include "datatypes.h" /* for uint8_t definition */
|
||||
|
||||
typedef uint8_t gf2_8;
|
||||
|
||||
#define gf2_8_field_polynomial 0x1B
|
||||
|
||||
/*
|
||||
* gf2_8_shift(x) returns
|
||||
*/
|
||||
|
||||
/*
|
||||
* gf2_8_shift(z) returns the result of the GF(2^8) 'multiply by x'
|
||||
* operation, using the field representation from AES; that is, the
|
||||
* next gf2_8 value in the cyclic representation of that field. The
|
||||
* value z should be an uint8_t.
|
||||
*/
|
||||
|
||||
#define gf2_8_shift(z) (((z) & 128) ? \
|
||||
(((z) << 1) ^ gf2_8_field_polynomial) : ((z) << 1))
|
||||
|
||||
gf2_8
|
||||
gf2_8_compute_inverse(gf2_8 x);
|
||||
|
||||
void
|
||||
test_gf2_8(void);
|
||||
|
||||
gf2_8
|
||||
gf2_8_multiply(gf2_8 x, gf2_8 y);
|
||||
|
||||
#endif /* GF2_8_H */
|
||||
|
|
@ -1,78 +0,0 @@
|
|||
/*
|
||||
* hmac.h
|
||||
*
|
||||
* interface to hmac auth_type_t
|
||||
*
|
||||
* 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 HMAC_H
|
||||
#define HMAC_H
|
||||
|
||||
#include "auth.h"
|
||||
#include "sha1.h"
|
||||
|
||||
typedef struct {
|
||||
uint8_t opad[64];
|
||||
sha1_ctx_t ctx;
|
||||
sha1_ctx_t init_ctx;
|
||||
} hmac_ctx_t;
|
||||
|
||||
err_status_t
|
||||
hmac_alloc(auth_t **a, int key_len, int out_len);
|
||||
|
||||
err_status_t
|
||||
hmac_dealloc(auth_t *a);
|
||||
|
||||
err_status_t
|
||||
hmac_init(hmac_ctx_t *state, const uint8_t *key, int key_len);
|
||||
|
||||
err_status_t
|
||||
hmac_start(hmac_ctx_t *state);
|
||||
|
||||
err_status_t
|
||||
hmac_update(hmac_ctx_t *state, const uint8_t *message, int msg_octets);
|
||||
|
||||
err_status_t
|
||||
hmac_compute(hmac_ctx_t *state, const void *message,
|
||||
int msg_octets, int tag_len, uint8_t *result);
|
||||
|
||||
|
||||
#endif /* HMAC_H */
|
||||
|
|
@ -1,155 +0,0 @@
|
|||
/*
|
||||
* integers.h
|
||||
*
|
||||
* defines integer types (or refers to their definitions)
|
||||
*
|
||||
* 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 INTEGERS_H
|
||||
#define INTEGERS_H
|
||||
|
||||
#include "config.h" /* configuration file, using autoconf */
|
||||
|
||||
#ifdef SRTP_KERNEL
|
||||
|
||||
#include "kernel_compat.h"
|
||||
|
||||
#else /* SRTP_KERNEL */
|
||||
|
||||
/* use standard integer definitions, if they're available */
|
||||
#ifdef HAVE_STDLIB_H
|
||||
# include <stdlib.h>
|
||||
#endif
|
||||
#ifdef HAVE_STDINT_H
|
||||
# include <stdint.h>
|
||||
#endif
|
||||
#ifdef HAVE_INTTYPES_H
|
||||
# include <inttypes.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_TYPES_H
|
||||
# include <sys/types.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_INT_TYPES_H
|
||||
# include <sys/int_types.h> /* this exists on Sun OS */
|
||||
#endif
|
||||
#ifdef HAVE_MACHINE_TYPES_H
|
||||
# include <machine/types.h>
|
||||
#endif
|
||||
|
||||
#ifndef WIN32
|
||||
# define SIZEOF_UNSIGNED_LONG_LONG 8
|
||||
#endif
|
||||
|
||||
/* Can we do 64 bit integers? */
|
||||
#ifndef HAVE_UINT64_T
|
||||
# if SIZEOF_UNSIGNED_LONG == 8
|
||||
typedef unsigned long uint64_t;
|
||||
# elif SIZEOF_UNSIGNED_LONG_LONG == 8
|
||||
//typedef unsigned long long uint64_t;
|
||||
# else
|
||||
# ifdef _WIN32
|
||||
typedef unsigned __int64 uint64_t;
|
||||
# else
|
||||
# define NO_64BIT_MATH 1
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* Reasonable defaults for 32 bit machines - you may need to
|
||||
* edit these definitions for your own machine. */
|
||||
#ifndef HAVE_UINT8_T
|
||||
typedef unsigned char uint8_t;
|
||||
#endif
|
||||
#ifndef HAVE_UINT16_T
|
||||
typedef unsigned short int uint16_t;
|
||||
#endif
|
||||
#ifndef HAVE_UINT32_T
|
||||
typedef unsigned int uint32_t;
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef NO_64BIT_MATH
|
||||
typedef double uint64_t;
|
||||
/* assert that sizeof(double) == 8 */
|
||||
extern uint64_t make64(uint32_t high, uint32_t low);
|
||||
extern uint32_t high32(uint64_t value);
|
||||
extern uint32_t low32(uint64_t value);
|
||||
#endif
|
||||
|
||||
#endif /* SRTP_KERNEL */
|
||||
|
||||
/* These macros are to load and store 32-bit values from un-aligned
|
||||
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 */
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
#define PUT_32(addr,value) \
|
||||
{ \
|
||||
((unsigned char *) (addr))[0] = (value >> 24); \
|
||||
((unsigned char *) (addr))[1] = (value >> 16) & 0xff; \
|
||||
((unsigned char *) (addr))[2] = (value >> 8) & 0xff; \
|
||||
((unsigned char *) (addr))[3] = (value) & 0xff; \
|
||||
}
|
||||
#define GET_32(addr) ((((unsigned char *) (addr))[0] << 24) | \
|
||||
(((unsigned char *) (addr))[1] << 16) | \
|
||||
(((unsigned char *) (addr))[2] << 8) | \
|
||||
(((unsigned char *) (addr))[3]))
|
||||
#else
|
||||
#define PUT_32(addr,value) \
|
||||
{ \
|
||||
((unsigned char *) (addr))[3] = (value >> 24); \
|
||||
((unsigned char *) (addr))[2] = (value >> 16) & 0xff; \
|
||||
((unsigned char *) (addr))[1] = (value >> 8) & 0xff; \
|
||||
((unsigned char *) (addr))[0] = (value) & 0xff; \
|
||||
}
|
||||
#define GET_32(addr) ((((unsigned char *) (addr))[3] << 24) | \
|
||||
(((unsigned char *) (addr))[2] << 16) | \
|
||||
(((unsigned char *) (addr))[1] << 8) | \
|
||||
(((unsigned char *) (addr))[0]))
|
||||
#endif // WORDS_BIGENDIAN
|
||||
#else
|
||||
#define PUT_32(addr,value) *(((uint32_t *) (addr)) = (value)
|
||||
#define GET_32(addr) (*(((uint32_t *) (addr)))
|
||||
#endif
|
||||
|
||||
#endif /* INTEGERS_H */
|
||||
|
|
@ -1,84 +0,0 @@
|
|||
/*
|
||||
* kernel_compat.h
|
||||
*
|
||||
* Compatibility stuff for building in kernel context where standard
|
||||
* C headers and library are not available.
|
||||
*
|
||||
* Marcus Sundberg
|
||||
* Ingate Systems AB
|
||||
*/
|
||||
/*
|
||||
*
|
||||
* Copyright(c) 2005 Ingate Systems AB
|
||||
* 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 author(s) 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 KERNEL_COMPAT_H
|
||||
#define KERNEL_COMPAT_H
|
||||
|
||||
#ifdef SRTP_KERNEL_LINUX
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/random.h>
|
||||
#include <linux/byteorder/generic.h>
|
||||
|
||||
|
||||
#define err_report(priority, ...) \
|
||||
do {\
|
||||
if (priority <= err_level) {\
|
||||
printk(__VA_ARGS__);\
|
||||
}\
|
||||
}while(0)
|
||||
|
||||
#define clock() (jiffies)
|
||||
#define time(x) (jiffies)
|
||||
|
||||
/* rand() implementation. */
|
||||
#define RAND_MAX 32767
|
||||
|
||||
static inline int rand(void)
|
||||
{
|
||||
uint32_t temp;
|
||||
get_random_bytes(&temp, sizeof(temp));
|
||||
return temp % (RAND_MAX+1);
|
||||
}
|
||||
|
||||
/* stdio/stdlib implementation. */
|
||||
#define printf(...) printk(__VA_ARGS__)
|
||||
#define exit(n) panic("%s:%d: exit(%d)\n", __FILE__, __LINE__, (n))
|
||||
|
||||
#endif /* SRTP_KERNEL_LINUX */
|
||||
|
||||
#endif /* KERNEL_COMPAT_H */
|
||||
|
|
@ -1,82 +0,0 @@
|
|||
/*
|
||||
* key.h
|
||||
*
|
||||
* key usage limits enforcement
|
||||
*
|
||||
* 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 KEY_H
|
||||
#define KEY_H
|
||||
|
||||
#include "rdbx.h" /* for xtd_seq_num_t */
|
||||
#include "err.h"
|
||||
|
||||
typedef struct key_limit_ctx_t *key_limit_t;
|
||||
|
||||
typedef enum {
|
||||
key_event_normal,
|
||||
key_event_soft_limit,
|
||||
key_event_hard_limit
|
||||
} key_event_t;
|
||||
|
||||
err_status_t
|
||||
key_limit_set(key_limit_t key, const xtd_seq_num_t s);
|
||||
|
||||
err_status_t
|
||||
key_limit_clone(key_limit_t original, key_limit_t *new_key);
|
||||
|
||||
err_status_t
|
||||
key_limit_check(const key_limit_t key);
|
||||
|
||||
key_event_t
|
||||
key_limit_update(key_limit_t key);
|
||||
|
||||
typedef enum {
|
||||
key_state_normal,
|
||||
key_state_past_soft_limit,
|
||||
key_state_expired
|
||||
} key_state_t;
|
||||
|
||||
typedef struct key_limit_ctx_t {
|
||||
xtd_seq_num_t num_left;
|
||||
key_state_t state;
|
||||
} key_limit_ctx_t;
|
||||
|
||||
#endif /* KEY_H */
|
||||
|
|
@ -1,68 +0,0 @@
|
|||
/*
|
||||
* null-auth.h
|
||||
*
|
||||
* 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 NULL_AUTH_H
|
||||
#define NULL_AUTH_H
|
||||
|
||||
#include "auth.h"
|
||||
|
||||
typedef struct {
|
||||
char foo;
|
||||
} null_auth_ctx_t;
|
||||
|
||||
err_status_t
|
||||
null_auth_alloc(auth_t **a, int key_len, int out_len);
|
||||
|
||||
err_status_t
|
||||
null_auth_dealloc(auth_t *a);
|
||||
|
||||
err_status_t
|
||||
null_auth_init(null_auth_ctx_t *state, const uint8_t *key, int key_len);
|
||||
|
||||
err_status_t
|
||||
null_auth_compute (null_auth_ctx_t *state, uint8_t *message,
|
||||
int msg_octets, int tag_len, uint8_t *result);
|
||||
|
||||
|
||||
#endif /* NULL_AUTH_H */
|
||||
|
|
@ -1,80 +0,0 @@
|
|||
/*
|
||||
* null-cipher.h
|
||||
*
|
||||
* header file for the null cipher
|
||||
*
|
||||
*
|
||||
* 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 NULL_CIPHER_H
|
||||
#define NULL_CIPHER_H
|
||||
|
||||
#include "datatypes.h"
|
||||
#include "cipher.h"
|
||||
|
||||
typedef struct {
|
||||
char foo ;/* empty, for now */
|
||||
} null_cipher_ctx_t;
|
||||
|
||||
|
||||
/*
|
||||
* none of these functions do anything (though future versions may keep
|
||||
* track of bytes encrypted, number of instances, and/or other info).
|
||||
*/
|
||||
|
||||
err_status_t
|
||||
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 segment_index);
|
||||
|
||||
err_status_t
|
||||
null_cipher_encrypt(null_cipher_ctx_t *c,
|
||||
unsigned char *buf, unsigned int *bytes_to_encr);
|
||||
|
||||
|
||||
err_status_t
|
||||
null_cipher_encrypt_aligned(null_cipher_ctx_t *c,
|
||||
unsigned char *buf, int bytes_to_encr);
|
||||
|
||||
#endif /* NULL_CIPHER_H */
|
||||
|
|
@ -1,54 +0,0 @@
|
|||
/*
|
||||
* prng.h
|
||||
*
|
||||
* pseudorandom source
|
||||
*
|
||||
* David A. McGrew
|
||||
* Cisco Systems, Inc.
|
||||
*/
|
||||
|
||||
#ifndef PRNG_H
|
||||
#define PRNG_H
|
||||
|
||||
#include "rand_source.h" /* for rand_source_func_t definition */
|
||||
#include "aes.h" /* for aes */
|
||||
#include "aes_icm.h" /* for aes ctr */
|
||||
|
||||
#define MAX_PRNG_OUT_LEN 0xffffffffU
|
||||
|
||||
/*
|
||||
* x917_prng is an ANSI X9.17-like AES-based PRNG
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
v128_t state; /* state data */
|
||||
aes_expanded_key_t key; /* secret key */
|
||||
uint32_t octet_count; /* number of octets output since last init */
|
||||
rand_source_func_t rand; /* random source for re-initialization */
|
||||
} x917_prng_t;
|
||||
|
||||
err_status_t
|
||||
x917_prng_init(rand_source_func_t random_source);
|
||||
|
||||
err_status_t
|
||||
x917_prng_get_octet_string(uint8_t *dest, uint32_t len);
|
||||
|
||||
|
||||
/*
|
||||
* ctr_prng is an AES-CTR based PRNG
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
uint32_t octet_count; /* number of octets output since last init */
|
||||
aes_icm_ctx_t state; /* state data */
|
||||
rand_source_func_t rand; /* random source for re-initialization */
|
||||
} ctr_prng_t;
|
||||
|
||||
err_status_t
|
||||
ctr_prng_init(rand_source_func_t random_source);
|
||||
|
||||
err_status_t
|
||||
ctr_prng_get_octet_string(void *dest, uint32_t len);
|
||||
|
||||
|
||||
#endif
|
||||
|
|
@ -1,91 +0,0 @@
|
|||
/*
|
||||
* rand_source.h
|
||||
*
|
||||
* implements a random source based on /dev/random
|
||||
*
|
||||
* 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 RAND_SOURCE
|
||||
#define RAND_SOURCE
|
||||
|
||||
#include "err.h"
|
||||
#include "datatypes.h"
|
||||
|
||||
err_status_t
|
||||
rand_source_init(void);
|
||||
|
||||
/*
|
||||
* rand_source_get_octet_string() writes a random octet string.
|
||||
*
|
||||
* The function call rand_source_get_octet_string(dest, len) writes
|
||||
* len octets of random data to the location to which dest points,
|
||||
* and returns an error code. This error code should be checked,
|
||||
* and if a failure is reported, the data in the buffer MUST NOT
|
||||
* be used.
|
||||
*
|
||||
* warning: If the return code is not checked, then non-random
|
||||
* data may inadvertently be used.
|
||||
*
|
||||
* returns:
|
||||
* - err_status_ok if no problems occured.
|
||||
* - [other] a problem occured, and no assumptions should
|
||||
* be made about the contents of the destination
|
||||
* buffer.
|
||||
*/
|
||||
|
||||
err_status_t
|
||||
rand_source_get_octet_string(void *dest, uint32_t length);
|
||||
|
||||
err_status_t
|
||||
rand_source_deinit(void);
|
||||
|
||||
/*
|
||||
* function prototype for a random source function
|
||||
*
|
||||
* A rand_source_func_t writes num_octets at the location indicated by
|
||||
* dest and returns err_status_ok. Any other return value indicates
|
||||
* failure.
|
||||
*/
|
||||
|
||||
typedef err_status_t (*rand_source_func_t)
|
||||
(void *dest, uint32_t num_octets);
|
||||
|
||||
#endif /* RAND_SOURCE */
|
||||
|
|
@ -1,94 +0,0 @@
|
|||
/*
|
||||
* replay-database.h
|
||||
*
|
||||
* interface for a replay database for packet security
|
||||
*
|
||||
* David A. McGrew
|
||||
* Cisco Systems, Inc.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef REPLAY_DB_H
|
||||
#define REPLAY_DB_H
|
||||
|
||||
#include "integers.h" /* for uint32_t */
|
||||
#include "datatypes.h" /* for v128_t */
|
||||
#include "err.h" /* for err_status_t */
|
||||
|
||||
/*
|
||||
* if the ith least significant bit is one, then the packet index
|
||||
* window_end-i is in the database
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
uint32_t window_start; /* packet index of the first bit in bitmask */
|
||||
v128_t bitmask;
|
||||
} rdb_t;
|
||||
|
||||
#define rdb_bits_in_bitmask (8*sizeof(v128_t))
|
||||
|
||||
/*
|
||||
* rdb init
|
||||
*
|
||||
* initalizes rdb
|
||||
*
|
||||
* returns err_status_ok on success, err_status_t_fail otherwise
|
||||
*/
|
||||
|
||||
err_status_t
|
||||
rdb_init(rdb_t *rdb);
|
||||
|
||||
|
||||
/*
|
||||
* rdb_check
|
||||
*
|
||||
* checks to see if index appears in rdb
|
||||
*
|
||||
* returns err_status_fail if the index already appears in rdb,
|
||||
* returns err_status_ok otherwise
|
||||
*/
|
||||
|
||||
err_status_t
|
||||
rdb_check(const rdb_t *rdb, uint32_t rdb_index);
|
||||
|
||||
/*
|
||||
* rdb_add_index
|
||||
*
|
||||
* adds index to rdb_t (and does *not* check if index appears in db)
|
||||
*
|
||||
* returns err_status_ok on success, err_status_fail otherwise
|
||||
*
|
||||
*/
|
||||
|
||||
err_status_t
|
||||
rdb_add_index(rdb_t *rdb, uint32_t rdb_index);
|
||||
|
||||
/*
|
||||
* the functions rdb_increment() and rdb_get_value() are for use by
|
||||
* senders, not receivers - DO NOT use these functions on the same
|
||||
* rdb_t upon which rdb_add_index is used!
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* rdb_increment(db) increments the sequence number in db, if it is
|
||||
* not too high
|
||||
*
|
||||
* return values:
|
||||
*
|
||||
* err_status_ok no problem
|
||||
* err_status_key_expired sequence number too high
|
||||
*
|
||||
*/
|
||||
err_status_t
|
||||
rdb_increment(rdb_t *rdb);
|
||||
|
||||
/*
|
||||
* rdb_get_value(db) returns the current sequence number of db
|
||||
*/
|
||||
|
||||
uint32_t
|
||||
rdb_get_value(const rdb_t *rdb);
|
||||
|
||||
|
||||
#endif /* REPLAY_DB_H */
|
||||
|
|
@ -1,186 +0,0 @@
|
|||
/*
|
||||
* rdbx.h
|
||||
*
|
||||
* replay database with extended packet indices, using a rollover counter
|
||||
*
|
||||
* David A. McGrew
|
||||
* Cisco Systems, Inc.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef RDBX_H
|
||||
#define RDBX_H
|
||||
|
||||
#include "datatypes.h"
|
||||
#include "err.h"
|
||||
|
||||
/* #define ROC_TEST */
|
||||
|
||||
#ifndef ROC_TEST
|
||||
|
||||
typedef uint16_t sequence_number_t; /* 16 bit sequence number */
|
||||
typedef uint32_t rollover_counter_t; /* 32 bit rollover counter */
|
||||
|
||||
#else /* use small seq_num and roc datatypes for testing purposes */
|
||||
|
||||
typedef unsigned char sequence_number_t; /* 8 bit sequence number */
|
||||
typedef uint16_t rollover_counter_t; /* 16 bit rollover counter */
|
||||
|
||||
#endif
|
||||
|
||||
#define seq_num_median (1 << (8*sizeof(sequence_number_t) - 1))
|
||||
#define seq_num_max (1 << (8*sizeof(sequence_number_t)))
|
||||
|
||||
/*
|
||||
* An xtd_seq_num_t is a 64-bit unsigned integer used as an 'extended'
|
||||
* sequence number.
|
||||
*/
|
||||
|
||||
typedef uint64_t xtd_seq_num_t;
|
||||
|
||||
|
||||
/*
|
||||
* An rdbx_t is a replay database with extended range; it uses an
|
||||
* xtd_seq_num_t and a bitmask of recently received indices.
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
xtd_seq_num_t index;
|
||||
bitvector_t bitmask;
|
||||
} rdbx_t;
|
||||
|
||||
|
||||
/*
|
||||
* rdbx_init(rdbx_ptr, ws)
|
||||
*
|
||||
* 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, unsigned long ws);
|
||||
|
||||
|
||||
/*
|
||||
* rdbx_dealloc(rdbx_ptr)
|
||||
*
|
||||
* frees memory associated with the rdbx
|
||||
*/
|
||||
|
||||
err_status_t
|
||||
rdbx_dealloc(rdbx_t *rdbx);
|
||||
|
||||
|
||||
/*
|
||||
* rdbx_estimate_index(rdbx, guess, s)
|
||||
*
|
||||
* given an rdbx and a sequence number s (from a newly arrived packet),
|
||||
* sets the contents of *guess to contain the best guess of the packet
|
||||
* index to which s corresponds, and returns the difference between
|
||||
* *guess and the locally stored synch info
|
||||
*/
|
||||
|
||||
int
|
||||
rdbx_estimate_index(const rdbx_t *rdbx,
|
||||
xtd_seq_num_t *guess,
|
||||
sequence_number_t s);
|
||||
|
||||
/*
|
||||
* rdbx_check(rdbx, delta);
|
||||
*
|
||||
* rdbx_check(&r, delta) checks to see if the xtd_seq_num_t
|
||||
* which is at rdbx->window_start + delta is in the rdb
|
||||
*
|
||||
*/
|
||||
|
||||
err_status_t
|
||||
rdbx_check(const rdbx_t *rdbx, int difference);
|
||||
|
||||
/*
|
||||
* replay_add_index(rdbx, delta)
|
||||
*
|
||||
* adds the xtd_seq_num_t at rdbx->window_start + delta to replay_db
|
||||
* (and does *not* check if that xtd_seq_num_t appears in db)
|
||||
*
|
||||
* this function should be called *only* after replay_check has
|
||||
* indicated that the index does not appear in the rdbx, and a mutex
|
||||
* should protect the rdbx between these calls if necessary.
|
||||
*/
|
||||
|
||||
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) */
|
||||
|
||||
void
|
||||
index_init(xtd_seq_num_t *pi);
|
||||
|
||||
/* index_advance(&pi, s) advances a xtd_seq_num_t forward by s */
|
||||
|
||||
void
|
||||
index_advance(xtd_seq_num_t *pi, sequence_number_t s);
|
||||
|
||||
|
||||
/*
|
||||
* index_guess(local, guess, s)
|
||||
*
|
||||
* given a xtd_seq_num_t local (which represents the highest
|
||||
* known-to-be-good index) and a sequence number s (from a newly
|
||||
* arrived packet), sets the contents of *guess to contain the best
|
||||
* guess of the packet index to which s corresponds, and returns the
|
||||
* difference between *guess and *local
|
||||
*/
|
||||
|
||||
int
|
||||
index_guess(const xtd_seq_num_t *local,
|
||||
xtd_seq_num_t *guess,
|
||||
sequence_number_t s);
|
||||
|
||||
|
||||
#endif /* RDBX_H */
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -1,108 +0,0 @@
|
|||
/*
|
||||
* sha1.h
|
||||
*
|
||||
* interface to the Secure Hash Algorithm v.1 (SHA-1), specified in
|
||||
* FIPS 180-1
|
||||
*
|
||||
* 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 SHA1_H
|
||||
#define SHA1_H
|
||||
|
||||
#include "err.h"
|
||||
#include "datatypes.h"
|
||||
|
||||
typedef struct {
|
||||
uint32_t H[5]; /* state vector */
|
||||
uint32_t M[16]; /* message buffer */
|
||||
int octets_in_buffer; /* octets of message in buffer */
|
||||
uint32_t num_bits_in_msg; /* total number of bits in message */
|
||||
} sha1_ctx_t;
|
||||
|
||||
/*
|
||||
* sha1(&ctx, msg, len, output) hashes the len octets starting at msg
|
||||
* into the SHA1 context, then writes the result to the 20 octets at
|
||||
* output
|
||||
*
|
||||
*/
|
||||
|
||||
void
|
||||
sha1(const uint8_t *message, int octets_in_msg, uint32_t output[5]);
|
||||
|
||||
/*
|
||||
* srtp_sha1_init(&ctx) initializes the SHA1 context ctx
|
||||
*
|
||||
* sha1_update(&ctx, msg, len) hashes the len octets starting at msg
|
||||
* into the SHA1 context
|
||||
*
|
||||
* sha1_final(&ctx, output) performs the final processing of the SHA1
|
||||
* context and writes the result to the 20 octets at output
|
||||
*
|
||||
*/
|
||||
|
||||
void
|
||||
srtp_sha1_init(sha1_ctx_t *ctx);
|
||||
|
||||
void
|
||||
srtp_sha1_update(sha1_ctx_t *ctx, const uint8_t *M, int octets_in_msg);
|
||||
|
||||
void
|
||||
srtp_sha1_final(sha1_ctx_t *ctx, uint32_t output[5]);
|
||||
|
||||
/*
|
||||
* The sha1_core function is INTERNAL to SHA-1, but it is declared
|
||||
* here because it is also used by the cipher SEAL 3.0 in its key
|
||||
* setup algorithm.
|
||||
*/
|
||||
|
||||
/*
|
||||
* sha1_core(M, H) computes the core sha1 compression function, where M is
|
||||
* the next part of the message and H is the intermediate state {H0,
|
||||
* H1, ...}
|
||||
*
|
||||
* this function does not do any of the padding required in the
|
||||
* complete sha1 function
|
||||
*/
|
||||
|
||||
void
|
||||
sha1_core(const uint32_t M[16], uint32_t hash_value[5]);
|
||||
|
||||
#endif /* SHA1_H */
|
||||
|
|
@ -1,69 +0,0 @@
|
|||
/*
|
||||
* stats.h
|
||||
*
|
||||
* interface to statistical test functions
|
||||
*
|
||||
* 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 STAT_H
|
||||
#define STAT_H
|
||||
|
||||
#include "datatypes.h" /* for uint8_t */
|
||||
#include "err.h" /* for err_status_t */
|
||||
#include "rand_source.h" /* for rand_source_func_t definition */
|
||||
|
||||
err_status_t
|
||||
stat_test_monobit(uint8_t *data);
|
||||
|
||||
err_status_t
|
||||
stat_test_poker(uint8_t *data);
|
||||
|
||||
err_status_t
|
||||
stat_test_runs(uint8_t *data);
|
||||
|
||||
err_status_t
|
||||
stat_test_rand_source(rand_source_func_t rs);
|
||||
|
||||
err_status_t
|
||||
stat_test_rand_source_with_repetition(rand_source_func_t source, unsigned num_trials);
|
||||
|
||||
#endif /* STAT_H */
|
||||
|
|
@ -1,139 +0,0 @@
|
|||
/*
|
||||
* xfm.h
|
||||
*
|
||||
* interface for abstract crypto transform
|
||||
*
|
||||
* David A. McGrew
|
||||
* Cisco Systems, Inc.
|
||||
*/
|
||||
|
||||
#ifndef XFM_H
|
||||
#define XFM_H
|
||||
|
||||
#include "crypto_kernel.h"
|
||||
#include "err.h"
|
||||
|
||||
/**
|
||||
* @defgroup Crypto Cryptography
|
||||
*
|
||||
* A simple interface to an abstract cryptographic transform that
|
||||
* provides both confidentiality and message authentication.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief applies a crypto transform
|
||||
*
|
||||
* The function pointer xfm_func_t points to a function that
|
||||
* implements a crypto transform, and provides a uniform API for
|
||||
* accessing crypto mechanisms.
|
||||
*
|
||||
* @param key location of secret key
|
||||
*
|
||||
* @param clear data to be authenticated only
|
||||
*
|
||||
* @param clear_len length of data to be authenticated only
|
||||
*
|
||||
* @param iv location to write the Initialization Vector (IV)
|
||||
*
|
||||
* @param protect location of the data to be encrypted and
|
||||
* authenticated (before the function call), and the ciphertext
|
||||
* and authentication tag (after the call)
|
||||
*
|
||||
* @param protected_len location of the length of the data to be
|
||||
* encrypted and authenticated (before the function call), and the
|
||||
* length of the ciphertext (after the call)
|
||||
*
|
||||
* @param auth_tag location to write auth tag
|
||||
*/
|
||||
|
||||
typedef err_status_t (*xfm_func_t)
|
||||
(void *key,
|
||||
void *clear,
|
||||
unsigned clear_len,
|
||||
void *iv,
|
||||
void *protect,
|
||||
unsigned *protected_len,
|
||||
void *auth_tag
|
||||
);
|
||||
|
||||
typedef
|
||||
err_status_t (*xfm_inv_t)
|
||||
(void *key, /* location of secret key */
|
||||
void *clear, /* data to be authenticated only */
|
||||
unsigned clear_len, /* length of data to be authenticated only */
|
||||
void *iv, /* location of iv */
|
||||
void *opaque, /* data to be decrypted and authenticated */
|
||||
unsigned *opaque_len, /* location of the length of data to be
|
||||
* decrypted and authd (before and after)
|
||||
*/
|
||||
void *auth_tag /* location of auth tag */
|
||||
);
|
||||
|
||||
typedef struct xfm_ctx_t {
|
||||
xfm_func_t func;
|
||||
xfm_inv_t inv;
|
||||
unsigned key_len;
|
||||
unsigned iv_len;
|
||||
unsigned auth_tag_len;
|
||||
} xfm_ctx_t;
|
||||
|
||||
typedef xfm_ctx_t *xfm_t;
|
||||
|
||||
#define xfm_get_key_len(xfm) ((xfm)->key_len)
|
||||
|
||||
#define xfm_get_iv_len(xfm) ((xfm)->iv_len)
|
||||
|
||||
#define xfm_get_auth_tag_len(xfm) ((xfm)->auth_tag_len)
|
||||
|
||||
|
||||
/* cryptoalgo - 5/28 */
|
||||
|
||||
typedef err_status_t (*cryptoalg_func_t)
|
||||
(void *key,
|
||||
void *clear,
|
||||
unsigned clear_len,
|
||||
void *iv,
|
||||
void *opaque,
|
||||
unsigned *opaque_len
|
||||
);
|
||||
|
||||
typedef
|
||||
err_status_t (*cryptoalg_inv_t)
|
||||
(void *key, /* location of secret key */
|
||||
void *clear, /* data to be authenticated only */
|
||||
unsigned clear_len, /* length of data to be authenticated only */
|
||||
void *iv, /* location of iv */
|
||||
void *opaque, /* data to be decrypted and authenticated */
|
||||
unsigned *opaque_len /* location of the length of data to be
|
||||
* decrypted and authd (before and after)
|
||||
*/
|
||||
);
|
||||
|
||||
typedef struct cryptoalg_ctx_t {
|
||||
cryptoalg_func_t enc;
|
||||
cryptoalg_inv_t dec;
|
||||
unsigned key_len;
|
||||
unsigned iv_len;
|
||||
unsigned auth_tag_len;
|
||||
unsigned max_expansion;
|
||||
} cryptoalg_ctx_t;
|
||||
|
||||
typedef cryptoalg_ctx_t *cryptoalg_t;
|
||||
|
||||
#define cryptoalg_get_key_len(cryptoalg) ((cryptoalg)->key_len)
|
||||
|
||||
#define cryptoalg_get_iv_len(cryptoalg) ((cryptoalg)->iv_len)
|
||||
|
||||
#define cryptoalg_get_auth_tag_len(cryptoalg) ((cryptoalg)->auth_tag_len)
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* XFM_H */
|
||||
|
||||
|
||||
|
|
@ -1,119 +0,0 @@
|
|||
/*
|
||||
* alloc.c
|
||||
*
|
||||
* memory allocation and deallocation
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "alloc.h"
|
||||
#include "crypto_kernel.h"
|
||||
|
||||
/* the debug module for memory allocation */
|
||||
|
||||
debug_module_t mod_alloc = {
|
||||
0, /* debugging is off by default */
|
||||
"alloc" /* printable name for module */
|
||||
};
|
||||
|
||||
/*
|
||||
* Nota bene: the debugging statements for crypto_alloc() and
|
||||
* crypto_free() have identical prefixes, which include the addresses
|
||||
* of the memory locations on which they are operating. This fact can
|
||||
* be used to locate memory leaks, by turning on memory debugging,
|
||||
* grepping for 'alloc', then matching alloc and free calls by
|
||||
* address.
|
||||
*/
|
||||
|
||||
#ifdef SRTP_KERNEL_LINUX
|
||||
|
||||
#include <linux/interrupt.h>
|
||||
|
||||
void *
|
||||
crypto_alloc(size_t size) {
|
||||
void *ptr;
|
||||
|
||||
ptr = kmalloc(size, in_interrupt() ? GFP_ATOMIC : GFP_KERNEL);
|
||||
|
||||
if (ptr) {
|
||||
debug_print(mod_alloc, "(location: %p) allocated", ptr);
|
||||
} else
|
||||
debug_print(mod_alloc, "allocation failed (asked for %d bytes)\n", size);
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void
|
||||
crypto_free(void *ptr) {
|
||||
|
||||
debug_print(mod_alloc, "(location: %p) freed", ptr);
|
||||
|
||||
kfree(ptr);
|
||||
}
|
||||
|
||||
|
||||
#elif defined(HAVE_STDLIB_H)
|
||||
|
||||
void *
|
||||
crypto_alloc(size_t size) {
|
||||
void *ptr;
|
||||
|
||||
ptr = malloc(size);
|
||||
|
||||
if (ptr) {
|
||||
debug_print(mod_alloc, "(location: %p) allocated", ptr);
|
||||
} else
|
||||
debug_print(mod_alloc, "allocation failed (asked for %d bytes)\n", size);
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void
|
||||
crypto_free(void *ptr) {
|
||||
|
||||
debug_print(mod_alloc, "(location: %p) freed", ptr);
|
||||
|
||||
free(ptr);
|
||||
}
|
||||
|
||||
#else /* we need to define our own memory allocation routines */
|
||||
|
||||
#error no memory allocation defined yet
|
||||
|
||||
#endif
|
||||
|
|
@ -1,573 +0,0 @@
|
|||
/*
|
||||
* crypto_kernel.c
|
||||
*
|
||||
* header for the cryptographic kernel
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include "alloc.h"
|
||||
|
||||
#include "crypto_kernel.h"
|
||||
|
||||
/* the debug module for the crypto_kernel */
|
||||
|
||||
debug_module_t mod_crypto_kernel = {
|
||||
0, /* debugging is off by default */
|
||||
"crypto kernel" /* printable name for module */
|
||||
};
|
||||
|
||||
/*
|
||||
* other debug modules that can be included in the kernel
|
||||
*/
|
||||
|
||||
extern debug_module_t mod_auth;
|
||||
extern debug_module_t mod_cipher;
|
||||
extern debug_module_t mod_stat;
|
||||
extern debug_module_t mod_alloc;
|
||||
|
||||
/*
|
||||
* cipher types that can be included in the kernel
|
||||
*/
|
||||
|
||||
extern cipher_type_t null_cipher;
|
||||
extern cipher_type_t aes_icm;
|
||||
extern cipher_type_t aes_cbc;
|
||||
|
||||
|
||||
/*
|
||||
* auth func types that can be included in the kernel
|
||||
*/
|
||||
|
||||
extern auth_type_t null_auth;
|
||||
extern auth_type_t hmac;
|
||||
|
||||
/* crypto_kernel is a global variable, the only one of its datatype */
|
||||
|
||||
crypto_kernel_t
|
||||
crypto_kernel = {
|
||||
crypto_kernel_state_insecure, /* start off in insecure state */
|
||||
NULL, /* no cipher types yet */
|
||||
NULL, /* no auth types yet */
|
||||
NULL /* no debug modules yet */
|
||||
};
|
||||
|
||||
#define MAX_RNG_TRIALS 25
|
||||
|
||||
err_status_t
|
||||
crypto_kernel_init() {
|
||||
err_status_t status;
|
||||
|
||||
/* check the security state */
|
||||
if (crypto_kernel.state == crypto_kernel_state_secure) {
|
||||
|
||||
/*
|
||||
* we're already in the secure state, but we've been asked to
|
||||
* re-initialize, so we just re-run the self-tests and then return
|
||||
*/
|
||||
return crypto_kernel_status();
|
||||
}
|
||||
|
||||
/* initialize error reporting system */
|
||||
status = err_reporting_init("crypto");
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
/* load debug modules */
|
||||
status = crypto_kernel_load_debug_module(&mod_crypto_kernel);
|
||||
if (status)
|
||||
return status;
|
||||
status = crypto_kernel_load_debug_module(&mod_auth);
|
||||
if (status)
|
||||
return status;
|
||||
status = crypto_kernel_load_debug_module(&mod_cipher);
|
||||
if (status)
|
||||
return status;
|
||||
status = crypto_kernel_load_debug_module(&mod_stat);
|
||||
if (status)
|
||||
return status;
|
||||
status = crypto_kernel_load_debug_module(&mod_alloc);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
/* initialize random number generator */
|
||||
status = rand_source_init();
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
/* run FIPS-140 statistical tests on rand_source */
|
||||
status = stat_test_rand_source_with_repetition(rand_source_get_octet_string, MAX_RNG_TRIALS);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
/* initialize pseudorandom number generator */
|
||||
status = ctr_prng_init(rand_source_get_octet_string);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
/* run FIPS-140 statistical tests on ctr_prng */
|
||||
status = stat_test_rand_source_with_repetition(ctr_prng_get_octet_string, MAX_RNG_TRIALS);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
/* load cipher types */
|
||||
status = crypto_kernel_load_cipher_type(&null_cipher, NULL_CIPHER);
|
||||
if (status)
|
||||
return status;
|
||||
status = crypto_kernel_load_cipher_type(&aes_icm, AES_ICM);
|
||||
if (status)
|
||||
return status;
|
||||
status = crypto_kernel_load_cipher_type(&aes_cbc, AES_CBC);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
/* load auth func types */
|
||||
status = crypto_kernel_load_auth_type(&null_auth, NULL_AUTH);
|
||||
if (status)
|
||||
return status;
|
||||
status = crypto_kernel_load_auth_type(&hmac, HMAC_SHA1);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
/* change state to secure */
|
||||
crypto_kernel.state = crypto_kernel_state_secure;
|
||||
|
||||
return err_status_ok;
|
||||
}
|
||||
|
||||
err_status_t
|
||||
crypto_kernel_status() {
|
||||
err_status_t status;
|
||||
kernel_cipher_type_t *ctype = crypto_kernel.cipher_type_list;
|
||||
kernel_auth_type_t *atype = crypto_kernel.auth_type_list;
|
||||
kernel_debug_module_t *dm = crypto_kernel.debug_module_list;
|
||||
|
||||
/* run FIPS-140 statistical tests on rand_source */
|
||||
printf("testing rand_source...");
|
||||
status = stat_test_rand_source_with_repetition(rand_source_get_octet_string, MAX_RNG_TRIALS);
|
||||
if (status) {
|
||||
printf("failed\n");
|
||||
crypto_kernel.state = crypto_kernel_state_insecure;
|
||||
return status;
|
||||
}
|
||||
printf("passed\n");
|
||||
|
||||
/* for each cipher type, describe and test */
|
||||
while(ctype != NULL) {
|
||||
printf("cipher: %s\n", ctype->cipher_type->description);
|
||||
printf(" instance count: %d\n", ctype->cipher_type->ref_count);
|
||||
printf(" self-test: ");
|
||||
status = cipher_type_self_test(ctype->cipher_type);
|
||||
if (status) {
|
||||
printf("failed with error code %d\n", status);
|
||||
exit(status);
|
||||
}
|
||||
printf("passed\n");
|
||||
ctype = ctype->next;
|
||||
}
|
||||
|
||||
/* for each auth type, describe and test */
|
||||
while(atype != NULL) {
|
||||
printf("auth func: %s\n", atype->auth_type->description);
|
||||
printf(" instance count: %d\n", atype->auth_type->ref_count);
|
||||
printf(" self-test: ");
|
||||
status = auth_type_self_test(atype->auth_type);
|
||||
if (status) {
|
||||
printf("failed with error code %d\n", status);
|
||||
exit(status);
|
||||
}
|
||||
printf("passed\n");
|
||||
atype = atype->next;
|
||||
}
|
||||
|
||||
/* describe each debug module */
|
||||
printf("debug modules loaded:\n");
|
||||
while (dm != NULL) {
|
||||
printf(" %s ", dm->mod->name);
|
||||
if (dm->mod->on)
|
||||
printf("(on)\n");
|
||||
else
|
||||
printf("(off)\n");
|
||||
dm = dm->next;
|
||||
}
|
||||
|
||||
return err_status_ok;
|
||||
}
|
||||
|
||||
err_status_t
|
||||
crypto_kernel_list_debug_modules() {
|
||||
kernel_debug_module_t *dm = crypto_kernel.debug_module_list;
|
||||
|
||||
/* describe each debug module */
|
||||
printf("debug modules loaded:\n");
|
||||
while (dm != NULL) {
|
||||
printf(" %s ", dm->mod->name);
|
||||
if (dm->mod->on)
|
||||
printf("(on)\n");
|
||||
else
|
||||
printf("(off)\n");
|
||||
dm = dm->next;
|
||||
}
|
||||
|
||||
return err_status_ok;
|
||||
}
|
||||
|
||||
err_status_t
|
||||
crypto_kernel_shutdown() {
|
||||
err_status_t status;
|
||||
|
||||
/*
|
||||
* free dynamic memory used in crypto_kernel at present
|
||||
*/
|
||||
|
||||
/* walk down cipher type list, freeing memory */
|
||||
while (crypto_kernel.cipher_type_list != NULL) {
|
||||
kernel_cipher_type_t *ctype = crypto_kernel.cipher_type_list;
|
||||
crypto_kernel.cipher_type_list = ctype->next;
|
||||
debug_print(mod_crypto_kernel,
|
||||
"freeing memory for cipher %s",
|
||||
ctype->cipher_type->description);
|
||||
crypto_free(ctype);
|
||||
}
|
||||
|
||||
/* walk down authetication module list, freeing memory */
|
||||
while (crypto_kernel.auth_type_list != NULL) {
|
||||
kernel_auth_type_t *atype = crypto_kernel.auth_type_list;
|
||||
crypto_kernel.auth_type_list = atype->next;
|
||||
debug_print(mod_crypto_kernel,
|
||||
"freeing memory for authentication %s",
|
||||
atype->auth_type->description);
|
||||
crypto_free(atype);
|
||||
}
|
||||
|
||||
/* walk down debug module list, freeing memory */
|
||||
while (crypto_kernel.debug_module_list != NULL) {
|
||||
kernel_debug_module_t *kdm = crypto_kernel.debug_module_list;
|
||||
crypto_kernel.debug_module_list = kdm->next;
|
||||
debug_print(mod_crypto_kernel,
|
||||
"freeing memory for debug module %s",
|
||||
kdm->mod->name);
|
||||
crypto_free(kdm);
|
||||
}
|
||||
|
||||
/* de-initialize random number generator */ status = rand_source_deinit();
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
/* return to insecure state */
|
||||
crypto_kernel.state = crypto_kernel_state_insecure;
|
||||
|
||||
return err_status_ok;
|
||||
}
|
||||
|
||||
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) {
|
||||
return status;
|
||||
}*/
|
||||
|
||||
/* walk down list, checking if this type is in the list already */
|
||||
ctype = crypto_kernel.cipher_type_list;
|
||||
while (ctype != NULL) {
|
||||
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;
|
||||
}
|
||||
|
||||
/* if not found, put new_ct at the head of the list */
|
||||
if (ctype == NULL) {
|
||||
/* allocate memory */
|
||||
new_ctype = (kernel_cipher_type_t *) crypto_alloc(sizeof(kernel_cipher_type_t));
|
||||
if (new_ctype == NULL)
|
||||
return err_status_alloc_fail;
|
||||
new_ctype->next = crypto_kernel.cipher_type_list;
|
||||
|
||||
/* set head of list to new cipher type */
|
||||
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)
|
||||
crypto_kernel_load_debug_module(new_ct->debug);
|
||||
/* we could check for errors here */
|
||||
|
||||
return err_status_ok;
|
||||
}
|
||||
|
||||
err_status_t
|
||||
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) {
|
||||
return status;
|
||||
}
|
||||
|
||||
/* walk down list, checking if this type is in the list already */
|
||||
atype = crypto_kernel.auth_type_list;
|
||||
while (atype != NULL) {
|
||||
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;
|
||||
}
|
||||
|
||||
/* if not found, put new_at at the head of the list */
|
||||
if (atype == NULL) {
|
||||
/* allocate memory */
|
||||
new_atype = (kernel_auth_type_t *)crypto_alloc(sizeof(kernel_auth_type_t));
|
||||
if (new_atype == NULL)
|
||||
return err_status_alloc_fail;
|
||||
|
||||
new_atype->next = crypto_kernel.auth_type_list;
|
||||
/* set head of list to new auth type */
|
||||
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)
|
||||
crypto_kernel_load_debug_module(new_at->debug);
|
||||
/* we could check for errors here */
|
||||
|
||||
return err_status_ok;
|
||||
|
||||
}
|
||||
|
||||
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) {
|
||||
kernel_cipher_type_t *ctype;
|
||||
|
||||
/* walk down list, looking for id */
|
||||
ctype = crypto_kernel.cipher_type_list;
|
||||
while (ctype != NULL) {
|
||||
if (id == ctype->id)
|
||||
return ctype->cipher_type;
|
||||
ctype = ctype->next;
|
||||
}
|
||||
|
||||
/* haven't found the right one, indicate failure by returning NULL */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
err_status_t
|
||||
crypto_kernel_alloc_cipher(cipher_type_id_t id,
|
||||
cipher_pointer_t *cp,
|
||||
int key_len) {
|
||||
cipher_type_t *ct;
|
||||
|
||||
/*
|
||||
* if the crypto_kernel is not yet initialized, we refuse to allocate
|
||||
* any ciphers - this is a bit extra-paranoid
|
||||
*/
|
||||
if (crypto_kernel.state != crypto_kernel_state_secure)
|
||||
return err_status_init_fail;
|
||||
|
||||
ct = crypto_kernel_get_cipher_type(id);
|
||||
if (!ct)
|
||||
return err_status_fail;
|
||||
|
||||
return ((ct)->alloc(cp, key_len));
|
||||
}
|
||||
|
||||
|
||||
|
||||
auth_type_t *
|
||||
crypto_kernel_get_auth_type(auth_type_id_t id) {
|
||||
kernel_auth_type_t *atype;
|
||||
|
||||
/* walk down list, looking for id */
|
||||
atype = crypto_kernel.auth_type_list;
|
||||
while (atype != NULL) {
|
||||
if (id == atype->id)
|
||||
return atype->auth_type;
|
||||
atype = atype->next;
|
||||
}
|
||||
|
||||
/* haven't found the right one, indicate failure by returning NULL */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
err_status_t
|
||||
crypto_kernel_alloc_auth(auth_type_id_t id,
|
||||
auth_pointer_t *ap,
|
||||
int key_len,
|
||||
int tag_len) {
|
||||
auth_type_t *at;
|
||||
|
||||
/*
|
||||
* if the crypto_kernel is not yet initialized, we refuse to allocate
|
||||
* any auth functions - this is a bit extra-paranoid
|
||||
*/
|
||||
if (crypto_kernel.state != crypto_kernel_state_secure)
|
||||
return err_status_init_fail;
|
||||
|
||||
at = crypto_kernel_get_auth_type(id);
|
||||
if (!at)
|
||||
return err_status_fail;
|
||||
|
||||
return ((at)->alloc(ap, key_len, tag_len));
|
||||
}
|
||||
|
||||
err_status_t
|
||||
crypto_kernel_load_debug_module(debug_module_t *new_dm) {
|
||||
kernel_debug_module_t *kdm, *new;
|
||||
|
||||
/* defensive coding */
|
||||
if (new_dm == NULL)
|
||||
return err_status_bad_param;
|
||||
|
||||
/* walk down list, checking if this type is in the list already */
|
||||
kdm = crypto_kernel.debug_module_list;
|
||||
while (kdm != NULL) {
|
||||
if (strncmp(new_dm->name, kdm->mod->name, 64) == 0)
|
||||
return err_status_bad_param;
|
||||
kdm = kdm->next;
|
||||
}
|
||||
|
||||
/* put new_dm at the head of the list */
|
||||
/* allocate memory */
|
||||
new = (kernel_debug_module_t *)crypto_alloc(sizeof(kernel_debug_module_t));
|
||||
if (new == NULL)
|
||||
return err_status_alloc_fail;
|
||||
|
||||
/* set fields */
|
||||
new->mod = new_dm;
|
||||
new->next = crypto_kernel.debug_module_list;
|
||||
|
||||
/* set head of list to new cipher type */
|
||||
crypto_kernel.debug_module_list = new;
|
||||
|
||||
return err_status_ok;
|
||||
}
|
||||
|
||||
err_status_t
|
||||
crypto_kernel_set_debug_module(char *name, int on) {
|
||||
kernel_debug_module_t *kdm;
|
||||
|
||||
/* walk down list, checking if this type is in the list already */
|
||||
kdm = crypto_kernel.debug_module_list;
|
||||
while (kdm != NULL) {
|
||||
if (strncmp(name, kdm->mod->name, 64) == 0) {
|
||||
kdm->mod->on = on;
|
||||
return err_status_ok;
|
||||
}
|
||||
kdm = kdm->next;
|
||||
}
|
||||
|
||||
return err_status_fail;
|
||||
}
|
||||
|
||||
err_status_t
|
||||
crypto_get_random(unsigned char *buffer, unsigned int length) {
|
||||
if (crypto_kernel.state == crypto_kernel_state_secure)
|
||||
return ctr_prng_get_octet_string(buffer, length);
|
||||
else
|
||||
return err_status_fail;
|
||||
}
|
||||
|
|
@ -1,148 +0,0 @@
|
|||
/*
|
||||
* err.c
|
||||
*
|
||||
* error status reporting functions
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "err.h"
|
||||
|
||||
#ifdef ERR_REPORTING_SYSLOG
|
||||
# ifdef HAVE_SYSLOG_H
|
||||
# include <syslog.h>
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
||||
/* err_level reflects the level of errors that are reported */
|
||||
|
||||
err_reporting_level_t err_level = err_level_none;
|
||||
|
||||
#ifdef SRTP_KERNEL_LINUX
|
||||
err_status_t
|
||||
err_reporting_init(char *ident) {
|
||||
|
||||
return err_status_ok;
|
||||
}
|
||||
|
||||
#else /* SRTP_KERNEL_LINUX */
|
||||
|
||||
/* err_file is the FILE to which errors are reported */
|
||||
|
||||
static FILE *err_file = NULL;
|
||||
|
||||
err_status_t
|
||||
err_reporting_init(char *ident) {
|
||||
#ifdef ERR_REPORTING_SYSLOG
|
||||
openlog(ident, LOG_PID, LOG_AUTHPRIV);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Believe it or not, openlog doesn't return an error on failure.
|
||||
* But then, neither does the syslog() call...
|
||||
*/
|
||||
|
||||
#ifdef ERR_REPORTING_STDOUT
|
||||
err_file = stdout;
|
||||
#elif defined(USE_ERR_REPORTING_FILE)
|
||||
/* open file for error reporting */
|
||||
err_file = fopen(ERR_REPORTING_FILE, "w");
|
||||
if (err_file == NULL)
|
||||
return err_status_init_fail;
|
||||
#endif
|
||||
|
||||
return err_status_ok;
|
||||
}
|
||||
|
||||
void
|
||||
err_report(int priority, char *format, ...) {
|
||||
va_list args;
|
||||
|
||||
if (priority <= err_level) {
|
||||
|
||||
va_start(args, format);
|
||||
if (err_file != NULL) {
|
||||
vfprintf(err_file, format, args);
|
||||
/* fprintf(err_file, "\n"); */
|
||||
}
|
||||
#ifdef ERR_REPORTING_SYSLOG
|
||||
if (1) { /* FIXME: Make this a runtime option. */
|
||||
int syslogpri;
|
||||
|
||||
switch (priority) {
|
||||
case err_level_emergency:
|
||||
syslogpri = LOG_EMERG;
|
||||
break;
|
||||
case err_level_alert:
|
||||
syslogpri = LOG_ALERT;
|
||||
break;
|
||||
case err_level_critical:
|
||||
syslogpri = LOG_CRIT;
|
||||
break;
|
||||
case err_level_error:
|
||||
syslogpri = LOG_ERR;
|
||||
break;
|
||||
case err_level_warning:
|
||||
syslogpri = LOG_WARNING;
|
||||
break;
|
||||
case err_level_notice:
|
||||
syslogpri = LOG_NOTICE;
|
||||
break;
|
||||
case err_level_info:
|
||||
syslogpri = LOG_INFO;
|
||||
break;
|
||||
case err_level_debug:
|
||||
case err_level_none:
|
||||
default:
|
||||
syslogpri = LOG_DEBUG;
|
||||
break;
|
||||
}
|
||||
|
||||
vsyslog(syslogpri, format, args);
|
||||
#endif
|
||||
va_end(args);
|
||||
}
|
||||
}
|
||||
#endif /* SRTP_KERNEL_LINUX */
|
||||
|
||||
void
|
||||
err_reporting_set_level(err_reporting_level_t lvl) {
|
||||
err_level = lvl;
|
||||
}
|
||||
|
|
@ -1,115 +0,0 @@
|
|||
/*
|
||||
* key.c
|
||||
*
|
||||
* key usage limits enforcement
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "key.h"
|
||||
|
||||
#define soft_limit 0x10000
|
||||
|
||||
err_status_t
|
||||
key_limit_set(key_limit_t key, const xtd_seq_num_t s) {
|
||||
#ifdef NO_64BIT_MATH
|
||||
if (high32(s) == 0 && low32(s) < soft_limit)
|
||||
return err_status_bad_param;
|
||||
#else
|
||||
if (s < soft_limit)
|
||||
return err_status_bad_param;
|
||||
#endif
|
||||
key->num_left = s;
|
||||
key->state = key_state_normal;
|
||||
return err_status_ok;
|
||||
}
|
||||
|
||||
err_status_t
|
||||
key_limit_clone(key_limit_t original, key_limit_t *new_key) {
|
||||
if (original == NULL)
|
||||
return err_status_bad_param;
|
||||
*new_key = original;
|
||||
return err_status_ok;
|
||||
}
|
||||
|
||||
err_status_t
|
||||
key_limit_check(const key_limit_t key) {
|
||||
if (key->state == key_state_expired)
|
||||
return err_status_key_expired;
|
||||
return err_status_ok;
|
||||
}
|
||||
|
||||
key_event_t
|
||||
key_limit_update(key_limit_t key) {
|
||||
#ifdef NO_64BIT_MATH
|
||||
if (low32(key->num_left) == 0)
|
||||
{
|
||||
// carry
|
||||
key->num_left = make64(high32(key->num_left)-1,low32(key->num_left) - 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
// no carry
|
||||
key->num_left = make64(high32(key->num_left),low32(key->num_left) - 1);
|
||||
}
|
||||
if (high32(key->num_left) != 0 || low32(key->num_left) >= soft_limit) {
|
||||
return key_event_normal; /* we're above the soft limit */
|
||||
}
|
||||
#else
|
||||
key->num_left--;
|
||||
if (key->num_left >= soft_limit) {
|
||||
return key_event_normal; /* we're above the soft limit */
|
||||
}
|
||||
#endif
|
||||
if (key->state == key_state_normal) {
|
||||
/* we just passed the soft limit, so change the state */
|
||||
key->state = key_state_past_soft_limit;
|
||||
}
|
||||
#ifdef NO_64BIT_MATH
|
||||
if (low32(key->num_left) == 0 && high32(key->num_left == 0))
|
||||
#else
|
||||
if (key->num_left < 1)
|
||||
#endif
|
||||
{ /* we just hit the hard limit */
|
||||
key->state = key_state_expired;
|
||||
return key_event_hard_limit;
|
||||
}
|
||||
return key_event_soft_limit;
|
||||
}
|
||||
|
||||
|
|
@ -1,718 +0,0 @@
|
|||
/*
|
||||
* datatypes.c
|
||||
*
|
||||
* data types for finite fields and functions for input, output, and
|
||||
* manipulation
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "datatypes.h"
|
||||
|
||||
int
|
||||
octet_weight[256] = {
|
||||
0, 1, 1, 2, 1, 2, 2, 3,
|
||||
1, 2, 2, 3, 2, 3, 3, 4,
|
||||
1, 2, 2, 3, 2, 3, 3, 4,
|
||||
2, 3, 3, 4, 3, 4, 4, 5,
|
||||
1, 2, 2, 3, 2, 3, 3, 4,
|
||||
2, 3, 3, 4, 3, 4, 4, 5,
|
||||
2, 3, 3, 4, 3, 4, 4, 5,
|
||||
3, 4, 4, 5, 4, 5, 5, 6,
|
||||
1, 2, 2, 3, 2, 3, 3, 4,
|
||||
2, 3, 3, 4, 3, 4, 4, 5,
|
||||
2, 3, 3, 4, 3, 4, 4, 5,
|
||||
3, 4, 4, 5, 4, 5, 5, 6,
|
||||
2, 3, 3, 4, 3, 4, 4, 5,
|
||||
3, 4, 4, 5, 4, 5, 5, 6,
|
||||
3, 4, 4, 5, 4, 5, 5, 6,
|
||||
4, 5, 5, 6, 5, 6, 6, 7,
|
||||
1, 2, 2, 3, 2, 3, 3, 4,
|
||||
2, 3, 3, 4, 3, 4, 4, 5,
|
||||
2, 3, 3, 4, 3, 4, 4, 5,
|
||||
3, 4, 4, 5, 4, 5, 5, 6,
|
||||
2, 3, 3, 4, 3, 4, 4, 5,
|
||||
3, 4, 4, 5, 4, 5, 5, 6,
|
||||
3, 4, 4, 5, 4, 5, 5, 6,
|
||||
4, 5, 5, 6, 5, 6, 6, 7,
|
||||
2, 3, 3, 4, 3, 4, 4, 5,
|
||||
3, 4, 4, 5, 4, 5, 5, 6,
|
||||
3, 4, 4, 5, 4, 5, 5, 6,
|
||||
4, 5, 5, 6, 5, 6, 6, 7,
|
||||
3, 4, 4, 5, 4, 5, 5, 6,
|
||||
4, 5, 5, 6, 5, 6, 6, 7,
|
||||
4, 5, 5, 6, 5, 6, 6, 7,
|
||||
5, 6, 6, 7, 6, 7, 7, 8
|
||||
};
|
||||
|
||||
int
|
||||
octet_get_weight(uint8_t octet) {
|
||||
extern int octet_weight[256];
|
||||
|
||||
return octet_weight[octet];
|
||||
}
|
||||
|
||||
/*
|
||||
* bit_string is a buffer that is used to hold output strings, e.g.
|
||||
* for printing.
|
||||
*/
|
||||
|
||||
/* the value MAX_PRINT_STRING_LEN is defined in datatypes.h */
|
||||
|
||||
char bit_string[MAX_PRINT_STRING_LEN];
|
||||
|
||||
uint8_t
|
||||
nibble_to_hex_char(uint8_t nibble) {
|
||||
char buf[16] = {'0', '1', '2', '3', '4', '5', '6', '7',
|
||||
'8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
|
||||
return buf[nibble & 0xF];
|
||||
}
|
||||
|
||||
char *
|
||||
octet_string_hex_string(const void *s, int length) {
|
||||
const uint8_t *str = (const uint8_t *)s;
|
||||
int i;
|
||||
|
||||
/* double length, since one octet takes two hex characters */
|
||||
length *= 2;
|
||||
|
||||
/* truncate string if it would be too long */
|
||||
if (length > MAX_PRINT_STRING_LEN)
|
||||
length = MAX_PRINT_STRING_LEN-1;
|
||||
|
||||
for (i=0; i < length; i+=2) {
|
||||
bit_string[i] = nibble_to_hex_char(*str >> 4);
|
||||
bit_string[i+1] = nibble_to_hex_char(*str++ & 0xF);
|
||||
}
|
||||
bit_string[i] = 0; /* null terminate string */
|
||||
return bit_string;
|
||||
}
|
||||
|
||||
static inline int
|
||||
hex_char_to_nibble(uint8_t c) {
|
||||
switch(c) {
|
||||
case ('0'): return 0x0;
|
||||
case ('1'): return 0x1;
|
||||
case ('2'): return 0x2;
|
||||
case ('3'): return 0x3;
|
||||
case ('4'): return 0x4;
|
||||
case ('5'): return 0x5;
|
||||
case ('6'): return 0x6;
|
||||
case ('7'): return 0x7;
|
||||
case ('8'): return 0x8;
|
||||
case ('9'): return 0x9;
|
||||
case ('a'): return 0xa;
|
||||
case ('A'): return 0xa;
|
||||
case ('b'): return 0xb;
|
||||
case ('B'): return 0xb;
|
||||
case ('c'): return 0xc;
|
||||
case ('C'): return 0xc;
|
||||
case ('d'): return 0xd;
|
||||
case ('D'): return 0xd;
|
||||
case ('e'): return 0xe;
|
||||
case ('E'): return 0xe;
|
||||
case ('f'): return 0xf;
|
||||
case ('F'): return 0xf;
|
||||
default: return -1; /* this flags an error */
|
||||
}
|
||||
/* NOTREACHED */
|
||||
return -1; /* this keeps compilers from complaining */
|
||||
}
|
||||
|
||||
int
|
||||
is_hex_string(char *s) {
|
||||
while(*s != 0)
|
||||
if (hex_char_to_nibble(*s++) == -1)
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* hex_string_to_octet_string converts a hexadecimal string
|
||||
* of length 2 * len to a raw octet string of length len
|
||||
*/
|
||||
|
||||
int
|
||||
hex_string_to_octet_string(char *raw, char *hex, int len) {
|
||||
uint8_t x;
|
||||
int tmp;
|
||||
int hex_len;
|
||||
|
||||
hex_len = 0;
|
||||
while (hex_len < len) {
|
||||
tmp = hex_char_to_nibble(hex[0]);
|
||||
if (tmp == -1)
|
||||
return hex_len;
|
||||
x = (tmp << 4);
|
||||
hex_len++;
|
||||
tmp = hex_char_to_nibble(hex[1]);
|
||||
if (tmp == -1)
|
||||
return hex_len;
|
||||
x |= (tmp & 0xff);
|
||||
hex_len++;
|
||||
*raw++ = x;
|
||||
hex += 2;
|
||||
}
|
||||
return hex_len;
|
||||
}
|
||||
|
||||
char *
|
||||
v128_hex_string(v128_t *x) {
|
||||
int i, j;
|
||||
|
||||
for (i=j=0; i < 16; i++) {
|
||||
bit_string[j++] = nibble_to_hex_char(x->v8[i] >> 4);
|
||||
bit_string[j++] = nibble_to_hex_char(x->v8[i] & 0xF);
|
||||
}
|
||||
|
||||
bit_string[j] = 0; /* null terminate string */
|
||||
return bit_string;
|
||||
}
|
||||
|
||||
char *
|
||||
v128_bit_string(v128_t *x) {
|
||||
int j, i;
|
||||
uint32_t mask;
|
||||
|
||||
for (j=i=0; j < 4; j++) {
|
||||
for (mask=0x80000000; mask > 0; mask >>= 1) {
|
||||
if (x->v32[j] & mask)
|
||||
bit_string[i] = '1';
|
||||
else
|
||||
bit_string[i] = '0';
|
||||
++i;
|
||||
}
|
||||
}
|
||||
bit_string[128] = 0; /* null terminate string */
|
||||
|
||||
return bit_string;
|
||||
}
|
||||
|
||||
void
|
||||
v128_copy_octet_string(v128_t *x, const uint8_t s[16]) {
|
||||
#ifdef ALIGNMENT_32BIT_REQUIRED
|
||||
if ((((uint32_t) &s[0]) & 0x3) != 0)
|
||||
#endif
|
||||
{
|
||||
x->v8[0] = s[0];
|
||||
x->v8[1] = s[1];
|
||||
x->v8[2] = s[2];
|
||||
x->v8[3] = s[3];
|
||||
x->v8[4] = s[4];
|
||||
x->v8[5] = s[5];
|
||||
x->v8[6] = s[6];
|
||||
x->v8[7] = s[7];
|
||||
x->v8[8] = s[8];
|
||||
x->v8[9] = s[9];
|
||||
x->v8[10] = s[10];
|
||||
x->v8[11] = s[11];
|
||||
x->v8[12] = s[12];
|
||||
x->v8[13] = s[13];
|
||||
x->v8[14] = s[14];
|
||||
x->v8[15] = s[15];
|
||||
}
|
||||
#ifdef ALIGNMENT_32BIT_REQUIRED
|
||||
else
|
||||
{
|
||||
v128_t *v = (v128_t *) &s[0];
|
||||
|
||||
v128_copy(x,v);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef DATATYPES_USE_MACROS /* little functions are not macros */
|
||||
|
||||
void
|
||||
v128_set_to_zero(v128_t *x) {
|
||||
_v128_set_to_zero(x);
|
||||
}
|
||||
|
||||
void
|
||||
v128_copy(v128_t *x, const v128_t *y) {
|
||||
_v128_copy(x, y);
|
||||
}
|
||||
|
||||
void
|
||||
v128_xor(v128_t *z, v128_t *x, v128_t *y) {
|
||||
_v128_xor(z, x, y);
|
||||
}
|
||||
|
||||
void
|
||||
v128_and(v128_t *z, v128_t *x, v128_t *y) {
|
||||
_v128_and(z, x, y);
|
||||
}
|
||||
|
||||
void
|
||||
v128_or(v128_t *z, v128_t *x, v128_t *y) {
|
||||
_v128_or(z, x, y);
|
||||
}
|
||||
|
||||
void
|
||||
v128_complement(v128_t *x) {
|
||||
_v128_complement(x);
|
||||
}
|
||||
|
||||
int
|
||||
v128_is_eq(const v128_t *x, const v128_t *y) {
|
||||
return _v128_is_eq(x, y);
|
||||
}
|
||||
|
||||
int
|
||||
v128_xor_eq(v128_t *x, const v128_t *y) {
|
||||
return _v128_xor_eq(x, y);
|
||||
}
|
||||
|
||||
int
|
||||
v128_get_bit(const v128_t *x, int i) {
|
||||
return _v128_get_bit(x, i);
|
||||
}
|
||||
|
||||
void
|
||||
v128_set_bit(v128_t *x, int i) {
|
||||
_v128_set_bit(x, i);
|
||||
}
|
||||
|
||||
void
|
||||
v128_clear_bit(v128_t *x, int i){
|
||||
_v128_clear_bit(x, i);
|
||||
}
|
||||
|
||||
void
|
||||
v128_set_bit_to(v128_t *x, int i, int y){
|
||||
_v128_set_bit_to(x, i, y);
|
||||
}
|
||||
|
||||
|
||||
#endif /* DATATYPES_USE_MACROS */
|
||||
|
||||
void
|
||||
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 (shift > 127) {
|
||||
v128_set_to_zero(x);
|
||||
return;
|
||||
}
|
||||
|
||||
if (bit_index == 0) {
|
||||
|
||||
/* copy each word from left size to right side */
|
||||
x->v32[4-1] = x->v32[4-1-base_index];
|
||||
for (i=4-1; i > base_index; i--)
|
||||
x->v32[i-1] = x->v32[i-1-base_index];
|
||||
|
||||
} else {
|
||||
|
||||
/* set each word to the "or" of the two bit-shifted words */
|
||||
for (i = 4; i > base_index; i--) {
|
||||
from = i-1 - base_index;
|
||||
b = x->v32[from] << bit_index;
|
||||
if (from > 0)
|
||||
b |= x->v32[from-1] >> (32-bit_index);
|
||||
x->v32[i-1] = b;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* now wrap up the final portion */
|
||||
for (i=0; i < base_index; i++)
|
||||
x->v32[i] = 0;
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
v128_left_shift(v128_t *x, int shift) {
|
||||
int i;
|
||||
const int base_index = shift >> 5;
|
||||
const int bit_index = shift & 31;
|
||||
|
||||
if (shift > 127) {
|
||||
v128_set_to_zero(x);
|
||||
return;
|
||||
}
|
||||
|
||||
if (bit_index == 0) {
|
||||
for (i=0; i < 4 - base_index; i++)
|
||||
x->v32[i] = x->v32[i+base_index];
|
||||
} else {
|
||||
for (i=0; i < 4 - base_index - 1; i++)
|
||||
x->v32[i] = (x->v32[i+base_index] >> bit_index) ^
|
||||
(x->v32[i+base_index+1] << (32 - bit_index));
|
||||
x->v32[4 - base_index-1] = x->v32[4-1] >> bit_index;
|
||||
}
|
||||
|
||||
/* now wrap up the final portion */
|
||||
for (i = 4 - base_index; i < 4; i++)
|
||||
x->v32[i] = 0;
|
||||
|
||||
}
|
||||
|
||||
/* 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) {
|
||||
uint8_t *end = b + len;
|
||||
while (b < end)
|
||||
if (*a++ != *b++)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
octet_string_set_to_zero(uint8_t *s, int len) {
|
||||
uint8_t *end = s + len;
|
||||
|
||||
do {
|
||||
*s = 0;
|
||||
} while (++s < end);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* From RFC 1521: The Base64 Alphabet
|
||||
*
|
||||
* Value Encoding Value Encoding Value Encoding Value Encoding
|
||||
* 0 A 17 R 34 i 51 z
|
||||
* 1 B 18 S 35 j 52 0
|
||||
* 2 C 19 T 36 k 53 1
|
||||
* 3 D 20 U 37 l 54 2
|
||||
* 4 E 21 V 38 m 55 3
|
||||
* 5 F 22 W 39 n 56 4
|
||||
* 6 G 23 X 40 o 57 5
|
||||
* 7 H 24 Y 41 p 58 6
|
||||
* 8 I 25 Z 42 q 59 7
|
||||
* 9 J 26 a 43 r 60 8
|
||||
* 10 K 27 b 44 s 61 9
|
||||
* 11 L 28 c 45 t 62 +
|
||||
* 12 M 29 d 46 u 63 /
|
||||
* 13 N 30 e 47 v
|
||||
* 14 O 31 f 48 w (pad) =
|
||||
* 15 P 32 g 49 x
|
||||
* 16 Q 33 h 50 y
|
||||
*/
|
||||
|
||||
int
|
||||
base64_char_to_sextet(uint8_t c) {
|
||||
switch(c) {
|
||||
case 'A':
|
||||
return 0;
|
||||
case 'B':
|
||||
return 1;
|
||||
case 'C':
|
||||
return 2;
|
||||
case 'D':
|
||||
return 3;
|
||||
case 'E':
|
||||
return 4;
|
||||
case 'F':
|
||||
return 5;
|
||||
case 'G':
|
||||
return 6;
|
||||
case 'H':
|
||||
return 7;
|
||||
case 'I':
|
||||
return 8;
|
||||
case 'J':
|
||||
return 9;
|
||||
case 'K':
|
||||
return 10;
|
||||
case 'L':
|
||||
return 11;
|
||||
case 'M':
|
||||
return 12;
|
||||
case 'N':
|
||||
return 13;
|
||||
case 'O':
|
||||
return 14;
|
||||
case 'P':
|
||||
return 15;
|
||||
case 'Q':
|
||||
return 16;
|
||||
case 'R':
|
||||
return 17;
|
||||
case 'S':
|
||||
return 18;
|
||||
case 'T':
|
||||
return 19;
|
||||
case 'U':
|
||||
return 20;
|
||||
case 'V':
|
||||
return 21;
|
||||
case 'W':
|
||||
return 22;
|
||||
case 'X':
|
||||
return 23;
|
||||
case 'Y':
|
||||
return 24;
|
||||
case 'Z':
|
||||
return 25;
|
||||
case 'a':
|
||||
return 26;
|
||||
case 'b':
|
||||
return 27;
|
||||
case 'c':
|
||||
return 28;
|
||||
case 'd':
|
||||
return 29;
|
||||
case 'e':
|
||||
return 30;
|
||||
case 'f':
|
||||
return 31;
|
||||
case 'g':
|
||||
return 32;
|
||||
case 'h':
|
||||
return 33;
|
||||
case 'i':
|
||||
return 34;
|
||||
case 'j':
|
||||
return 35;
|
||||
case 'k':
|
||||
return 36;
|
||||
case 'l':
|
||||
return 37;
|
||||
case 'm':
|
||||
return 38;
|
||||
case 'n':
|
||||
return 39;
|
||||
case 'o':
|
||||
return 40;
|
||||
case 'p':
|
||||
return 41;
|
||||
case 'q':
|
||||
return 42;
|
||||
case 'r':
|
||||
return 43;
|
||||
case 's':
|
||||
return 44;
|
||||
case 't':
|
||||
return 45;
|
||||
case 'u':
|
||||
return 46;
|
||||
case 'v':
|
||||
return 47;
|
||||
case 'w':
|
||||
return 48;
|
||||
case 'x':
|
||||
return 49;
|
||||
case 'y':
|
||||
return 50;
|
||||
case 'z':
|
||||
return 51;
|
||||
case '0':
|
||||
return 52;
|
||||
case '1':
|
||||
return 53;
|
||||
case '2':
|
||||
return 54;
|
||||
case '3':
|
||||
return 55;
|
||||
case '4':
|
||||
return 56;
|
||||
case '5':
|
||||
return 57;
|
||||
case '6':
|
||||
return 58;
|
||||
case '7':
|
||||
return 59;
|
||||
case '8':
|
||||
return 60;
|
||||
case '9':
|
||||
return 61;
|
||||
case '+':
|
||||
return 62;
|
||||
case '/':
|
||||
return 63;
|
||||
case '=':
|
||||
return 64;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* base64_string_to_octet_string converts a hexadecimal string
|
||||
* of length 2 * len to a raw octet string of length len
|
||||
*/
|
||||
|
||||
int
|
||||
base64_string_to_octet_string(char *raw, char *base64, int len) {
|
||||
uint8_t x;
|
||||
int tmp;
|
||||
int base64_len;
|
||||
|
||||
base64_len = 0;
|
||||
while (base64_len < len) {
|
||||
tmp = base64_char_to_sextet(base64[0]);
|
||||
if (tmp == -1)
|
||||
return base64_len;
|
||||
x = (tmp << 6);
|
||||
base64_len++;
|
||||
tmp = base64_char_to_sextet(base64[1]);
|
||||
if (tmp == -1)
|
||||
return base64_len;
|
||||
x |= (tmp & 0xffff);
|
||||
base64_len++;
|
||||
*raw++ = x;
|
||||
base64 += 2;
|
||||
}
|
||||
return base64_len;
|
||||
}
|
||||
|
|
@ -1,83 +0,0 @@
|
|||
/*
|
||||
* gf2_8.c
|
||||
*
|
||||
* GF(256) finite field implementation, with the representation used
|
||||
* in the AES cipher.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include "datatypes.h"
|
||||
#include "gf2_8.h"
|
||||
|
||||
/* gf2_8_shift() moved to gf2_8.h as an inline function */
|
||||
|
||||
gf2_8
|
||||
gf2_8_multiply(gf2_8 x, gf2_8 y) {
|
||||
gf2_8 z = 0;
|
||||
|
||||
if (y & 1) z ^= x; x = gf2_8_shift(x);
|
||||
if (y & 2) z ^= x; x = gf2_8_shift(x);
|
||||
if (y & 4) z ^= x; x = gf2_8_shift(x);
|
||||
if (y & 8) z ^= x; x = gf2_8_shift(x);
|
||||
if (y & 16) z ^= x; x = gf2_8_shift(x);
|
||||
if (y & 32) z ^= x; x = gf2_8_shift(x);
|
||||
if (y & 64) z ^= x; x = gf2_8_shift(x);
|
||||
if (y & 128) z ^= x;
|
||||
|
||||
return z;
|
||||
}
|
||||
|
||||
|
||||
/* this should use the euclidean algorithm */
|
||||
|
||||
gf2_8
|
||||
gf2_8_compute_inverse(gf2_8 x) {
|
||||
unsigned int i;
|
||||
|
||||
if (x == 0) return 0; /* zero is a special case */
|
||||
for (i=0; i < 256; i++)
|
||||
if (gf2_8_multiply((gf2_8) i, x) == 1)
|
||||
return (gf2_8) i;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -1,802 +0,0 @@
|
|||
/*
|
||||
* math.c
|
||||
*
|
||||
* crypto math operations and data types
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "crypto_math.h"
|
||||
|
||||
int
|
||||
octet_weight[256] = {
|
||||
0, 1, 1, 2, 1, 2, 2, 3,
|
||||
1, 2, 2, 3, 2, 3, 3, 4,
|
||||
1, 2, 2, 3, 2, 3, 3, 4,
|
||||
2, 3, 3, 4, 3, 4, 4, 5,
|
||||
1, 2, 2, 3, 2, 3, 3, 4,
|
||||
2, 3, 3, 4, 3, 4, 4, 5,
|
||||
2, 3, 3, 4, 3, 4, 4, 5,
|
||||
3, 4, 4, 5, 4, 5, 5, 6,
|
||||
1, 2, 2, 3, 2, 3, 3, 4,
|
||||
2, 3, 3, 4, 3, 4, 4, 5,
|
||||
2, 3, 3, 4, 3, 4, 4, 5,
|
||||
3, 4, 4, 5, 4, 5, 5, 6,
|
||||
2, 3, 3, 4, 3, 4, 4, 5,
|
||||
3, 4, 4, 5, 4, 5, 5, 6,
|
||||
3, 4, 4, 5, 4, 5, 5, 6,
|
||||
4, 5, 5, 6, 5, 6, 6, 7,
|
||||
1, 2, 2, 3, 2, 3, 3, 4,
|
||||
2, 3, 3, 4, 3, 4, 4, 5,
|
||||
2, 3, 3, 4, 3, 4, 4, 5,
|
||||
3, 4, 4, 5, 4, 5, 5, 6,
|
||||
2, 3, 3, 4, 3, 4, 4, 5,
|
||||
3, 4, 4, 5, 4, 5, 5, 6,
|
||||
3, 4, 4, 5, 4, 5, 5, 6,
|
||||
4, 5, 5, 6, 5, 6, 6, 7,
|
||||
2, 3, 3, 4, 3, 4, 4, 5,
|
||||
3, 4, 4, 5, 4, 5, 5, 6,
|
||||
3, 4, 4, 5, 4, 5, 5, 6,
|
||||
4, 5, 5, 6, 5, 6, 6, 7,
|
||||
3, 4, 4, 5, 4, 5, 5, 6,
|
||||
4, 5, 5, 6, 5, 6, 6, 7,
|
||||
4, 5, 5, 6, 5, 6, 6, 7,
|
||||
5, 6, 6, 7, 6, 7, 7, 8
|
||||
};
|
||||
|
||||
int
|
||||
low_bit[256] = {
|
||||
-1, 0, 1, 0, 2, 0, 1, 0,
|
||||
3, 0, 1, 0, 2, 0, 1, 0,
|
||||
4, 0, 1, 0, 2, 0, 1, 0,
|
||||
3, 0, 1, 0, 2, 0, 1, 0,
|
||||
5, 0, 1, 0, 2, 0, 1, 0,
|
||||
3, 0, 1, 0, 2, 0, 1, 0,
|
||||
4, 0, 1, 0, 2, 0, 1, 0,
|
||||
3, 0, 1, 0, 2, 0, 1, 0,
|
||||
6, 0, 1, 0, 2, 0, 1, 0,
|
||||
3, 0, 1, 0, 2, 0, 1, 0,
|
||||
4, 0, 1, 0, 2, 0, 1, 0,
|
||||
3, 0, 1, 0, 2, 0, 1, 0,
|
||||
5, 0, 1, 0, 2, 0, 1, 0,
|
||||
3, 0, 1, 0, 2, 0, 1, 0,
|
||||
4, 0, 1, 0, 2, 0, 1, 0,
|
||||
3, 0, 1, 0, 2, 0, 1, 0,
|
||||
7, 0, 1, 0, 2, 0, 1, 0,
|
||||
3, 0, 1, 0, 2, 0, 1, 0,
|
||||
4, 0, 1, 0, 2, 0, 1, 0,
|
||||
3, 0, 1, 0, 2, 0, 1, 0,
|
||||
5, 0, 1, 0, 2, 0, 1, 0,
|
||||
3, 0, 1, 0, 2, 0, 1, 0,
|
||||
4, 0, 1, 0, 2, 0, 1, 0,
|
||||
3, 0, 1, 0, 2, 0, 1, 0,
|
||||
6, 0, 1, 0, 2, 0, 1, 0,
|
||||
3, 0, 1, 0, 2, 0, 1, 0,
|
||||
4, 0, 1, 0, 2, 0, 1, 0,
|
||||
3, 0, 1, 0, 2, 0, 1, 0,
|
||||
5, 0, 1, 0, 2, 0, 1, 0,
|
||||
3, 0, 1, 0, 2, 0, 1, 0,
|
||||
4, 0, 1, 0, 2, 0, 1, 0,
|
||||
3, 0, 1, 0, 2, 0, 1, 0
|
||||
};
|
||||
|
||||
|
||||
int
|
||||
high_bit[256] = {
|
||||
-1, 0, 1, 1, 2, 2, 2, 2,
|
||||
3, 3, 3, 3, 3, 3, 3, 3,
|
||||
4, 4, 4, 4, 4, 4, 4, 4,
|
||||
4, 4, 4, 4, 4, 4, 4, 4,
|
||||
5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5,
|
||||
6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6,
|
||||
7, 7, 7, 7, 7, 7, 7, 7,
|
||||
7, 7, 7, 7, 7, 7, 7, 7,
|
||||
7, 7, 7, 7, 7, 7, 7, 7,
|
||||
7, 7, 7, 7, 7, 7, 7, 7,
|
||||
7, 7, 7, 7, 7, 7, 7, 7,
|
||||
7, 7, 7, 7, 7, 7, 7, 7,
|
||||
7, 7, 7, 7, 7, 7, 7, 7,
|
||||
7, 7, 7, 7, 7, 7, 7, 7,
|
||||
7, 7, 7, 7, 7, 7, 7, 7,
|
||||
7, 7, 7, 7, 7, 7, 7, 7,
|
||||
7, 7, 7, 7, 7, 7, 7, 7,
|
||||
7, 7, 7, 7, 7, 7, 7, 7,
|
||||
7, 7, 7, 7, 7, 7, 7, 7,
|
||||
7, 7, 7, 7, 7, 7, 7, 7,
|
||||
7, 7, 7, 7, 7, 7, 7, 7,
|
||||
7, 7, 7, 7, 7, 7, 7, 7
|
||||
};
|
||||
|
||||
static int
|
||||
octet_get_weight(uint8_t octet) {
|
||||
extern int octet_weight[256];
|
||||
|
||||
return octet_weight[octet];
|
||||
}
|
||||
|
||||
unsigned char
|
||||
v32_weight(v32_t a) {
|
||||
unsigned int wt = 0;
|
||||
|
||||
wt += octet_weight[a.v8[0]]; /* note: endian-ness makes no difference */
|
||||
wt += octet_weight[a.v8[1]];
|
||||
wt += octet_weight[a.v8[2]];
|
||||
wt += octet_weight[a.v8[3]];
|
||||
|
||||
return wt;
|
||||
}
|
||||
|
||||
unsigned char
|
||||
v32_distance(v32_t x, v32_t y) {
|
||||
x.value ^= y.value;
|
||||
return v32_weight(x);
|
||||
}
|
||||
|
||||
unsigned int
|
||||
v32_dot_product(v32_t a, v32_t b) {
|
||||
a.value &= b.value;
|
||||
return v32_weight(a) & 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* _bit_string returns a NULL-terminated character string suitable for
|
||||
* printing
|
||||
*/
|
||||
|
||||
#define MAX_STRING_LENGTH 1024
|
||||
|
||||
char bit_string[MAX_STRING_LENGTH];
|
||||
|
||||
char *
|
||||
octet_bit_string(uint8_t x) {
|
||||
int mask, index;
|
||||
|
||||
for (mask = 1, index = 0; mask < 256; mask <<= 1)
|
||||
if ((x & mask) == 0)
|
||||
bit_string[index++] = '0';
|
||||
else
|
||||
bit_string[index++] = '1';
|
||||
|
||||
bit_string[index++] = 0; /* NULL terminate string */
|
||||
|
||||
return bit_string;
|
||||
}
|
||||
|
||||
char *
|
||||
v16_bit_string(v16_t x) {
|
||||
int i, mask, index;
|
||||
|
||||
for (i = index = 0; i < 2; i++) {
|
||||
for (mask = 1; mask < 256; mask <<= 1)
|
||||
if ((x.v8[i] & mask) == 0)
|
||||
bit_string[index++] = '0';
|
||||
else
|
||||
bit_string[index++] = '1';
|
||||
}
|
||||
bit_string[index++] = 0; /* NULL terminate string */
|
||||
return bit_string;
|
||||
}
|
||||
|
||||
char *
|
||||
v32_bit_string(v32_t x) {
|
||||
int i, mask, index;
|
||||
|
||||
for (i = index = 0; i < 4; i++) {
|
||||
for (mask = 128; mask > 0; mask >>= 1)
|
||||
if ((x.v8[i] & mask) == 0)
|
||||
bit_string[index++] = '0';
|
||||
else
|
||||
bit_string[index++] = '1';
|
||||
}
|
||||
bit_string[index++] = 0; /* NULL terminate string */
|
||||
return bit_string;
|
||||
}
|
||||
|
||||
char *
|
||||
v64_bit_string(const v64_t *x) {
|
||||
int i, mask, index;
|
||||
|
||||
for (i = index = 0; i < 8; i++) {
|
||||
for (mask = 1; mask < 256; mask <<= 1)
|
||||
if ((x->v8[i] & mask) == 0)
|
||||
bit_string[index++] = '0';
|
||||
else
|
||||
bit_string[index++] = '1';
|
||||
}
|
||||
bit_string[index++] = 0; /* NULL terminate string */
|
||||
return bit_string;
|
||||
}
|
||||
|
||||
char *
|
||||
v128_bit_string(v128_t *x) {
|
||||
int j, index;
|
||||
uint32_t mask;
|
||||
|
||||
for (j=index=0; j < 4; j++) {
|
||||
for (mask=0x80000000; mask > 0; mask >>= 1) {
|
||||
if (x->v32[j] & mask)
|
||||
bit_string[index] = '1';
|
||||
else
|
||||
bit_string[index] = '0';
|
||||
++index;
|
||||
}
|
||||
}
|
||||
bit_string[128] = 0; /* null terminate string */
|
||||
|
||||
return bit_string;
|
||||
}
|
||||
|
||||
static uint8_t
|
||||
nibble_to_hex_char(uint8_t nibble) {
|
||||
char buf[16] = {'0', '1', '2', '3', '4', '5', '6', '7',
|
||||
'8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
|
||||
return buf[nibble & 0xF];
|
||||
}
|
||||
|
||||
char *
|
||||
octet_hex_string(uint8_t x) {
|
||||
|
||||
bit_string[0] = nibble_to_hex_char(x >> 4);
|
||||
bit_string[1] = nibble_to_hex_char(x & 0xF);
|
||||
|
||||
bit_string[2] = 0; /* null terminate string */
|
||||
return bit_string;
|
||||
}
|
||||
|
||||
char *
|
||||
octet_string_hex_string(const void *str, int length) {
|
||||
const uint8_t *s = str;
|
||||
int i;
|
||||
|
||||
/* double length, since one octet takes two hex characters */
|
||||
length *= 2;
|
||||
|
||||
/* truncate string if it would be too long */
|
||||
if (length > MAX_STRING_LENGTH)
|
||||
length = MAX_STRING_LENGTH-1;
|
||||
|
||||
for (i=0; i < length; i+=2) {
|
||||
bit_string[i] = nibble_to_hex_char(*s >> 4);
|
||||
bit_string[i+1] = nibble_to_hex_char(*s++ & 0xF);
|
||||
}
|
||||
bit_string[i] = 0; /* null terminate string */
|
||||
return bit_string;
|
||||
}
|
||||
|
||||
char *
|
||||
v16_hex_string(v16_t x) {
|
||||
int i, j;
|
||||
|
||||
for (i=j=0; i < 2; i++) {
|
||||
bit_string[j++] = nibble_to_hex_char(x.v8[i] >> 4);
|
||||
bit_string[j++] = nibble_to_hex_char(x.v8[i] & 0xF);
|
||||
}
|
||||
|
||||
bit_string[j] = 0; /* null terminate string */
|
||||
return bit_string;
|
||||
}
|
||||
|
||||
char *
|
||||
v32_hex_string(v32_t x) {
|
||||
int i, j;
|
||||
|
||||
for (i=j=0; i < 4; i++) {
|
||||
bit_string[j++] = nibble_to_hex_char(x.v8[i] >> 4);
|
||||
bit_string[j++] = nibble_to_hex_char(x.v8[i] & 0xF);
|
||||
}
|
||||
|
||||
bit_string[j] = 0; /* null terminate string */
|
||||
return bit_string;
|
||||
}
|
||||
|
||||
char *
|
||||
v64_hex_string(const v64_t *x) {
|
||||
int i, j;
|
||||
|
||||
for (i=j=0; i < 8; i++) {
|
||||
bit_string[j++] = nibble_to_hex_char(x->v8[i] >> 4);
|
||||
bit_string[j++] = nibble_to_hex_char(x->v8[i] & 0xF);
|
||||
}
|
||||
|
||||
bit_string[j] = 0; /* null terminate string */
|
||||
return bit_string;
|
||||
}
|
||||
|
||||
char *
|
||||
v128_hex_string(v128_t *x) {
|
||||
int i, j;
|
||||
|
||||
for (i=j=0; i < 16; i++) {
|
||||
bit_string[j++] = nibble_to_hex_char(x->v8[i] >> 4);
|
||||
bit_string[j++] = nibble_to_hex_char(x->v8[i] & 0xF);
|
||||
}
|
||||
|
||||
bit_string[j] = 0; /* null terminate string */
|
||||
return bit_string;
|
||||
}
|
||||
|
||||
char *
|
||||
char_to_hex_string(char *x, int num_char) {
|
||||
int i, j;
|
||||
|
||||
if (num_char >= 16)
|
||||
num_char = 16;
|
||||
for (i=j=0; i < num_char; i++) {
|
||||
bit_string[j++] = nibble_to_hex_char(x[i] >> 4);
|
||||
bit_string[j++] = nibble_to_hex_char(x[i] & 0xF);
|
||||
}
|
||||
|
||||
bit_string[j] = 0; /* null terminate string */
|
||||
return bit_string;
|
||||
}
|
||||
|
||||
int
|
||||
hex_char_to_nibble(uint8_t c) {
|
||||
switch(c) {
|
||||
case ('0'): return 0x0;
|
||||
case ('1'): return 0x1;
|
||||
case ('2'): return 0x2;
|
||||
case ('3'): return 0x3;
|
||||
case ('4'): return 0x4;
|
||||
case ('5'): return 0x5;
|
||||
case ('6'): return 0x6;
|
||||
case ('7'): return 0x7;
|
||||
case ('8'): return 0x8;
|
||||
case ('9'): return 0x9;
|
||||
case ('a'): return 0xa;
|
||||
case ('A'): return 0xa;
|
||||
case ('b'): return 0xb;
|
||||
case ('B'): return 0xb;
|
||||
case ('c'): return 0xc;
|
||||
case ('C'): return 0xc;
|
||||
case ('d'): return 0xd;
|
||||
case ('D'): return 0xd;
|
||||
case ('e'): return 0xe;
|
||||
case ('E'): return 0xe;
|
||||
case ('f'): return 0xf;
|
||||
case ('F'): return 0xf;
|
||||
default: return -1; /* this flags an error */
|
||||
}
|
||||
/* NOTREACHED */
|
||||
return -1; /* this keeps compilers from complaining */
|
||||
}
|
||||
|
||||
int
|
||||
is_hex_string(char *s) {
|
||||
while(*s != 0)
|
||||
if (hex_char_to_nibble(*s++) == -1)
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
uint8_t
|
||||
hex_string_to_octet(char *s) {
|
||||
uint8_t x;
|
||||
|
||||
x = (hex_char_to_nibble(s[0]) << 4)
|
||||
| hex_char_to_nibble(s[1] & 0xFF);
|
||||
|
||||
return x;
|
||||
}
|
||||
|
||||
/*
|
||||
* hex_string_to_octet_string converts a hexadecimal string
|
||||
* of length 2 * len to a raw octet string of length len
|
||||
*/
|
||||
|
||||
static int
|
||||
hex_string_to_octet_string(char *raw, char *hex, int len) {
|
||||
uint8_t x;
|
||||
int tmp;
|
||||
int hex_len;
|
||||
|
||||
hex_len = 0;
|
||||
while (hex_len < len) {
|
||||
tmp = hex_char_to_nibble(hex[0]);
|
||||
if (tmp == -1)
|
||||
return hex_len;
|
||||
x = (tmp << 4);
|
||||
hex_len++;
|
||||
tmp = hex_char_to_nibble(hex[1]);
|
||||
if (tmp == -1)
|
||||
return hex_len;
|
||||
x |= (tmp & 0xff);
|
||||
hex_len++;
|
||||
*raw++ = x;
|
||||
hex += 2;
|
||||
}
|
||||
return hex_len;
|
||||
}
|
||||
|
||||
v16_t
|
||||
hex_string_to_v16(char *s) {
|
||||
v16_t x;
|
||||
int i, j;
|
||||
|
||||
for (i=j=0; i < 4; i += 2, j++) {
|
||||
x.v8[j] = (hex_char_to_nibble(s[i]) << 4)
|
||||
| hex_char_to_nibble(s[i+1] & 0xFF);
|
||||
}
|
||||
return x;
|
||||
}
|
||||
|
||||
v32_t
|
||||
hex_string_to_v32(char *s) {
|
||||
v32_t x;
|
||||
int i, j;
|
||||
|
||||
for (i=j=0; i < 8; i += 2, j++) {
|
||||
x.v8[j] = (hex_char_to_nibble(s[i]) << 4)
|
||||
| hex_char_to_nibble(s[i+1] & 0xFF);
|
||||
}
|
||||
return x;
|
||||
}
|
||||
|
||||
v64_t
|
||||
hex_string_to_v64(char *s) {
|
||||
v64_t x;
|
||||
int i, j;
|
||||
|
||||
for (i=j=0; i < 16; i += 2, j++) {
|
||||
x.v8[j] = (hex_char_to_nibble(s[i]) << 4)
|
||||
| hex_char_to_nibble(s[i+1] & 0xFF);
|
||||
}
|
||||
return x;
|
||||
}
|
||||
|
||||
v128_t
|
||||
hex_string_to_v128(char *s) {
|
||||
v128_t x;
|
||||
int i, j;
|
||||
|
||||
for (i=j=0; i < 32; i += 2, j++) {
|
||||
x.v8[j] = (hex_char_to_nibble(s[i]) << 4)
|
||||
| hex_char_to_nibble(s[i+1] & 0xFF);
|
||||
}
|
||||
return x;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* the matrix A[] is stored in column format, i.e., A[i] is the ith
|
||||
* column of the matrix
|
||||
*/
|
||||
|
||||
uint8_t
|
||||
A_times_x_plus_b(uint8_t A[8], uint8_t x, uint8_t b) {
|
||||
int index = 0;
|
||||
unsigned mask;
|
||||
|
||||
for (mask=1; mask < 256; mask *= 2) {
|
||||
if (x & mask)
|
||||
b^= A[index];
|
||||
++index;
|
||||
}
|
||||
|
||||
return b;
|
||||
}
|
||||
|
||||
void
|
||||
v16_copy_octet_string(v16_t *x, const uint8_t s[2]) {
|
||||
x->v8[0] = s[0];
|
||||
x->v8[1] = s[1];
|
||||
}
|
||||
|
||||
void
|
||||
v32_copy_octet_string(v32_t *x, const uint8_t s[4]) {
|
||||
x->v8[0] = s[0];
|
||||
x->v8[1] = s[1];
|
||||
x->v8[2] = s[2];
|
||||
x->v8[3] = s[3];
|
||||
}
|
||||
|
||||
void
|
||||
v64_copy_octet_string(v64_t *x, const uint8_t s[8]) {
|
||||
x->v8[0] = s[0];
|
||||
x->v8[1] = s[1];
|
||||
x->v8[2] = s[2];
|
||||
x->v8[3] = s[3];
|
||||
x->v8[4] = s[4];
|
||||
x->v8[5] = s[5];
|
||||
x->v8[6] = s[6];
|
||||
x->v8[7] = s[7];
|
||||
}
|
||||
|
||||
void
|
||||
v128_copy_octet_string(v128_t *x, const uint8_t s[16]) {
|
||||
x->v8[0] = s[0];
|
||||
x->v8[1] = s[1];
|
||||
x->v8[2] = s[2];
|
||||
x->v8[3] = s[3];
|
||||
x->v8[4] = s[4];
|
||||
x->v8[5] = s[5];
|
||||
x->v8[6] = s[6];
|
||||
x->v8[7] = s[7];
|
||||
x->v8[8] = s[8];
|
||||
x->v8[9] = s[9];
|
||||
x->v8[10] = s[10];
|
||||
x->v8[11] = s[11];
|
||||
x->v8[12] = s[12];
|
||||
x->v8[13] = s[13];
|
||||
x->v8[14] = s[14];
|
||||
x->v8[15] = s[15];
|
||||
|
||||
}
|
||||
|
||||
#ifndef DATATYPES_USE_MACROS /* little functions are not macros */
|
||||
|
||||
void
|
||||
v128_set_to_zero(v128_t *x) {
|
||||
_v128_set_to_zero(x);
|
||||
}
|
||||
|
||||
void
|
||||
v128_copy(v128_t *x, const v128_t *y) {
|
||||
_v128_copy(x, y);
|
||||
}
|
||||
|
||||
void
|
||||
v128_xor(v128_t *z, v128_t *x, v128_t *y) {
|
||||
_v128_xor(z, x, y);
|
||||
}
|
||||
|
||||
void
|
||||
v128_and(v128_t *z, v128_t *x, v128_t *y) {
|
||||
_v128_and(z, x, y);
|
||||
}
|
||||
|
||||
void
|
||||
v128_or(v128_t *z, v128_t *x, v128_t *y) {
|
||||
_v128_or(z, x, y);
|
||||
}
|
||||
|
||||
void
|
||||
v128_complement(v128_t *x) {
|
||||
_v128_complement(x);
|
||||
}
|
||||
|
||||
int
|
||||
v128_is_eq(const v128_t *x, const v128_t *y) {
|
||||
return _v128_is_eq(x, y);
|
||||
}
|
||||
|
||||
int
|
||||
v128_get_bit(const v128_t *x, int i) {
|
||||
return _v128_get_bit(x, i);
|
||||
}
|
||||
|
||||
void
|
||||
v128_set_bit(v128_t *x, int i) {
|
||||
_v128_set_bit(x, i);
|
||||
}
|
||||
|
||||
void
|
||||
v128_clear_bit(v128_t *x, int i){
|
||||
_v128_clear_bit(x, i);
|
||||
}
|
||||
|
||||
void
|
||||
v128_set_bit_to(v128_t *x, int i, int y){
|
||||
_v128_set_bit_to(x, i, y);
|
||||
}
|
||||
|
||||
|
||||
#endif /* DATATYPES_USE_MACROS */
|
||||
|
||||
|
||||
static inline void
|
||||
v128_left_shift2(v128_t *x, int num_bits) {
|
||||
int i;
|
||||
int word_shift = num_bits >> 5;
|
||||
int bit_shift = num_bits & 31;
|
||||
|
||||
for (i=0; i < (4-word_shift); i++) {
|
||||
x->v32[i] = x->v32[i+word_shift] << bit_shift;
|
||||
}
|
||||
|
||||
for ( ; i < word_shift; i++) {
|
||||
x->v32[i] = 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
v128_right_shift(v128_t *x, int index) {
|
||||
const int base_index = index >> 5;
|
||||
const int bit_index = index & 31;
|
||||
int i, from;
|
||||
uint32_t b;
|
||||
|
||||
if (index > 127) {
|
||||
v128_set_to_zero(x);
|
||||
return;
|
||||
}
|
||||
|
||||
if (bit_index == 0) {
|
||||
|
||||
/* copy each word from left size to right side */
|
||||
x->v32[4-1] = x->v32[4-1-base_index];
|
||||
for (i=4-1; i > base_index; i--)
|
||||
x->v32[i-1] = x->v32[i-1-base_index];
|
||||
|
||||
} else {
|
||||
|
||||
/* set each word to the "or" of the two bit-shifted words */
|
||||
for (i = 4; i > base_index; i--) {
|
||||
from = i-1 - base_index;
|
||||
b = x->v32[from] << bit_index;
|
||||
if (from > 0)
|
||||
b |= x->v32[from-1] >> (32-bit_index);
|
||||
x->v32[i-1] = b;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* now wrap up the final portion */
|
||||
for (i=0; i < base_index; i++)
|
||||
x->v32[i] = 0;
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
v128_left_shift(v128_t *x, int index) {
|
||||
int i;
|
||||
const int base_index = index >> 5;
|
||||
const int bit_index = index & 31;
|
||||
|
||||
if (index > 127) {
|
||||
v128_set_to_zero(x);
|
||||
return;
|
||||
}
|
||||
|
||||
if (bit_index == 0) {
|
||||
for (i=0; i < 4 - base_index; i++)
|
||||
x->v32[i] = x->v32[i+base_index];
|
||||
} else {
|
||||
for (i=0; i < 4 - base_index - 1; i++)
|
||||
x->v32[i] = (x->v32[i+base_index] << bit_index) ^
|
||||
(x->v32[i+base_index+1] >> (32 - bit_index));
|
||||
x->v32[4 - base_index-1] = x->v32[4-1] << bit_index;
|
||||
}
|
||||
|
||||
/* now wrap up the final portion */
|
||||
for (i = 4 - base_index; i < 4; i++)
|
||||
x->v32[i] = 0;
|
||||
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
void
|
||||
v128_add(v128_t *z, v128_t *x, v128_t *y) {
|
||||
/* integer addition modulo 2^128 */
|
||||
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
uint64_t tmp;
|
||||
|
||||
tmp = x->v32[3] + y->v32[3];
|
||||
z->v32[3] = (uint32_t) tmp;
|
||||
|
||||
tmp = x->v32[2] + y->v32[2] + (tmp >> 32);
|
||||
z->v32[2] = (uint32_t) tmp;
|
||||
|
||||
tmp = x->v32[1] + y->v32[1] + (tmp >> 32);
|
||||
z->v32[1] = (uint32_t) tmp;
|
||||
|
||||
tmp = x->v32[0] + y->v32[0] + (tmp >> 32);
|
||||
z->v32[0] = (uint32_t) tmp;
|
||||
|
||||
#else /* assume little endian architecture */
|
||||
uint64_t tmp;
|
||||
|
||||
tmp = htonl(x->v32[3]) + htonl(y->v32[3]);
|
||||
z->v32[3] = ntohl((uint32_t) tmp);
|
||||
|
||||
tmp = htonl(x->v32[2]) + htonl(y->v32[2]) + htonl(tmp >> 32);
|
||||
z->v32[2] = ntohl((uint32_t) tmp);
|
||||
|
||||
tmp = htonl(x->v32[1]) + htonl(y->v32[1]) + htonl(tmp >> 32);
|
||||
z->v32[1] = ntohl((uint32_t) tmp);
|
||||
|
||||
tmp = htonl(x->v32[0]) + htonl(y->v32[0]) + htonl(tmp >> 32);
|
||||
z->v32[0] = ntohl((uint32_t) tmp);
|
||||
|
||||
#endif /* WORDS_BIGENDIAN */
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
static int
|
||||
octet_string_is_eq(uint8_t *a, uint8_t *b, int len) {
|
||||
uint8_t *end = b + len;
|
||||
while (b < end)
|
||||
if (*a++ != *b++)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
octet_string_set_to_zero(uint8_t *s, int len) {
|
||||
uint8_t *end = s + len;
|
||||
|
||||
do {
|
||||
*s = 0;
|
||||
} while (++s < end);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* functions below not yet tested! */
|
||||
|
||||
int
|
||||
v32_low_bit(v32_t *w) {
|
||||
int value;
|
||||
|
||||
value = low_bit[w->v8[0]];
|
||||
if (value != -1)
|
||||
return value;
|
||||
value = low_bit[w->v8[1]];
|
||||
if (value != -1)
|
||||
return value + 8;
|
||||
value = low_bit[w->v8[2]];
|
||||
if (value != -1)
|
||||
return value + 16;
|
||||
value = low_bit[w->v8[3]];
|
||||
if (value == -1)
|
||||
return -1;
|
||||
return value + 24;
|
||||
}
|
||||
|
||||
/* high_bit not done yet */
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -1,367 +0,0 @@
|
|||
/*
|
||||
* stats.c
|
||||
*
|
||||
* statistical tests for randomness (FIPS 140-2, Section 4.9)
|
||||
*
|
||||
* David A. McGrew
|
||||
* Cisco Systems, Inc.
|
||||
*/
|
||||
|
||||
#include "stat.h"
|
||||
|
||||
debug_module_t mod_stat = {
|
||||
0, /* debugging is off by default */
|
||||
(char *)"stat test" /* printable module name */
|
||||
};
|
||||
|
||||
/*
|
||||
* each test assumes that 20,000 bits (2500 octets) of data is
|
||||
* provided as input
|
||||
*/
|
||||
|
||||
#define STAT_TEST_DATA_LEN 2500
|
||||
|
||||
err_status_t
|
||||
stat_test_monobit(uint8_t *data) {
|
||||
uint8_t *data_end = data + STAT_TEST_DATA_LEN;
|
||||
uint16_t ones_count;
|
||||
|
||||
ones_count = 0;
|
||||
while (data < data_end) {
|
||||
ones_count += octet_get_weight(*data);
|
||||
data++;
|
||||
}
|
||||
|
||||
debug_print(mod_stat, "bit count: %d", ones_count);
|
||||
|
||||
if ((ones_count < 9725) || (ones_count > 10275))
|
||||
return err_status_algo_fail;
|
||||
|
||||
return err_status_ok;
|
||||
}
|
||||
|
||||
err_status_t
|
||||
stat_test_poker(uint8_t *data) {
|
||||
int i;
|
||||
uint8_t *data_end = data + STAT_TEST_DATA_LEN;
|
||||
double poker;
|
||||
uint16_t f[16] = {
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0
|
||||
};
|
||||
|
||||
while (data < data_end) {
|
||||
f[*data & 0x0f]++; /* increment freq. count for low nibble */
|
||||
f[(*data) >> 4]++; /* increment freq. count for high nibble */
|
||||
data++;
|
||||
}
|
||||
|
||||
poker = 0.0;
|
||||
for (i=0; i < 16; i++)
|
||||
poker += (double) f[i] * f[i];
|
||||
|
||||
poker *= (16.0 / 5000.0);
|
||||
poker -= 5000.0;
|
||||
|
||||
debug_print(mod_stat, "poker test: %f\n", poker);
|
||||
|
||||
if ((poker < 2.16) || (poker > 46.17))
|
||||
return err_status_algo_fail;
|
||||
|
||||
return err_status_ok;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* runs[i] holds the number of runs of size (i-1)
|
||||
*/
|
||||
|
||||
err_status_t
|
||||
stat_test_runs(uint8_t *data) {
|
||||
uint8_t *data_end = data + STAT_TEST_DATA_LEN;
|
||||
uint16_t runs[6] = { 0, 0, 0, 0, 0, 0 };
|
||||
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 };
|
||||
int state = 0;
|
||||
uint16_t mask;
|
||||
int i;
|
||||
|
||||
/*
|
||||
* the state variable holds the number of bits in the
|
||||
* current run (or gap, if negative)
|
||||
*/
|
||||
|
||||
while (data < data_end) {
|
||||
|
||||
/* loop over the bits of this byte */
|
||||
for (mask = 1; mask < 256; mask <<= 1) {
|
||||
if (*data & mask) {
|
||||
|
||||
/* next bit is a one */
|
||||
if (state > 0) {
|
||||
|
||||
/* prefix is a run, so increment the run-count */
|
||||
state++;
|
||||
|
||||
/* check for long runs */
|
||||
if (state > 25) {
|
||||
debug_print(mod_stat, ">25 runs: %d", state);
|
||||
return err_status_algo_fail;
|
||||
}
|
||||
|
||||
} else if (state < 0) {
|
||||
|
||||
/* prefix is a gap */
|
||||
if (state < -25) {
|
||||
debug_print(mod_stat, ">25 gaps: %d", state);
|
||||
return err_status_algo_fail; /* long-runs test failed */
|
||||
}
|
||||
if (state < -6) {
|
||||
state = -6; /* group together gaps > 5 */
|
||||
}
|
||||
gaps[-1-state]++; /* increment gap count */
|
||||
state = 1; /* set state at one set bit */
|
||||
} else {
|
||||
|
||||
/* state is zero; this happens only at initialization */
|
||||
state = 1;
|
||||
}
|
||||
} else {
|
||||
|
||||
/* next bit is a zero */
|
||||
if (state > 0) {
|
||||
|
||||
/* prefix is a run */
|
||||
if (state > 25) {
|
||||
debug_print(mod_stat, ">25 runs (2): %d", state);
|
||||
return err_status_algo_fail; /* long-runs test failed */
|
||||
}
|
||||
if (state > 6) {
|
||||
state = 6; /* group together runs > 5 */
|
||||
}
|
||||
runs[state-1]++; /* increment run count */
|
||||
state = -1; /* set state at one zero bit */
|
||||
} else if (state < 0) {
|
||||
|
||||
/* prefix is a gap, so increment gap-count (decrement state) */
|
||||
state--;
|
||||
|
||||
/* check for long gaps */
|
||||
if (state < -25) {
|
||||
debug_print(mod_stat, ">25 gaps (2): %d", state);
|
||||
return err_status_algo_fail;
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
/* state is zero; this happens only at initialization */
|
||||
state = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* move along to next octet */
|
||||
data++;
|
||||
}
|
||||
|
||||
if (mod_stat.on) {
|
||||
debug_print(mod_stat, "runs test", NULL);
|
||||
for (i=0; i < 6; i++)
|
||||
debug_print(mod_stat, " runs[]: %d", runs[i]);
|
||||
for (i=0; i < 6; i++)
|
||||
debug_print(mod_stat, " gaps[]: %d", gaps[i]);
|
||||
}
|
||||
|
||||
/* check run and gap counts against the fixed limits */
|
||||
for (i=0; i < 6; i++)
|
||||
if ( (runs[i] < lo_value[i] ) || (runs[i] > hi_value[i])
|
||||
|| (gaps[i] < lo_value[i] ) || (gaps[i] > hi_value[i]))
|
||||
return err_status_algo_fail;
|
||||
|
||||
|
||||
return err_status_ok;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* the function stat_test_rand_source applys the FIPS-140-2 statistical
|
||||
* tests to the random source defined by rs
|
||||
*
|
||||
*/
|
||||
|
||||
#define RAND_SRC_BUF_OCTETS 50 /* this value MUST divide 2500! */
|
||||
|
||||
err_status_t
|
||||
stat_test_rand_source(rand_source_func_t get_rand_bytes) {
|
||||
int i;
|
||||
double poker;
|
||||
uint8_t *data, *data_end;
|
||||
uint16_t f[16] = {
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0
|
||||
};
|
||||
uint8_t buffer[RAND_SRC_BUF_OCTETS];
|
||||
err_status_t status;
|
||||
int ones_count = 0;
|
||||
uint16_t runs[6] = { 0, 0, 0, 0, 0, 0 };
|
||||
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 };
|
||||
int state = 0;
|
||||
uint16_t mask;
|
||||
|
||||
/* counters for monobit, poker, and runs tests are initialized above */
|
||||
|
||||
/* main loop: fill buffer, update counters for stat tests */
|
||||
for (i=0; i < 2500; i+=RAND_SRC_BUF_OCTETS) {
|
||||
|
||||
/* fill data buffer */
|
||||
status = get_rand_bytes(buffer, RAND_SRC_BUF_OCTETS);
|
||||
if (status) {
|
||||
debug_print(mod_stat, "couldn't get rand bytes: %d",status);
|
||||
return status;
|
||||
}
|
||||
|
||||
#if 0
|
||||
debug_print(mod_stat, "%s",
|
||||
octet_string_hex_string(buffer, RAND_SRC_BUF_OCTETS));
|
||||
#endif
|
||||
|
||||
data = buffer;
|
||||
data_end = data + RAND_SRC_BUF_OCTETS;
|
||||
while (data < data_end) {
|
||||
|
||||
/* update monobit test counter */
|
||||
ones_count += octet_get_weight(*data);
|
||||
|
||||
/* update poker test counters */
|
||||
f[*data & 0x0f]++; /* increment freq. count for low nibble */
|
||||
f[(*data) >> 4]++; /* increment freq. count for high nibble */
|
||||
|
||||
/* update runs test counters */
|
||||
/* loop over the bits of this byte */
|
||||
for (mask = 1; mask < 256; mask <<= 1) {
|
||||
if (*data & mask) {
|
||||
|
||||
/* next bit is a one */
|
||||
if (state > 0) {
|
||||
|
||||
/* prefix is a run, so increment the run-count */
|
||||
state++;
|
||||
|
||||
/* check for long runs */
|
||||
if (state > 25) {
|
||||
debug_print(mod_stat, ">25 runs (3): %d", state);
|
||||
return err_status_algo_fail;
|
||||
}
|
||||
|
||||
} else if (state < 0) {
|
||||
|
||||
/* prefix is a gap */
|
||||
if (state < -25) {
|
||||
debug_print(mod_stat, ">25 gaps (3): %d", state);
|
||||
return err_status_algo_fail; /* long-runs test failed */
|
||||
}
|
||||
if (state < -6) {
|
||||
state = -6; /* group together gaps > 5 */
|
||||
}
|
||||
gaps[-1-state]++; /* increment gap count */
|
||||
state = 1; /* set state at one set bit */
|
||||
} else {
|
||||
|
||||
/* state is zero; this happens only at initialization */
|
||||
state = 1;
|
||||
}
|
||||
} else {
|
||||
|
||||
/* next bit is a zero */
|
||||
if (state > 0) {
|
||||
|
||||
/* prefix is a run */
|
||||
if (state > 25) {
|
||||
debug_print(mod_stat, ">25 runs (4): %d", state);
|
||||
return err_status_algo_fail; /* long-runs test failed */
|
||||
}
|
||||
if (state > 6) {
|
||||
state = 6; /* group together runs > 5 */
|
||||
}
|
||||
runs[state-1]++; /* increment run count */
|
||||
state = -1; /* set state at one zero bit */
|
||||
} else if (state < 0) {
|
||||
|
||||
/* prefix is a gap, so increment gap-count (decrement state) */
|
||||
state--;
|
||||
|
||||
/* check for long gaps */
|
||||
if (state < -25) {
|
||||
debug_print(mod_stat, ">25 gaps (4): %d", state);
|
||||
return err_status_algo_fail;
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
/* state is zero; this happens only at initialization */
|
||||
state = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* advance data pointer */
|
||||
data++;
|
||||
}
|
||||
}
|
||||
|
||||
/* check to see if test data is within bounds */
|
||||
|
||||
/* check monobit test data */
|
||||
|
||||
debug_print(mod_stat, "stat: bit count: %d", ones_count);
|
||||
|
||||
if ((ones_count < 9725) || (ones_count > 10275)) {
|
||||
debug_print(mod_stat, "stat: failed monobit test %d", ones_count);
|
||||
return err_status_algo_fail;
|
||||
}
|
||||
|
||||
/* check poker test data */
|
||||
poker = 0.0;
|
||||
for (i=0; i < 16; i++)
|
||||
poker += (double) f[i] * f[i];
|
||||
|
||||
poker *= (16.0 / 5000.0);
|
||||
poker -= 5000.0;
|
||||
|
||||
debug_print(mod_stat, "stat: poker test: %f", poker);
|
||||
|
||||
if ((poker < 2.16) || (poker > 46.17)) {
|
||||
debug_print(mod_stat, "stat: failed poker test", NULL);
|
||||
return err_status_algo_fail;
|
||||
}
|
||||
|
||||
/* check run and gap counts against the fixed limits */
|
||||
for (i=0; i < 6; i++)
|
||||
if ((runs[i] < lo_value[i] ) || (runs[i] > hi_value[i])
|
||||
|| (gaps[i] < lo_value[i] ) || (gaps[i] > hi_value[i])) {
|
||||
debug_print(mod_stat, "stat: failed run/gap test", NULL);
|
||||
return err_status_algo_fail;
|
||||
}
|
||||
|
||||
debug_print(mod_stat, "passed random stat test", NULL);
|
||||
return err_status_ok;
|
||||
}
|
||||
|
||||
err_status_t
|
||||
stat_test_rand_source_with_repetition(rand_source_func_t source, unsigned num_trials) {
|
||||
unsigned int i;
|
||||
err_status_t err = err_status_algo_fail;
|
||||
|
||||
for (i=0; i < num_trials; i++) {
|
||||
err = stat_test_rand_source(source);
|
||||
if (err == err_status_ok) {
|
||||
return err_status_ok;
|
||||
}
|
||||
debug_print(mod_stat, "failed stat test (try number %d)\n", i);
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
|
@ -1,137 +0,0 @@
|
|||
/*
|
||||
* rdb.c
|
||||
*
|
||||
* Implements a replay database for packet security
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include "rdb.h"
|
||||
|
||||
|
||||
/*
|
||||
* this implementation of a replay database works as follows:
|
||||
*
|
||||
* window_start is the index of the first packet in the window
|
||||
* bitmask a bit-buffer, containing the most recently entered
|
||||
* index as the leftmost bit
|
||||
*
|
||||
*/
|
||||
|
||||
/* rdb_init initalizes rdb */
|
||||
|
||||
err_status_t
|
||||
rdb_init(rdb_t *rdb) {
|
||||
v128_set_to_zero(&rdb->bitmask);
|
||||
rdb->window_start = 0;
|
||||
return err_status_ok;
|
||||
}
|
||||
|
||||
/*
|
||||
* rdb_check checks to see if index appears in rdb
|
||||
*/
|
||||
|
||||
err_status_t
|
||||
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 (p_index >= rdb->window_start + rdb_bits_in_bitmask)
|
||||
return err_status_ok;
|
||||
|
||||
/* if the index appears before the window, its bad */
|
||||
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, (p_index - rdb->window_start)) == 1)
|
||||
return err_status_replay_fail;
|
||||
|
||||
/* otherwise, the index is okay */
|
||||
return err_status_ok;
|
||||
}
|
||||
|
||||
/*
|
||||
* rdb_add_index adds index to rdb_t (and does *not* check if
|
||||
* index appears in db)
|
||||
*
|
||||
* this function should be called only after rdb_check has
|
||||
* indicated that the index does not appear in the rdb, e.g., a mutex
|
||||
* should protect the rdb between these calls
|
||||
*/
|
||||
|
||||
err_status_t
|
||||
rdb_add_index(rdb_t *rdb, uint32_t p_index) {
|
||||
int delta;
|
||||
|
||||
/* here we *assume* that p_index > rdb->window_start */
|
||||
|
||||
delta = (p_index - rdb->window_start);
|
||||
if (delta < rdb_bits_in_bitmask) {
|
||||
|
||||
/* if the p_index is within the window, set the appropriate bit */
|
||||
v128_set_bit(&rdb->bitmask, delta);
|
||||
|
||||
} else {
|
||||
|
||||
delta -= rdb_bits_in_bitmask - 1;
|
||||
|
||||
/* shift the window forward by delta bits*/
|
||||
v128_left_shift(&rdb->bitmask, delta);
|
||||
v128_set_bit(&rdb->bitmask, rdb_bits_in_bitmask-1);
|
||||
rdb->window_start += delta;
|
||||
|
||||
}
|
||||
|
||||
return err_status_ok;
|
||||
}
|
||||
|
||||
err_status_t
|
||||
rdb_increment(rdb_t *rdb) {
|
||||
|
||||
if (rdb->window_start++ > 0x7fffffff)
|
||||
return err_status_key_expired;
|
||||
return err_status_ok;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
rdb_get_value(const rdb_t *rdb) {
|
||||
return rdb->window_start;
|
||||
}
|
||||
|
|
@ -1,352 +0,0 @@
|
|||
/*
|
||||
* rdbx.c
|
||||
*
|
||||
* a replay database with extended range, using a rollover counter
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "rdbx.h"
|
||||
|
||||
|
||||
/*
|
||||
* from RFC 3711:
|
||||
*
|
||||
* A receiver reconstructs the index i of a packet with sequence
|
||||
* number SEQ using the estimate
|
||||
*
|
||||
* i = 2^16 * v + SEQ,
|
||||
*
|
||||
* 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).
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* rdbx implementation notes
|
||||
*
|
||||
* A xtd_seq_num_t is essentially a sequence number for which some of
|
||||
* the data on the wire are implicit. It logically consists of a
|
||||
* rollover counter and a sequence number; the sequence number is the
|
||||
* explicit part, and the rollover counter is the implicit part.
|
||||
*
|
||||
* Upon receiving a sequence_number (e.g. in a newly received SRTP
|
||||
* packet), the complete xtd_seq_num_t can be estimated by using a
|
||||
* local xtd_seq_num_t as a basis. This is done using the function
|
||||
* index_guess(&local, &guess, seq_from_packet). This function
|
||||
* returns the difference of the guess and the local value. The local
|
||||
* xtd_seq_num_t can be moved forward to the guess using the function
|
||||
* index_advance(&guess, delta), where delta is the difference.
|
||||
*
|
||||
*
|
||||
* A rdbx_t consists of a xtd_seq_num_t and a bitmask. The index is highest
|
||||
* sequence number that has been received, and the bitmask indicates
|
||||
* which of the recent indicies have been received as well. The
|
||||
* highest bit in the bitmask corresponds to the index in the bitmask.
|
||||
*/
|
||||
|
||||
|
||||
void
|
||||
index_init(xtd_seq_num_t *pi) {
|
||||
#ifdef NO_64BIT_MATH
|
||||
*pi = make64(0,0);
|
||||
#else
|
||||
*pi = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
index_advance(xtd_seq_num_t *pi, sequence_number_t s) {
|
||||
#ifdef NO_64BIT_MATH
|
||||
/* a > ~b means a+b will generate a carry */
|
||||
/* s is uint16 here */
|
||||
*pi = make64(high32(*pi) + (s > ~low32(*pi) ? 1 : 0),low32(*pi) + s);
|
||||
#else
|
||||
*pi += s;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* index_guess(local, guess, s)
|
||||
*
|
||||
* given a xtd_seq_num_t local (which represents the last
|
||||
* known-to-be-good received xtd_seq_num_t) and a sequence number s
|
||||
* (from a newly arrived packet), sets the contents of *guess to
|
||||
* contain the best guess of the packet index to which s corresponds,
|
||||
* and returns the difference between *guess and *local
|
||||
*
|
||||
* nota bene - the output is a signed integer, DON'T cast it to a
|
||||
* unsigned integer!
|
||||
*/
|
||||
|
||||
int
|
||||
index_guess(const xtd_seq_num_t *local,
|
||||
xtd_seq_num_t *guess,
|
||||
sequence_number_t s) {
|
||||
#ifdef NO_64BIT_MATH
|
||||
uint32_t local_roc = ((high32(*local) << 16) |
|
||||
(low32(*local) >> 16));
|
||||
uint16_t local_seq = (uint16_t) (low32(*local));
|
||||
#else
|
||||
uint32_t local_roc = (uint32_t)(*local >> 16);
|
||||
uint16_t local_seq = (uint16_t) *local;
|
||||
#endif
|
||||
#ifdef NO_64BIT_MATH
|
||||
uint32_t guess_roc = ((high32(*guess) << 16) |
|
||||
(low32(*guess) >> 16));
|
||||
uint16_t guess_seq = (uint16_t) (low32(*guess));
|
||||
#else
|
||||
uint32_t guess_roc = (uint32_t)(*guess >> 16);
|
||||
uint16_t guess_seq = (uint16_t) *guess;
|
||||
#endif
|
||||
int difference;
|
||||
|
||||
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;
|
||||
} 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;
|
||||
} else {
|
||||
difference = s - local_seq;
|
||||
guess_roc = local_roc;
|
||||
}
|
||||
}
|
||||
guess_seq = s;
|
||||
|
||||
/* Note: guess_roc is 32 bits, so this generates a 48-bit result! */
|
||||
#ifdef NO_64BIT_MATH
|
||||
*guess = make64(guess_roc >> 16,
|
||||
(guess_roc << 16) | guess_seq);
|
||||
#else
|
||||
*guess = (((uint64_t) guess_roc) << 16) | guess_seq;
|
||||
#endif
|
||||
|
||||
return difference;
|
||||
}
|
||||
|
||||
/*
|
||||
* rdbx
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* rdbx_init(&r, ws) initializes the rdbx_t pointed to by r with window size ws
|
||||
*/
|
||||
|
||||
err_status_t
|
||||
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
|
||||
* which is at rdbx->index + delta is in the rdb
|
||||
*/
|
||||
|
||||
err_status_t
|
||||
rdbx_check(const rdbx_t *rdbx, int delta) {
|
||||
|
||||
if (delta > 0) { /* if delta is positive, it's good */
|
||||
return err_status_ok;
|
||||
} 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 (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;
|
||||
}
|
||||
/* otherwise, the index is okay */
|
||||
|
||||
return err_status_ok;
|
||||
}
|
||||
|
||||
/*
|
||||
* rdbx_add_index adds the xtd_seq_num_t at rdbx->window_start + d to
|
||||
* replay_db (and does *not* check if that xtd_seq_num_t appears in db)
|
||||
*
|
||||
* this function should be called only after replay_check has
|
||||
* indicated that the index does not appear in the rdbx, e.g., a mutex
|
||||
* should protect the rdbx between these calls if need be
|
||||
*/
|
||||
|
||||
err_status_t
|
||||
rdbx_add_index(rdbx_t *rdbx, int delta) {
|
||||
|
||||
if (delta > 0) {
|
||||
/* shift forward by delta */
|
||||
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 */
|
||||
bitvector_set_bit(&rdbx->bitmask, bitvector_get_length(&rdbx->bitmask) -1 + delta);
|
||||
}
|
||||
|
||||
/* note that we need not consider the case that delta == 0 */
|
||||
|
||||
return err_status_ok;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* rdbx_estimate_index(rdbx, guess, s)
|
||||
*
|
||||
* given an rdbx and a sequence number s (from a newly arrived packet),
|
||||
* sets the contents of *guess to contain the best guess of the packet
|
||||
* index to which s corresponds, and returns the difference between
|
||||
* *guess and the locally stored synch info
|
||||
*/
|
||||
|
||||
int
|
||||
rdbx_estimate_index(const rdbx_t *rdbx,
|
||||
xtd_seq_num_t *guess,
|
||||
sequence_number_t s) {
|
||||
|
||||
/*
|
||||
* if the sequence number and rollover counter in the rdbx are
|
||||
* non-zero, then use the index_guess(...) function, otherwise, just
|
||||
* set the rollover counter to zero (since the index_guess(...)
|
||||
* function might incorrectly guess that the rollover counter is
|
||||
* 0xffffffff)
|
||||
*/
|
||||
|
||||
#ifdef NO_64BIT_MATH
|
||||
/* seq_num_median = 0x8000 */
|
||||
if (high32(rdbx->index) > 0 ||
|
||||
low32(rdbx->index) > seq_num_median)
|
||||
#else
|
||||
if (rdbx->index > seq_num_median)
|
||||
#endif
|
||||
return index_guess(&rdbx->index, guess, s);
|
||||
|
||||
#ifdef NO_64BIT_MATH
|
||||
*guess = make64(0,(uint32_t) s);
|
||||
#else
|
||||
*guess = s;
|
||||
#endif
|
||||
|
||||
#ifdef NO_64BIT_MATH
|
||||
return s - (uint16_t) low32(rdbx->index);
|
||||
#else
|
||||
return s - (uint16_t) rdbx->index;
|
||||
#endif
|
||||
}
|
||||
|
|
@ -1,105 +0,0 @@
|
|||
/*
|
||||
* ut_sim.c
|
||||
*
|
||||
* an unreliable transport simulator
|
||||
* (for testing replay databases and suchlike)
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include "ut_sim.h"
|
||||
|
||||
|
||||
int
|
||||
ut_compar(const void *a, const void *b) {
|
||||
return rand() > (RAND_MAX/2) ? -1 : 1;
|
||||
}
|
||||
|
||||
void
|
||||
ut_init(ut_connection *utc) {
|
||||
int i;
|
||||
utc->index = 0;
|
||||
|
||||
for (i=0; i < UT_BUF; i++)
|
||||
utc->buffer[i] = i;
|
||||
|
||||
qsort(utc->buffer, UT_BUF, sizeof(uint32_t), ut_compar);
|
||||
|
||||
utc->index = UT_BUF - 1;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
ut_next_index(ut_connection *utc) {
|
||||
uint32_t tmp;
|
||||
|
||||
tmp = utc->buffer[0];
|
||||
utc->index++;
|
||||
utc->buffer[0] = utc->index;
|
||||
|
||||
qsort(utc->buffer, UT_BUF, sizeof(uint32_t), ut_compar);
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#ifdef UT_TEST
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
int
|
||||
main() {
|
||||
uint32_t i, irecvd, idiff;
|
||||
ut_connection utc;
|
||||
|
||||
ut_init(&utc);
|
||||
|
||||
for (i=0; i < 1000; i++) {
|
||||
irecvd = ut_next_index(&utc);
|
||||
idiff = i - irecvd;
|
||||
printf("%lu\t%lu\t%d\n", i, irecvd, idiff);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
|
@ -1,108 +0,0 @@
|
|||
/*
|
||||
* ctr_prng.c
|
||||
*
|
||||
* counter mode based pseudorandom source
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include "prng.h"
|
||||
|
||||
/* single, global prng structure */
|
||||
|
||||
ctr_prng_t ctr_prng;
|
||||
|
||||
err_status_t
|
||||
ctr_prng_init(rand_source_func_t random_source) {
|
||||
uint8_t tmp_key[32];
|
||||
err_status_t status;
|
||||
|
||||
/* initialize output count to zero */
|
||||
ctr_prng.octet_count = 0;
|
||||
|
||||
/* set random source */
|
||||
ctr_prng.rand = random_source;
|
||||
|
||||
/* initialize secret key from random source */
|
||||
status = random_source(tmp_key, 32);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
/* initialize aes ctr context with random key */
|
||||
status = aes_icm_context_init(&ctr_prng.state, tmp_key, 30);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
return err_status_ok;
|
||||
}
|
||||
|
||||
err_status_t
|
||||
ctr_prng_get_octet_string(void *dest, uint32_t len) {
|
||||
err_status_t status;
|
||||
|
||||
/*
|
||||
* if we need to re-initialize the prng, do so now
|
||||
*
|
||||
* avoid 32-bit overflows by subtracting instead of adding
|
||||
*/
|
||||
if (ctr_prng.octet_count > MAX_PRNG_OUT_LEN - len) {
|
||||
status = ctr_prng_init(ctr_prng.rand);
|
||||
if (status)
|
||||
return status;
|
||||
}
|
||||
ctr_prng.octet_count += len;
|
||||
|
||||
/*
|
||||
* write prng output
|
||||
*/
|
||||
status = aes_icm_output(&ctr_prng.state, (uint8_t*)dest, len);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
return err_status_ok;
|
||||
}
|
||||
|
||||
err_status_t
|
||||
ctr_prng_deinit(void) {
|
||||
|
||||
/* nothing */
|
||||
|
||||
return err_status_ok;
|
||||
}
|
||||
|
|
@ -1,180 +0,0 @@
|
|||
/*
|
||||
* prng.c
|
||||
*
|
||||
* pseudorandom source
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include "prng.h"
|
||||
|
||||
/* single, global prng structure */
|
||||
|
||||
x917_prng_t x917_prng;
|
||||
|
||||
err_status_t
|
||||
x917_prng_init(rand_source_func_t random_source) {
|
||||
uint8_t tmp_key[16];
|
||||
err_status_t status;
|
||||
|
||||
/* initialize output count to zero */
|
||||
x917_prng.octet_count = 0;
|
||||
|
||||
/* set random source */
|
||||
x917_prng.rand = random_source;
|
||||
|
||||
/* initialize secret key from random source */
|
||||
status = random_source(tmp_key, 16);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
/* expand aes 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);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
return err_status_ok;
|
||||
}
|
||||
|
||||
err_status_t
|
||||
x917_prng_get_octet_string(uint8_t *dest, uint32_t len) {
|
||||
uint32_t t;
|
||||
v128_t buffer;
|
||||
uint32_t i, tail_len;
|
||||
err_status_t status;
|
||||
|
||||
/*
|
||||
* if we need to re-initialize the prng, do so now
|
||||
*
|
||||
* avoid overflows by subtracting instead of adding
|
||||
*/
|
||||
if (x917_prng.octet_count > MAX_PRNG_OUT_LEN - len) {
|
||||
status = x917_prng_init(x917_prng.rand);
|
||||
if (status)
|
||||
return status;
|
||||
}
|
||||
x917_prng.octet_count += len;
|
||||
|
||||
/* find out the time */
|
||||
t = (uint32_t)time(NULL);
|
||||
|
||||
/* loop until we have output enough data */
|
||||
for (i=0; i < len/16; i++) {
|
||||
|
||||
/* exor time into state */
|
||||
x917_prng.state.v32[0] ^= t;
|
||||
|
||||
/* copy state into buffer */
|
||||
v128_copy(&buffer, &x917_prng.state);
|
||||
|
||||
/* apply aes to buffer */
|
||||
aes_encrypt(&buffer, &x917_prng.key);
|
||||
|
||||
/* write data to output */
|
||||
*dest++ = buffer.v8[0];
|
||||
*dest++ = buffer.v8[1];
|
||||
*dest++ = buffer.v8[2];
|
||||
*dest++ = buffer.v8[3];
|
||||
*dest++ = buffer.v8[4];
|
||||
*dest++ = buffer.v8[5];
|
||||
*dest++ = buffer.v8[6];
|
||||
*dest++ = buffer.v8[7];
|
||||
*dest++ = buffer.v8[8];
|
||||
*dest++ = buffer.v8[9];
|
||||
*dest++ = buffer.v8[10];
|
||||
*dest++ = buffer.v8[11];
|
||||
*dest++ = buffer.v8[12];
|
||||
*dest++ = buffer.v8[13];
|
||||
*dest++ = buffer.v8[14];
|
||||
*dest++ = buffer.v8[15];
|
||||
|
||||
/* exor time into buffer */
|
||||
buffer.v32[0] ^= t;
|
||||
|
||||
/* encrypt buffer */
|
||||
aes_encrypt(&buffer, &x917_prng.key);
|
||||
|
||||
/* copy buffer into state */
|
||||
v128_copy(&x917_prng.state, &buffer);
|
||||
|
||||
}
|
||||
|
||||
/* if we need to output any more octets, we'll do so now */
|
||||
tail_len = len % 16;
|
||||
if (tail_len) {
|
||||
|
||||
/* exor time into state */
|
||||
x917_prng.state.v32[0] ^= t;
|
||||
|
||||
/* copy value into buffer */
|
||||
v128_copy(&buffer, &x917_prng.state);
|
||||
|
||||
/* apply aes to buffer */
|
||||
aes_encrypt(&buffer, &x917_prng.key);
|
||||
|
||||
/* write data to output */
|
||||
for (i=0; i < tail_len; i++) {
|
||||
*dest++ = buffer.v8[i];
|
||||
}
|
||||
|
||||
/* now update the state one more time */
|
||||
|
||||
/* exor time into buffer */
|
||||
buffer.v32[0] ^= t;
|
||||
|
||||
/* encrypt buffer */
|
||||
aes_encrypt(&buffer, &x917_prng.key);
|
||||
|
||||
/* copy buffer into state */
|
||||
v128_copy(&x917_prng.state, &buffer);
|
||||
|
||||
}
|
||||
|
||||
return err_status_ok;
|
||||
}
|
||||
|
||||
err_status_t
|
||||
x917_prng_deinit(void) {
|
||||
|
||||
return err_status_ok;
|
||||
}
|
||||
|
|
@ -1,65 +0,0 @@
|
|||
/*
|
||||
* rand_linux_kernel.c
|
||||
*
|
||||
* implements a random source using Linux kernel functions
|
||||
*
|
||||
* Marcus Sundberg
|
||||
* Ingate Systems AB
|
||||
*/
|
||||
/*
|
||||
*
|
||||
* Copyright(c) 2005 Ingate Systems AB
|
||||
* 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 author(s) 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 "config.h"
|
||||
#include "rand_source.h"
|
||||
|
||||
|
||||
err_status_t
|
||||
rand_source_init(void) {
|
||||
return err_status_ok;
|
||||
}
|
||||
|
||||
err_status_t
|
||||
rand_source_get_octet_string(void *dest, uint32_t len) {
|
||||
|
||||
get_random_bytes(dest, len);
|
||||
|
||||
return err_status_ok;
|
||||
}
|
||||
|
||||
err_status_t
|
||||
rand_source_deinit(void) {
|
||||
return err_status_ok;
|
||||
}
|
||||
|
|
@ -1,158 +0,0 @@
|
|||
/*
|
||||
* rand_source.c
|
||||
*
|
||||
* implements a random source based on /dev/random
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "config.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
|
||||
|
||||
#include "rand_source.h"
|
||||
|
||||
|
||||
/*
|
||||
* 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
|
||||
rand_source_init(void) {
|
||||
if (dev_random_fdes >= 0) {
|
||||
/* already open */
|
||||
return err_status_ok;
|
||||
}
|
||||
#ifdef DEV_URANDOM
|
||||
/* open random source for reading */
|
||||
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 = RAND_SOURCE_READY;
|
||||
#endif
|
||||
return err_status_ok;
|
||||
}
|
||||
|
||||
err_status_t
|
||||
rand_source_get_octet_string(void *dest, uint32_t len) {
|
||||
|
||||
/*
|
||||
* read len octets from /dev/random to dest, and
|
||||
* check return value to make sure enough octets were
|
||||
* written
|
||||
*/
|
||||
#ifdef DEV_URANDOM
|
||||
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 = (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++ = val & 0xff;
|
||||
len--;
|
||||
}
|
||||
#endif
|
||||
return err_status_ok;
|
||||
}
|
||||
|
||||
err_status_t
|
||||
rand_source_deinit(void) {
|
||||
if (dev_random_fdes < 0)
|
||||
return err_status_dealloc_fail; /* well, we haven't really failed, *
|
||||
* but there is something wrong */
|
||||
#ifdef DEV_URANDOM
|
||||
close(dev_random_fdes);
|
||||
#endif
|
||||
dev_random_fdes = RAND_SOURCE_NOT_READY;
|
||||
|
||||
return err_status_ok;
|
||||
}
|
||||
|
|
@ -1,119 +0,0 @@
|
|||
/*
|
||||
* aes_calc.c
|
||||
*
|
||||
* A simple AES calculator for generating AES encryption values
|
||||
*
|
||||
* David A. McGrew
|
||||
* Cisco Systems, Inc.
|
||||
*/
|
||||
|
||||
/*
|
||||
|
||||
Example usage (with first NIST FIPS 197 test case):
|
||||
|
||||
[sh]$ test/aes_calc 000102030405060708090a0b0c0d0e0f 00112233445566778899aabbccddeeff -v
|
||||
plaintext: 00112233445566778899aabbccddeeff
|
||||
key: 000102030405060708090a0b0c0d0e0f
|
||||
ciphertext: 69c4e0d86a7b0430d8cdb78070b4c55a
|
||||
|
||||
*/
|
||||
|
||||
#include "aes.h"
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
void
|
||||
usage(char *prog_name) {
|
||||
printf("usage: %s <key> <plaintext> [-v]\n", prog_name);
|
||||
exit(255);
|
||||
}
|
||||
|
||||
#define AES_MAX_KEY_LEN 32
|
||||
|
||||
int
|
||||
main (int argc, char *argv[]) {
|
||||
v128_t data;
|
||||
uint8_t key[AES_MAX_KEY_LEN];
|
||||
aes_expanded_key_t exp_key;
|
||||
int key_len, len;
|
||||
int verbose;
|
||||
err_status_t status;
|
||||
|
||||
if (argc == 3) {
|
||||
/* we're not in verbose mode */
|
||||
verbose = 0;
|
||||
} else if (argc == 4) {
|
||||
if (strncmp(argv[3], "-v", 2) == 0) {
|
||||
/* we're in verbose mode */
|
||||
verbose = 1;
|
||||
} else {
|
||||
/* unrecognized flag, complain and exit */
|
||||
usage(argv[0]);
|
||||
}
|
||||
} else {
|
||||
/* we've been fed the wrong number of arguments - compain and exit */
|
||||
usage(argv[0]);
|
||||
}
|
||||
|
||||
/* read in key, checking length */
|
||||
if (strlen(argv[1]) > AES_MAX_KEY_LEN*2) {
|
||||
fprintf(stderr,
|
||||
"error: too many digits in key "
|
||||
"(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_MAX_KEY_LEN*2);
|
||||
/* check that hex string is the right length */
|
||||
if (len != 32 && len != 48 && len != 64) {
|
||||
fprintf(stderr,
|
||||
"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) {
|
||||
fprintf(stderr,
|
||||
"error: too many digits in plaintext "
|
||||
"(should be %d hexadecimal digits, found %u)\n",
|
||||
16*2, (unsigned)strlen(argv[2]));
|
||||
exit(1);
|
||||
}
|
||||
len = hex_string_to_octet_string((char *)(&data), argv[2], 16*2);
|
||||
/* check that hex string is the right length */
|
||||
if (len < 16*2) {
|
||||
fprintf(stderr,
|
||||
"error: too few digits in plaintext "
|
||||
"(should be %d hexadecimal digits, found %d)\n",
|
||||
16*2, len);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (verbose) {
|
||||
/* print out plaintext */
|
||||
printf("plaintext:\t%s\n", octet_string_hex_string((uint8_t *)&data, 16));
|
||||
}
|
||||
|
||||
/* encrypt plaintext */
|
||||
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);
|
||||
|
||||
/* write ciphertext to output */
|
||||
if (verbose) {
|
||||
printf("key:\t\t%s\n", octet_string_hex_string(key, key_len));
|
||||
printf("ciphertext:\t");
|
||||
}
|
||||
printf("%s\n", v128_hex_string(&data));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -1,200 +0,0 @@
|
|||
/*
|
||||
* auth_driver.c
|
||||
*
|
||||
* a driver for auth functions
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include <stdio.h> /* for printf() */
|
||||
#include <stdlib.h> /* for xalloc() */
|
||||
#include <unistd.h> /* for getopt() */
|
||||
|
||||
#include "auth.h"
|
||||
#include "null_auth.h"
|
||||
|
||||
#define PRINT_DEBUG_DATA 0
|
||||
|
||||
extern auth_type_t tmmhv2;
|
||||
|
||||
const uint16_t msg0[9] = {
|
||||
0x6015, 0xf141, 0x5ba1, 0x29a0, 0xf604, 0xd1c, 0x2d9, 0xaa8a, 0x7931
|
||||
};
|
||||
|
||||
/* key1 is for TAG_WORDS = 2 */
|
||||
|
||||
const uint16_t key1[47] = {
|
||||
0xe627, 0x6a01, 0x5ea7, 0xf27a, 0xc536, 0x2192, 0x11be, 0xea35,
|
||||
0xdb9d, 0x63d6, 0xfa8a, 0xfc45, 0xe08b, 0xd216, 0xced2, 0x7853,
|
||||
0x1a82, 0x22f5, 0x90fb, 0x1c29, 0x708e, 0xd06f, 0x82c3, 0xbee6,
|
||||
0x4f21, 0x6f33, 0x65c0, 0xd211, 0xc25e, 0x9138, 0x4fa3, 0x7c1f,
|
||||
0x61ac, 0x3489, 0x2976, 0x8c19, 0x8252, 0xddbf, 0xcad3, 0xc28f,
|
||||
0x68d6, 0x58dd, 0x504f, 0x2bbf, 0x0278, 0x70b7, 0xcfca
|
||||
};
|
||||
|
||||
double
|
||||
auth_bits_per_second(auth_t *h, int msg_len);
|
||||
|
||||
|
||||
void
|
||||
usage(char *prog_name) {
|
||||
printf("usage: %s [ -t | -v ]\n", prog_name);
|
||||
exit(255);
|
||||
}
|
||||
|
||||
#define MAX_MSG_LEN 2048
|
||||
|
||||
int
|
||||
main (int argc, char *argv[]) {
|
||||
auth_t *a = NULL;
|
||||
err_status_t status;
|
||||
int i;
|
||||
int c;
|
||||
unsigned do_timing_test = 0;
|
||||
unsigned do_validation = 0;
|
||||
|
||||
/* process input arguments */
|
||||
while (1) {
|
||||
c = getopt(argc, argv, "tv");
|
||||
if (c == -1)
|
||||
break;
|
||||
switch (c) {
|
||||
case 't':
|
||||
do_timing_test = 1;
|
||||
break;
|
||||
case 'v':
|
||||
do_validation = 1;
|
||||
break;
|
||||
default:
|
||||
usage(argv[0]);
|
||||
}
|
||||
}
|
||||
|
||||
printf("auth driver\nDavid A. McGrew\nCisco Systems, Inc.\n");
|
||||
|
||||
if (!do_validation && !do_timing_test)
|
||||
usage(argv[0]);
|
||||
|
||||
if (do_validation) {
|
||||
printf("running self-test for %s...", tmmhv2.description);
|
||||
status = tmmhv2_add_big_test();
|
||||
if (status) {
|
||||
printf("tmmhv2_add_big_test failed with error code %d\n", status);
|
||||
exit(status);
|
||||
}
|
||||
status = auth_type_self_test(&tmmhv2);
|
||||
if (status) {
|
||||
printf("failed with error code %d\n", status);
|
||||
exit(status);
|
||||
}
|
||||
printf("passed\n");
|
||||
}
|
||||
|
||||
if (do_timing_test) {
|
||||
|
||||
/* tmmhv2 timing test */
|
||||
status = auth_type_alloc(&tmmhv2, &a, 94, 4);
|
||||
if (status) {
|
||||
fprintf(stderr, "can't allocate tmmhv2\n");
|
||||
exit(status);
|
||||
}
|
||||
status = auth_init(a, (uint8_t *)key1);
|
||||
if (status) {
|
||||
printf("error initializaing auth function\n");
|
||||
exit(status);
|
||||
}
|
||||
|
||||
printf("timing %s (tag length %d)\n",
|
||||
tmmhv2.description, auth_get_tag_length(a));
|
||||
for (i=8; i <= MAX_MSG_LEN; i *= 2)
|
||||
printf("msg len: %d\tgigabits per second: %f\n",
|
||||
i, auth_bits_per_second(a, i) / 1E9);
|
||||
|
||||
status = auth_dealloc(a);
|
||||
if (status) {
|
||||
printf("error deallocating auth function\n");
|
||||
exit(status);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define NUM_TRIALS 100000
|
||||
|
||||
#include <time.h>
|
||||
|
||||
double
|
||||
auth_bits_per_second(auth_t *a, int msg_len_octets) {
|
||||
int i;
|
||||
clock_t timer;
|
||||
uint8_t *result;
|
||||
int msg_len = (msg_len_octets + 1)/2;
|
||||
uint16_t *msg_string;
|
||||
|
||||
/* create random message */
|
||||
msg_string = (uint16_t *) crypto_alloc(msg_len_octets);
|
||||
if (msg_string == NULL)
|
||||
return 0.0; /* indicate failure */
|
||||
for (i=0; i < msg_len; i++)
|
||||
msg_string[i] = (uint16_t) random();
|
||||
|
||||
/* allocate temporary storage for authentication tag */
|
||||
result = crypto_alloc(auth_get_tag_length(a));
|
||||
if (result == NULL) {
|
||||
free(msg_string);
|
||||
return 0.0; /* indicate failure */
|
||||
}
|
||||
|
||||
timer = clock();
|
||||
for (i=0; i < NUM_TRIALS; i++) {
|
||||
auth_compute(a, (uint8_t *)msg_string, msg_len_octets, (uint8_t *)result);
|
||||
}
|
||||
timer = clock() - timer;
|
||||
|
||||
free(msg_string);
|
||||
free(result);
|
||||
|
||||
return (double) NUM_TRIALS * 8 * msg_len_octets * CLOCKS_PER_SEC / timer;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1,531 +0,0 @@
|
|||
/*
|
||||
* cipher_driver.c
|
||||
*
|
||||
* A driver for the generic cipher type
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h> /* for printf() */
|
||||
#include <stdlib.h> /* for rand() */
|
||||
#include <string.h> /* for memset() */
|
||||
#include <unistd.h> /* for getopt() */
|
||||
#include "cipher.h"
|
||||
#include "aes_icm.h"
|
||||
#include "null_cipher.h"
|
||||
|
||||
#define PRINT_DEBUG 0
|
||||
|
||||
void
|
||||
cipher_driver_test_throughput(cipher_t *c);
|
||||
|
||||
err_status_t
|
||||
cipher_driver_self_test(cipher_type_t *ct);
|
||||
|
||||
|
||||
/*
|
||||
* cipher_driver_test_buffering(ct) tests the cipher's output
|
||||
* buffering for correctness by checking the consistency of succesive
|
||||
* calls
|
||||
*/
|
||||
|
||||
err_status_t
|
||||
cipher_driver_test_buffering(cipher_t *c);
|
||||
|
||||
|
||||
/*
|
||||
* functions for testing cipher cache thrash
|
||||
*/
|
||||
err_status_t
|
||||
cipher_driver_test_array_throughput(cipher_type_t *ct,
|
||||
int klen, int num_cipher);
|
||||
|
||||
void
|
||||
cipher_array_test_throughput(cipher_t *ca[], int num_cipher);
|
||||
|
||||
uint64_t
|
||||
cipher_array_bits_per_second(cipher_t *cipher_array[], int num_cipher,
|
||||
unsigned octets_in_buffer, int num_trials);
|
||||
|
||||
err_status_t
|
||||
cipher_array_delete(cipher_t *cipher_array[], int num_cipher);
|
||||
|
||||
err_status_t
|
||||
cipher_array_alloc_init(cipher_t ***cipher_array, int num_ciphers,
|
||||
cipher_type_t *ctype, int klen);
|
||||
|
||||
void
|
||||
usage(char *prog_name) {
|
||||
printf("usage: %s [ -t | -v | -a ]\n", prog_name);
|
||||
exit(255);
|
||||
}
|
||||
|
||||
void
|
||||
check_status(err_status_t s) {
|
||||
if (s) {
|
||||
printf("error (code %d)\n", s);
|
||||
exit(s);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* null_cipher, aes_icm, and aes_cbc are the cipher meta-objects
|
||||
* defined in the files in crypto/cipher subdirectory. these are
|
||||
* declared external so that we can use these cipher types here
|
||||
*/
|
||||
|
||||
extern cipher_type_t null_cipher;
|
||||
extern cipher_type_t aes_icm;
|
||||
extern cipher_type_t aes_cbc;
|
||||
|
||||
int
|
||||
main(int argc, char *argv[]) {
|
||||
cipher_t *c = NULL;
|
||||
err_status_t status;
|
||||
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, 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;
|
||||
unsigned do_validation = 0;
|
||||
unsigned do_array_timing_test = 0;
|
||||
|
||||
/* process input arguments */
|
||||
while (1) {
|
||||
q = getopt(argc, argv, "tva");
|
||||
if (q == -1)
|
||||
break;
|
||||
switch (q) {
|
||||
case 't':
|
||||
do_timing_test = 1;
|
||||
break;
|
||||
case 'v':
|
||||
do_validation = 1;
|
||||
break;
|
||||
case 'a':
|
||||
do_array_timing_test = 1;
|
||||
break;
|
||||
default:
|
||||
usage(argv[0]);
|
||||
}
|
||||
}
|
||||
|
||||
printf("cipher test driver\n"
|
||||
"David A. McGrew\n"
|
||||
"Cisco Systems, Inc.\n");
|
||||
|
||||
if (!do_validation && !do_timing_test && !do_array_timing_test)
|
||||
usage(argv[0]);
|
||||
|
||||
/* arry timing (cache thrash) test */
|
||||
if (do_array_timing_test) {
|
||||
int max_num_cipher = 1 << 16; /* number of ciphers in cipher_array */
|
||||
int num_cipher;
|
||||
|
||||
for (num_cipher=1; num_cipher < max_num_cipher; num_cipher *=8)
|
||||
cipher_driver_test_array_throughput(&null_cipher, 0, num_cipher);
|
||||
|
||||
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) {
|
||||
cipher_driver_self_test(&null_cipher);
|
||||
cipher_driver_self_test(&aes_icm);
|
||||
cipher_driver_self_test(&aes_cbc);
|
||||
}
|
||||
|
||||
/* do timing and/or buffer_test on null_cipher */
|
||||
status = cipher_type_alloc(&null_cipher, &c, 0);
|
||||
check_status(status);
|
||||
|
||||
status = cipher_init(c, NULL, 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);
|
||||
|
||||
|
||||
/* 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");
|
||||
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);
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
void
|
||||
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 = 1000000;
|
||||
|
||||
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",
|
||||
i, cipher_bits_per_second(c, i, num_trials) / 1e9);
|
||||
|
||||
}
|
||||
|
||||
err_status_t
|
||||
cipher_driver_self_test(cipher_type_t *ct) {
|
||||
err_status_t status;
|
||||
|
||||
printf("running cipher self-test for %s...", ct->description);
|
||||
status = cipher_type_self_test(ct);
|
||||
if (status) {
|
||||
printf("failed with error code %d\n", status);
|
||||
exit(status);
|
||||
}
|
||||
printf("passed\n");
|
||||
|
||||
return err_status_ok;
|
||||
}
|
||||
|
||||
/*
|
||||
* cipher_driver_test_buffering(ct) tests the cipher's output
|
||||
* buffering for correctness by checking the consistency of succesive
|
||||
* calls
|
||||
*/
|
||||
|
||||
err_status_t
|
||||
cipher_driver_test_buffering(cipher_t *c) {
|
||||
int i, j, num_trials = 1000;
|
||||
unsigned len, buflen = 1024;
|
||||
uint8_t buffer0[buflen], buffer1[buflen], *current, *end;
|
||||
uint8_t idx[16] = {
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x34
|
||||
};
|
||||
err_status_t status;
|
||||
|
||||
printf("testing output buffering for cipher %s...",
|
||||
c->type->description);
|
||||
|
||||
for (i=0; i < num_trials; i++) {
|
||||
|
||||
/* set buffers to zero */
|
||||
for (j=0; j < buflen; j++)
|
||||
buffer0[j] = buffer1[j] = 0;
|
||||
|
||||
/* initialize cipher */
|
||||
status = cipher_set_iv(c, idx);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
/* generate 'reference' value by encrypting all at once */
|
||||
status = cipher_encrypt(c, buffer0, &buflen);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
/* re-initialize cipher */
|
||||
status = cipher_set_iv(c, idx);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
/* now loop over short lengths until buffer1 is encrypted */
|
||||
current = buffer1;
|
||||
end = buffer1 + buflen;
|
||||
while (current < end) {
|
||||
|
||||
/* choose a short length */
|
||||
len = rand() & 0x01f;
|
||||
|
||||
/* make sure that len doesn't cause us to overreach the buffer */
|
||||
if (current + len > end)
|
||||
len = end - current;
|
||||
|
||||
status = cipher_encrypt(c, current, &len);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
/* advance pointer into buffer1 to reflect encryption */
|
||||
current += len;
|
||||
|
||||
/* if buffer1 is all encrypted, break out of loop */
|
||||
if (current == end)
|
||||
break;
|
||||
}
|
||||
|
||||
/* compare buffers */
|
||||
for (j=0; j < buflen; j++)
|
||||
if (buffer0[j] != buffer1[j]) {
|
||||
#if PRINT_DEBUG
|
||||
printf("test case %d failed at byte %d\n", i, j);
|
||||
printf("computed: %s\n", octet_string_hex_string(buffer1, buflen));
|
||||
printf("expected: %s\n", octet_string_hex_string(buffer0, buflen));
|
||||
#endif
|
||||
return err_status_algo_fail;
|
||||
}
|
||||
}
|
||||
|
||||
printf("passed\n");
|
||||
|
||||
return err_status_ok;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* The function cipher_test_throughput_array() tests the effect of CPU
|
||||
* cache thrash on cipher throughput.
|
||||
*
|
||||
* cipher_array_alloc_init(ctype, array, num_ciphers) creates an array
|
||||
* of cipher_t of type ctype
|
||||
*/
|
||||
|
||||
err_status_t
|
||||
cipher_array_alloc_init(cipher_t ***ca, int num_ciphers,
|
||||
cipher_type_t *ctype, int klen) {
|
||||
int i, j;
|
||||
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);
|
||||
if (cipher_array == NULL)
|
||||
return err_status_alloc_fail;
|
||||
|
||||
/* set ca to location of cipher_array */
|
||||
*ca = cipher_array;
|
||||
|
||||
/* allocate key */
|
||||
key = crypto_alloc(klen_pad);
|
||||
if (key == NULL) {
|
||||
free(cipher_array);
|
||||
return err_status_alloc_fail;
|
||||
}
|
||||
|
||||
/* allocate and initialize an array of ciphers */
|
||||
for (i=0; i < num_ciphers; i++) {
|
||||
|
||||
/* allocate cipher */
|
||||
status = cipher_type_alloc(ctype, cipher_array, klen);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
/* 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;
|
||||
|
||||
/* printf("%dth cipher is at %p\n", i, *cipher_array); */
|
||||
/* printf("%dth cipher description: %s\n", i, */
|
||||
/* (*cipher_array)->type->description); */
|
||||
|
||||
/* advance cipher array pointer */
|
||||
cipher_array++;
|
||||
}
|
||||
|
||||
crypto_free(key);
|
||||
|
||||
return err_status_ok;
|
||||
}
|
||||
|
||||
err_status_t
|
||||
cipher_array_delete(cipher_t *cipher_array[], int num_cipher) {
|
||||
int i;
|
||||
|
||||
for (i=0; i < num_cipher; i++) {
|
||||
cipher_dealloc(cipher_array[i]);
|
||||
}
|
||||
|
||||
free(cipher_array);
|
||||
|
||||
return err_status_ok;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* cipher_array_bits_per_second(c, l, t) computes (an estimate of) the
|
||||
* number of bits that a cipher implementation can encrypt in a second
|
||||
* when distinct keys are used to encrypt distinct messages
|
||||
*
|
||||
* c is a cipher (which MUST be allocated an initialized already), l
|
||||
* is the length in octets of the test data to be encrypted, and t is
|
||||
* the number of trials
|
||||
*
|
||||
* if an error is encountered, the value 0 is returned
|
||||
*/
|
||||
|
||||
uint64_t
|
||||
cipher_array_bits_per_second(cipher_t *cipher_array[], int num_cipher,
|
||||
unsigned octets_in_buffer, int num_trials) {
|
||||
int i;
|
||||
v128_t nonce;
|
||||
clock_t timer;
|
||||
unsigned char *enc_buf;
|
||||
int cipher_index = rand() % num_cipher;
|
||||
|
||||
/* 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) {
|
||||
/* 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_to_encrypt);
|
||||
|
||||
/* choose a cipher at random from the array*/
|
||||
cipher_index = (*((uint32_t *)enc_buf)) % num_cipher;
|
||||
}
|
||||
timer = clock() - timer;
|
||||
|
||||
free(enc_buf);
|
||||
|
||||
if (timer == 0) {
|
||||
/* Too fast! */
|
||||
return 0;
|
||||
}
|
||||
|
||||
return (uint64_t)CLOCKS_PER_SEC * num_trials * 8 * octets_in_buffer / timer;
|
||||
}
|
||||
|
||||
void
|
||||
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 = 1000000;
|
||||
|
||||
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,
|
||||
cipher_array_bits_per_second(ca, num_cipher, i, num_trials) / 1e9);
|
||||
|
||||
}
|
||||
|
||||
err_status_t
|
||||
cipher_driver_test_array_throughput(cipher_type_t *ct,
|
||||
int klen, int num_cipher) {
|
||||
cipher_t **ca = NULL;
|
||||
err_status_t status;
|
||||
|
||||
status = cipher_array_alloc_init(&ca, num_cipher, ct, klen);
|
||||
if (status) {
|
||||
printf("error: cipher_array_alloc_init() failed with error code %d\n",
|
||||
status);
|
||||
return status;
|
||||
}
|
||||
|
||||
cipher_array_test_throughput(ca, num_cipher);
|
||||
|
||||
cipher_array_delete(ca, num_cipher);
|
||||
|
||||
return err_status_ok;
|
||||
}
|
||||
|
|
@ -1,237 +0,0 @@
|
|||
/*
|
||||
* datatypes_driver.c
|
||||
*
|
||||
* a test driver for crypto/math datatypes
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include <stdio.h> /* for printf() */
|
||||
#include <string.h> /* for strlen() */
|
||||
#include "datatypes.h"
|
||||
|
||||
void
|
||||
byte_order(void);
|
||||
|
||||
void
|
||||
test_hex_string_funcs(void);
|
||||
|
||||
void
|
||||
print_string(char *s);
|
||||
|
||||
void
|
||||
test_bswap(void);
|
||||
|
||||
int
|
||||
main (void) {
|
||||
|
||||
/*
|
||||
* this program includes various and sundry tests for fundamental
|
||||
* datatypes. it's a grab-bag of throwaway code, retained only in
|
||||
* case of future problems
|
||||
*/
|
||||
|
||||
int i, j;
|
||||
v128_t x;
|
||||
char *r =
|
||||
"The Moving Finger writes; and, having writ,\n"
|
||||
"Moves on: nor all thy Piety nor Wit\n"
|
||||
"Shall lure it back to cancel half a Line,\n"
|
||||
"Nor all thy Tears wash out a Word of it.";
|
||||
char *s = "incomplet";
|
||||
|
||||
print_string(r);
|
||||
print_string(s);
|
||||
|
||||
byte_order();
|
||||
test_hex_string_funcs();
|
||||
|
||||
for (j=0; j < 128; j++) {
|
||||
v128_set_to_zero(&x);
|
||||
/* x.v32[0] = (1 << j); */
|
||||
v128_set_bit(&x, j);
|
||||
printf("%s\n", v128_bit_string(&x));
|
||||
v128_clear_bit(&x, j);
|
||||
printf("%s\n", v128_bit_string(&x));
|
||||
|
||||
}
|
||||
|
||||
printf("----------------------------------------------\n");
|
||||
v128_set_to_zero(&x);
|
||||
for (i=0; i < 128; i++) {
|
||||
v128_set_bit(&x, i);
|
||||
}
|
||||
printf("%s\n", v128_bit_string(&x));
|
||||
|
||||
printf("----------------------------------------------\n");
|
||||
v128_set_to_zero(&x);
|
||||
v128_set_bit(&x, 0);
|
||||
for (i=0; i < 128; i++) {
|
||||
printf("%s\n", v128_bit_string(&x));
|
||||
v128_right_shift(&x, 1);
|
||||
}
|
||||
printf("----------------------------------------------\n");
|
||||
v128_set_to_zero(&x);
|
||||
v128_set_bit(&x, 127);
|
||||
for (i=0; i < 128; i++) {
|
||||
printf("%s\n", v128_bit_string(&x));
|
||||
v128_left_shift(&x, 1);
|
||||
}
|
||||
printf("----------------------------------------------\n");
|
||||
for (i=0; i < 128; i++) {
|
||||
v128_set_to_zero(&x);
|
||||
v128_set_bit(&x, 127);
|
||||
v128_left_shift(&x, i);
|
||||
printf("%s\n", v128_bit_string(&x));
|
||||
}
|
||||
printf("----------------------------------------------\n");
|
||||
v128_set_to_zero(&x);
|
||||
for (i=0; i < 128; i+=2) {
|
||||
v128_set_bit(&x, i);
|
||||
}
|
||||
printf("bit_string: { %s }\n", v128_bit_string(&x));
|
||||
printf("get_bit: { ");
|
||||
for (i=0; i < 128; i++) {
|
||||
if (v128_get_bit(&x, i) == 1)
|
||||
printf("1");
|
||||
else
|
||||
printf("0");
|
||||
}
|
||||
printf(" } \n");
|
||||
|
||||
test_bswap();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* byte_order() prints out byte ordering of datatypes */
|
||||
|
||||
void
|
||||
byte_order(void) {
|
||||
int i;
|
||||
v128_t e;
|
||||
#if 0
|
||||
v16_t b;
|
||||
v32_t c;
|
||||
v64_t d;
|
||||
|
||||
for (i=0; i < sizeof(b); i++)
|
||||
b.octet[i] = i;
|
||||
for (i=0; i < sizeof(c); i++)
|
||||
c.octet[i] = i;
|
||||
for (i=0; i < sizeof(d); i++)
|
||||
d.octet[i] = i;
|
||||
|
||||
printf("v128_t:\t%s\n", v128_hex_string(&e));
|
||||
printf("v64_t:\t%s\n", v64_hex_string(&d));
|
||||
printf("v32_t:\t%s\n", v32_hex_string(c));
|
||||
printf("v16_t:\t%s\n", v16_hex_string(b));
|
||||
|
||||
c.value = 0x01020304;
|
||||
printf("v32_t:\t%s\n", v32_hex_string(c));
|
||||
b.value = 0x0102;
|
||||
printf("v16_t:\t%s\n", v16_hex_string(b));
|
||||
|
||||
printf("uint16_t ordering:\n");
|
||||
|
||||
c.value = 0x00010002;
|
||||
printf("v32_t:\t%x%x\n", c.v16[0], c.v16[1]);
|
||||
#endif
|
||||
|
||||
printf("byte ordering of crypto/math datatypes:\n");
|
||||
for (i=0; i < sizeof(e); i++)
|
||||
e.v8[i] = i;
|
||||
printf("v128_t: %s\n", v128_hex_string(&e));
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
test_hex_string_funcs(void) {
|
||||
char hex1[] = "abadcafe";
|
||||
char hex2[] = "0123456789abcdefqqqqq";
|
||||
char raw[10];
|
||||
int len;
|
||||
|
||||
len = hex_string_to_octet_string(raw, hex1, strlen(hex1));
|
||||
printf("computed length: %d\tstring: %s\n", len,
|
||||
octet_string_hex_string(raw, len/2));
|
||||
printf("expected length: %u\tstring: %s\n", (unsigned)strlen(hex1), hex1);
|
||||
|
||||
len = hex_string_to_octet_string(raw, hex2, strlen(hex2));
|
||||
printf("computed length: %d\tstring: %s\n", len,
|
||||
octet_string_hex_string(raw, len/2));
|
||||
printf("expected length: %d\tstring: %s\n", 16, "0123456789abcdef");
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
print_string(char *s) {
|
||||
int i;
|
||||
printf("%s\n", s);
|
||||
printf("strlen(s) = %u\n", (unsigned)strlen(s));
|
||||
printf("{ ");
|
||||
for (i=0; i < strlen(s); i++) {
|
||||
printf("0x%x, ", s[i]);
|
||||
if (((i+1) % 8) == 0)
|
||||
printf("\n ");
|
||||
}
|
||||
printf("}\n");
|
||||
}
|
||||
|
||||
void
|
||||
test_bswap(void) {
|
||||
uint32_t x = 0x11223344;
|
||||
uint64_t y = 0x1122334455667788LL;
|
||||
|
||||
printf("before: %0x\nafter: %0x\n", x, be32_to_cpu(x));
|
||||
printf("before: %0llx\nafter: %0llx\n", (unsigned long long)y,
|
||||
(unsigned long long)be64_to_cpu(y));
|
||||
|
||||
y = 1234;
|
||||
|
||||
printf("1234: %0llx\n", (unsigned long long)y);
|
||||
printf("as octet string: %s\n",
|
||||
octet_string_hex_string((uint8_t *) &y, 8));
|
||||
y = be64_to_cpu(y);
|
||||
printf("bswapped octet string: %s\n",
|
||||
octet_string_hex_string((uint8_t *) &y, 8));
|
||||
}
|
||||
|
|
@ -1,99 +0,0 @@
|
|||
/*
|
||||
* env.c
|
||||
*
|
||||
* prints out a brief report on the build environment
|
||||
*
|
||||
* 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>
|
||||
#include <string.h> /* for srtcmp() */
|
||||
#include "config.h"
|
||||
|
||||
int
|
||||
main(void) {
|
||||
int err_count = 0;
|
||||
char *str;
|
||||
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
printf("CPU set to big-endian\t\t\t(WORDS_BIGENDIAN == 1)\n");
|
||||
#else
|
||||
printf("CPU set to little-endian\t\t(WORDS_BIGENDIAN == 0)\n");
|
||||
#endif
|
||||
|
||||
#ifdef CPU_RISC
|
||||
printf("CPU set to RISC\t\t\t\t(CPU_RISC == 1)\n");
|
||||
#elif defined(CPU_CISC)
|
||||
printf("CPU set to CISC\t\t\t\t(CPU_CISC == 1)\n");
|
||||
#else
|
||||
printf("CPU set to an unknown type, probably due to a configuration error\n");
|
||||
err_count++;
|
||||
#endif
|
||||
|
||||
#ifdef CPU_ALTIVEC
|
||||
printf("CPU set to ALTIVEC\t\t\t\t(CPU_ALTIVEC == 0)\n");
|
||||
#endif
|
||||
|
||||
#ifndef NO_64BIT_MATH
|
||||
printf("using native 64-bit type\t\t(NO_64_BIT_MATH == 0)\n");
|
||||
#else
|
||||
printf("using built-in 64-bit math\t\t(NO_64_BIT_MATH == 1)\n");
|
||||
#endif
|
||||
|
||||
#ifdef ERR_REPORTING_STDOUT
|
||||
printf("using stdout for error reporting\t(ERR_REPORTING_STDOUT == 1)\n");
|
||||
#endif
|
||||
|
||||
#ifdef DEV_URANDOM
|
||||
str = DEV_URANDOM;
|
||||
#else
|
||||
str = "";
|
||||
#endif
|
||||
printf("using %s as a random source\t(DEV_URANDOM == %s)\n",
|
||||
str, str);
|
||||
if (strcmp("", str) == 0) {
|
||||
err_count++;
|
||||
}
|
||||
|
||||
if (err_count)
|
||||
printf("warning: configuration is probably in error "
|
||||
"(found %d problems)\n", err_count);
|
||||
|
||||
return err_count;
|
||||
}
|
||||
|
|
@ -1,126 +0,0 @@
|
|||
/*
|
||||
* kernel_driver.c
|
||||
*
|
||||
* a test driver for the crypto_kernel
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include <stdio.h> /* for printf() */
|
||||
#include <unistd.h> /* for getopt() */
|
||||
#include "crypto_kernel.h"
|
||||
|
||||
void
|
||||
usage(char *prog_name) {
|
||||
printf("usage: %s [ -v ][ -d debug_module ]*\n", prog_name);
|
||||
exit(255);
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char *argv[]) {
|
||||
extern char *optarg;
|
||||
int q;
|
||||
int do_validation = 0;
|
||||
err_status_t status;
|
||||
|
||||
if (argc == 1)
|
||||
usage(argv[0]);
|
||||
|
||||
/* initialize kernel - we need to do this before anything else */
|
||||
status = crypto_kernel_init();
|
||||
if (status) {
|
||||
printf("error: crypto_kernel init failed\n");
|
||||
exit(1);
|
||||
}
|
||||
printf("crypto_kernel successfully initalized\n");
|
||||
|
||||
/* process input arguments */
|
||||
while (1) {
|
||||
q = getopt(argc, argv, "vd:");
|
||||
if (q == -1)
|
||||
break;
|
||||
switch (q) {
|
||||
case 'v':
|
||||
do_validation = 1;
|
||||
break;
|
||||
case 'd':
|
||||
status = crypto_kernel_set_debug_module(optarg, 1);
|
||||
if (status) {
|
||||
printf("error: set debug module (%s) failed\n", optarg);
|
||||
exit(1);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
usage(argv[0]);
|
||||
}
|
||||
}
|
||||
|
||||
if (do_validation) {
|
||||
printf("checking crypto_kernel status...\n");
|
||||
status = crypto_kernel_status();
|
||||
if (status) {
|
||||
printf("failed\n");
|
||||
exit(1);
|
||||
}
|
||||
printf("crypto_kernel passed self-tests\n");
|
||||
}
|
||||
|
||||
status = crypto_kernel_shutdown();
|
||||
if (status) {
|
||||
printf("error: crypto_kernel shutdown failed\n");
|
||||
exit(1);
|
||||
}
|
||||
printf("crypto_kernel successfully shut down\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* crypto_kernel_cipher_test() is a test of the cipher interface
|
||||
* of the crypto_kernel
|
||||
*/
|
||||
|
||||
err_status_t
|
||||
crypto_kernel_cipher_test(void) {
|
||||
|
||||
/* not implemented yet! */
|
||||
|
||||
return err_status_ok;
|
||||
}
|
||||
|
|
@ -1,140 +0,0 @@
|
|||
/*
|
||||
* rand_gen.c
|
||||
*
|
||||
* a random source (random number generator)
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include <stdio.h> /* for printf() */
|
||||
#include <unistd.h> /* for getopt() */
|
||||
#include "crypto_kernel.h"
|
||||
|
||||
/*
|
||||
* MAX_PRINT_STRING_LEN is defined in datatypes.h, and is the length
|
||||
* of the largest hexadecimal string that can be generated by the
|
||||
* function octet_string_hex_string().
|
||||
*/
|
||||
|
||||
#define BUF_LEN (MAX_PRINT_STRING_LEN/2)
|
||||
|
||||
void
|
||||
usage(char *prog_name) {
|
||||
printf("usage: %s -n <num_bytes> [-l][ -d debug_module ]*\n"
|
||||
" -n <num> output <num> random bytes, where <num>"
|
||||
" is between zero and %d\n"
|
||||
" -l list the avaliable debug modules\n"
|
||||
" -d <mod> turn on debugging module <mod>\n",
|
||||
prog_name, BUF_LEN);
|
||||
exit(255);
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char *argv[]) {
|
||||
extern char *optarg;
|
||||
int q;
|
||||
int num_octets = 0;
|
||||
unsigned do_list_mods = 0;
|
||||
err_status_t status;
|
||||
|
||||
if (argc == 1)
|
||||
usage(argv[0]);
|
||||
|
||||
/* initialize kernel - we need to do this before anything else */
|
||||
status = crypto_kernel_init();
|
||||
if (status) {
|
||||
printf("error: crypto_kernel init failed\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* process input arguments */
|
||||
while (1) {
|
||||
q = getopt(argc, argv, "ld:n:");
|
||||
if (q == -1)
|
||||
break;
|
||||
switch (q) {
|
||||
case 'd':
|
||||
status = crypto_kernel_set_debug_module(optarg, 1);
|
||||
if (status) {
|
||||
printf("error: set debug module (%s) failed\n", optarg);
|
||||
exit(1);
|
||||
}
|
||||
break;
|
||||
case 'l':
|
||||
do_list_mods = 1;
|
||||
break;
|
||||
case 'n':
|
||||
num_octets = atoi(optarg);
|
||||
if (num_octets < 0 || num_octets > BUF_LEN)
|
||||
usage(argv[0]);
|
||||
break;
|
||||
default:
|
||||
usage(argv[0]);
|
||||
}
|
||||
}
|
||||
|
||||
if (do_list_mods) {
|
||||
status = crypto_kernel_list_debug_modules();
|
||||
if (status) {
|
||||
printf("error: list of debug modules failed\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
if (num_octets > 0) {
|
||||
uint8_t buffer[BUF_LEN];
|
||||
|
||||
status = crypto_get_random(buffer, num_octets);
|
||||
if (status) {
|
||||
printf("error: failure in random source\n");
|
||||
} else {
|
||||
printf("%s\n", octet_string_hex_string(buffer, num_octets));
|
||||
}
|
||||
}
|
||||
|
||||
status = crypto_kernel_shutdown();
|
||||
if (status) {
|
||||
printf("error: crypto_kernel shutdown failed\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -1,550 +0,0 @@
|
|||
/*
|
||||
* sha1_driver.c
|
||||
*
|
||||
* a test driver for SHA-1
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "sha1.h"
|
||||
|
||||
#define SHA_PASS 0
|
||||
#define SHA_FAIL 1
|
||||
|
||||
#define MAX_HASH_DATA_LEN 1024
|
||||
#define MAX_HASH_OUT_LEN 20
|
||||
|
||||
typedef struct hash_test_case_t {
|
||||
unsigned data_len; /* number of octets in data */
|
||||
unsigned hash_len; /* number of octets output by hash */
|
||||
uint8_t data[MAX_HASH_DATA_LEN]; /* message data */
|
||||
uint8_t hash[MAX_HASH_OUT_LEN]; /* expected hash output */
|
||||
struct hash_test_case_t *next_test_case;
|
||||
} hash_test_case_t;
|
||||
|
||||
hash_test_case_t *sha1_test_case_list;
|
||||
|
||||
err_status_t
|
||||
hash_test_case_add(hash_test_case_t **list_ptr,
|
||||
char *hex_data,
|
||||
unsigned data_len,
|
||||
char *hex_hash,
|
||||
unsigned hash_len) {
|
||||
hash_test_case_t *list_head = *list_ptr;
|
||||
hash_test_case_t *test_case;
|
||||
unsigned tmp_len;
|
||||
|
||||
test_case = malloc(sizeof(hash_test_case_t));
|
||||
if (test_case == NULL)
|
||||
return err_status_alloc_fail;
|
||||
|
||||
tmp_len = hex_string_to_octet_string((char *)test_case->data, hex_data, data_len*2);
|
||||
if (tmp_len != data_len*2)
|
||||
return err_status_parse_err;
|
||||
|
||||
tmp_len = hex_string_to_octet_string((char *)test_case->hash, hex_hash, hash_len*2);
|
||||
if (tmp_len != hash_len*2)
|
||||
return err_status_parse_err;
|
||||
|
||||
test_case->data_len = data_len;
|
||||
test_case->hash_len = hash_len;
|
||||
|
||||
/* add the new test case to the head of the list */
|
||||
test_case->next_test_case = list_head;
|
||||
*list_ptr = test_case;
|
||||
|
||||
return err_status_ok;
|
||||
}
|
||||
|
||||
err_status_t
|
||||
sha1_test_case_validate(const hash_test_case_t *test_case) {
|
||||
sha1_ctx_t ctx;
|
||||
uint32_t hash_value[5];
|
||||
|
||||
if (test_case == NULL)
|
||||
return err_status_bad_param;
|
||||
|
||||
if (test_case->hash_len != 20)
|
||||
return err_status_bad_param;
|
||||
if (test_case->data_len > MAX_HASH_DATA_LEN)
|
||||
return err_status_bad_param;
|
||||
|
||||
sha1_init(&ctx);
|
||||
sha1_update(&ctx, test_case->data, test_case->data_len);
|
||||
sha1_final(&ctx, hash_value);
|
||||
if (0 == memcmp(test_case->hash, hash_value, 20)) {
|
||||
#if VERBOSE
|
||||
printf("PASSED: reference value: %s\n",
|
||||
octet_string_hex_string((const uint8_t *)test_case->hash, 20));
|
||||
printf("PASSED: computed value: %s\n",
|
||||
octet_string_hex_string((const uint8_t *)hash_value, 20));
|
||||
#endif
|
||||
return err_status_ok;
|
||||
}
|
||||
|
||||
printf("reference value: %s\n",
|
||||
octet_string_hex_string((const uint8_t *)test_case->hash, 20));
|
||||
printf("computed value: %s\n",
|
||||
octet_string_hex_string((const uint8_t *)hash_value, 20));
|
||||
|
||||
return err_status_algo_fail;
|
||||
|
||||
}
|
||||
|
||||
struct hex_sha1_test_case_t {
|
||||
unsigned bit_len;
|
||||
char hex_data[MAX_HASH_DATA_LEN*2];
|
||||
char hex_hash[40];
|
||||
};
|
||||
|
||||
err_status_t
|
||||
sha1_add_test_cases(void) {
|
||||
int i;
|
||||
err_status_t err;
|
||||
|
||||
/*
|
||||
* these test cases are taken from the "SHA-1 Sample Vectors"
|
||||
* provided by NIST at http://csrc.nist.gov/cryptval/shs.html
|
||||
*/
|
||||
|
||||
struct hex_sha1_test_case_t tc[] = {
|
||||
{
|
||||
0,
|
||||
"",
|
||||
"da39a3ee5e6b4b0d3255bfef95601890afd80709"
|
||||
},
|
||||
{
|
||||
8,
|
||||
"a8",
|
||||
"99f2aa95e36f95c2acb0eaf23998f030638f3f15"
|
||||
},
|
||||
{
|
||||
16,
|
||||
"3000",
|
||||
"f944dcd635f9801f7ac90a407fbc479964dec024"
|
||||
},
|
||||
{
|
||||
24,
|
||||
"42749e",
|
||||
"a444319e9b6cc1e8464c511ec0969c37d6bb2619"
|
||||
},
|
||||
{
|
||||
32,
|
||||
"9fc3fe08",
|
||||
"16a0ff84fcc156fd5d3ca3a744f20a232d172253"
|
||||
},
|
||||
{
|
||||
40,
|
||||
"b5c1c6f1af",
|
||||
"fec9deebfcdedaf66dda525e1be43597a73a1f93"
|
||||
},
|
||||
{
|
||||
48,
|
||||
"e47571e5022e",
|
||||
"8ce051181f0ed5e9d0c498f6bc4caf448d20deb5"
|
||||
},
|
||||
{
|
||||
56,
|
||||
"3e1b28839fb758",
|
||||
"67da53837d89e03bf652ef09c369a3415937cfd3"
|
||||
},
|
||||
{
|
||||
64,
|
||||
"a81350cbb224cb90",
|
||||
"305e4ff9888ad855a78573cddf4c5640cce7e946"
|
||||
},
|
||||
{
|
||||
72, "c243d167923dec3ce1",
|
||||
"5902b77b3265f023f9bbc396ba1a93fa3509bde7"
|
||||
},
|
||||
{
|
||||
80,
|
||||
"50ac18c59d6a37a29bf4",
|
||||
"fcade5f5d156bf6f9af97bdfa9c19bccfb4ff6ab"
|
||||
},
|
||||
{
|
||||
88,
|
||||
"98e2b611ad3b1cccf634f6",
|
||||
"1d20fbe00533c10e3cbd6b27088a5de0c632c4b5"
|
||||
},
|
||||
{
|
||||
96,
|
||||
"73fe9afb68e1e8712e5d4eec",
|
||||
"7e1b7e0f7a8f3455a9c03e9580fd63ae205a2d93"
|
||||
},
|
||||
{
|
||||
104,
|
||||
"9e701ed7d412a9226a2a130e66",
|
||||
"706f0677146307b20bb0e8d6311e329966884d13"
|
||||
},
|
||||
{
|
||||
112,
|
||||
"6d3ee90413b0a7cbf69e5e6144ca",
|
||||
"a7241a703aaf0d53fe142f86bf2e849251fa8dff"
|
||||
},
|
||||
{
|
||||
120,
|
||||
"fae24d56514efcb530fd4802f5e71f",
|
||||
"400f53546916d33ad01a5e6df66822dfbdc4e9e6"
|
||||
},
|
||||
{
|
||||
128,
|
||||
"c5a22dd6eda3fe2bdc4ddb3ce6b35fd1",
|
||||
"fac8ab93c1ae6c16f0311872b984f729dc928ccd"
|
||||
},
|
||||
{
|
||||
136,
|
||||
"d98cded2adabf08fda356445c781802d95",
|
||||
"fba6d750c18da58f6e2aab10112b9a5ef3301b3b"
|
||||
},
|
||||
{
|
||||
144,
|
||||
"bcc6d7087a84f00103ccb32e5f5487a751a2",
|
||||
"29d27c2d44c205c8107f0351b05753ac708226b6"
|
||||
},
|
||||
{
|
||||
152,
|
||||
"36ecacb1055434190dbbc556c48bafcb0feb0d",
|
||||
"b971bfc1ebd6f359e8d74cb7ecfe7f898d0ba845"
|
||||
},
|
||||
{
|
||||
160,
|
||||
"5ff9edb69e8f6bbd498eb4537580b7fba7ad31d0",
|
||||
"96d08c430094b9fcc164ad2fb6f72d0a24268f68"
|
||||
},
|
||||
{
|
||||
168, "c95b441d8270822a46a798fae5defcf7b26abace36",
|
||||
"a287ea752a593d5209e287881a09c49fa3f0beb1"
|
||||
},
|
||||
{
|
||||
176,
|
||||
"83104c1d8a55b28f906f1b72cb53f68cbb097b44f860",
|
||||
"a06c713779cbd88519ed4a585ac0cb8a5e9d612b"
|
||||
},
|
||||
{
|
||||
184,
|
||||
"755175528d55c39c56493d697b790f099a5ce741f7754b",
|
||||
"bff7d52c13a3688132a1d407b1ab40f5b5ace298"
|
||||
},
|
||||
{
|
||||
192,
|
||||
"088fc38128bbdb9fd7d65228b3184b3faac6c8715f07272f",
|
||||
"c7566b91d7b6f56bdfcaa9781a7b6841aacb17e9"
|
||||
},
|
||||
{
|
||||
200,
|
||||
"a4a586eb9245a6c87e3adf1009ac8a49f46c07e14185016895",
|
||||
"ffa30c0b5c550ea4b1e34f8a60ec9295a1e06ac1"
|
||||
},
|
||||
{
|
||||
208,
|
||||
"8e7c555270c006092c2a3189e2a526b873e2e269f0fb28245256",
|
||||
"29e66ed23e914351e872aa761df6e4f1a07f4b81"
|
||||
},
|
||||
{
|
||||
216,
|
||||
"a5f3bfa6bb0ba3b59f6b9cbdef8a558ec565e8aa3121f405e7f2f0",
|
||||
"b28cf5e5b806a01491d41f69bd9248765c5dc292"
|
||||
},
|
||||
{
|
||||
224,
|
||||
"589054f0d2bd3c2c85b466bfd8ce18e6ec3e0b87d944cd093ba36469",
|
||||
"60224fb72c46069652cd78bcd08029ef64da62f3"
|
||||
},
|
||||
{
|
||||
232,
|
||||
"a0abb12083b5bbc78128601bf1cbdbc0fdf4b862b24d899953d8da0ff3",
|
||||
"b72c4a86f72608f24c05f3b9088ef92fba431df7"
|
||||
},
|
||||
{
|
||||
240,
|
||||
"82143f4cea6fadbf998e128a8811dc75301cf1db4f079501ea568da68eeb",
|
||||
"73779ad5d6b71b9b8328ef7220ff12eb167076ac"
|
||||
},
|
||||
{
|
||||
248,
|
||||
"9f1231dd6df1ff7bc0b0d4f989d048672683ce35d956d2f57913046267e6f3",
|
||||
"a09671d4452d7cf50015c914a1e31973d20cc1a0"
|
||||
},
|
||||
{
|
||||
256,
|
||||
"041c512b5eed791f80d3282f3a28df263bb1df95e1239a7650e5670fc2187919",
|
||||
"e88cdcd233d99184a6fd260b8fca1b7f7687aee0"
|
||||
},
|
||||
{
|
||||
264,
|
||||
"17e81f6ae8c2e5579d69dafa6e070e7111461552d314b691e7a3e7a4feb3fae418",
|
||||
"010def22850deb1168d525e8c84c28116cb8a269"
|
||||
},
|
||||
{
|
||||
272,
|
||||
"d15976b23a1d712ad28fad04d805f572026b54dd64961fda94d5355a0cc98620cf77",
|
||||
"aeaa40ba1717ed5439b1e6ea901b294ba500f9ad"
|
||||
},
|
||||
{
|
||||
280,
|
||||
"09fce4d434f6bd32a44e04b848ff50ec9f642a8a85b37a264dc73f130f22838443328f",
|
||||
"c6433791238795e34f080a5f1f1723f065463ca0"
|
||||
},
|
||||
{
|
||||
288, "f17af27d776ec82a257d8d46d2b46b639462c56984cc1be9c1222eadb8b26594a25c709d",
|
||||
"e21e22b89c1bb944a32932e6b2a2f20d491982c3"
|
||||
},
|
||||
{
|
||||
296,
|
||||
"b13ce635d6f8758143ffb114f2f601cb20b6276951416a2f94fbf4ad081779d79f4f195b22",
|
||||
"575323a9661f5d28387964d2ba6ab92c17d05a8a"
|
||||
},
|
||||
{
|
||||
304,
|
||||
"5498793f60916ff1c918dde572cdea76da8629ba4ead6d065de3dfb48de94d234cc1c5002910",
|
||||
"feb44494af72f245bfe68e86c4d7986d57c11db7"
|
||||
},
|
||||
{
|
||||
312,
|
||||
"498a1e0b39fa49582ae688cd715c86fbaf8a81b8b11b4d1594c49c902d197c8ba8a621fd6e3be5",
|
||||
"cff2290b3648ba2831b98dde436a72f9ebf51eee"
|
||||
},
|
||||
{
|
||||
320,
|
||||
"3a36ae71521f9af628b3e34dcb0d4513f84c78ee49f10416a98857150b8b15cb5c83afb4b570376e",
|
||||
"9b4efe9d27b965905b0c3dab67b8d7c9ebacd56c"
|
||||
},
|
||||
{
|
||||
328,
|
||||
"dcc76b40ae0ea3ba253e92ac50fcde791662c5b6c948538cffc2d95e9de99cac34dfca38910db2678f",
|
||||
"afedb0ff156205bcd831cbdbda43db8b0588c113"
|
||||
},
|
||||
{
|
||||
336,
|
||||
"5b5ec6ec4fd3ad9c4906f65c747fd4233c11a1736b6b228b92e90cddabb0c7c2fcf9716d3fad261dff33",
|
||||
"8deb1e858f88293a5e5e4d521a34b2a4efa70fc4"
|
||||
},
|
||||
{
|
||||
344,
|
||||
"df48a37b29b1d6de4e94717d60cdb4293fcf170bba388bddf7a9035a15d433f20fd697c3e4c8b8c5f590ab",
|
||||
"95cbdac0f74afa69cebd0e5c7defbc6faf0cbeaf"
|
||||
},
|
||||
{
|
||||
352,
|
||||
"1f179b3b82250a65e1b0aee949e218e2f45c7a8dbfd6ba08de05c55acfc226b48c68d7f7057e5675cd96fcfc",
|
||||
"f0307bcb92842e5ae0cd4f4f14f3df7f877fbef2"
|
||||
},
|
||||
{
|
||||
360,
|
||||
"ee3d72da3a44d971578972a8e6780ce64941267e0f7d0179b214fa97855e1790e888e09fbe3a70412176cb3b54",
|
||||
"7b13bb0dbf14964bd63b133ac85e22100542ef55"
|
||||
},
|
||||
{
|
||||
368,
|
||||
"d4d4c7843d312b30f610b3682254c8be96d5f6684503f8fbfbcd15774fc1b084d3741afb8d24aaa8ab9c104f7258",
|
||||
"c314d2b6cf439be678d2a74e890d96cfac1c02ed"
|
||||
},
|
||||
{
|
||||
376,
|
||||
"32c094944f5936a190a0877fb9178a7bf60ceae36fd530671c5b38c5dbd5e6a6c0d615c2ac8ad04b213cc589541cf6",
|
||||
"4d0be361e410b47a9d67d8ce0bb6a8e01c53c078"
|
||||
},
|
||||
{
|
||||
384,
|
||||
"e5d3180c14bf27a5409fa12b104a8fd7e9639609bfde6ee82bbf9648be2546d29688a65e2e3f3da47a45ac14343c9c02",
|
||||
"e5353431ffae097f675cbf498869f6fbb6e1c9f2"
|
||||
},
|
||||
{
|
||||
392,
|
||||
"e7b6e4b69f724327e41e1188a37f4fe38b1dba19cbf5a7311d6e32f1038e97ab506ee05aebebc1eed09fc0e357109818b9",
|
||||
"b8720a7068a085c018ab18961de2765aa6cd9ac4"
|
||||
},
|
||||
{
|
||||
400,
|
||||
"bc880cb83b8ac68ef2fedc2da95e7677ce2aa18b0e2d8b322701f67af7d5e7a0d96e9e33326ccb7747cfff0852b961bfd475",
|
||||
"b0732181568543ba85f2b6da602b4b065d9931aa"
|
||||
},
|
||||
{
|
||||
408,
|
||||
"235ea9c2ba7af25400f2e98a47a291b0bccdaad63faa2475721fda5510cc7dad814bce8dabb611790a6abe56030b798b75c944",
|
||||
"9c22674cf3222c3ba921672694aafee4ce67b96b"
|
||||
},
|
||||
{
|
||||
416,
|
||||
"07e3e29fed63104b8410f323b975fd9fba53f636af8c4e68a53fb202ca35dd9ee07cb169ec5186292e44c27e5696a967f5e67709",
|
||||
"d128335f4cecca9066cdae08958ce656ff0b4cfc"
|
||||
},
|
||||
{
|
||||
424,
|
||||
"65d2a1dd60a517eb27bfbf530cf6a5458f9d5f4730058bd9814379547f34241822bf67e6335a6d8b5ed06abf8841884c636a25733f",
|
||||
"0b67c57ac578de88a2ae055caeaec8bb9b0085a0"
|
||||
},
|
||||
{
|
||||
432,
|
||||
"dcc86b3bd461615bab739d8daafac231c0f462e819ad29f9f14058f3ab5b75941d4241ea2f17ebb8a458831b37a9b16dead4a76a9b0e",
|
||||
"c766f912a89d4ccda88e0cce6a713ef5f178b596"
|
||||
},
|
||||
{
|
||||
440,
|
||||
"4627d54f0568dc126b62a8c35fb46a9ac5024400f2995e51635636e1afc4373dbb848eb32df23914230560b82477e9c3572647a7f2bb92",
|
||||
"9aa3925a9dcb177b15ccff9b78e70cf344858779"
|
||||
},
|
||||
{
|
||||
448,
|
||||
"ba531affd4381168ef24d8b275a84d9254c7f5cc55fded53aa8024b2c5c5c8aa7146fe1d1b83d62b70467e9a2e2cb67b3361830adbab28d7",
|
||||
"4811fa30042fc076acf37c8e2274d025307e5943"
|
||||
},
|
||||
{
|
||||
456,
|
||||
"8764dcbcf89dcf4282eb644e3d568bdccb4b13508bfa7bfe0ffc05efd1390be22109969262992d377691eb4f77f3d59ea8466a74abf57b2ef4",
|
||||
"6743018450c9730761ee2b130df9b91c1e118150"
|
||||
},
|
||||
{
|
||||
464,
|
||||
"497d9df9ddb554f3d17870b1a31986c1be277bc44feff713544217a9f579623d18b5ffae306c25a45521d2759a72c0459b58957255ab592f3be4",
|
||||
"71ad4a19d37d92a5e6ef3694ddbeb5aa61ada645"
|
||||
},
|
||||
{
|
||||
472,
|
||||
"72c3c2e065aefa8d9f7a65229e818176eef05da83f835107ba90ec2e95472e73e538f783b416c04654ba8909f26a12db6e5c4e376b7615e4a25819",
|
||||
"a7d9dc68dacefb7d6116186048cb355cc548e11d"
|
||||
},
|
||||
{
|
||||
480,
|
||||
"7cc9894454d0055ab5069a33984e2f712bef7e3124960d33559f5f3b81906bb66fe64da13c153ca7f5cabc89667314c32c01036d12ecaf5f9a78de98",
|
||||
"142e429f0522ba5abf5131fa81df82d355b96909"
|
||||
},
|
||||
{
|
||||
488,
|
||||
"74e8404d5a453c5f4d306f2cfa338ca65501c840ddab3fb82117933483afd6913c56aaf8a0a0a6b2a342fc3d9dc7599f4a850dfa15d06c61966d74ea59",
|
||||
"ef72db70dcbcab991e9637976c6faf00d22caae9"
|
||||
},
|
||||
{
|
||||
496,
|
||||
"46fe5ed326c8fe376fcc92dc9e2714e2240d3253b105adfbb256ff7a19bc40975c604ad7c0071c4fd78a7cb64786e1bece548fa4833c04065fe593f6fb10",
|
||||
"f220a7457f4588d639dc21407c942e9843f8e26b"
|
||||
},
|
||||
{
|
||||
504,
|
||||
"836dfa2524d621cf07c3d2908835de859e549d35030433c796b81272fd8bc0348e8ddbc7705a5ad1fdf2155b6bc48884ac0cd376925f069a37849c089c8645",
|
||||
"ddd2117b6e309c233ede85f962a0c2fc215e5c69"
|
||||
},
|
||||
{
|
||||
512,
|
||||
"7e3a4c325cb9c52b88387f93d01ae86d42098f5efa7f9457388b5e74b6d28b2438d42d8b64703324d4aa25ab6aad153ae30cd2b2af4d5e5c00a8a2d0220c6116",
|
||||
"a3054427cdb13f164a610b348702724c808a0dcc"
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
for (i=0; i < 65; i++) {
|
||||
err = hash_test_case_add(&sha1_test_case_list,
|
||||
tc[i].hex_data,
|
||||
tc[i].bit_len/8,
|
||||
tc[i].hex_hash, 20);
|
||||
if (err) {
|
||||
printf("error adding hash test case (code %d)\n", err);
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
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) {
|
||||
hash_test_case_t *test_case;
|
||||
err_status_t err;
|
||||
|
||||
err = sha1_add_test_cases();
|
||||
if (err) {
|
||||
printf("error adding SHA1 test cases (error code %d)\n", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
if (sha1_test_case_list == NULL)
|
||||
return err_status_cant_check;
|
||||
|
||||
test_case = sha1_test_case_list;
|
||||
while (test_case != NULL) {
|
||||
err = sha1_test_case_validate(test_case);
|
||||
if (err) {
|
||||
printf("error validating hash test case (error code %d)\n", err);
|
||||
return err;
|
||||
}
|
||||
test_case = test_case->next_test_case;
|
||||
}
|
||||
|
||||
sha1_dealloc_test_cases();
|
||||
|
||||
return err_status_ok;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int
|
||||
main (void) {
|
||||
err_status_t err;
|
||||
|
||||
printf("sha1 test driver\n");
|
||||
|
||||
err = sha1_validate();
|
||||
if (err) {
|
||||
printf("SHA1 did not pass validation testing\n");
|
||||
return 1;
|
||||
}
|
||||
printf("SHA1 passed validation tests\n");
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
|
@ -1,139 +0,0 @@
|
|||
/*
|
||||
* stat-driver.c
|
||||
*
|
||||
* test driver for the stat_test functions
|
||||
*
|
||||
* David A. McGrew
|
||||
* Cisco Systems, Inc.
|
||||
*/
|
||||
|
||||
|
||||
#include <stdio.h> /* for printf() */
|
||||
|
||||
#include "err.h"
|
||||
#include "stat.h"
|
||||
|
||||
#include "cipher.h"
|
||||
|
||||
typedef struct {
|
||||
void *state;
|
||||
} random_source_t;
|
||||
|
||||
err_status_t
|
||||
random_source_alloc(void);
|
||||
|
||||
void
|
||||
err_check(err_status_t s) {
|
||||
if (s) {
|
||||
printf("error (code %d)\n", s);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char *argv[]) {
|
||||
uint8_t buffer[2500];
|
||||
unsigned int buf_len = 2500;
|
||||
int i, j;
|
||||
extern cipher_type_t aes_icm;
|
||||
cipher_t *c;
|
||||
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,
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05
|
||||
};
|
||||
v128_t nonce;
|
||||
int num_trials = 500;
|
||||
int num_fail;
|
||||
|
||||
printf("statistical tests driver\n");
|
||||
|
||||
for (i=0; i < 2500; i++)
|
||||
buffer[i] = 0;
|
||||
|
||||
/* run tests */
|
||||
printf("running stat_tests on all-null buffer, expecting failure\n");
|
||||
printf("monobit %d\n", stat_test_monobit(buffer));
|
||||
printf("poker %d\n", stat_test_poker(buffer));
|
||||
printf("runs %d\n", stat_test_runs(buffer));
|
||||
|
||||
for (i=0; i < 2500; i++)
|
||||
buffer[i] = rand();
|
||||
printf("running stat_tests on rand(), expecting success\n");
|
||||
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("running stat_tests on AES-128-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, 30));
|
||||
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));
|
||||
|
||||
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;
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -1,44 +0,0 @@
|
|||
# Makefile for libSRTP documentation
|
||||
#
|
||||
# David A. McGrew
|
||||
# Cisco Systems, Inc.
|
||||
#
|
||||
# This makefile does not use the autoconf system; we don't really need
|
||||
# it. We just run doxygen then latex. If you don't have either of
|
||||
# these, then there is no way that you can make your own
|
||||
# documentation. Of course, you can just go online at pick up the
|
||||
# documentation from http://srtp.sourceforge.net.
|
||||
|
||||
srcdir = .
|
||||
top_srcdir = ..
|
||||
top_builddir = ../
|
||||
|
||||
|
||||
# Determine the version of the library
|
||||
|
||||
version = $(shell cat $(top_srcdir)/VERSION)
|
||||
|
||||
|
||||
.PHONY: libsrtpdoc cryptodoc clean
|
||||
libsrtpdoc:
|
||||
@if test ! -e Doxyfile; then \
|
||||
echo "*** Sorry, can't build doc outside source dir"; exit 1; \
|
||||
fi
|
||||
sed 's/LIBSRTPVERSION/$(version)/' header.template > header.tex
|
||||
doxygen
|
||||
sed 's/\subsection/\section/' latex/index.tex > latex/index.tmp
|
||||
mv latex/index.tmp latex/index.tex
|
||||
cd latex; make
|
||||
cp latex/refman.pdf libsrtp.pdf
|
||||
|
||||
|
||||
cryptodoc: clean
|
||||
doxygen crypto.dox
|
||||
cd latex; make
|
||||
cp latex/refman.pdf crypto.pdf
|
||||
|
||||
clean:
|
||||
rm -rf latex/ header.tex
|
||||
for a in * ; do \
|
||||
if [ -f "$$a~" ] ; then rm -f $$a~; fi; \
|
||||
done;
|
||||
|
|
@ -1,44 +0,0 @@
|
|||
# Makefile for libSRTP documentation
|
||||
#
|
||||
# David A. McGrew
|
||||
# Cisco Systems, Inc.
|
||||
#
|
||||
# This makefile does not use the autoconf system; we don't really need
|
||||
# it. We just run doxygen then latex. If you don't have either of
|
||||
# these, then there is no way that you can make your own
|
||||
# documentation. Of course, you can just go online at pick up the
|
||||
# documentation from http://srtp.sourceforge.net.
|
||||
|
||||
srcdir = @srcdir@
|
||||
top_srcdir = @top_srcdir@
|
||||
top_builddir = @top_builddir@
|
||||
VPATH = @srcdir@
|
||||
|
||||
# Determine the version of the library
|
||||
|
||||
version = $(shell cat $(top_srcdir)/VERSION)
|
||||
|
||||
|
||||
.PHONY: libsrtpdoc cryptodoc clean
|
||||
libsrtpdoc:
|
||||
@if test ! -e Doxyfile; then \
|
||||
echo "*** Sorry, can't build doc outside source dir"; exit 1; \
|
||||
fi
|
||||
sed 's/LIBSRTPVERSION/$(version)/' header.template > header.tex
|
||||
doxygen
|
||||
sed 's/\subsection/\section/' latex/index.tex > latex/index.tmp
|
||||
mv latex/index.tmp latex/index.tex
|
||||
cd latex; make
|
||||
cp latex/refman.pdf libsrtp.pdf
|
||||
|
||||
|
||||
cryptodoc: clean
|
||||
doxygen crypto.dox
|
||||
cd latex; make
|
||||
cp latex/refman.pdf crypto.pdf
|
||||
|
||||
clean:
|
||||
rm -rf latex/ header.tex
|
||||
for a in * ; do \
|
||||
if [ -f "$$a~" ] ; then rm -f $$a~; fi; \
|
||||
done;
|
||||
|
|
@ -1,76 +0,0 @@
|
|||
/**
|
||||
|
||||
@defgroup CryptoKernel Cryptographic Kernel
|
||||
|
||||
All of the cryptographic functions are contained in a kernel.
|
||||
|
||||
*/
|
||||
|
||||
/**
|
||||
|
||||
@defgroup CipherImplementations Ciphers
|
||||
@ingroup CryptoKernel
|
||||
|
||||
@brief A generic cipher type enables cipher agility, that is, the
|
||||
ability to write code that runs with multiple cipher types.
|
||||
Ciphers can be used through the crypto kernel, or can be accessed
|
||||
directly, if need be.
|
||||
|
||||
@{
|
||||
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Allocates a cipher of a particular type.
|
||||
* @warning May be implemented as a macro.
|
||||
*/
|
||||
err_status_t
|
||||
cipher_type_alloc(cipher_type_t *ctype, cipher_t **cipher,
|
||||
unsigned key_len);
|
||||
|
||||
/**
|
||||
* @brief Initialized a cipher to use a particular key. May
|
||||
* be invoked more than once on the same cipher.
|
||||
* @warning May be implemented as a macro.
|
||||
*/
|
||||
|
||||
err_status_t
|
||||
cipher_init(cipher_t *cipher, const uint8_t *key);
|
||||
|
||||
/**
|
||||
* @brief Sets the initialization vector of a given cipher.
|
||||
* @warning May be implemented as a macro.
|
||||
*/
|
||||
|
||||
err_status_t
|
||||
cipher_set_iv(cipher_t *cipher, void *iv);
|
||||
|
||||
/**
|
||||
* @brief Encrypts a buffer with a given cipher.
|
||||
* @warning May be implemented as a macro.
|
||||
*/
|
||||
|
||||
err_status_t
|
||||
cipher_encrypt(cipher_t *cipher, void *buf, unsigned int *len);
|
||||
|
||||
/**
|
||||
* @brief Sets a buffer to the keystream generated by the cipher.
|
||||
* @warning May be implemented as a macro.
|
||||
*/
|
||||
err_status_t
|
||||
cipher_output(cipher_t *c, uint8_t *buffer, int num_octets_to_output);
|
||||
|
||||
/**
|
||||
* @brief Deallocates a cipher.
|
||||
* @warning May be implemented as a macro.
|
||||
*/
|
||||
err_status_t
|
||||
cipher_dealloc(cipher_t *cipher);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
*/
|
||||
File diff suppressed because one or more lines are too long
|
|
@ -1,115 +0,0 @@
|
|||
% header.tex
|
||||
%
|
||||
% header file for the libSRTP documentation - based on the header
|
||||
% file generated by doxygen, with the initial chapters of the
|
||||
% original libSRTP documentation tacked on
|
||||
%
|
||||
\documentclass[letterpaper]{book}
|
||||
\usepackage{makeidx}
|
||||
\usepackage{fancyhdr}
|
||||
\usepackage{graphicx}
|
||||
\usepackage{multicol}
|
||||
\usepackage{float}
|
||||
\usepackage{textcomp}
|
||||
\usepackage{alltt}
|
||||
\usepackage{times}
|
||||
\usepackage{graphicx}
|
||||
\ifx\pdfoutput\undefined
|
||||
\usepackage[ps2pdf,
|
||||
pagebackref=true,
|
||||
colorlinks=true,
|
||||
linkcolor=blue
|
||||
]{hyperref}
|
||||
\else
|
||||
\usepackage[pdftex,
|
||||
pagebackref=true,
|
||||
colorlinks=true,
|
||||
linkcolor=blue
|
||||
]{hyperref}
|
||||
\fi
|
||||
\usepackage{doxygen}
|
||||
\makeindex
|
||||
\setcounter{tocdepth}{1}
|
||||
\renewcommand{\footrulewidth}{0.4pt}
|
||||
|
||||
% these lengths are from DAM
|
||||
\textwidth = 6.5 in
|
||||
%\textheight = 9 in
|
||||
\oddsidemargin = 0.0 in
|
||||
\evensidemargin = 0.0 in
|
||||
\topmargin = 0.0 in
|
||||
\headheight = 0.0 in
|
||||
%\headsep = 0.0 in
|
||||
\parskip = 0.2in
|
||||
\parindent = 0.0in
|
||||
|
||||
% these header and footer definitions from DAM
|
||||
\lhead{libSRTP}
|
||||
\chead{}
|
||||
\rhead{\rightmark}
|
||||
%\rhead{\slshape }
|
||||
\lfoot{}
|
||||
\cfoot{ \thepage }
|
||||
\rfoot{}
|
||||
%\fancyhead[LE,RO]{\rightmark }
|
||||
%\fancyhead[LO,RE]{\slshape }
|
||||
|
||||
% let's use the palatino font
|
||||
\fontfamily{ppl}
|
||||
\selectfont
|
||||
|
||||
|
||||
\begin{document}
|
||||
\begin{titlepage}
|
||||
\vspace*{4cm}
|
||||
%\begin{center}
|
||||
{\Huge
|
||||
libSRTP LIBSRTPVERSION Overview and Reference Manual\\
|
||||
\hrulefill
|
||||
}\\
|
||||
\vspace*{0cm}
|
||||
\begin{flushright}
|
||||
{\Large David A. McGrew \\ \texttt{mcgrew@cisco.com} }\\
|
||||
\vspace*{0.5cm}
|
||||
\end{flushright}
|
||||
%\end{center}
|
||||
|
||||
%\includegraphics[scale=.8]{phone}
|
||||
|
||||
\end{titlepage}
|
||||
|
||||
|
||||
\clearemptydoublepage
|
||||
\vspace*{3cm}
|
||||
{\LARGE Preface}
|
||||
\vspace{1cm}
|
||||
|
||||
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. 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.
|
||||
|
||||
\copyright 2001-2005 by David A. McGrew, Cisco Systems, Inc.
|
||||
\thispagestyle{empty}
|
||||
|
||||
\clearemptydoublepage
|
||||
\pagenumbering{roman}
|
||||
\tableofcontents
|
||||
%\clearemptydoublepage
|
||||
|
||||
\clearemptydoublepage
|
||||
\pagenumbering{arabic}
|
||||
|
||||
|
||||
|
|
@ -1,395 +0,0 @@
|
|||
/**
|
||||
|
||||
@mainpage Introduction to libSRTP
|
||||
|
||||
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 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,
|
||||
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.
|
||||
|
||||
This document is organized as follows. The first chapter provides
|
||||
background material on SRTP and overview of libSRTP. The following
|
||||
chapters provide a detailed reference to the libSRTP API and related
|
||||
functions. The reference material is created automatically (using the
|
||||
doxygen utility) from comments embedded in some of the C header
|
||||
files. The documentation is organized into modules in order to improve
|
||||
its clarity. These modules do not directly correspond to files. An
|
||||
underlying cryptographic kernel provides much of the basic
|
||||
functionality of libSRTP, but is mostly undocumented because it does
|
||||
its work behind the scenes.
|
||||
|
||||
@section LICENSE License and Disclaimer
|
||||
|
||||
libSRTP is distributed under the following license, which is included
|
||||
in the source code distribution. It is reproduced in the manual in
|
||||
case you got the library from another source.
|
||||
|
||||
@latexonly
|
||||
\begin{quote}
|
||||
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:
|
||||
\begin{itemize}
|
||||
\item Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
\item 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.
|
||||
\item 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.
|
||||
\end{itemize}
|
||||
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.
|
||||
\end{quote}
|
||||
@endlatexonly
|
||||
|
||||
@section Features Supported Features
|
||||
|
||||
This library supports all of the mandatory-to-implement features of
|
||||
SRTP (as defined by the most recent Internet Draft). Some of these
|
||||
features can be selected (or de-selected) at run time by setting an
|
||||
appropriate policy; this is done using the structure srtp_policy_t.
|
||||
Some other behaviors of the protocol can be adapted by defining an
|
||||
approriate event handler for the exceptional events; see the @ref
|
||||
SRTPevents section.
|
||||
|
||||
Some options that are not included in the specification are supported.
|
||||
Most notably, the TMMH authentication function is included, though it
|
||||
was removed from the SRTP Internet Draft during the summer of 2002.
|
||||
|
||||
|
||||
@latexonly
|
||||
Some options that are described in the SRTP specification are not
|
||||
supported. This includes
|
||||
\begin{itemize}
|
||||
\item the Master Key Index (MKI),
|
||||
\item key derivation rates other than zero,
|
||||
\item the cipher F8,
|
||||
\item anti-replay lists with sizes other than 128,
|
||||
\item the use of the packet index to select between master keys.
|
||||
\end{itemize}
|
||||
@endlatexonly
|
||||
|
||||
The user should be aware that it is possible to misuse this libary,
|
||||
and that the result may be that the security level it provides is
|
||||
inadequate. If you are implementing a feature using this library, you
|
||||
will want to read the Security Considerations section of the Internet
|
||||
Draft. In addition, it is important that you read and understand the
|
||||
terms outlined in the @ref LICENSE section.
|
||||
|
||||
|
||||
@section Installing Installing and Building libSRTP
|
||||
|
||||
@latexonly
|
||||
|
||||
To install libSRTP, download the latest release of the distribution
|
||||
from \texttt{srtp.sourceforge.net}. The format of the names of the
|
||||
distributions are \texttt{srtp-A.B.C.tgz}, where \texttt{A} is the
|
||||
version number, \texttt{B} is the major release number, \texttt{C} is
|
||||
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 source files
|
||||
will go is named \texttt{srtp}.
|
||||
|
||||
libSRTP uses the GNU \texttt{autoconf} and \texttt{make}
|
||||
utilities\footnote{BSD make will not work; if both versions of make
|
||||
are on your platform, you can invoke GNU make as \texttt{gmake}.}. In
|
||||
the \texttt{srtp} directory, run the configure script and then make:
|
||||
\begin{verbatim}
|
||||
./configure [ options ]
|
||||
make
|
||||
\end{verbatim}
|
||||
The configure script accepts the following options:
|
||||
\begin{quote}
|
||||
\begin{description}
|
||||
\item[--help] provides a usage summary.
|
||||
\item[--disable-debug] compiles libSRTP without the runtime
|
||||
dynamic debugging system.
|
||||
\item[--enable-generic-aesicm] compile in changes for ismacryp
|
||||
\item[--enable-syslog] use syslog for error reporting.
|
||||
\item[--disable-stdout] diables stdout for error reporting.
|
||||
\item[--enable-console] use \texttt{/dev/console} for error reporting
|
||||
\item[--gdoi] use GDOI key management (disabled at present).
|
||||
\end{description}
|
||||
\end{quote}
|
||||
|
||||
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
|
||||
file that can be opened by libSRTP, and debug messages will be sent to
|
||||
it.
|
||||
|
||||
This package has been tested on the following platforms: Mac OS X
|
||||
(powerpc-apple-darwin1.4), Cygwin (i686-pc-cygwin), Solaris
|
||||
(sparc-sun-solaris2.6), RedHat Linux 7.1 and 9 (i686-pc-linux), and
|
||||
OpenBSD (sparc-unknown-openbsd2.7).
|
||||
|
||||
|
||||
@endlatexonly
|
||||
|
||||
@section Applications Applications
|
||||
|
||||
@latexonly
|
||||
|
||||
Several test drivers and a simple and portable srtp application are
|
||||
included in the \texttt{test/} subdirectory.
|
||||
|
||||
\begin{center}
|
||||
\begin{tabular}{ll}
|
||||
\hline
|
||||
Test driver & Function tested \\
|
||||
\hline
|
||||
kernel\_driver & crypto kernel (ciphers, auth funcs, rng) \\
|
||||
srtp\_driver & srtp in-memory tests (does not use the network) \\
|
||||
rdbx\_driver & rdbx (extended replay database) \\
|
||||
roc\_driver & extended sequence number functions \\
|
||||
replay\_driver & replay database \\
|
||||
cipher\_driver & ciphers \\
|
||||
auth\_driver & hash functions \\
|
||||
\hline
|
||||
\end{tabular}
|
||||
\end{center}
|
||||
|
||||
The app rtpw is a simple rtp application which reads words from
|
||||
/usr/dict/words and then sends them out one at a time using [s]rtp.
|
||||
Manual srtp keying uses the -k option; automated key management
|
||||
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]}
|
||||
|
||||
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
|
||||
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 receive words \\
|
||||
-k $<$key$>$ & use SRTP master key $<$key$>$, where the
|
||||
key is a hexadecimal value (without the
|
||||
leading "0x") \\
|
||||
-e & encrypt/decrypt (for data confidentiality)
|
||||
(requires use of -k option as well)\\
|
||||
-a & message authentication
|
||||
(requires use of -k option as well) \\
|
||||
-l & list the available debug modules \\
|
||||
-d $<$debug$>$ & turn on debugging for module $<$debug$>$ \\
|
||||
\end{tabular}
|
||||
\end{center}
|
||||
|
||||
In order to get a random 30-byte value for use as a key/salt pair, you
|
||||
can use the \texttt{rand\_gen} utility in the \texttt{test/}
|
||||
subdirectory.
|
||||
|
||||
An example of an SRTP session using two rtpw programs follows:
|
||||
|
||||
\begin{verbatim}
|
||||
[sh1] set k=`test/rand_gen -n 30`
|
||||
[sh1] echo $k
|
||||
c1eec3717da76195bb878578790af71c4ee9f859e197a414a78d5abc7451
|
||||
[sh1]$ test/rtpw -s -k $k -ea 0.0.0.0 9999
|
||||
Security services: confidentiality message authentication
|
||||
set master key/salt to C1EEC3717DA76195BB878578790AF71C/4EE9F859E197A414A78D5ABC7451
|
||||
setting SSRC to 2078917053
|
||||
sending word: A
|
||||
sending word: a
|
||||
sending word: aa
|
||||
sending word: aal
|
||||
sending word: aalii
|
||||
sending word: aam
|
||||
sending word: Aani
|
||||
sending word: aardvark
|
||||
...
|
||||
|
||||
[sh2] set k=c1eec3717da76195bb878578790af71c4ee9f859e197a414a78d5abc7451
|
||||
[sh2]$ test/rtpw -r -k $k -ea 0.0.0.0 9999
|
||||
security services: confidentiality message authentication
|
||||
set master key/salt to C1EEC3717DA76195BB878578790AF71C/4EE9F859E197A414A78D5ABC7451
|
||||
19 octets received from SSRC 2078917053 word: A
|
||||
19 octets received from SSRC 2078917053 word: a
|
||||
20 octets received from SSRC 2078917053 word: aa
|
||||
21 octets received from SSRC 2078917053 word: aal
|
||||
...
|
||||
\end{verbatim}
|
||||
|
||||
|
||||
@endlatexonly
|
||||
|
||||
|
||||
@section Review Secure RTP Background
|
||||
|
||||
In this section we review SRTP and introduce some terms that are used
|
||||
in libSRTP. An RTP session is defined by a pair of destination
|
||||
transport addresses, that is, a network address plus a pair of UDP
|
||||
ports for RTP and RTCP. RTCP, the RTP control protocol, is used to
|
||||
coordinate between the participants in an RTP session, e.g. to provide
|
||||
feedback from receivers to senders. An @e SRTP @e session is
|
||||
similarly defined; it is just an RTP session for which the SRTP
|
||||
profile is being used. An SRTP session consists of the traffic sent
|
||||
to the SRTP or SRTCP destination transport addresses. Each
|
||||
participant in a session is identified by a synchronization source
|
||||
(SSRC) identifier. Some participants may not send any SRTP traffic;
|
||||
they are called receivers, even though they send out SRTCP traffic,
|
||||
such as receiver reports.
|
||||
|
||||
RTP allows multiple sources to send RTP and RTCP traffic during the
|
||||
same session. The synchronization source identifier (SSRC) is used to
|
||||
distinguish these sources. In libSRTP, we call the SRTP and SRTCP
|
||||
traffic from a particular source a @e stream. Each stream has its own
|
||||
SSRC, sequence number, rollover counter, and other data. A particular
|
||||
choice of options, cryptographic mechanisms, and keys is called a @e
|
||||
policy. Each stream within a session can have a distinct policy
|
||||
applied to it. A session policy is a collection of stream policies.
|
||||
|
||||
A single policy can be used for all of the streams in a given session,
|
||||
though the case in which a single @e key is shared across multiple
|
||||
streams requires care. When key sharing is used, the SSRC values that
|
||||
identify the streams @b must be distinct. This requirement can be
|
||||
enforced by using the convention that each SRTP and SRTCP key is used
|
||||
for encryption by only a single sender. In other words, the key is
|
||||
shared only across streams that originate from a particular device (of
|
||||
course, other SRTP participants will need to use the key for
|
||||
decryption). libSRTP supports this enforcement by detecting the case
|
||||
in which a key is used for both inbound and outbound data.
|
||||
|
||||
|
||||
@section Overview libSRTP Overview
|
||||
|
||||
libSRTP provides functions for protecting RTP and RTCP. RTP packets
|
||||
can be encrypted and authenticated (using the srtp_protect()
|
||||
function), turning them into SRTP packets. Similarly, SRTP packets
|
||||
can be decrypted and have their authentication verified (using the
|
||||
srtp_unprotect() function), turning them into RTP packets. Similar
|
||||
functions apply security to RTCP packets.
|
||||
|
||||
The typedef srtp_stream_t points to a structure holding all of the
|
||||
state associated with an SRTP stream, including the keys and
|
||||
parameters for cipher and message authentication functions and the
|
||||
anti-replay data. A particular srtp_stream_t holds the information
|
||||
needed to protect a particular RTP and RTCP stream. This datatype
|
||||
is intentionally opaque in order to better seperate the libSRTP
|
||||
API from its implementation.
|
||||
|
||||
Within an SRTP session, there can be multiple streams, each
|
||||
originating from a particular sender. Each source uses a distinct
|
||||
stream context to protect the RTP and RTCP stream that it is
|
||||
originating. The typedef srtp_t points to a structure holding all of
|
||||
the state associated with an SRTP session. There can be multiple
|
||||
stream contexts associated with a single srtp_t. A stream context
|
||||
cannot exist indepent from an srtp_t, though of course an srtp_t can
|
||||
be created that contains only a single stream context. A device
|
||||
participating in an SRTP session must have a stream context for each
|
||||
source in that session, so that it can process the data that it
|
||||
receives from each sender.
|
||||
|
||||
|
||||
In libSRTP, a session is created using the function srtp_create().
|
||||
The policy to be implemented in the session is passed into this
|
||||
function as an srtp_policy_t structure. A single one of these
|
||||
structures describes the policy of a single stream. These structures
|
||||
can also be linked together to form an entire session policy. A linked
|
||||
list of srtp_policy_t structures is equivalent to a session policy.
|
||||
In such a policy, we refer to a single srtp_policy_t as an @e element.
|
||||
|
||||
An srtp_policy_t strucutre contains two crypto_policy_t structures
|
||||
that describe the cryptograhic policies for RTP and RTCP, as well as
|
||||
the SRTP master key and the SSRC value. The SSRC describes what to
|
||||
protect (e.g. which stream), and the crypto_policy_t structures
|
||||
describe how to protect it. The key is contained in a policy element
|
||||
because it simplifies the interface to the library. In many cases, it
|
||||
is desirable to use the same cryptographic policies across all of the
|
||||
streams in a session, but to use a distinct key for each stream. A
|
||||
crypto_policy_t structure can be initialized by using either the
|
||||
crypto_policy_set_rtp_default() or crypto_policy_set_rtcp_default()
|
||||
functions, which set a crypto policy structure to the default policies
|
||||
for RTP and RTCP protection, respectively.
|
||||
|
||||
@section Example Example Code
|
||||
|
||||
This section provides a simple example of how to use libSRTP. The
|
||||
example code lacks error checking, but is functional. Here we assume
|
||||
that the value ssrc is already set to describe the SSRC of the stream
|
||||
that we are sending, and that the functions get_rtp_packet() and
|
||||
send_srtp_packet() are available to us. The former puts an RTP packet
|
||||
into the buffer and returns the number of octets written to that
|
||||
buffer. The latter sends the RTP packet in the buffer, given the
|
||||
length as its second argument.
|
||||
|
||||
@verbatim
|
||||
srtp_t session;
|
||||
srtp_policy_t policy;
|
||||
uint8_t key[30];
|
||||
|
||||
// initialize libSRTP
|
||||
srtp_init();
|
||||
|
||||
// set policy to describe a policy for an SRTP stream
|
||||
crypto_policy_set_rtp_default(&policy.rtp);
|
||||
crypto_policy_set_rtcp_default(&policy.rtcp);
|
||||
policy.ssrc = ssrc;
|
||||
policy.key = key;
|
||||
policy.next = NULL;
|
||||
|
||||
// set key to random value
|
||||
crypto_get_random(key, 30);
|
||||
|
||||
// allocate and initialize the SRTP session
|
||||
srtp_create(&session, &policy);
|
||||
|
||||
// main loop: get rtp packets, send srtp packets
|
||||
while (1) {
|
||||
char rtp_buffer[2048];
|
||||
unsigned len;
|
||||
|
||||
len = get_rtp_packet(rtp_buffer);
|
||||
srtp_protect(session, rtp_buffer, &len);
|
||||
send_srtp_packet(rtp_buffer, len);
|
||||
}
|
||||
@endverbatim
|
||||
|
||||
@section ISMAcryp ISMA Encryption Support
|
||||
|
||||
The Internet Streaming Media Alliance (ISMA) specifies a way
|
||||
to pre-encrypt a media file prior to streaming. This method
|
||||
is an alternative to SRTP encryption, which is potentially
|
||||
useful when a particular media file will be streamed
|
||||
multiple times. The specification is available online
|
||||
at http://www.isma.tv/specreq.nsf/SpecRequest.
|
||||
|
||||
libSRTP provides the encryption and decryption functions needed for ISMAcryp
|
||||
in the library @t libaesicm.a, which is included in the default
|
||||
Makefile target. This library is used by the MPEG4IP project; see
|
||||
http://mpeg4ip.sourceforge.net/.
|
||||
|
||||
Note that ISMAcryp does not provide authentication for
|
||||
RTP nor RTCP, nor confidentiality for RTCP.
|
||||
ISMAcryp RECOMMENDS the use of SRTP message authentication for ISMAcryp
|
||||
streams while using ISMAcryp encryption to protect the media itself.
|
||||
|
||||
|
||||
*/
|
||||
Binary file not shown.
|
|
@ -1,21 +0,0 @@
|
|||
SRTP and ICM References
|
||||
September, 2005
|
||||
|
||||
This document provides references for the various cryptographic
|
||||
functions used in libSRTP and libaesicm.
|
||||
|
||||
Secure RTP is defined in RFC 3711, which is included in this
|
||||
distribution for convenience. The counter mode definition is in
|
||||
Section 4.1.1 of the SRTP draft.
|
||||
|
||||
SHA-1 is defined in FIPS-180-1, available online at the NIST website.
|
||||
|
||||
HMAC is defined in RFC2104, and HMAC-SHA1 test vectors are available
|
||||
in RFC2202, which are available online at http://www.ietf.org/rfc/
|
||||
|
||||
ICM is defined by draft-irtf-cfrg-icm-00.txt, and its application in
|
||||
ISMAcryp (the Internet Streaming Media Alliance 1.0 Encryption and
|
||||
Authentication) is defined in that specification. It is available
|
||||
from http://www.isma.tv/.
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -1,201 +0,0 @@
|
|||
/*
|
||||
* 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 */
|
||||
|
|
@ -1,60 +0,0 @@
|
|||
/*
|
||||
* 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 */
|
||||
|
|
@ -1,139 +0,0 @@
|
|||
/*
|
||||
* rtp.h
|
||||
*
|
||||
* rtp interface for srtp reference implementation
|
||||
*
|
||||
* David A. McGrew
|
||||
* Cisco Systems, Inc.
|
||||
*
|
||||
* data types:
|
||||
*
|
||||
* rtp_msg_t an rtp message (the data that goes on the wire)
|
||||
* rtp_sender_t sender side socket and rtp info
|
||||
* rtp_receiver_t receiver side socket and rtp info
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
* 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_H
|
||||
#define RTP_H
|
||||
|
||||
#ifdef HAVE_NETINET_IN_H
|
||||
# include <netinet/in.h>
|
||||
#elif defined HAVE_WINSOCK2_H
|
||||
# include <winsock2.h>
|
||||
#endif
|
||||
|
||||
#include "srtp.h"
|
||||
|
||||
typedef struct rtp_sender_ctx_t *rtp_sender_t;
|
||||
|
||||
typedef struct rtp_receiver_ctx_t *rtp_receiver_t;
|
||||
|
||||
int
|
||||
rtp_sendto(rtp_sender_t sender, const void* msg, int len);
|
||||
|
||||
int
|
||||
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 */
|
||||
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 */
|
||||
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 */
|
||||
|
|
@ -1,74 +0,0 @@
|
|||
/*
|
||||
* 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 */
|
||||
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue