Skip to content

Commit

Permalink
Merge pull request #224 from rsith71/mkiSupport
Browse files Browse the repository at this point in the history
Apply MKI Support Patch
  • Loading branch information
pabuhler committed Feb 21, 2017
2 parents 7591886 + 626e9e8 commit 29c6509
Show file tree
Hide file tree
Showing 8 changed files with 1,584 additions and 451 deletions.
2 changes: 1 addition & 1 deletion Makefile.in
Expand Up @@ -186,7 +186,7 @@ test/srtp_driver$(EXE): test/srtp_driver.c test/util.c test/getopt_s.c
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
test/dtls_srtp_driver$(EXE): test/dtls_srtp_driver.c test/getopt_s.c test/util.c
$(COMPILE) $(LDFLAGS) -o $@ $^ $(LIBS) $(SRTPLIB)

crypto/test/cipher_driver$(EXE): crypto/test/cipher_driver.c test/getopt_s.c
Expand Down
251 changes: 246 additions & 5 deletions include/srtp.h
Expand Up @@ -78,15 +78,29 @@ extern "C" {

#define SRTP_MAX_TAG_LEN 16

/**
* SRTP_MAX_MKI_LEN is the maximum size the MKI could be which is
* 128 bytes
*/
#define SRTP_MAX_MKI_LEN 128


/**
* SRTP_MAX_TRAILER_LEN is the maximum length of the SRTP trailer
* (authentication tag and MKI) supported by libSRTP. This value is
* the maximum number of octets that will be added to an RTP packet by
* the maixmum number of octets that will be added to an RTP packet by
* srtp_protect().
*
* @brief the maximum number of octets added by srtp_protect().
*/
#define SRTP_MAX_TRAILER_LEN SRTP_MAX_TAG_LEN
#define SRTP_MAX_TRAILER_LEN SRTP_MAX_TAG_LEN + SRTP_MAX_MKI_LEN

/**
* SRTP_MAX_NUM_MASTER_KEYS is the maximum number of Master keys for
* MKI supported by libSRTP.
*
*/
#define SRTP_MAX_NUM_MASTER_KEYS 16

/*
* SRTP_AEAD_SALT_LEN is the length of the SALT values used with
Expand Down Expand Up @@ -267,7 +281,8 @@ typedef enum {
srtp_err_status_parse_err = 21, /**< error parsing data */
srtp_err_status_encode_err = 22, /**< error encoding data */
srtp_err_status_semaphore_err = 23,/**< error while using semaphores */
srtp_err_status_pfkey_err = 24 /**< error while using pfkey */
srtp_err_status_pfkey_err = 24, /**< error while using pfkey */
srtp_err_status_bad_mki = 25 /**< error MKI present in packet is invalid */
} srtp_err_status_t;


Expand Down Expand Up @@ -364,6 +379,17 @@ typedef struct srtp_ekt_policy_ctx_t *srtp_ekt_policy_t;
*/
typedef struct srtp_ekt_stream_ctx_t *srtp_ekt_stream_t;

/**
* @brief srtp_master_key_t represents a master key. There will
* be a Master Key Index and the Master Key associated with the
* Master Key Index. Need to also keep track of the Master Key
* Index Size to correctly read it from a packet.
*/
typedef struct srtp_master_key_t {
unsigned char *key;
unsigned char *mki_id;
unsigned int mki_size;
} srtp_master_key_t;

/**
* @brief represents the policy for an SRTP session.
Expand Down Expand Up @@ -401,7 +427,9 @@ typedef struct srtp_policy_t {
srtp_crypto_policy_t rtp; /**< SRTP crypto policy. */
srtp_crypto_policy_t rtcp; /**< SRTCP crypto policy. */
unsigned char *key; /**< Pointer to the SRTP master key for
* this stream. */
* this stream. */
srtp_master_key_t **keys; /** Array of Master Key structures */
unsigned long num_master_keys; /** Number of master keys */
srtp_ekt_policy_t ekt; /**< Pointer to the EKT policy structure
* for this stream (if any) */
unsigned long window_size; /**< The window size to use for replay
Expand Down Expand Up @@ -495,7 +523,59 @@ srtp_err_status_t srtp_shutdown(void);
*/

srtp_err_status_t srtp_protect(srtp_t ctx, void *rtp_hdr, int *len_ptr);


/**
* @brief srtp_protect_mki() is the Secure RTP sender-side packet processing
* function that can utilize MKI.
*
* The function call srtp_protect(ctx, rtp_hdr, len_ptr) applies SRTP
* protection to the RTP packet rtp_hdr (which has length *len_ptr) using
* the SRTP context ctx. If srtp_err_status_ok is returned, then rtp_hdr
* points to the resulting SRTP packet and *len_ptr is the number of
* octets in that packet; otherwise, no assumptions should be made
* about the value of either data elements.
*
* The sequence numbers of the RTP packets presented to this function
* need not be consecutive, but they @b must be out of order by less
* than 2^15 = 32,768 packets.
*
* @warning This function assumes that it can write the authentication
* tag into the location in memory immediately following the RTP
* packet, and assumes that the RTP packet is aligned on a 32-bit
* boundary.
*
* @warning This function assumes that it can write SRTP_MAX_TRAILER_LEN
* into the location in memory immediately following the RTP packet.
* Callers MUST ensure that this much writable memory is available in
* the buffer that holds the RTP packet.
*
* @param ctx is the SRTP context to use in processing the packet.
*
* @param rtp_hdr is a pointer to the RTP packet (before the call); after
* the function returns, it points to the srtp packet.
*
* @param len_ptr is a pointer to the length in octets of the complete
* RTP packet (header and body) before the function call, and of the
* complete SRTP packet after the call, if srtp_err_status_ok was returned.
* Otherwise, the value of the data to which it points is undefined.
*
* @param use_mki is a boolean to tell the system if mki is being used. If
* set to false then will use the first set of session keys. If set to true will
* use the session keys identified by the mki_index
*
* @param mki_index integer value specifying which set of session kesy should be
* used if use_mki is set to true.
*
* @return
* - srtp_err_status_ok no problems
* - srtp_err_status_replay_fail rtp sequence number was non-increasing
* - @e other failure in cryptographic mechanisms
*/

srtp_err_status_t srtp_protect_mki(srtp_ctx_t *ctx, void *rtp_hdr,
int *pkt_octet_len, unsigned int use_mki,
unsigned int mki_index);

/**
* @brief srtp_unprotect() is the Secure RTP receiver-side packet
* processing function.
Expand Down Expand Up @@ -539,6 +619,50 @@ srtp_err_status_t srtp_protect(srtp_t ctx, void *rtp_hdr, int *len_ptr);

srtp_err_status_t srtp_unprotect(srtp_t ctx, void *srtp_hdr, int *len_ptr);

/**
* @brief srtp_unprotect_mki() is the Secure RTP receiver-side packet
* processing function that checks for MKI.
*
* The function call srtp_unprotect(ctx, srtp_hdr, len_ptr) verifies
* the Secure RTP protection of the SRTP packet pointed to by srtp_hdr
* (which has length *len_ptr), using the SRTP context ctx. If
* srtp_err_status_ok is returned, then srtp_hdr points to the resulting
* RTP packet and *len_ptr is the number of octets in that packet;
* otherwise, no assumptions should be made about the value of either
* data elements.
*
* The sequence numbers of the RTP packets presented to this function
* need not be consecutive, but they @b must be out of order by less
* than 2^15 = 32,768 packets.
*
* @warning This function assumes that the SRTP packet is aligned on a
* 32-bit boundary.
*
* @param ctx is the SRTP session which applies to the particular packet.
*
* @param srtp_hdr is a pointer to the header of the SRTP packet
* (before the call). after the function returns, it points to the
* rtp packet if srtp_err_status_ok was returned; otherwise, the value of
* the data to which it points is undefined.
*
* @param len_ptr is a pointer to the length in octets of the complete
* srtp packet (header and body) before the function call, and of the
* complete rtp packet after the call, if srtp_err_status_ok was returned.
* Otherwise, the value of the data to which it points is undefined.
*
* @return
* - srtp_err_status_ok if the RTP packet is valid.
* - srtp_err_status_auth_fail if the SRTP packet failed the message
* authentication check.
* - srtp_err_status_replay_fail if the SRTP packet is a replay (e.g. packet has
* already been processed and accepted).
* - srtp_err_status_bad_mki if the MKI in the packet is not a known MKI id
* - [other] if there has been an error in the cryptographic mechanisms.
*
*/

srtp_err_status_t srtp_unprotect_mki(srtp_t ctx, void *srtp_hdr, int *len_ptr,
unsigned int use_mki);

/**
* @brief srtp_create() allocates and initializes an SRTP session.
Expand Down Expand Up @@ -1245,6 +1369,55 @@ srtp_append_salt_to_key(unsigned char *key, unsigned int bytes_in_key,

srtp_err_status_t srtp_protect_rtcp(srtp_t ctx, void *rtcp_hdr, int *pkt_octet_len);


/**
* @brief srtp_protect_rtcp_mki() is the Secure RTCP sender-side packet
* processing function that can utilize mki.
*
* The function call srtp_protect_rtcp(ctx, rtp_hdr, len_ptr) applies
* SRTCP protection to the RTCP packet rtcp_hdr (which has length
* *len_ptr) using the SRTP session context ctx. If srtp_err_status_ok is
* returned, then rtp_hdr points to the resulting SRTCP packet and
* *len_ptr is the number of octets in that packet; otherwise, no
* assumptions should be made about the value of either data elements.
*
* @warning This function assumes that it can write the authentication
* tag into the location in memory immediately following the RTCP
* packet, and assumes that the RTCP packet is aligned on a 32-bit
* boundary.
*
* @warning This function assumes that it can write SRTP_MAX_TRAILER_LEN+4
* into the location in memory immediately following the RTCP packet.
* Callers MUST ensure that this much writable memory is available in
* the buffer that holds the RTCP packet.
*
* @param ctx is the SRTP context to use in processing the packet.
*
* @param rtcp_hdr is a pointer to the RTCP packet (before the call); after
* the function returns, it points to the srtp packet.
*
* @param pkt_octet_len is a pointer to the length in octets of the
* complete RTCP packet (header and body) before the function call,
* and of the complete SRTCP packet after the call, if srtp_err_status_ok
* was returned. Otherwise, the value of the data to which it points
* is undefined.
*
* @param use_mki is a boolean to tell the system if mki is being used. If
* set to false then will use the first set of session keys. If set to true will
* use the session keys identified by the mki_index
*
* @param mki_index integer value specifying which set of session kesy should be
* used if use_mki is set to true.
*
* @return
* - srtp_err_status_ok if there were no problems.
* - [other] if there was a failure in
* the cryptographic mechanisms.
*/

srtp_err_status_t srtp_protect_rtcp_mki(srtp_t ctx, void *rtcp_hdr, int *pkt_octet_len,
unsigned int use_mki, unsigned int mki_index);

/**
* @brief srtp_unprotect_rtcp() is the Secure RTCP receiver-side packet
* processing function.
Expand Down Expand Up @@ -1286,6 +1459,50 @@ srtp_err_status_t srtp_protect_rtcp(srtp_t ctx, void *rtcp_hdr, int *pkt_octet_l

srtp_err_status_t srtp_unprotect_rtcp(srtp_t ctx, void *srtcp_hdr, int *pkt_octet_len);

/**
* @brief srtp_unprotect_rtcp() is the Secure RTCP receiver-side packet
* processing function.
*
* The function call srtp_unprotect_rtcp(ctx, srtp_hdr, len_ptr)
* verifies the Secure RTCP protection of the SRTCP packet pointed to
* by srtcp_hdr (which has length *len_ptr), using the SRTP session
* context ctx. If srtp_err_status_ok is returned, then srtcp_hdr points
* to the resulting RTCP packet and *len_ptr is the number of octets
* in that packet; otherwise, no assumptions should be made about the
* value of either data elements.
*
* @warning This function assumes that the SRTCP packet is aligned on a
* 32-bit boundary.
*
* @param ctx is a pointer to the srtp_t which applies to the
* particular packet.
*
* @param srtcp_hdr is a pointer to the header of the SRTCP packet
* (before the call). After the function returns, it points to the
* rtp packet if srtp_err_status_ok was returned; otherwise, the value of
* the data to which it points is undefined.
*
* @param pkt_octet_len is a pointer to the length in octets of the
* complete SRTCP packet (header and body) before the function call,
* and of the complete rtp packet after the call, if srtp_err_status_ok was
* returned. Otherwise, the value of the data to which it points is
* undefined.
*
* @return
* - srtp_err_status_ok if the RTCP packet is valid.
* - srtp_err_status_auth_fail if the SRTCP packet failed the message
* authentication check.
* - srtp_err_status_replay_fail if the SRTCP packet is a replay (e.g. has
* already been processed and accepted).
* - srtp_err_status_bad_mki if the MKI in the packet is not a known MKI id
* - [other] if there has been an error in the cryptographic mechanisms.
*
*/

srtp_err_status_t srtp_unprotect_rtcp_mki(srtp_t ctx, void *srtcp_hdr,
int *pkt_octet_len,
unsigned int use_mki);

/**
* @}
*/
Expand Down Expand Up @@ -1468,6 +1685,30 @@ srtp_err_status_t srtp_set_debug_module(char *mod_name, int v);
*/
srtp_err_status_t srtp_list_debug_modules(void);

/**
* @brief srtp_get_protect_trailer_length(session, use_mki, mki_index, length)
*
* Determines the length of the amount of data Lib SRTP will add to the
* packet during the protect process. The length is returned in the length parameter
*
* returns err_status_ok on success, err_status_bad_mki if the MKI index is invalid
*
*/
srtp_err_status_t srtp_get_protect_trailer_length(srtp_t session, uint32_t use_mki,
uint32_t mki_index, uint32_t *length);

/**
* @brief srtp_get_protect_rtcp_trailer_length(session, use_mki, mki_index, length)
*
* Determines the length of the amount of data Lib SRTP will add to the
* packet during the protect process. The length is returned in the length parameter
*
* returns err_status_ok on success, err_status_bad_mki if the MKI index is invalid
*
*/
srtp_err_status_t srtp_get_protect_rtcp_trailer_length(srtp_t session, uint32_t use_mki,
uint32_t mki_index, uint32_t *length);


/**
* @}
Expand Down
42 changes: 33 additions & 9 deletions include/srtp_priv.h
Expand Up @@ -81,7 +81,18 @@ srtp_stream_t srtp_get_stream(srtp_t srtp, uint32_t ssrc);
* srtp_stream_init_keys(s, k) (re)initializes the srtp_stream_t s by
* deriving all of the needed keys using the KDF and the key k.
*/
srtp_err_status_t srtp_stream_init_keys(srtp_stream_t srtp, const void *key);
srtp_err_status_t srtp_stream_init_keys(srtp_stream_ctx_t *srtp,
srtp_master_key_t *master_key,
const unsigned int current_mki_index);

/*
* srtp_stream_init_all_master_keys(s, k, m) (re)initializes the srtp_stream_t s by
* deriving all of the needed keys for all the master keys using the KDF and the keys from k.
*/
srtp_err_status_t srtp_steam_init_all_master_keys(srtp_stream_ctx_t *srtp,
unsigned char *key,
srtp_master_key_t **keys,
const unsigned int max_master_keys);

/*
* srtp_stream_init(s, p) initializes the srtp_stream_t s to
Expand All @@ -100,6 +111,25 @@ typedef enum direction_t {
dir_srtp_receiver = 2
} direction_t;

/*
* srtp_session_keys_t will contain the encryption, hmac, salt keys
* for both SRTP and SRTCP. The session keys will also contain the
* MKI ID which is used to identify the session keys.
*/
typedef struct srtp_session_keys_t {
srtp_cipher_t *rtp_cipher;
srtp_cipher_t *rtp_xtn_hdr_cipher;
srtp_auth_t *rtp_auth;
srtp_cipher_t *rtcp_cipher;
srtp_auth_t *rtcp_auth;
uint8_t salt[SRTP_AEAD_SALT_LEN];
uint8_t c_salt[SRTP_AEAD_SALT_LEN];
uint8_t *mki_id;
unsigned int mki_size;
srtp_key_limit_ctx_t *limit;
} srtp_session_keys_t;


/*
* an srtp_stream_t has its own SSRC, encryption key, authentication
* key, sequence number, and replay database
Expand All @@ -110,21 +140,15 @@ typedef enum direction_t {

typedef struct srtp_stream_ctx_t_ {
uint32_t ssrc;
srtp_cipher_t *rtp_cipher;
srtp_cipher_t *rtp_xtn_hdr_cipher;
srtp_auth_t *rtp_auth;
srtp_session_keys_t *session_keys;
unsigned int num_master_keys;
srtp_rdbx_t rtp_rdbx;
srtp_sec_serv_t rtp_services;
srtp_cipher_t *rtcp_cipher;
srtp_auth_t *rtcp_auth;
srtp_rdb_t rtcp_rdb;
srtp_sec_serv_t rtcp_services;
srtp_key_limit_ctx_t *limit;
direction_t direction;
int allow_repeat_tx;
srtp_ekt_stream_t ekt;
uint8_t salt[SRTP_AEAD_SALT_LEN]; /* used with GCM mode for SRTP */
uint8_t c_salt[SRTP_AEAD_SALT_LEN]; /* used with GCM mode for SRTCP */
int *enc_xtn_hdr;
int enc_xtn_hdr_count;
struct srtp_stream_ctx_t_ *next; /* linked list of streams */
Expand Down

0 comments on commit 29c6509

Please sign in to comment.