mirror of
https://github.com/ossrs/srs.git
synced 2025-03-09 15:49:59 +00:00
SRT: Build SRT from source by SRS. 4.0.115
This commit is contained in:
parent
262f0fc8c8
commit
90f1b482ab
115 changed files with 44513 additions and 19 deletions
22
trunk/3rdparty/srt-1-fit/haicrypt/cryspr-config.h
vendored
Normal file
22
trunk/3rdparty/srt-1-fit/haicrypt/cryspr-config.h
vendored
Normal file
|
@ -0,0 +1,22 @@
|
|||
#ifndef INC__CRYSPR_CONFIG_H
|
||||
#define INC__CRYSPR_CONFIG_H
|
||||
|
||||
// Size of the single block for encryption.
|
||||
// This might need tweaking for particular implementation library.
|
||||
#define CRYSPR_AESBLKSZ 16 /* 128-bit */
|
||||
|
||||
#if defined(USE_OPENSSL)
|
||||
#include "cryspr-openssl.h"
|
||||
#define cryspr4SRT() crysprOpenSSL()
|
||||
#elif defined(USE_GNUTLS)
|
||||
#include "cryspr-gnutls.h"
|
||||
#define cryspr4SRT() crysprGnuTLS()
|
||||
#elif defined(USE_MBEDTLS)
|
||||
#include "cryspr-mbedtls.h"
|
||||
#define cryspr4SRT() crysprMbedtls()
|
||||
#else
|
||||
#error Cryspr implementation not selected. Please define USE_* + OPENSSL/GNUTLS/MBEDTLS.
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
178
trunk/3rdparty/srt-1-fit/haicrypt/cryspr-gnutls.c
vendored
Normal file
178
trunk/3rdparty/srt-1-fit/haicrypt/cryspr-gnutls.c
vendored
Normal file
|
@ -0,0 +1,178 @@
|
|||
/*
|
||||
* SRT - Secure, Reliable, Transport
|
||||
* Copyright (c) 2019 Haivision Systems Inc.
|
||||
*
|
||||
* 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/.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
written by
|
||||
Haivision Systems Inc.
|
||||
|
||||
2019-06-27 (jdube)
|
||||
GnuTLS/Nettle CRYSPR/4SRT (CRYypto Service PRovider for SRT)
|
||||
*****************************************************************************/
|
||||
|
||||
#include "hcrypt.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
typedef struct tag_crysprGnuTLS_AES_cb {
|
||||
CRYSPR_cb ccb; /* CRYSPR control block */
|
||||
/* Add other cryptolib specific data here */
|
||||
} crysprGnuTLS_cb;
|
||||
|
||||
|
||||
int crysprGnuTLS_Prng(unsigned char *rn, int len)
|
||||
{
|
||||
return(gnutls_rnd(GNUTLS_RND_KEY,(rn),(len)) < 0 ? -1 : 0);
|
||||
}
|
||||
|
||||
int crysprGnuTLS_AES_SetKey(
|
||||
bool bEncrypt, /* true:encrypt key, false:decrypt key*/
|
||||
const unsigned char *kstr, /* key string */
|
||||
size_t kstr_len, /* kstr length in bytes (16, 24, or 32 bytes (for AES128,AES192, or AES256) */
|
||||
CRYSPR_AESCTX *aes_key) /* Cryptolib Specific AES key context */
|
||||
{
|
||||
if (bEncrypt) { /* Encrypt key */
|
||||
if (!(kstr_len == 16 || kstr_len == 24 || kstr_len == 32)) {
|
||||
HCRYPT_LOG(LOG_ERR, "%s", "AES_set_encrypt_key(kek) bad length\n");
|
||||
return -1;
|
||||
}
|
||||
aes_set_encrypt_key (aes_key, kstr_len, kstr);
|
||||
} else { /* Decrypt key */
|
||||
if (!(kstr_len == 16 || kstr_len == 24 || kstr_len == 32)) {
|
||||
HCRYPT_LOG(LOG_ERR, "%s", "AES_set_decrypt_key(kek) bad length\n");
|
||||
return -1;
|
||||
}
|
||||
aes_set_decrypt_key (aes_key, kstr_len, kstr);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
int crysprGnuTLS_AES_EcbCipher( /* AES Electronic Codebook cipher*/
|
||||
bool bEncrypt, /* true:encrypt, false:decrypt */
|
||||
CRYSPR_AESCTX *aes_key, /* CryptoLib AES context */
|
||||
const unsigned char *indata,/* src (clear text)*/
|
||||
size_t inlen, /* length */
|
||||
unsigned char *out_txt, /* dst (cipher text) */
|
||||
size_t *outlen) /* dst len */
|
||||
{
|
||||
int nblk = inlen/CRYSPR_AESBLKSZ;
|
||||
int nmore = inlen%CRYSPR_AESBLKSZ;
|
||||
int i;
|
||||
|
||||
if (bEncrypt) {
|
||||
/* Encrypt packet payload, block by block, in output buffer */
|
||||
for (i=0; i<nblk; i++){
|
||||
aes_encrypt(aes_key, CRYSPR_AESBLKSZ, &out_txt[(i*CRYSPR_AESBLKSZ)], &indata[(i*CRYSPR_AESBLKSZ)]);
|
||||
}
|
||||
/* Encrypt last incomplete block */
|
||||
if (0 < nmore) {
|
||||
unsigned char intxt[CRYSPR_AESBLKSZ];
|
||||
|
||||
memcpy(intxt, &indata[(nblk*CRYSPR_AESBLKSZ)], nmore);
|
||||
memset(intxt+nmore, 0, CRYSPR_AESBLKSZ-nmore);
|
||||
aes_encrypt(aes_key, CRYSPR_AESBLKSZ, &out_txt[(nblk*CRYSPR_AESBLKSZ)], intxt);
|
||||
nblk++;
|
||||
}
|
||||
if (outlen != NULL) *outlen = nblk*CRYSPR_AESBLKSZ;
|
||||
} else { /* Decrypt */
|
||||
for (i=0; i<nblk; i++){
|
||||
aes_decrypt(aes_key, CRYSPR_AESBLKSZ, &out_txt[(i*CRYSPR_AESBLKSZ)], &indata[(i*CRYSPR_AESBLKSZ)]);
|
||||
}
|
||||
/* Encrypt last incomplete block */
|
||||
if (0 < nmore) {
|
||||
//shall not happens in decrypt
|
||||
}
|
||||
if (outlen != NULL) *outlen = nblk*CRYSPR_AESBLKSZ;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int crysprGnuTLS_AES_CtrCipher( /* AES-CTR128 Encryption */
|
||||
bool bEncrypt, /* true:encrypt, false:decrypt */
|
||||
CRYSPR_AESCTX *aes_key, /* CryptoLib AES context */
|
||||
unsigned char *iv, /* iv */
|
||||
const unsigned char *indata,/* src */
|
||||
size_t inlen, /* src length */
|
||||
unsigned char *out_txt) /* dest buffer[inlen] */
|
||||
{
|
||||
(void)bEncrypt; /* CTR mode encrypt for both encryption and decryption */
|
||||
|
||||
ctr_crypt (aes_key, /* ctx */
|
||||
(nettle_cipher_func*)aes_encrypt, /* nettle_cipher_func */
|
||||
CRYSPR_AESBLKSZ, /* cipher blocksize */
|
||||
iv, /* iv */
|
||||
inlen, /* length */
|
||||
out_txt, /* dest */
|
||||
indata); /* src */
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CRYSPR_HAS_PBKDF2
|
||||
/*
|
||||
* Password-based Key Derivation Function
|
||||
*/
|
||||
int crysprGnuTLS_KmPbkdf2(
|
||||
CRYSPR_cb *cryspr_cb,
|
||||
char *passwd, /* passphrase */
|
||||
size_t passwd_len, /* passphrase len */
|
||||
unsigned char *salt, /* salt */
|
||||
size_t salt_len, /* salt_len */
|
||||
int itr, /* iterations */
|
||||
size_t key_len, /* key_len */
|
||||
unsigned char *out) /* derived key buffer[key_len]*/
|
||||
{
|
||||
(void)cryspr_cb;
|
||||
|
||||
pbkdf2_hmac_sha1(passwd_len,(const uint8_t *)passwd,itr,salt_len,salt,key_len,out);
|
||||
return(0);
|
||||
}
|
||||
#endif /* CRYSPR_HAS_PBKDF2 */
|
||||
|
||||
static CRYSPR_methods crysprGnuTLS_methods;
|
||||
|
||||
CRYSPR_methods *crysprGnuTLS(void)
|
||||
{
|
||||
if(NULL == crysprGnuTLS_methods.open) {
|
||||
crysprInit(&crysprGnuTLS_methods); /* Set default methods */
|
||||
|
||||
/* CryptoLib Primitive API */
|
||||
crysprGnuTLS_methods.prng = crysprGnuTLS_Prng;
|
||||
crysprGnuTLS_methods.aes_set_key = crysprGnuTLS_AES_SetKey;
|
||||
#if CRYSPR_HAS_AESCTR
|
||||
crysprGnuTLS_methods.aes_ctr_cipher = crysprGnuTLS_AES_CtrCipher;
|
||||
#endif
|
||||
#if !(CRYSPR_HAS_AESCTR && CRYSPR_HAS_AESKWRAP)
|
||||
/* AES-ECB only required if cryspr has no AES-CTR or no AES KeyWrap */
|
||||
crysprGnuTLS_methods.aes_ecb_cipher = crysprGnuTLS_AES_EcbCipher;
|
||||
#endif
|
||||
#if !CRYSPR_HAS_PBKDF2
|
||||
crysprGnuTLS_methods.sha1_msg_digest= crysprGnuTLS_SHA1_MsgDigest; //Onl required if using generic KmPbkdf2
|
||||
#endif
|
||||
|
||||
//--Crypto Session (Top API)
|
||||
// crysprGnuTLS_methods.open =
|
||||
// crysprGnuTLS_methods.close =
|
||||
//--Keying material (km) encryption
|
||||
#if CRYSPR_HAS_PBKDF2
|
||||
crysprGnuTLS_methods.km_pbkdf2 = crysprGnuTLS_KmPbkdf2;
|
||||
#endif
|
||||
// crysprGnuTLS_methods.km_setkey =
|
||||
// crysprGnuTLS_methods.km_wrap =
|
||||
// crysprGnuTLS_methods.km_unwrap =
|
||||
//--Media stream (ms) encryption
|
||||
// crysprGnuTLS_methods.ms_setkey =
|
||||
// crysprGnuTLS_methods.ms_encrypt =
|
||||
// crysprGnuTLS_methods.ms_decrypt =
|
||||
}
|
||||
return(&crysprGnuTLS_methods);
|
||||
}
|
||||
|
||||
|
||||
|
61
trunk/3rdparty/srt-1-fit/haicrypt/cryspr-gnutls.h
vendored
Normal file
61
trunk/3rdparty/srt-1-fit/haicrypt/cryspr-gnutls.h
vendored
Normal file
|
@ -0,0 +1,61 @@
|
|||
/*
|
||||
* SRT - Secure, Reliable, Transport
|
||||
* Copyright (c) 2019 Haivision Systems Inc.
|
||||
*
|
||||
* 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/.
|
||||
*
|
||||
*/
|
||||
|
||||
/*****************************************************************************
|
||||
written by
|
||||
Haivision Systems Inc.
|
||||
|
||||
2019-06-27 (jdube)
|
||||
GnuTLS/Nettle CRYSPR/4SRT (CRYypto Service PRovider for SRT)
|
||||
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef CRYSPR_GNUTLS_H
|
||||
#define CRYSPR_GNUTLS_H
|
||||
|
||||
#include <gnutls/gnutls.h>
|
||||
#include <gnutls/crypto.h> //gnutls_rnd()
|
||||
|
||||
#include <nettle/aes.h> //has AES cipher
|
||||
#include <nettle/ctr.h> //has CTR cipher mode
|
||||
#include <nettle/pbkdf2.h> //has Password-based Key Derivation Function 2
|
||||
//#include <nettle/sha1.h> //No need for sha1 since we have pbkdf2
|
||||
|
||||
|
||||
/* Define CRYSPR_HAS_AESCTR to 1 if this CRYSPR has AESCTR cipher mode
|
||||
if not set it 0 to use enable CTR cipher mode implementation using ECB cipher mode
|
||||
and provide the aes_ecb_cipher method.
|
||||
*/
|
||||
#define CRYSPR_HAS_AESCTR 1
|
||||
|
||||
/* Define CRYSPR_HAS_AESKWRAP to 1 if this CRYSPR has AES Key Wrap
|
||||
if not set to 0 to enable default/fallback crysprFallback_AES_WrapKey/crysprFallback_AES_UnwrapKey methods
|
||||
and provide the aes_ecb_cipher method .
|
||||
*/
|
||||
#define CRYSPR_HAS_AESKWRAP 0
|
||||
|
||||
/* Define CRYSPR_HAS_PBKDF2 to 1 if this CRYSPR has SHA1-HMAC Password-based Key Derivaion Function 2
|
||||
if not set to 0 to enable not-yet-implemented/fallback crysprFallback.km_pbkdf2 method
|
||||
and provide the sha1_msg_digest method.
|
||||
*/
|
||||
#define CRYSPR_HAS_PBKDF2 1
|
||||
|
||||
/*
|
||||
#define CRYSPR_AESCTX to the CRYSPR specifix AES key context object.
|
||||
This type reserves room in the CRYPSPR control block for Haicrypt KEK and SEK
|
||||
It is set from hte keystring through CRYSPR_methods.aes_set_key and passed
|
||||
to CRYSPR_methods.aes_XXX.
|
||||
*/
|
||||
typedef struct aes_ctx CRYSPR_AESCTX; /* CRYpto Service PRovider AES key context */
|
||||
|
||||
struct tag_CRYSPR_methods *crysprGnuTLS(void);
|
||||
|
||||
#endif /* CRYSPR_GNUTLS_H */
|
||||
|
235
trunk/3rdparty/srt-1-fit/haicrypt/cryspr-mbedtls.c
vendored
Normal file
235
trunk/3rdparty/srt-1-fit/haicrypt/cryspr-mbedtls.c
vendored
Normal file
|
@ -0,0 +1,235 @@
|
|||
/*
|
||||
* SRT - Secure, Reliable, Transport
|
||||
* Copyright (c) 2019 Haivision Systems Inc.
|
||||
*
|
||||
* 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/.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
written by
|
||||
Haivision Systems Inc.
|
||||
|
||||
2019-06-27 (jdube)
|
||||
GnuTLS/Nettle CRYSPR/4SRT (CRYypto Service PRovider for SRT)
|
||||
*****************************************************************************/
|
||||
|
||||
#include "hcrypt.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <mbedtls/aes.h>
|
||||
#include <mbedtls/md.h>
|
||||
#include <mbedtls/pkcs5.h>
|
||||
#include <mbedtls/entropy.h>
|
||||
|
||||
// Static members of cryspr::mbedtls class.
|
||||
static mbedtls_ctr_drbg_context crysprMbedtls_ctr_drbg;
|
||||
static mbedtls_entropy_context crysprMbedtls_entropy;
|
||||
static mbedtls_md_context_t crysprMbedtls_mdctx;
|
||||
|
||||
typedef struct tag_crysprGnuTLS_AES_cb {
|
||||
CRYSPR_cb ccb; /* CRYSPR control block */
|
||||
/* Add other cryptolib specific data here */
|
||||
} crysprMbedtls_cb;
|
||||
|
||||
|
||||
int crysprMbedtls_Prng(unsigned char *rn, int len)
|
||||
{
|
||||
int ret = mbedtls_ctr_drbg_random( &crysprMbedtls_ctr_drbg, rn, len );
|
||||
if (ret != 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int crysprMbedtls_AES_SetKey(
|
||||
bool bEncrypt, /* true:encrypt key, false:decrypt key*/
|
||||
const unsigned char *kstr, /* key string */
|
||||
size_t kstr_len, /* kstr length in bytes (16, 24, or 32 bytes, for AES128,AES192, or AES256) */
|
||||
CRYSPR_AESCTX *aes_key) /* Cryptolib Specific AES key context */
|
||||
{
|
||||
if (!(kstr_len == 16 || kstr_len == 24 || kstr_len == 32)) {
|
||||
HCRYPT_LOG(LOG_ERR, "%s", "AES_set_encrypt_key(kek) bad length\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
int ret;
|
||||
|
||||
// mbedtls uses the "bits" convention (128, 192, 254), just like openssl.
|
||||
// kstr_len is in "bytes" convention (16, 24, 32).
|
||||
|
||||
if (bEncrypt) { /* Encrypt key */
|
||||
ret = mbedtls_aes_setkey_enc(aes_key, kstr, kstr_len*8);
|
||||
} else { /* Decrypt key */
|
||||
ret = mbedtls_aes_setkey_dec(aes_key, kstr, kstr_len*8);
|
||||
}
|
||||
|
||||
return ret == 0 ? 0 : -1;
|
||||
}
|
||||
|
||||
int crysprMbedtls_AES_EcbCipher( /* AES Electronic Codebook cipher*/
|
||||
bool bEncrypt, /* true:encrypt, false:decrypt */
|
||||
CRYSPR_AESCTX *aes_key, /* CryptoLib AES context */
|
||||
const unsigned char *indata,/* src (clear text)*/
|
||||
size_t inlen, /* length */
|
||||
unsigned char *out_txt, /* dst (cipher text) */
|
||||
size_t *outlen) /* dst len */
|
||||
{
|
||||
int nblk = inlen/CRYSPR_AESBLKSZ;
|
||||
int nmore = inlen%CRYSPR_AESBLKSZ;
|
||||
int i;
|
||||
|
||||
if (bEncrypt) {
|
||||
/* Encrypt packet payload, block by block, in output buffer */
|
||||
for (i = 0; i < nblk; i++) {
|
||||
// NOTE: CRYSPR_AESBLKSZ is implicitly the ONLY POSSIBLE
|
||||
// size of the block.
|
||||
mbedtls_aes_crypt_ecb(aes_key, MBEDTLS_AES_ENCRYPT,
|
||||
&indata[(i*CRYSPR_AESBLKSZ)],
|
||||
&out_txt[(i*CRYSPR_AESBLKSZ)]);
|
||||
}
|
||||
/* Encrypt last incomplete block */
|
||||
if (0 < nmore) {
|
||||
unsigned char intxt[CRYSPR_AESBLKSZ];
|
||||
|
||||
memcpy(intxt, &indata[(nblk*CRYSPR_AESBLKSZ)], nmore);
|
||||
memset(intxt+nmore, 0, CRYSPR_AESBLKSZ-nmore);
|
||||
mbedtls_aes_crypt_ecb(aes_key, MBEDTLS_AES_ENCRYPT,
|
||||
intxt,
|
||||
&out_txt[(nblk*CRYSPR_AESBLKSZ)]);
|
||||
nblk++;
|
||||
}
|
||||
if (outlen != NULL) *outlen = nblk*CRYSPR_AESBLKSZ;
|
||||
} else { /* Decrypt */
|
||||
for (i=0; i<nblk; i++){
|
||||
mbedtls_aes_crypt_ecb(aes_key, MBEDTLS_AES_DECRYPT,
|
||||
&indata[(i*CRYSPR_AESBLKSZ)],
|
||||
&out_txt[(i*CRYSPR_AESBLKSZ)]);
|
||||
}
|
||||
/* Encrypt last incomplete block */
|
||||
if (0 < nmore) {
|
||||
//shall not happens in decrypt
|
||||
}
|
||||
if (outlen != NULL) *outlen = nblk*CRYSPR_AESBLKSZ;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int crysprMbedtls_AES_CtrCipher( /* AES-CTR128 Encryption */
|
||||
bool bEncrypt, /* true:encrypt, false:decrypt */
|
||||
CRYSPR_AESCTX *aes_key, /* CryptoLib AES context */
|
||||
unsigned char *iv, /* iv */
|
||||
const unsigned char *indata,/* src */
|
||||
size_t inlen, /* src length */
|
||||
unsigned char *out_txt) /* dest buffer[inlen] */
|
||||
{
|
||||
unsigned char ctr[CRYSPR_AESBLKSZ];
|
||||
size_t blk_ofs = 0;
|
||||
(void)bEncrypt; /* CTR mode encrypt for both encryption and decryption */
|
||||
|
||||
memset(&ctr[0], 0, sizeof(ctr));
|
||||
|
||||
mbedtls_aes_crypt_ctr(aes_key,
|
||||
inlen,
|
||||
&blk_ofs,
|
||||
iv,
|
||||
ctr,
|
||||
indata,
|
||||
out_txt);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Password-based Key Derivation Function
|
||||
*/
|
||||
int crysprMbedtls_KmPbkdf2(
|
||||
CRYSPR_cb *cryspr_cb,
|
||||
char *passwd, /* passphrase */
|
||||
size_t passwd_len, /* passphrase len */
|
||||
unsigned char *salt, /* salt */
|
||||
size_t salt_len, /* salt_len */
|
||||
int itr, /* iterations */
|
||||
size_t key_len, /* key_len */
|
||||
unsigned char *out) /* derived key buffer[key_len]*/
|
||||
{
|
||||
(void)cryspr_cb;
|
||||
|
||||
int ret = mbedtls_pkcs5_pbkdf2_hmac(&crysprMbedtls_mdctx,
|
||||
(unsigned char*)passwd, passwd_len, salt, salt_len,
|
||||
itr, key_len, out);
|
||||
|
||||
if (ret == 0)
|
||||
return 0;
|
||||
|
||||
// XXX report error, log?
|
||||
return -1;
|
||||
}
|
||||
|
||||
static CRYSPR_methods crysprMbedtls_methods;
|
||||
|
||||
CRYSPR_methods *crysprMbedtls(void)
|
||||
{
|
||||
if (crysprMbedtls_methods.open)
|
||||
return(&crysprMbedtls_methods);
|
||||
|
||||
crysprInit(&crysprMbedtls_methods); /* Set default methods */
|
||||
|
||||
/* CryptoLib Primitive API */
|
||||
crysprMbedtls_methods.prng = crysprMbedtls_Prng;
|
||||
crysprMbedtls_methods.aes_set_key = crysprMbedtls_AES_SetKey;
|
||||
#if CRYSPR_HAS_AESCTR
|
||||
crysprMbedtls_methods.aes_ctr_cipher = crysprMbedtls_AES_CtrCipher;
|
||||
#endif
|
||||
#if !(CRYSPR_HAS_AESCTR && CRYSPR_HAS_AESKWRAP)
|
||||
/* AES-ECB only required if cryspr has no AES-CTR or no AES KeyWrap */
|
||||
crysprMbedtls_methods.aes_ecb_cipher = crysprMbedtls_AES_EcbCipher;
|
||||
#endif
|
||||
#if !CRYSPR_HAS_PBKDF2
|
||||
crysprMbedtls_methods.sha1_msg_digest= crysprMbedtls_SHA1_MsgDigest; //Onl required if using generic KmPbkdf2
|
||||
#endif
|
||||
|
||||
//--Crypto Session (Top API)
|
||||
// crysprMbedtls_methods.open =
|
||||
// crysprMbedtls_methods.close =
|
||||
//--Keying material (km) encryption
|
||||
crysprMbedtls_methods.km_pbkdf2 = crysprMbedtls_KmPbkdf2;
|
||||
// crysprMbedtls_methods.km_setkey =
|
||||
// crysprMbedtls_methods.km_wrap =
|
||||
// crysprMbedtls_methods.km_unwrap =
|
||||
//--Media stream (ms) encryption
|
||||
// crysprMbedtls_methods.ms_setkey =
|
||||
// crysprMbedtls_methods.ms_encrypt =
|
||||
// crysprMbedtls_methods.ms_decrypt =
|
||||
|
||||
// Initialize extra static data
|
||||
mbedtls_entropy_init( &crysprMbedtls_entropy );
|
||||
mbedtls_ctr_drbg_init( &crysprMbedtls_ctr_drbg );
|
||||
|
||||
int ret;
|
||||
if ( (ret = mbedtls_ctr_drbg_seed( &crysprMbedtls_ctr_drbg, mbedtls_entropy_func,
|
||||
&crysprMbedtls_entropy, NULL, 0)) != 0 )
|
||||
{
|
||||
HCRYPT_LOG(LOG_CRIT, "crysprMbedtls: STATIC INIT FAILED on mbedtls_ctr_drbg_init: -0x%04x", -ret);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Ok, mbedtls with all flexibility you couldn't make it more complicated.
|
||||
|
||||
mbedtls_md_init(&crysprMbedtls_mdctx);
|
||||
const mbedtls_md_info_t* ifo = mbedtls_md_info_from_type(MBEDTLS_MD_SHA1);
|
||||
const int yes_use_hmac = 1;
|
||||
mbedtls_md_setup(&crysprMbedtls_mdctx, ifo, yes_use_hmac);
|
||||
|
||||
|
||||
return(&crysprMbedtls_methods);
|
||||
}
|
||||
|
||||
|
||||
|
63
trunk/3rdparty/srt-1-fit/haicrypt/cryspr-mbedtls.h
vendored
Normal file
63
trunk/3rdparty/srt-1-fit/haicrypt/cryspr-mbedtls.h
vendored
Normal file
|
@ -0,0 +1,63 @@
|
|||
/*
|
||||
* SRT - Secure, Reliable, Transport
|
||||
* Copyright (c) 2019 Haivision Systems Inc.
|
||||
*
|
||||
* 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/.
|
||||
*
|
||||
*/
|
||||
|
||||
/*****************************************************************************
|
||||
written by
|
||||
Haivision Systems Inc.
|
||||
|
||||
2019-06-27 (jdube)
|
||||
GnuTLS/Nettle CRYSPR/4SRT (CRYypto Service PRovider for SRT)
|
||||
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef CRYSPR_GNUTLS_H
|
||||
#define CRYSPR_GNUTLS_H
|
||||
|
||||
#include <mbedtls/ctr_drbg.h>
|
||||
#include <mbedtls/aes.h>
|
||||
|
||||
|
||||
/* Define CRYSPR_HAS_AESCTR to 1 if this CRYSPR has AESCTR cipher mode
|
||||
if not set it 0 to use enable CTR cipher mode implementation using ECB cipher mode
|
||||
and provide the aes_ecb_cipher method.
|
||||
*/
|
||||
#define CRYSPR_HAS_AESCTR 1
|
||||
|
||||
/* Define CRYSPR_HAS_AESKWRAP to 1 if this CRYSPR has AES Key Wrap
|
||||
if not set to 0 to enable default/fallback crysprFallback_AES_WrapKey/crysprFallback_AES_UnwrapKey methods
|
||||
and provide the aes_ecb_cipher method .
|
||||
*/
|
||||
#define CRYSPR_HAS_AESKWRAP 0
|
||||
|
||||
/* Define CRYSPR_HAS_PBKDF2 to 1 if this CRYSPR has SHA1-HMAC Password-based Key Derivaion Function 2
|
||||
if not set to 0 to enable not-yet-implemented/fallback crysprFallback.km_pbkdf2 method
|
||||
and provide the sha1_msg_digest method.
|
||||
*/
|
||||
#define CRYSPR_HAS_PBKDF2 1
|
||||
|
||||
// mbedtls uses in the enc/dec functions 16-byte blocks
|
||||
// for xcryption. This is not marked by any constant. See
|
||||
// e.g. <mbedtls/aes.h>, mbedtls_aes_crypt_ecb signature.
|
||||
#if CRYSPR_AESBLKSZ != 16
|
||||
#error mbedtls requires AES single block size 16 bytes, implicitly.
|
||||
#endif
|
||||
|
||||
/*
|
||||
#define CRYSPR_AESCTX to the CRYSPR specifix AES key context object.
|
||||
This type reserves room in the CRYPSPR control block for Haicrypt KEK and SEK
|
||||
It is set from hte keystring through CRYSPR_methods.aes_set_key and passed
|
||||
to CRYSPR_methods.aes_XXX.
|
||||
*/
|
||||
typedef struct mbedtls_aes_context CRYSPR_AESCTX; /* CRYpto Service PRovider AES key context */
|
||||
|
||||
struct tag_CRYSPR_methods *crysprMbedtls(void);
|
||||
|
||||
#endif /* CRYSPR_GNUTLS_H */
|
||||
|
218
trunk/3rdparty/srt-1-fit/haicrypt/cryspr-openssl.c
vendored
Normal file
218
trunk/3rdparty/srt-1-fit/haicrypt/cryspr-openssl.c
vendored
Normal file
|
@ -0,0 +1,218 @@
|
|||
/*
|
||||
* SRT - Secure, Reliable, Transport
|
||||
* Copyright (c) 2019 Haivision Systems Inc.
|
||||
*
|
||||
* 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/.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
written by
|
||||
Haivision Systems Inc.
|
||||
|
||||
2019-06-26 (jdube)
|
||||
OpenSSL CRYSPR/4SRT (CRYypto Service PRovider for SRT).
|
||||
*****************************************************************************/
|
||||
|
||||
#include "hcrypt.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
|
||||
typedef struct tag_crysprOpenSSL_AES_cb {
|
||||
CRYSPR_cb ccb;
|
||||
/* Add cryptolib specific data here */
|
||||
} crysprOpenSSL_cb;
|
||||
|
||||
|
||||
int crysprOpenSSL_Prng(unsigned char *rn, int len)
|
||||
{
|
||||
return(RAND_bytes(rn, len) <= 0 ? -1 : 0);
|
||||
}
|
||||
|
||||
int crysprOpenSSL_AES_SetKey(
|
||||
bool bEncrypt, /* true Enxcrypt key, false: decrypt */
|
||||
const unsigned char *kstr, /* key sttring*/
|
||||
size_t kstr_len, /* kstr len in bytes (16, 24, or 32 bytes (for AES128,AES192, or AES256) */
|
||||
CRYSPR_AESCTX *aes_key) /* CRYpto Service PRovider AES Key context */
|
||||
{
|
||||
if (bEncrypt) { /* Encrypt key */
|
||||
if (AES_set_encrypt_key(kstr, kstr_len * 8, aes_key)) {
|
||||
HCRYPT_LOG(LOG_ERR, "%s", "AES_set_encrypt_key(kek) failed\n");
|
||||
return(-1);
|
||||
}
|
||||
} else { /* Decrypt key */
|
||||
if (AES_set_decrypt_key(kstr, kstr_len * 8, aes_key)) {
|
||||
HCRYPT_LOG(LOG_ERR, "%s", "AES_set_decrypt_key(kek) failed\n");
|
||||
return(-1);
|
||||
}
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
#if !(CRYSPR_HAS_AESCTR && CRYSPR_HAS_AESKWRAP)
|
||||
|
||||
int crysprOpenSSL_AES_EcbCipher(
|
||||
bool bEncrypt, /* true:encrypt, false:decrypt */
|
||||
CRYSPR_AESCTX *aes_key, /* CRYpto Service PRovider AES Key context */
|
||||
const unsigned char *indata,/* src (clear text if encrypt, cipher text otherwise)*/
|
||||
size_t inlen, /* indata length */
|
||||
unsigned char *out_txt, /* dst (cipher text if encrypt, clear text otherwise) */
|
||||
size_t *outlen) /* in/out dst len */
|
||||
{
|
||||
int nblk = inlen/CRYSPR_AESBLKSZ;
|
||||
int nmore = inlen%CRYSPR_AESBLKSZ;
|
||||
size_t outsiz = (outlen ? *outlen : 0);
|
||||
int i;
|
||||
|
||||
if (outsiz % CRYSPR_AESBLKSZ) return(-1); /* output buf size must be a multiple of AES block size (16) */
|
||||
if (bEncrypt) {
|
||||
if (outsiz > 16 && outsiz < (nblk+nmore)*CRYSPR_AESBLKSZ) return(-1); /* output buf size must have room for PKCS7 padding */
|
||||
/* Encrypt packet payload, block by block, in output buffer */
|
||||
for (i=0; i<nblk; i++){
|
||||
AES_ecb_encrypt(&indata[(i*CRYSPR_AESBLKSZ)],
|
||||
&out_txt[(i*CRYSPR_AESBLKSZ)], aes_key, AES_ENCRYPT);
|
||||
}
|
||||
/* Encrypt last incomplete block */
|
||||
if (0 < nmore) {
|
||||
unsigned char intxt[CRYSPR_AESBLKSZ];
|
||||
/* PKCS7 padding: padding value is number of bytes padded */
|
||||
memcpy(intxt, &indata[(nblk*CRYSPR_AESBLKSZ)], nmore);
|
||||
memset(intxt+nmore, CRYSPR_AESBLKSZ-nmore, CRYSPR_AESBLKSZ-nmore);
|
||||
AES_ecb_encrypt(intxt, &out_txt[(nblk*CRYSPR_AESBLKSZ)], aes_key, AES_ENCRYPT);
|
||||
nblk++;
|
||||
}
|
||||
if (outlen != NULL) *outlen = nblk*CRYSPR_AESBLKSZ;
|
||||
} else { /* Decrypt */
|
||||
for (i=0; i<nblk; i++){
|
||||
AES_ecb_encrypt(&indata[(i*CRYSPR_AESBLKSZ)],
|
||||
&out_txt[(i*CRYSPR_AESBLKSZ)], aes_key, AES_DECRYPT);
|
||||
}
|
||||
/* Encrypt last incomplete block */
|
||||
if (0 < nmore) {
|
||||
//shall not happens in decrypt
|
||||
}
|
||||
if (outlen != NULL) *outlen = nblk*CRYSPR_AESBLKSZ;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif /* !(CRYSPR_HAS_AESCTR && CRYSPR_HAS_AESKWRAP) */
|
||||
|
||||
int crysprOpenSSL_AES_CtrCipher(
|
||||
bool bEncrypt, /* true:encrypt, false:decrypt */
|
||||
CRYSPR_AESCTX *aes_key, /* CRYpto Service PRovider AES Key context */
|
||||
unsigned char *iv, /* iv */
|
||||
const unsigned char *indata,/* src */
|
||||
size_t inlen, /* length */
|
||||
unsigned char *out_txt) /* dest */
|
||||
{
|
||||
unsigned char ctr[CRYSPR_AESBLKSZ];
|
||||
unsigned blk_ofs = 0;
|
||||
(void)bEncrypt; /* CTR mode encrypt for both encryption and decryption */
|
||||
|
||||
memset(&ctr[0], 0, sizeof(ctr));
|
||||
#if (OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(OPENSSL_IS_BORINGSSL))
|
||||
CRYPTO_ctr128_encrypt(indata, out_txt,
|
||||
inlen, aes_key, iv, ctr, &blk_ofs, (block128_f) AES_encrypt);
|
||||
#else
|
||||
AES_ctr128_encrypt(indata, out_txt,
|
||||
inlen, aes_key, iv, ctr, &blk_ofs);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Password-based Key Derivation Function
|
||||
*/
|
||||
int crysprOpenSSL_KmPbkdf2(
|
||||
CRYSPR_cb *cryspr_cb,
|
||||
char *passwd, /* passphrase */
|
||||
size_t passwd_len, /* passphrase len */
|
||||
unsigned char *salt, /* salt */
|
||||
size_t salt_len, /* salt_len */
|
||||
int itr, /* iterations */
|
||||
size_t key_len, /* key_len */
|
||||
unsigned char *out) /* derived key */
|
||||
{
|
||||
(void)cryspr_cb;
|
||||
int rc = PKCS5_PBKDF2_HMAC_SHA1(passwd,passwd_len,salt,salt_len,itr,key_len,out);
|
||||
return(rc == 1? 0 : -1);
|
||||
}
|
||||
|
||||
#if CRYSPR_HAS_AESKWRAP
|
||||
int crysprOpenSSL_KmWrap(CRYSPR_cb *cryspr_cb,
|
||||
unsigned char *wrap,
|
||||
const unsigned char *sek,
|
||||
unsigned int seklen)
|
||||
{
|
||||
crysprOpenSSL_cb *aes_data = (crysprOpenSSL_cb *)cryspr_cb;
|
||||
AES_KEY *kek = &aes_data->ccb.aes_kek; //key encrypting key
|
||||
|
||||
return(((seklen + HAICRYPT_WRAPKEY_SIGN_SZ) == (unsigned int)AES_wrap_key(kek, NULL, wrap, sek, seklen)) ? 0 : -1);
|
||||
}
|
||||
|
||||
int crysprOpenSSL_KmUnwrap(
|
||||
CRYSPR_cb *cryspr_cb,
|
||||
unsigned char *sek, //Stream encrypting key
|
||||
const unsigned char *wrap,
|
||||
unsigned int wraplen)
|
||||
{
|
||||
crysprOpenSSL_cb *aes_data = (crysprOpenSSL_cb *)cryspr_cb;
|
||||
AES_KEY *kek = &aes_data->ccb.aes_kek; //key encrypting key
|
||||
|
||||
return(((wraplen - HAICRYPT_WRAPKEY_SIGN_SZ) == (unsigned int)AES_unwrap_key(kek, NULL, sek, wrap, wraplen)) ? 0 : -1);
|
||||
}
|
||||
#endif /*CRYSPR_HAS_AESKWRAP*/
|
||||
|
||||
|
||||
static CRYSPR_methods crysprOpenSSL_methods;
|
||||
|
||||
CRYSPR_methods *crysprOpenSSL(void)
|
||||
{
|
||||
if(NULL == crysprOpenSSL_methods.open) {
|
||||
crysprInit(&crysprOpenSSL_methods); //Default/fallback methods
|
||||
|
||||
crysprOpenSSL_methods.prng = crysprOpenSSL_Prng;
|
||||
//--CryptoLib Primitive API-----------------------------------------------
|
||||
crysprOpenSSL_methods.aes_set_key = crysprOpenSSL_AES_SetKey;
|
||||
#if CRYSPR_HAS_AESCTR
|
||||
crysprOpenSSL_methods.aes_ctr_cipher = crysprOpenSSL_AES_CtrCipher;
|
||||
#endif
|
||||
#if !(CRYSPR_HAS_AESCTR && CRYSPR_HAS_AESKWRAP)
|
||||
/* AES-ECB only required if cryspr has no AES-CTR and no AES KeyWrap */
|
||||
/* OpenSSL has both AESCTR and AESKWRP and the AESECB wrapper is only used
|
||||
to test the falback methods */
|
||||
crysprOpenSSL_methods.aes_ecb_cipher = crysprOpenSSL_AES_EcbCipher;
|
||||
#endif
|
||||
#if !CRYSPR_HAS_PBKDF2
|
||||
crysprOpenSSL_methods.sha1_msg_digest= NULL; //Required to use eventual default/fallback KmPbkdf2
|
||||
#endif
|
||||
|
||||
//--Crypto Session API-----------------------------------------
|
||||
// crysprOpenSSL_methods.open =
|
||||
// crysprOpenSSL_methods.close =
|
||||
//--Keying material (km) encryption
|
||||
|
||||
#if CRYSPR_HAS_PBKDF2
|
||||
crysprOpenSSL_methods.km_pbkdf2 = crysprOpenSSL_KmPbkdf2;
|
||||
#else
|
||||
#error There is no default/fallback method for PBKDF2
|
||||
#endif
|
||||
// crysprOpenSSL_methods.km_setkey =
|
||||
#if CRYSPR_HAS_AESKWRAP
|
||||
crysprOpenSSL_methods.km_wrap = crysprOpenSSL_KmWrap;
|
||||
crysprOpenSSL_methods.km_unwrap = crysprOpenSSL_KmUnwrap;
|
||||
#endif
|
||||
|
||||
//--Media stream (ms) encryption
|
||||
// crysprOpenSSL_methods.ms_setkey =
|
||||
// crysprOpenSSL_methods.ms_encrypt =
|
||||
// crysprOpenSSL_methods.ms_decrypt =
|
||||
}
|
||||
return(&crysprOpenSSL_methods);
|
||||
}
|
||||
|
||||
|
65
trunk/3rdparty/srt-1-fit/haicrypt/cryspr-openssl.h
vendored
Normal file
65
trunk/3rdparty/srt-1-fit/haicrypt/cryspr-openssl.h
vendored
Normal file
|
@ -0,0 +1,65 @@
|
|||
/*
|
||||
* SRT - Secure, Reliable, Transport
|
||||
* Copyright (c) 2019 Haivision Systems Inc.
|
||||
*
|
||||
* 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/.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
written by
|
||||
Haivision Systems Inc.
|
||||
|
||||
2019-06-26 (jdube)
|
||||
OpenSSL Direct AES CRYSPR/4SRT (CRYypto Service PRovider for SRT).
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef CRYSPR_OPENSSL_H
|
||||
#define CRYSPR_OPENSSL_H
|
||||
|
||||
#include <openssl/evp.h> /* PKCS5_xxx() */
|
||||
#include <openssl/aes.h> /* AES_xxx() */
|
||||
#if (OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(OPENSSL_IS_BORINGSSL))
|
||||
# include <openssl/modes.h> /* CRYPTO_xxx() */
|
||||
#endif
|
||||
#include <openssl/rand.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/opensslv.h> /* OPENSSL_VERSION_NUMBER */
|
||||
|
||||
/* Define CRYSPR_HAS_AESCTR to 1 if this CRYSPR has AESCTR cipher mode
|
||||
if not set it 0 to use enable CTR cipher mode implementation using ECB cipher mode
|
||||
and provide the aes_ecb_cipher method.
|
||||
*/
|
||||
#define CRYSPR_HAS_AESCTR 1
|
||||
|
||||
/* Define CRYSPR_HAS_AESKWRAP to 1 if this CRYSPR has AES Key Wrap
|
||||
if not set to 0 to enable default/fallback crysprFallback_AES_WrapKey/crysprFallback_AES_UnwrapKey methods
|
||||
and provide the aes_ecb_cipher method .
|
||||
*/
|
||||
#if (OPENSSL_VERSION_NUMBER < 0x0090808fL) //0.9.8h
|
||||
#define CRYSPR_HAS_AESKWRAP 0
|
||||
#else
|
||||
#define CRYSPR_HAS_AESKWRAP 1
|
||||
#endif
|
||||
|
||||
/* Define CRYSPR_HAS_PBKDF2 to 1 if this CRYSPR has SHA1-HMAC Password-based Key Derivaion Function 2
|
||||
if not set to 0 to enable not-yet-implemented/fallback crysprFallback.km_pbkdf2 method
|
||||
and provide the sha1_msg_digest method.
|
||||
*/
|
||||
#define CRYSPR_HAS_PBKDF2 1 /* Define to 1 if CRYSPR has Password-based Key Derivaion Function 2 */
|
||||
|
||||
/*
|
||||
#define CRYSPR_AESCTX to the CRYSPR specifix AES key context object.
|
||||
This type reserves room in the CRYPSPR control block for Haicrypt KEK and SEK
|
||||
It is set from hte keystring through CRYSPR_methods.aes_set_key and passed
|
||||
to CRYSPR_methods.aes_*.
|
||||
*/
|
||||
typedef AES_KEY CRYSPR_AESCTX; /* CRYpto Service PRovider AES key context */
|
||||
|
||||
struct tag_CRYSPR_methods *crysprOpenSSL(void);
|
||||
|
||||
#endif /* CRYSPR_OPENSSL_H */
|
||||
|
709
trunk/3rdparty/srt-1-fit/haicrypt/cryspr.c
vendored
Normal file
709
trunk/3rdparty/srt-1-fit/haicrypt/cryspr.c
vendored
Normal file
|
@ -0,0 +1,709 @@
|
|||
/*
|
||||
* SRT - Secure, Reliable, Transport
|
||||
* Copyright (c) 2019 Haivision Systems Inc.
|
||||
*
|
||||
* 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/.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
written by
|
||||
Haivision Systems Inc.
|
||||
|
||||
2019-06-28 (jdube)
|
||||
CRYSPR/4SRT Initial implementation.
|
||||
*****************************************************************************/
|
||||
|
||||
#include "hcrypt.h"
|
||||
#include "cryspr.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
int crysprStub_Prng(unsigned char *rn, int len)
|
||||
{
|
||||
(void)rn;
|
||||
(void)len;
|
||||
return(0);
|
||||
}
|
||||
|
||||
int crysprStub_AES_SetKey(
|
||||
bool bEncrypt, /* true Enxcrypt key, false: decrypt */
|
||||
const unsigned char *kstr, /* key sttring*/
|
||||
size_t kstr_len, /* kstr len in bytes (16, 24, or 32 bytes (for AES128,AES192, or AES256) */
|
||||
CRYSPR_AESCTX *aes_key) /* Cryptolib Specific AES key context */
|
||||
{
|
||||
(void)bEncrypt;
|
||||
(void)kstr;
|
||||
(void)kstr_len;
|
||||
(void)aes_key;
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
int crysprStub_AES_EcbCipher(
|
||||
bool bEncrypt, /* true:encrypt, false:decrypt */
|
||||
CRYSPR_AESCTX *aes_key, /* AES context */
|
||||
const unsigned char *indata,/* src (clear text)*/
|
||||
size_t inlen, /* length */
|
||||
unsigned char *out_txt, /* dst (cipher text) */
|
||||
size_t *outlen) /* dst len */
|
||||
{
|
||||
(void)bEncrypt;
|
||||
(void)aes_key;
|
||||
(void)indata;
|
||||
(void)inlen;
|
||||
(void)out_txt;
|
||||
(void)outlen;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int crysprStub_AES_CtrCipher(
|
||||
bool bEncrypt, /* true:encrypt, false:decrypt */
|
||||
CRYSPR_AESCTX *aes_key, /* AES context */
|
||||
unsigned char *iv, /* iv */
|
||||
const unsigned char *indata,/* src */
|
||||
size_t inlen, /* length */
|
||||
unsigned char *out_txt) /* dest */
|
||||
{
|
||||
(void)bEncrypt;
|
||||
(void)aes_key;
|
||||
(void)iv;
|
||||
(void)indata;
|
||||
(void)inlen;
|
||||
(void)out_txt;
|
||||
|
||||
return(-1);
|
||||
}
|
||||
|
||||
unsigned char *crysprStub_SHA1_MsgDigest(
|
||||
const unsigned char *m, /* in: message */
|
||||
size_t m_len, /* message length */
|
||||
unsigned char *md) /* out: message digest buffer *160 bytes */
|
||||
{
|
||||
(void)m;
|
||||
(void)m_len;
|
||||
(void)md;
|
||||
|
||||
return(NULL);//return md;
|
||||
}
|
||||
|
||||
/*
|
||||
* Password-based Key Derivation Function
|
||||
*/
|
||||
int crysprStub_KmPbkdf2(
|
||||
CRYSPR_cb *cryspr_cb,
|
||||
char *passwd, /* passphrase */
|
||||
size_t passwd_len, /* passphrase len */
|
||||
unsigned char *salt, /* salt */
|
||||
size_t salt_len, /* salt_len */
|
||||
int itr, /* iterations */
|
||||
size_t key_len, /* key_len */
|
||||
unsigned char *out) /* derived key */
|
||||
{
|
||||
(void)cryspr_cb;
|
||||
(void)passwd;
|
||||
(void)passwd_len;
|
||||
(void)salt;
|
||||
(void)salt_len;
|
||||
(void)itr;
|
||||
(void)key_len;
|
||||
(void)out;
|
||||
|
||||
/* >>Todo:
|
||||
* develop PBKDF2 using SHA1 primitive cryspr_cb->cryspr->sha1_msg_digest() for cryptolibs not providing it
|
||||
*/
|
||||
return(-1);
|
||||
}
|
||||
|
||||
static int crysprFallback_KmSetKey(CRYSPR_cb *cryspr_cb, bool bWrap, const unsigned char *kek, size_t kek_len)
|
||||
{
|
||||
CRYSPR_AESCTX *aes_kek = &cryspr_cb->aes_kek;
|
||||
|
||||
if (cryspr_cb->cryspr->aes_set_key(bWrap, kek, kek_len, aes_kek)) {
|
||||
HCRYPT_LOG(LOG_ERR, "AES_set_%s_key(kek) failed\n", bWrap? "encrypt": "decrypt");
|
||||
return(-1);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
/*
|
||||
* AES_wrap_key()/AES_unwrap_key() introduced in openssl 0.9.8h
|
||||
* Here is an implementation using AES native API for cryspr not providing it.
|
||||
*/
|
||||
|
||||
static const unsigned char default_iv[] = {
|
||||
0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6,
|
||||
};
|
||||
int crysprFallback_AES_WrapKey(CRYSPR_cb *cryspr_cb,
|
||||
unsigned char *out,
|
||||
const unsigned char *in,
|
||||
unsigned int inlen)
|
||||
{
|
||||
unsigned char *A, B[16], *R;
|
||||
const unsigned char *iv = default_iv;
|
||||
unsigned int i, j, t;
|
||||
if ((inlen & 0x7) || (inlen < 8))
|
||||
return -1;
|
||||
A = B;
|
||||
t = 1;
|
||||
memcpy(out + 8, in, inlen);
|
||||
|
||||
memcpy(A, iv, 8);
|
||||
|
||||
for (j = 0; j < 6; j++)
|
||||
{
|
||||
R = out + 8;
|
||||
for (i = 0; i < inlen; i += 8, t++, R += 8)
|
||||
{
|
||||
memcpy(B + 8, R, 8);
|
||||
{
|
||||
size_t outlen = 16;
|
||||
cryspr_cb->cryspr->aes_ecb_cipher(true, &cryspr_cb->aes_kek, B, 16, B, &outlen);
|
||||
}
|
||||
A[7] ^= (unsigned char)(t & 0xff);
|
||||
if (t > 0xff)
|
||||
{
|
||||
A[6] ^= (unsigned char)((t >> 8) & 0xff);
|
||||
A[5] ^= (unsigned char)((t >> 16) & 0xff);
|
||||
A[4] ^= (unsigned char)((t >> 24) & 0xff);
|
||||
}
|
||||
memcpy(R, B + 8, 8);
|
||||
}
|
||||
}
|
||||
memcpy(out, A, 8);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int crysprFallback_AES_UnwrapKey(CRYSPR_cb *cryspr_cb,
|
||||
unsigned char *out,
|
||||
const unsigned char *in,
|
||||
unsigned int inlen)
|
||||
{
|
||||
unsigned char *A, B[16], *R;
|
||||
const unsigned char *iv = default_iv;
|
||||
unsigned int i, j, t;
|
||||
inlen -= 8;
|
||||
if (inlen & 0x7)
|
||||
return -1;
|
||||
if (inlen < 8)
|
||||
return -1;
|
||||
A = B;
|
||||
t = 6 * (inlen >> 3);
|
||||
memcpy(A, in, 8);
|
||||
memcpy(out, in + 8, inlen);
|
||||
for (j = 0; j < 6; j++)
|
||||
{
|
||||
R = out + inlen - 8;
|
||||
for (i = 0; i < inlen; i += 8, t--, R -= 8)
|
||||
{
|
||||
A[7] ^= (unsigned char)(t & 0xff);
|
||||
if (t > 0xff)
|
||||
{
|
||||
A[6] ^= (unsigned char)((t >> 8) & 0xff);
|
||||
A[5] ^= (unsigned char)((t >> 16) & 0xff);
|
||||
A[4] ^= (unsigned char)((t >> 24) & 0xff);
|
||||
}
|
||||
memcpy(B + 8, R, 8);
|
||||
{
|
||||
size_t outlen = 16;
|
||||
cryspr_cb->cryspr->aes_ecb_cipher(false, &cryspr_cb->aes_kek, B, 16, B, &outlen);
|
||||
}
|
||||
memcpy(R, B + 8, 8);
|
||||
}
|
||||
}
|
||||
if (memcmp(A, iv, 8))
|
||||
{
|
||||
memset(out, 0, inlen);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static unsigned char *_crysprFallback_GetOutbuf(CRYSPR_cb *cryspr_cb, size_t pfx_len, size_t out_len)
|
||||
{
|
||||
unsigned char *out_buf;
|
||||
|
||||
if ((pfx_len + out_len) > (cryspr_cb->outbuf_siz - cryspr_cb->outbuf_ofs)) {
|
||||
/* Not enough room left, circle buffers */
|
||||
cryspr_cb->outbuf_ofs = 0;
|
||||
}
|
||||
out_buf = &cryspr_cb->outbuf[cryspr_cb->outbuf_ofs];
|
||||
cryspr_cb->outbuf_ofs += (pfx_len + out_len);
|
||||
return(out_buf);
|
||||
}
|
||||
|
||||
static CRYSPR_cb *crysprFallback_Open(CRYSPR_methods *cryspr, size_t max_len)
|
||||
{
|
||||
CRYSPR_cb *cryspr_cb;
|
||||
unsigned char *membuf;
|
||||
size_t memsiz, padded_len = hcryptMsg_PaddedLen(max_len, 128/8);
|
||||
|
||||
HCRYPT_LOG(LOG_DEBUG, "%s", "Using OpenSSL AES\n");
|
||||
|
||||
memsiz = sizeof(*cryspr_cb) + (CRYSPR_OUTMSGMAX * padded_len);
|
||||
#if !CRYSPR_HAS_AESCTR
|
||||
memsiz += HCRYPT_CTR_STREAM_SZ;
|
||||
#endif /* !CRYSPR_HAS_AESCTR */
|
||||
|
||||
cryspr_cb = malloc(memsiz);
|
||||
if (NULL == cryspr_cb) {
|
||||
HCRYPT_LOG(LOG_ERR, "malloc(%zd) failed\n", memsiz);
|
||||
return(NULL);
|
||||
}
|
||||
membuf = (unsigned char *)cryspr_cb;
|
||||
membuf += sizeof(*cryspr_cb);
|
||||
|
||||
#if !CRYSPR_HAS_AESCTR
|
||||
cryspr_cb->ctr_stream = membuf;
|
||||
membuf += HCRYPT_CTR_STREAM_SZ;
|
||||
cryspr_cb->ctr_stream_siz = HCRYPT_CTR_STREAM_SZ;
|
||||
cryspr_cb->ctr_stream_len = 0;
|
||||
#endif /* !CRYSPR_HAS_AESCTR */
|
||||
|
||||
cryspr_cb->outbuf = membuf;
|
||||
cryspr_cb->outbuf_siz = CRYSPR_OUTMSGMAX * padded_len;
|
||||
cryspr_cb->outbuf_ofs = 0;
|
||||
// membuf += cryspr_cb->outbuf_siz;
|
||||
|
||||
cryspr_cb->cryspr=(CRYSPR_methods *)cryspr;
|
||||
|
||||
return(cryspr_cb);
|
||||
}
|
||||
|
||||
static int crysprFallback_Close(CRYSPR_cb *cryspr_cb)
|
||||
{
|
||||
if (NULL != cryspr_cb) {
|
||||
free(cryspr_cb);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
static int crysprFallback_MsSetKey(CRYSPR_cb *cryspr_cb, hcrypt_Ctx *ctx, const unsigned char *key, size_t key_len)
|
||||
{
|
||||
CRYSPR_AESCTX *aes_sek = &cryspr_cb->aes_sek[hcryptCtx_GetKeyIndex(ctx)]; /* Ctx tells if it's for odd or even key */
|
||||
|
||||
if ((ctx->flags & HCRYPT_CTX_F_ENCRYPT) /* Encrypt key */
|
||||
|| (ctx->mode == HCRYPT_CTX_MODE_AESCTR)) { /* CTR mode decrypts using encryption methods */
|
||||
if (cryspr_cb->cryspr->aes_set_key(true, key, key_len, aes_sek)) {
|
||||
HCRYPT_LOG(LOG_ERR, "%s", "CRYSPR->set_encrypt_key(sek) failed\n");
|
||||
return(-1);
|
||||
}
|
||||
} else { /* Decrypt key */
|
||||
if (cryspr_cb->cryspr->aes_set_key(false, key, key_len, aes_sek)) {
|
||||
HCRYPT_LOG(LOG_ERR, "%s", "CRYSPR->set_decrypt_key(sek) failed\n");
|
||||
return(-1);
|
||||
}
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
#if !CRYSPR_HAS_AESCTR
|
||||
static int _crysprFallback_AES_SetCtrStream(CRYSPR_cb *cryspr_cb, hcrypt_Ctx *ctx, size_t len, unsigned char *iv)
|
||||
{
|
||||
/* Counter stream:
|
||||
* 0 1 2 3 4 5 nblk
|
||||
* +---+---+---+---+---+---+---+---+
|
||||
* |blk|blk|blk|blk|blk|blk|...|blk|
|
||||
* +---+---+---+---+---+---+---+---+
|
||||
*/
|
||||
|
||||
/* IV (128-bit):
|
||||
* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
|
||||
* +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|
||||
* | 0s | pki | ctr |
|
||||
* +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|
||||
* XOR
|
||||
* +---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|
||||
* | nonce +
|
||||
* +---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|
||||
*
|
||||
* pki (32-bit): packet index
|
||||
* ctr (16-bit): block counter
|
||||
* nonce (112-bit): number used once (salt)
|
||||
*/
|
||||
unsigned char ctr[HCRYPT_CTR_BLK_SZ];
|
||||
unsigned nblk;
|
||||
|
||||
ASSERT(NULL != cryspr_cb);
|
||||
ASSERT(NULL != ctx);
|
||||
|
||||
memcpy(ctr, iv, HCRYPT_CTR_BLK_SZ);
|
||||
|
||||
nblk = (len + (HCRYPT_CTR_BLK_SZ-1))/HCRYPT_CTR_BLK_SZ;
|
||||
if ((nblk * HCRYPT_CTR_BLK_SZ) <= cryspr_cb->ctr_stream_siz) {
|
||||
unsigned blk;
|
||||
unsigned char *csp = &cryspr_cb->ctr_stream[0];
|
||||
|
||||
for(blk = 0; blk < nblk; blk++) {
|
||||
memcpy(csp, ctr, HCRYPT_CTR_BLK_SZ);
|
||||
csp += HCRYPT_CTR_BLK_SZ;
|
||||
if (0 == ++(ctr[HCRYPT_CTR_BLK_SZ-1])) ++(ctr[HCRYPT_CTR_BLK_SZ-2]);
|
||||
}
|
||||
cryspr_cb->ctr_stream_len = nblk * HCRYPT_CTR_BLK_SZ;
|
||||
} else {
|
||||
HCRYPT_LOG(LOG_ERR, "packet too long(%zd)\n", len);
|
||||
return(-1);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
#endif
|
||||
|
||||
static int crysprFallback_MsEncrypt(
|
||||
CRYSPR_cb *cryspr_cb,
|
||||
hcrypt_Ctx *ctx,
|
||||
hcrypt_DataDesc *in_data, int nbin ATR_UNUSED,
|
||||
void *out_p[], size_t out_len_p[], int *nbout_p)
|
||||
{
|
||||
unsigned char *out_msg;
|
||||
size_t out_len = 0; //payload size
|
||||
int pfx_len;
|
||||
|
||||
ASSERT(NULL != ctx);
|
||||
ASSERT(NULL != cryspr_cb);
|
||||
ASSERT((NULL != in_data) || (1 == nbin)); //Only one in_data[] supported
|
||||
|
||||
/*
|
||||
* Get message prefix length
|
||||
* to reserve room for unencrypted message header in output buffer
|
||||
*/
|
||||
pfx_len = ctx->msg_info->pfx_len;
|
||||
|
||||
/* Get buffer room from the internal circular output buffer */
|
||||
out_msg = _crysprFallback_GetOutbuf(cryspr_cb, pfx_len, in_data[0].len);
|
||||
|
||||
if (NULL != out_msg) {
|
||||
switch(ctx->mode) {
|
||||
case HCRYPT_CTX_MODE_AESCTR: /* Counter mode */
|
||||
{
|
||||
#if CRYSPR_HAS_AESCTR
|
||||
/* Get current key (odd|even) from context */
|
||||
CRYSPR_AESCTX *aes_key = &cryspr_cb->aes_sek[hcryptCtx_GetKeyIndex(ctx)];
|
||||
unsigned char iv[CRYSPR_AESBLKSZ];
|
||||
|
||||
/* Get input packet index (in network order) */
|
||||
hcrypt_Pki pki = hcryptMsg_GetPki(ctx->msg_info, in_data[0].pfx, 1);
|
||||
|
||||
/*
|
||||
* Compute the Initial Vector
|
||||
* IV (128-bit):
|
||||
* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
|
||||
* +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|
||||
* | 0s | pki | ctr |
|
||||
* +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|
||||
* XOR
|
||||
* +---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|
||||
* | nonce +
|
||||
* +---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|
||||
*
|
||||
* pki (32-bit): packet index
|
||||
* ctr (16-bit): block counter
|
||||
* nonce (112-bit): number used once (salt)
|
||||
*/
|
||||
hcrypt_SetCtrIV((unsigned char *)&pki, ctx->salt, iv);
|
||||
|
||||
cryspr_cb->cryspr->aes_ctr_cipher(true, aes_key, iv, in_data[0].payload, in_data[0].len,
|
||||
&out_msg[pfx_len]);
|
||||
#else /*CRYSPR_HAS_AESCTR*/
|
||||
/* Get current key (odd|even) from context */
|
||||
CRYSPR_AESCTX *aes_key = &cryspr_cb->aes_sek[hcryptCtx_GetKeyIndex(ctx)];
|
||||
unsigned char iv[CRYSPR_AESBLKSZ];
|
||||
int iret = 0;
|
||||
|
||||
/* Get input packet index (in network order) */
|
||||
hcrypt_Pki pki = hcryptMsg_GetPki(ctx->msg_info, in_data[0].pfx, 1);
|
||||
|
||||
/*
|
||||
* Compute the Initial Vector
|
||||
* IV (128-bit):
|
||||
* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
|
||||
* +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|
||||
* | 0s | pki | ctr |
|
||||
* +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|
||||
* XOR
|
||||
* +---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|
||||
* | nonce +
|
||||
* +---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|
||||
*
|
||||
* pki (32-bit): packet index
|
||||
* ctr (16-bit): block counter
|
||||
* nonce (112-bit): number used once (salt)
|
||||
*/
|
||||
hcrypt_SetCtrIV((unsigned char *)&pki, ctx->salt, iv);
|
||||
|
||||
/* Create CtrStream. May be longer than in_len (next cryspr block size boundary) */
|
||||
iret = _crysprFallback_AES_SetCtrStream(cryspr_cb, ctx, in_data[0].len, iv);
|
||||
if (iret) {
|
||||
return(iret);
|
||||
}
|
||||
/* Reserve output buffer for cryspr */
|
||||
out_msg = _crysprFallback_GetOutbuf(cryspr_cb, pfx_len, cryspr_cb->ctr_stream_len);
|
||||
|
||||
/* Create KeyStream (encrypt CtrStream) */
|
||||
iret = cryspr_cb->cryspr->aes_ecb_cipher(true, aes_key,
|
||||
cryspr_cb->ctr_stream, cryspr_cb->ctr_stream_len,
|
||||
&out_msg[pfx_len], &out_len);
|
||||
if (iret) {
|
||||
HCRYPT_LOG(LOG_ERR, "%s", "hcOpenSSL_AES_ecb_cipher(encrypt, failed\n");
|
||||
return(iret);
|
||||
}
|
||||
#endif/*CRYSPR_HAS_AESCTR*/
|
||||
/* Prepend packet prefix (clear text) in output buffer */
|
||||
memcpy(out_msg, in_data[0].pfx, pfx_len);
|
||||
/* CTR mode output length is same as input, no padding */
|
||||
out_len = in_data[0].len;
|
||||
break;
|
||||
}
|
||||
case HCRYPT_CTX_MODE_CLRTXT: /* Clear text mode (transparent mode for tests) */
|
||||
memcpy(&out_msg[pfx_len], in_data[0].payload, in_data[0].len);
|
||||
memcpy(out_msg, in_data[0].pfx, pfx_len);
|
||||
out_len = in_data[0].len;
|
||||
break;
|
||||
default:
|
||||
/* Unsupported cipher mode */
|
||||
return(-1);
|
||||
}
|
||||
} else {
|
||||
/* input data too big */
|
||||
return(-1);
|
||||
}
|
||||
|
||||
if (out_len > 0) {
|
||||
/* Encrypted messages have been produced */
|
||||
if (NULL == out_p) {
|
||||
/*
|
||||
* Application did not provided output buffer,
|
||||
* so copy encrypted message back in input buffer
|
||||
*/
|
||||
memcpy(in_data[0].pfx, out_msg, pfx_len);
|
||||
#if !CRYSPR_HAS_AESCTR
|
||||
if (ctx->mode == HCRYPT_CTX_MODE_AESCTR) {
|
||||
/* XOR KeyStream with input text directly in input buffer */
|
||||
hcrypt_XorStream(in_data[0].payload, &out_msg[pfx_len], out_len);
|
||||
}else{
|
||||
/* Copy output data back in input buffer */
|
||||
memcpy(in_data[0].payload, &out_msg[pfx_len], out_len);
|
||||
}
|
||||
#else /* CRYSPR_HAS_AESCTR */
|
||||
/* Copy output data back in input buffer */
|
||||
memcpy(in_data[0].payload, &out_msg[pfx_len], out_len);
|
||||
#endif /* CRYSPR_HAS_AESCTR */
|
||||
} else {
|
||||
/* Copy header in output buffer if needed */
|
||||
if (pfx_len > 0) memcpy(out_msg, in_data[0].pfx, pfx_len);
|
||||
#if !CRYSPR_HAS_AESCTR
|
||||
if (ctx->mode == HCRYPT_CTX_MODE_AESCTR) {
|
||||
hcrypt_XorStream(&out_msg[pfx_len], in_data[0].payload, out_len);
|
||||
}
|
||||
#endif /* CRYSPR_HAS_AESCTR */
|
||||
out_p[0] = out_msg;
|
||||
out_len_p[0] = pfx_len + out_len;
|
||||
*nbout_p = 1;
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* Nothing out
|
||||
* This is not an error for implementations using deferred/async processing
|
||||
* with co-processor, DSP, crypto hardware, etc.
|
||||
* Submitted input data could be returned encrypted in a next call.
|
||||
*/
|
||||
if (nbout_p != NULL) *nbout_p = 0;
|
||||
return(-1);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
static int crysprFallback_MsDecrypt(CRYSPR_cb *cryspr_cb, hcrypt_Ctx *ctx,
|
||||
hcrypt_DataDesc *in_data, int nbin ATR_UNUSED, void *out_p[], size_t out_len_p[], int *nbout_p)
|
||||
{
|
||||
unsigned char *out_txt;
|
||||
size_t out_len;
|
||||
int iret = 0;
|
||||
|
||||
ASSERT(NULL != cryspr_cb);
|
||||
ASSERT(NULL != ctx);
|
||||
ASSERT((NULL != in_data) || (1 == nbin)); //Only one in_data[] supported
|
||||
|
||||
/* Reserve output buffer (w/no header) */
|
||||
out_txt = _crysprFallback_GetOutbuf(cryspr_cb, 0, in_data[0].len);
|
||||
|
||||
if (NULL != out_txt) {
|
||||
switch(ctx->mode) {
|
||||
case HCRYPT_CTX_MODE_AESCTR:
|
||||
{
|
||||
#if CRYSPR_HAS_AESCTR
|
||||
/* Get current key (odd|even) from context */
|
||||
CRYSPR_AESCTX *aes_key = &cryspr_cb->aes_sek[hcryptCtx_GetKeyIndex(ctx)];
|
||||
unsigned char iv[CRYSPR_AESBLKSZ];
|
||||
|
||||
/* Get input packet index (in network order) */
|
||||
hcrypt_Pki pki = hcryptMsg_GetPki(ctx->msg_info, in_data[0].pfx, 1);
|
||||
|
||||
/*
|
||||
* Compute the Initial Vector
|
||||
* IV (128-bit):
|
||||
* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
|
||||
* +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|
||||
* | 0s | pki | ctr |
|
||||
* +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|
||||
* XOR
|
||||
* +---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|
||||
* | nonce +
|
||||
* +---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|
||||
*
|
||||
* pki (32-bit): packet index
|
||||
* ctr (16-bit): block counter
|
||||
* nonce (112-bit): number used once (salt)
|
||||
*/
|
||||
hcrypt_SetCtrIV((unsigned char *)&pki, ctx->salt, iv);
|
||||
|
||||
cryspr_cb->cryspr->aes_ctr_cipher(false, aes_key, iv, in_data[0].payload, in_data[0].len,
|
||||
out_txt);
|
||||
out_len = in_data[0].len;
|
||||
#else /*CRYSPR_HAS_AESCTR*/
|
||||
/* Get current key (odd|even) from context */
|
||||
CRYSPR_AESCTX *aes_key = &cryspr_cb->aes_sek[hcryptCtx_GetKeyIndex(ctx)];
|
||||
unsigned char iv[CRYSPR_AESBLKSZ];
|
||||
int iret = 0;
|
||||
|
||||
/* Get input packet index (in network order) */
|
||||
hcrypt_Pki pki = hcryptMsg_GetPki(ctx->msg_info, in_data[0].pfx, 1);
|
||||
|
||||
/*
|
||||
* Compute the Initial Vector
|
||||
* IV (128-bit):
|
||||
* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
|
||||
* +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|
||||
* | 0s | pki | ctr |
|
||||
* +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|
||||
* XOR
|
||||
* +---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|
||||
* | nonce +
|
||||
* +---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|
||||
*
|
||||
* pki (32-bit): packet index
|
||||
* ctr (16-bit): block counter
|
||||
* nonce (112-bit): number used once (salt)
|
||||
*/
|
||||
hcrypt_SetCtrIV((unsigned char *)&pki, ctx->salt, iv);
|
||||
|
||||
/* Create CtrStream. May be longer than in_len (next cipher block size boundary) */
|
||||
iret = _crysprFallback_AES_SetCtrStream(cryspr_cb, ctx, in_data[0].len, iv);
|
||||
if (iret) {
|
||||
return(iret);
|
||||
}
|
||||
/* Reserve output buffer for cryspr */
|
||||
out_txt = _crysprFallback_GetOutbuf(cryspr_cb, 0, cryspr_cb->ctr_stream_len);
|
||||
|
||||
/* Create KeyStream (encrypt CtrStream) */
|
||||
iret = cryspr_cb->cryspr->aes_ecb_cipher(true, aes_key,
|
||||
cryspr_cb->ctr_stream, cryspr_cb->ctr_stream_len,
|
||||
out_txt, &out_len);
|
||||
if (iret) {
|
||||
HCRYPT_LOG(LOG_ERR, "%s", "crysprNatural_AES_ecb_cipher(encrypt failed\n");
|
||||
return(iret);
|
||||
}
|
||||
|
||||
#endif /*CRYSPR_HAS_AESCTR*/
|
||||
break;
|
||||
}
|
||||
case HCRYPT_CTX_MODE_CLRTXT:
|
||||
memcpy(out_txt, in_data[0].payload, in_data[0].len);
|
||||
out_len = in_data[0].len;
|
||||
break;
|
||||
default:
|
||||
return(-1);
|
||||
}
|
||||
} else {
|
||||
return(-1);
|
||||
}
|
||||
|
||||
if (out_len > 0) {
|
||||
if (NULL == out_p) {
|
||||
/*
|
||||
* Application did not provided output buffer,
|
||||
* so copy encrypted message back in input buffer
|
||||
*/
|
||||
#if !CRYSPR_HAS_AESCTR
|
||||
if (ctx->mode == HCRYPT_CTX_MODE_AESCTR) {
|
||||
/* XOR KeyStream with input text directly in input buffer */
|
||||
hcrypt_XorStream(in_data[0].payload, out_txt, out_len);
|
||||
}else{
|
||||
/* Copy output data back in input buffer */
|
||||
memcpy(in_data[0].payload, out_txt, out_len);
|
||||
}
|
||||
#else /* CRYSPR_HAS_AESCTR */
|
||||
/* Copy output data back in input buffer */
|
||||
memcpy(in_data[0].payload, out_txt, out_len);
|
||||
#endif /* CRYSPR_HAS_AESCTR */
|
||||
} else {
|
||||
/* Copy header in output buffer if needed */
|
||||
#if !CRYSPR_HAS_AESCTR
|
||||
if (ctx->mode == HCRYPT_CTX_MODE_AESCTR) {
|
||||
hcrypt_XorStream(out_txt, in_data[0].payload, out_len);
|
||||
}
|
||||
#endif /* CRYSPR_HAS_AESCTR */
|
||||
out_p[0] = out_txt;
|
||||
out_len_p[0] = out_len;
|
||||
*nbout_p = 1;
|
||||
}
|
||||
iret = 0;
|
||||
} else {
|
||||
if (NULL != nbout_p) *nbout_p = 0;
|
||||
iret = -1;
|
||||
}
|
||||
|
||||
#if 0
|
||||
{ /* Debug decryption errors */
|
||||
static int nberr = 0;
|
||||
|
||||
if (out_txt[0] != 0x47){
|
||||
if ((++nberr == 1)
|
||||
|| ((nberr > 500) && (0 == ((((unsigned char *)&MSmsg->pki)[2] & 0x0F)|((unsigned char *)&MSmsg->pki)[3])))) {
|
||||
HCRYPT_LOG(LOG_DEBUG, "keyindex=%d\n", hcryptCtx_GetKeyIndex(ctx));
|
||||
HCRYPT_PRINTKEY(ctx->sek, ctx->sek_len, "sek");
|
||||
HCRYPT_PRINTKEY(ctx->salt, ctx->salt_len, "salt");
|
||||
}
|
||||
} else {
|
||||
nberr = 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return(iret);
|
||||
}
|
||||
|
||||
|
||||
CRYSPR_methods *crysprInit(CRYSPR_methods *cryspr)
|
||||
{
|
||||
/* CryptoLib Primitive API */
|
||||
cryspr->prng = crysprStub_Prng;
|
||||
cryspr->aes_set_key = crysprStub_AES_SetKey;
|
||||
cryspr->aes_ecb_cipher = crysprStub_AES_EcbCipher;
|
||||
cryspr->aes_ctr_cipher = crysprStub_AES_CtrCipher;
|
||||
cryspr->sha1_msg_digest = crysprStub_SHA1_MsgDigest;
|
||||
|
||||
|
||||
/* Crypto Session API */
|
||||
cryspr->open = crysprFallback_Open;
|
||||
cryspr->close = crysprFallback_Close;
|
||||
//Keying material (km) encryption
|
||||
cryspr->km_pbkdf2 = crysprStub_KmPbkdf2;
|
||||
cryspr->km_setkey = crysprFallback_KmSetKey;
|
||||
cryspr->km_wrap = crysprFallback_AES_WrapKey;
|
||||
cryspr->km_unwrap = crysprFallback_AES_UnwrapKey;
|
||||
//Media stream (ms) encryption
|
||||
cryspr->ms_setkey = crysprFallback_MsSetKey;
|
||||
cryspr->ms_encrypt = crysprFallback_MsEncrypt;
|
||||
cryspr->ms_decrypt = crysprFallback_MsDecrypt;
|
||||
|
||||
return(cryspr);
|
||||
}
|
||||
|
||||
HaiCrypt_Cryspr HaiCryptCryspr_Get_Instance(void)
|
||||
{
|
||||
return((HaiCrypt_Cryspr)cryspr4SRT());
|
||||
}
|
203
trunk/3rdparty/srt-1-fit/haicrypt/cryspr.h
vendored
Normal file
203
trunk/3rdparty/srt-1-fit/haicrypt/cryspr.h
vendored
Normal file
|
@ -0,0 +1,203 @@
|
|||
/*
|
||||
* SRT - Secure, Reliable, Transport
|
||||
* Copyright (c) 2019 Haivision Systems Inc.
|
||||
*
|
||||
* 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/.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
written by
|
||||
Haivision Systems Inc.
|
||||
|
||||
2019-06-28 (jdube)
|
||||
CRYSPR/4SRT Initial implementation.
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef CRYSPR_H
|
||||
#define CRYSPR_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#if !defined(HAISRT_VERSION_INT)
|
||||
#include "haicrypt.h"
|
||||
#include "hcrypt_msg.h"
|
||||
#else
|
||||
// Included by haisrt.h or similar
|
||||
#include "haisrt/haicrypt.h"
|
||||
#include "haisrt/hcrypt_msg.h"
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "cryspr-config.h"
|
||||
|
||||
typedef struct tag_CRYSPR_cb {
|
||||
CRYSPR_AESCTX aes_kek; /* Key Encrypting Key (KEK) */
|
||||
CRYSPR_AESCTX aes_sek[2]; /* even/odd Stream Encrypting Key (SEK) */
|
||||
|
||||
struct tag_CRYSPR_methods *cryspr;
|
||||
|
||||
#if !CRYSPR_HAS_AESCTR
|
||||
/* Reserve room to build the counter stream ourself */
|
||||
#define HCRYPT_CTR_BLK_SZ CRYSPR_AESBLKSZ
|
||||
#define HCRYPT_CTR_STREAM_SZ 2048
|
||||
unsigned char * ctr_stream;
|
||||
size_t ctr_stream_len; /* Content size */
|
||||
size_t ctr_stream_siz; /* Allocated length */
|
||||
#endif /* !CRYSPR_HAS_AESCTR */
|
||||
|
||||
#define CRYSPR_OUTMSGMAX 6
|
||||
uint8_t * outbuf; /* output circle buffer */
|
||||
size_t outbuf_ofs; /* write offset in circle buffer */
|
||||
size_t outbuf_siz; /* circle buffer size */
|
||||
} CRYSPR_cb;
|
||||
|
||||
typedef struct tag_CRYSPR_methods {
|
||||
/*
|
||||
* prng:
|
||||
* Pseudo-Random Number Generator
|
||||
*/
|
||||
int (*prng)(
|
||||
unsigned char *rn, /* out: pseudo random number */
|
||||
int rn_len);
|
||||
|
||||
int (*aes_set_key)(
|
||||
bool bEncrypt, /* true Enxcrypt key, false: decrypt */
|
||||
const unsigned char *kstr,/* key string*/
|
||||
size_t kstr_len, /* kstr len in bytes (16, 24, or 32 bytes (for AES128,AES192, or AES256) */
|
||||
CRYSPR_AESCTX *aeskey); /* Cryptolib Specific AES key context */
|
||||
|
||||
int (*aes_ecb_cipher)(
|
||||
bool bEncrypt, /* true:encrypt false:decrypt */
|
||||
CRYSPR_AESCTX *aes_key, /* ctx */
|
||||
const unsigned char *indata, /* src (clear text)*/
|
||||
size_t inlen, /* src length */
|
||||
unsigned char *out_txt, /* dst (cipher text) */
|
||||
size_t *outlen); /* dst length */
|
||||
|
||||
int (*aes_ctr_cipher)(
|
||||
bool bEncrypt, /* true:encrypt false:decrypt (don't care with CTR) */
|
||||
CRYSPR_AESCTX *aes_key, /* ctx */
|
||||
unsigned char *iv, /* iv */
|
||||
const unsigned char *indata, /* src (clear text) */
|
||||
size_t inlen, /* src length */
|
||||
unsigned char *out_txt);/* dest */
|
||||
|
||||
unsigned char *(*sha1_msg_digest)(
|
||||
const unsigned char *m, /* in: message */
|
||||
size_t m_len, /* message length */
|
||||
unsigned char *md); /* out: message digest buffer *160 bytes */
|
||||
|
||||
/*
|
||||
* open:
|
||||
* Create a cipher instance
|
||||
* Allocate output buffers
|
||||
*/
|
||||
CRYSPR_cb *(*open)(
|
||||
struct tag_CRYSPR_methods *cryspr,
|
||||
size_t max_len); /* Maximum packet length that will be encrypted/decrypted */
|
||||
|
||||
/*
|
||||
* close:
|
||||
* Release any cipher resources
|
||||
*/
|
||||
int (*close)(
|
||||
CRYSPR_cb *cryspr_data); /* Cipher handle, internal data */
|
||||
|
||||
/*
|
||||
* pbkdf2_hmac_sha1
|
||||
* Password-based Key Derivation Function 2
|
||||
*/
|
||||
int (*km_pbkdf2)(
|
||||
CRYSPR_cb *cryspr_cb, /* Cryspr Control Block */
|
||||
char *passwd, /* passphrase */
|
||||
size_t passwd_len, /* passphrase len */
|
||||
unsigned char *salt, /* salt */
|
||||
size_t salt_len, /* salt_len */
|
||||
int itr, /* iterations */
|
||||
size_t out_len, /* key_len */
|
||||
unsigned char *out); /* derived key */
|
||||
|
||||
/*
|
||||
* km_setkey:
|
||||
* Set the Key Encypting Key for Wrap (Encryption) or UnWrap (Decryption).
|
||||
* Context (ctx) tells if it's for Wrap or Unwrap
|
||||
* A Context flags (ctx->flags) also tells if this is for wrap(encryption) or unwrap(decryption) context (HCRYPT_CTX_F_ENCRYPT)
|
||||
*/
|
||||
int (*km_setkey)(
|
||||
CRYSPR_cb *cryspr_cb, /* Cryspr Control Block */
|
||||
bool bWrap, /* True: Wrap KEK, False: Unwrap KEK */
|
||||
const unsigned char *kek, size_t kek_len); /* KEK: Key Encrypting Key */
|
||||
|
||||
/*
|
||||
* km_wrap:
|
||||
* wrap media stream key
|
||||
*/
|
||||
int (*km_wrap)(CRYSPR_cb *cryspr_cb,
|
||||
unsigned char *wrap,
|
||||
const unsigned char *sek,
|
||||
unsigned int seklen);
|
||||
|
||||
/*
|
||||
* km_unwrap:
|
||||
* wrap media stream key
|
||||
*/
|
||||
int (*km_unwrap)(CRYSPR_cb *cryspr_cb,
|
||||
unsigned char *sek,
|
||||
const unsigned char *wrap,
|
||||
unsigned int wraplen);
|
||||
/*
|
||||
* setkey:
|
||||
* Set the Odd or Even, Encryption or Decryption key.
|
||||
* Context (ctx) tells if it's for Odd or Even key (hcryptCtx_GetKeyIndex(ctx))
|
||||
* A Context flags (ctx->flags) also tells if this is an encryption or decryption context (HCRYPT_CTX_F_ENCRYPT)
|
||||
*/
|
||||
int (*ms_setkey)(
|
||||
CRYSPR_cb *cryspr_cb, /* Cryspr Control Block */
|
||||
hcrypt_Ctx *ctx, /* HaiCrypt Context (cipher, keys, Odd/Even, etc..) */
|
||||
const unsigned char *key, size_t kwelen); /* New Key */
|
||||
|
||||
/*
|
||||
* encrypt:
|
||||
* Submit a list of nbin clear transport packets (hcrypt_DataDesc *in_data) to encryption
|
||||
* returns *nbout encrypted data packets of length out_len_p[] into out_p[]
|
||||
*
|
||||
* If cipher implements deferred encryption (co-processor, async encryption),
|
||||
* it may return no encrypted packets, or encrypted packets for clear text packets of a previous call.
|
||||
*/
|
||||
int (*ms_encrypt)(
|
||||
CRYSPR_cb *cryspr_cb, /* Cryspr Control Block */
|
||||
hcrypt_Ctx *ctx, /* HaiCrypt Context (cipher, keys, Odd/Even, etc..) */
|
||||
hcrypt_DataDesc *in_data, int nbin, /* Clear text transport packets: header and payload */
|
||||
void *out_p[], size_t out_len_p[], int *nbout); /* Encrypted packets */
|
||||
|
||||
/*
|
||||
* decrypt:
|
||||
* Submit a list of nbin encrypted transport packets (hcrypt_DataDesc *in_data) to decryption
|
||||
* returns *nbout clear text data packets of length out_len_p[] into out_p[]
|
||||
*
|
||||
* If cipher implements deferred decryption (co-processor, async encryption),
|
||||
* it may return no decrypted packets, or decrypted packets for encrypted packets of a previous call.
|
||||
*/
|
||||
int (*ms_decrypt)(
|
||||
CRYSPR_cb *cryspr_cb, /* Cryspr Control Block */
|
||||
hcrypt_Ctx *ctx, /* HaiCrypt Context (cipher, keys, Odd/Even, etc..) */
|
||||
hcrypt_DataDesc *in_data, int nbin, /* Clear text transport packets: header and payload */
|
||||
void *out_p[], size_t out_len_p[], int *nbout); /* Encrypted packets */
|
||||
|
||||
} CRYSPR_methods;
|
||||
|
||||
CRYSPR_methods *crysprInit(CRYSPR_methods *cryspr);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* CRYSPR_H */
|
27
trunk/3rdparty/srt-1-fit/haicrypt/filelist-gnutls.maf
vendored
Normal file
27
trunk/3rdparty/srt-1-fit/haicrypt/filelist-gnutls.maf
vendored
Normal file
|
@ -0,0 +1,27 @@
|
|||
# This file is currently reserved for future refactoring, when all headers
|
||||
# are going to be moved here. This is the list of headers considered to be
|
||||
# attached to the installation package. Once possible, please move the below
|
||||
# header files from ../include back to this directory.
|
||||
PUBLIC HEADERS
|
||||
haicrypt.h
|
||||
hcrypt_ctx.h
|
||||
hcrypt_msg.h
|
||||
|
||||
PRIVATE HEADERS
|
||||
hcrypt.h
|
||||
cryspr.h
|
||||
cryspr-gnutls.h
|
||||
haicrypt_log.h
|
||||
|
||||
SOURCES
|
||||
cryspr.c
|
||||
cryspr-gnutls.c
|
||||
hcrypt.c
|
||||
hcrypt_ctx_rx.c
|
||||
hcrypt_ctx_tx.c
|
||||
hcrypt_rx.c
|
||||
hcrypt_sa.c
|
||||
hcrypt_tx.c
|
||||
hcrypt_xpt_srt.c
|
||||
hcrypt_xpt_sta.c
|
||||
haicrypt_log.cpp
|
25
trunk/3rdparty/srt-1-fit/haicrypt/filelist-mbedtls.maf
vendored
Normal file
25
trunk/3rdparty/srt-1-fit/haicrypt/filelist-mbedtls.maf
vendored
Normal file
|
@ -0,0 +1,25 @@
|
|||
# HaiCrypt library contents
|
||||
|
||||
PUBLIC HEADERS
|
||||
haicrypt.h
|
||||
hcrypt_ctx.h
|
||||
hcrypt_msg.h
|
||||
|
||||
PRIVATE HEADERS
|
||||
hcrypt.h
|
||||
cryspr.h
|
||||
cryspr-mbedtls.h
|
||||
haicrypt_log.h
|
||||
|
||||
SOURCES
|
||||
cryspr.c
|
||||
cryspr-mbedtls.c
|
||||
hcrypt.c
|
||||
hcrypt_ctx_rx.c
|
||||
hcrypt_ctx_tx.c
|
||||
hcrypt_rx.c
|
||||
hcrypt_sa.c
|
||||
hcrypt_tx.c
|
||||
hcrypt_xpt_srt.c
|
||||
hcrypt_xpt_sta.c
|
||||
haicrypt_log.cpp
|
25
trunk/3rdparty/srt-1-fit/haicrypt/filelist-openssl.maf
vendored
Normal file
25
trunk/3rdparty/srt-1-fit/haicrypt/filelist-openssl.maf
vendored
Normal file
|
@ -0,0 +1,25 @@
|
|||
# HaiCrypt library contents
|
||||
|
||||
PUBLIC HEADERS
|
||||
haicrypt.h
|
||||
hcrypt_ctx.h
|
||||
hcrypt_msg.h
|
||||
|
||||
PRIVATE HEADERS
|
||||
hcrypt.h
|
||||
cryspr.h
|
||||
cryspr-openssl.h
|
||||
haicrypt_log.h
|
||||
|
||||
SOURCES
|
||||
cryspr.c
|
||||
cryspr-openssl.c
|
||||
hcrypt.c
|
||||
hcrypt_ctx_rx.c
|
||||
hcrypt_ctx_tx.c
|
||||
hcrypt_rx.c
|
||||
hcrypt_sa.c
|
||||
hcrypt_tx.c
|
||||
hcrypt_xpt_srt.c
|
||||
hcrypt_xpt_sta.c
|
||||
haicrypt_log.cpp
|
138
trunk/3rdparty/srt-1-fit/haicrypt/haicrypt.h
vendored
Normal file
138
trunk/3rdparty/srt-1-fit/haicrypt/haicrypt.h
vendored
Normal file
|
@ -0,0 +1,138 @@
|
|||
/*
|
||||
* SRT - Secure, Reliable, Transport
|
||||
* Copyright (c) 2018 Haivision Systems Inc.
|
||||
*
|
||||
* 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/.
|
||||
*
|
||||
*/
|
||||
|
||||
/*****************************************************************************
|
||||
written by
|
||||
Haivision Systems Inc.
|
||||
|
||||
2011-06-23 (jdube)
|
||||
HaiCrypt initial implementation.
|
||||
2014-03-11 (jdube)
|
||||
Adaptation for SRT.
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef HAICRYPT_H
|
||||
#define HAICRYPT_H
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// setup exports
|
||||
#if defined _WIN32 && !defined __MINGW__
|
||||
#ifdef HAICRYPT_DYNAMIC
|
||||
#ifdef HAICRYPT_EXPORTS
|
||||
#define HAICRYPT_API __declspec(dllexport)
|
||||
#else
|
||||
#define HAICRYPT_API __declspec(dllimport)
|
||||
#endif
|
||||
#else
|
||||
#define HAICRYPT_API
|
||||
#endif
|
||||
#else
|
||||
#define HAICRYPT_API
|
||||
#endif
|
||||
|
||||
typedef void *HaiCrypt_Cryspr;
|
||||
|
||||
HAICRYPT_API HaiCrypt_Cryspr HaiCryptCryspr_Get_Instance (void); /* Return a default cryspr instance */
|
||||
|
||||
#define HAICRYPT_CIPHER_BLK_SZ 16 /* AES Block Size */
|
||||
|
||||
#define HAICRYPT_PWD_MAX_SZ 80 /* MAX password (for Password-based Key Derivation) */
|
||||
#define HAICRYPT_KEY_MAX_SZ 32 /* MAX key */
|
||||
#define HAICRYPT_SECRET_MAX_SZ (HAICRYPT_PWD_MAX_SZ > HAICRYPT_KEY_MAX_SZ ? HAICRYPT_PWD_MAX_SZ : HAICRYPT_KEY_MAX_SZ)
|
||||
|
||||
|
||||
#define HAICRYPT_SALT_SZ 16
|
||||
|
||||
#define HAICRYPT_WRAPKEY_SIGN_SZ 8 /* RFC3394 AES KeyWrap signature size */
|
||||
|
||||
#define HAICRYPT_PBKDF2_SALT_LEN 8 /* PKCS#5 PBKDF2 Password based key derivation salt length */
|
||||
#define HAICRYPT_PBKDF2_ITER_CNT 2048 /* PKCS#5 PBKDF2 Password based key derivation iteration count */
|
||||
|
||||
#define HAICRYPT_TS_PKT_SZ 188 /* Transport Stream packet size */
|
||||
|
||||
typedef struct {
|
||||
#define HAICRYPT_SECTYP_UNDEF 0
|
||||
#define HAICRYPT_SECTYP_PRESHARED 1 /* Preshared KEK */
|
||||
#define HAICRYPT_SECTYP_PASSPHRASE 2 /* Password */
|
||||
unsigned typ;
|
||||
size_t len;
|
||||
unsigned char str[HAICRYPT_SECRET_MAX_SZ];
|
||||
}HaiCrypt_Secret;
|
||||
|
||||
typedef struct {
|
||||
#define HAICRYPT_CFG_F_TX 0x01 /* !TX -> RX */
|
||||
#define HAICRYPT_CFG_F_CRYPTO 0x02 /* Perform crypto Tx:Encrypt Rx:Decrypt */
|
||||
#define HAICRYPT_CFG_F_FEC 0x04 /* Do Forward Error Correction */
|
||||
unsigned flags;
|
||||
|
||||
HaiCrypt_Secret secret; /* Security Association */
|
||||
|
||||
HaiCrypt_Cryspr cryspr; /* CRYSPR implementation */
|
||||
#define HAICRYPT_DEF_KEY_LENGTH 16 /* default key length (bytes) */
|
||||
size_t key_len; /* SEK length (bytes) */
|
||||
#define HAICRYPT_DEF_DATA_MAX_LENGTH 1500 /* default packet data length (bytes) */
|
||||
size_t data_max_len; /* Maximum data_len passed to HaiCrypt (bytes) */
|
||||
|
||||
#define HAICRYPT_XPT_STANDALONE 0
|
||||
#define HAICRYPT_XPT_SRT 1
|
||||
int xport;
|
||||
|
||||
#define HAICRYPT_DEF_KM_TX_PERIOD 1000 /* Keying Material Default Tx Period (msec) */
|
||||
unsigned int km_tx_period_ms; /* Keying Material Tx period (msec) */
|
||||
#define HAICRYPT_DEF_KM_REFRESH_RATE 0x1000000 /* Keying Material Default Refresh Rate (pkts) */
|
||||
unsigned int km_refresh_rate_pkt; /* Keying Material Refresh Rate (pkts) */
|
||||
#define HAICRYPT_DEF_KM_PRE_ANNOUNCE 0x1000 /* Keying Material Default Pre/Post Announce (pkts) */
|
||||
unsigned int km_pre_announce_pkt; /* Keying Material Pre/Post Announce (pkts) */
|
||||
}HaiCrypt_Cfg;
|
||||
|
||||
typedef enum HaiCrypt_CryptoDir { HAICRYPT_CRYPTO_DIR_RX, HAICRYPT_CRYPTO_DIR_TX } HaiCrypt_CryptoDir;
|
||||
|
||||
//typedef void *HaiCrypt_Handle;
|
||||
// internally it will be correctly interpreted,
|
||||
// for the outsider it's just some kinda incomplete type
|
||||
// but still if you use any kinda pointer instead, you'll get complaints
|
||||
typedef struct hcrypt_Session_str* HaiCrypt_Handle;
|
||||
|
||||
|
||||
|
||||
HAICRYPT_API int HaiCrypt_SetLogLevel(int level, int logfa);
|
||||
|
||||
HAICRYPT_API int HaiCrypt_Create(const HaiCrypt_Cfg *cfg, HaiCrypt_Handle *phhc);
|
||||
HAICRYPT_API int HaiCrypt_Clone(HaiCrypt_Handle hhcSrc, HaiCrypt_CryptoDir tx, HaiCrypt_Handle *phhc);
|
||||
HAICRYPT_API int HaiCrypt_Close(HaiCrypt_Handle hhc);
|
||||
HAICRYPT_API int HaiCrypt_Tx_GetBuf(HaiCrypt_Handle hhc, size_t data_len, unsigned char **in_p);
|
||||
HAICRYPT_API int HaiCrypt_Tx_Process(HaiCrypt_Handle hhc, unsigned char *in, size_t in_len,
|
||||
void *out_p[], size_t out_len_p[], int maxout);
|
||||
HAICRYPT_API int HaiCrypt_Rx_Process(HaiCrypt_Handle hhc, unsigned char *in, size_t in_len,
|
||||
void *out_p[], size_t out_len_p[], int maxout);
|
||||
|
||||
HAICRYPT_API int HaiCrypt_Tx_GetKeyFlags(HaiCrypt_Handle hhc);
|
||||
HAICRYPT_API int HaiCrypt_Tx_ManageKeys(HaiCrypt_Handle hhc, void *out_p[], size_t out_len_p[], int maxout);
|
||||
HAICRYPT_API int HaiCrypt_Tx_Data(HaiCrypt_Handle hhc, unsigned char *pfx, unsigned char *data, size_t data_len);
|
||||
HAICRYPT_API int HaiCrypt_Rx_Data(HaiCrypt_Handle hhc, unsigned char *pfx, unsigned char *data, size_t data_len);
|
||||
|
||||
/* Status values */
|
||||
|
||||
#define HAICRYPT_ERROR -1
|
||||
#define HAICRYPT_ERROR_WRONG_SECRET -2
|
||||
#define HAICRYPT_OK 0
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* HAICRYPT_H */
|
120
trunk/3rdparty/srt-1-fit/haicrypt/haicrypt_log.cpp
vendored
Normal file
120
trunk/3rdparty/srt-1-fit/haicrypt/haicrypt_log.cpp
vendored
Normal file
|
@ -0,0 +1,120 @@
|
|||
/*
|
||||
* SRT - Secure, Reliable, Transport
|
||||
* Copyright (c) 2018 Haivision Systems Inc.
|
||||
*
|
||||
* 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/.
|
||||
*
|
||||
*/
|
||||
|
||||
#if ENABLE_HAICRYPT_LOGGING
|
||||
|
||||
#include "hcrypt.h"
|
||||
#include "haicrypt.h"
|
||||
#include "../srtcore/srt.h"
|
||||
#include "../srtcore/logging.h"
|
||||
|
||||
extern srt_logging::LogConfig srt_logger_config;
|
||||
|
||||
// LOGFA symbol defined in srt.h
|
||||
srt_logging::Logger hclog(SRT_LOGFA_HAICRYPT, srt_logger_config, "SRT.k");
|
||||
|
||||
extern "C" {
|
||||
|
||||
int HaiCrypt_SetLogLevel(int level, int logfa)
|
||||
{
|
||||
srt_setloglevel(level);
|
||||
if (logfa != SRT_LOGFA_GENERAL) // General can't be turned on or off
|
||||
{
|
||||
srt_addlogfa(logfa);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// HaiCrypt will be using its own FA, which will be turned off by default.
|
||||
|
||||
// Templates made C way.
|
||||
// It's tempting to use the HAICRYPT_DEFINE_LOG_DISPATCHER macro here because it would provide the
|
||||
// exact signature that is needed here, the problem is though that this would expand the LOGLEVEL
|
||||
// parameter, which is also a macro, into the value that the macro designates, which would generate
|
||||
// the HaiCrypt_LogF_0 instead of HaiCrypt_LogF_LOG_DEBUG, for example.
|
||||
#define HAICRYPT_DEFINE_LOG_DISPATCHER(LOGLEVEL, dispatcher) \
|
||||
int HaiCrypt_LogF_##LOGLEVEL ( const char* file, int line, const char* function, const char* format, ...) \
|
||||
{ \
|
||||
va_list ap; \
|
||||
va_start(ap, format); \
|
||||
srt_logging::LogDispatcher& lg = hclog.dispatcher; \
|
||||
if (!lg.CheckEnabled()) return -1; \
|
||||
lg().setloc(file, line, function).vform(format, ap); \
|
||||
va_end(ap); \
|
||||
return 0; \
|
||||
}
|
||||
|
||||
|
||||
HAICRYPT_DEFINE_LOG_DISPATCHER(LOG_DEBUG, Debug);
|
||||
HAICRYPT_DEFINE_LOG_DISPATCHER(LOG_NOTICE, Note);
|
||||
HAICRYPT_DEFINE_LOG_DISPATCHER(LOG_INFO, Note);
|
||||
HAICRYPT_DEFINE_LOG_DISPATCHER(LOG_WARNING, Warn);
|
||||
HAICRYPT_DEFINE_LOG_DISPATCHER(LOG_ERR, Error);
|
||||
HAICRYPT_DEFINE_LOG_DISPATCHER(LOG_CRIT, Fatal);
|
||||
HAICRYPT_DEFINE_LOG_DISPATCHER(LOG_ALERT, Fatal);
|
||||
HAICRYPT_DEFINE_LOG_DISPATCHER(LOG_EMERG, Fatal);
|
||||
|
||||
|
||||
static void DumpCfgFlags(int flags, std::ostream& out)
|
||||
{
|
||||
static struct { int flg; const char* desc; } flgtable [] = {
|
||||
#define HCRYPTF(name) { HAICRYPT_CFG_F_##name, #name }
|
||||
HCRYPTF(TX),
|
||||
HCRYPTF(CRYPTO),
|
||||
HCRYPTF(FEC)
|
||||
#undef HCRYPTF
|
||||
};
|
||||
size_t flgtable_size = sizeof(flgtable)/sizeof(flgtable[0]);
|
||||
size_t i;
|
||||
|
||||
out << "{";
|
||||
const char* sep = "";
|
||||
const char* sep_bar = " | ";
|
||||
for (i = 0; i < flgtable_size; ++i)
|
||||
{
|
||||
if ( (flgtable[i].flg & flags) != 0 )
|
||||
{
|
||||
out << sep << flgtable[i].desc;
|
||||
sep = sep_bar;
|
||||
}
|
||||
}
|
||||
out << "}";
|
||||
}
|
||||
|
||||
void HaiCrypt_DumpConfig(const HaiCrypt_Cfg* cfg)
|
||||
{
|
||||
std::ostringstream cfg_flags;
|
||||
|
||||
DumpCfgFlags(cfg->flags, cfg_flags);
|
||||
|
||||
LOGC(hclog.Debug, log << "CFG DUMP: flags=" << cfg_flags.str()
|
||||
<< " xport=" << (cfg->xport == HAICRYPT_XPT_SRT ? "SRT" : "INVALID")
|
||||
<< " cipher="
|
||||
<< (cfg->cipher == HaiCryptCipher_OpenSSL_EVP_CTR() ? "OSSL-EVP-CTR":
|
||||
cfg->cipher == HaiCryptCipher_OpenSSL_AES() ? "OSSL-AES":
|
||||
// This below is used as the only one when Nettle is used. When OpenSSL
|
||||
// is used, one of the above will trigger, and the one below will then never trigger.
|
||||
cfg->cipher == HaiCryptCipher_Get_Instance() ? "Nettle-AES":
|
||||
"UNKNOWN")
|
||||
<< " key_len=" << cfg->key_len << " data_max_len=" << cfg->data_max_len);
|
||||
|
||||
|
||||
LOGC(hclog.Debug, log << "CFG DUMP: txperiod="
|
||||
<< cfg->km_tx_period_ms << "ms kmrefresh=" << cfg->km_refresh_rate_pkt
|
||||
<< " kmpreannounce=" << cfg->km_pre_announce_pkt
|
||||
<< " secret "
|
||||
<< "{tp=" << (cfg->secret.typ == 1 ? "PSK" : cfg->secret.typ == 2 ? "PWD" : "???")
|
||||
<< " len=" << cfg->secret.len << " pwd=" << cfg->secret.str << "}");
|
||||
|
||||
}
|
||||
|
||||
} // extern "C"
|
||||
|
||||
#endif // Block for the whole file
|
34
trunk/3rdparty/srt-1-fit/haicrypt/haicrypt_log.h
vendored
Normal file
34
trunk/3rdparty/srt-1-fit/haicrypt/haicrypt_log.h
vendored
Normal file
|
@ -0,0 +1,34 @@
|
|||
#ifndef IMC__HAICRYPT_LOG_H
|
||||
#define IMC__HAICRYPT_LOG_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define HAICRYPT_DECLARE_LOG_DISPATCHER(LOGLEVEL) \
|
||||
int HaiCrypt_LogF_##LOGLEVEL ( const char* file, int line, const char* function, const char* format, ...)
|
||||
|
||||
// Now declare all dispatcher functions
|
||||
|
||||
HAICRYPT_DECLARE_LOG_DISPATCHER(LOG_DEBUG);
|
||||
HAICRYPT_DECLARE_LOG_DISPATCHER(LOG_NOTICE);
|
||||
HAICRYPT_DECLARE_LOG_DISPATCHER(LOG_INFO);
|
||||
HAICRYPT_DECLARE_LOG_DISPATCHER(LOG_WARNING);
|
||||
HAICRYPT_DECLARE_LOG_DISPATCHER(LOG_ERR);
|
||||
HAICRYPT_DECLARE_LOG_DISPATCHER(LOG_CRIT);
|
||||
HAICRYPT_DECLARE_LOG_DISPATCHER(LOG_ALERT);
|
||||
HAICRYPT_DECLARE_LOG_DISPATCHER(LOG_EMERG);
|
||||
|
||||
#define HCRYPT_LOG_INIT()
|
||||
#define HCRYPT_LOG_EXIT()
|
||||
#define HCRYPT_LOG(lvl, fmt, ...) HaiCrypt_LogF_##lvl (__FILE__, __LINE__, __FUNCTION__, fmt, __VA_ARGS__)
|
||||
|
||||
#if ENABLE_HAICRYPT_LOGGING == 2
|
||||
#define HCRYPT_DEV 1
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // macroguard
|
342
trunk/3rdparty/srt-1-fit/haicrypt/hcrypt.c
vendored
Normal file
342
trunk/3rdparty/srt-1-fit/haicrypt/hcrypt.c
vendored
Normal file
|
@ -0,0 +1,342 @@
|
|||
/*
|
||||
* SRT - Secure, Reliable, Transport
|
||||
* Copyright (c) 2018 Haivision Systems Inc.
|
||||
*
|
||||
* 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/.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
written by
|
||||
Haivision Systems Inc.
|
||||
|
||||
2011-06-23 (jdube)
|
||||
HaiCrypt initial implementation.
|
||||
2014-03-11 (jdube)
|
||||
Adaptation for SRT.
|
||||
*****************************************************************************/
|
||||
|
||||
#include <stdio.h> /* snprintf */
|
||||
#include <stdlib.h> /* NULL, malloc, free */
|
||||
#include <string.h> /* memcpy, memset */
|
||||
#ifdef _WIN32
|
||||
#include <winsock2.h>
|
||||
#include <ws2tcpip.h>
|
||||
#else
|
||||
#include <sys/time.h> /* timerclear */
|
||||
#endif
|
||||
|
||||
#include "hcrypt.h"
|
||||
|
||||
#if ENABLE_HAICRYPT_LOGGING
|
||||
void HaiCrypt_DumpConfig(const HaiCrypt_Cfg* cfg);
|
||||
#else
|
||||
#define HaiCrypt_DumpConfig(x) (void)0
|
||||
#endif
|
||||
|
||||
|
||||
static hcrypt_Session* sHaiCrypt_PrepareHandle(const HaiCrypt_Cfg* cfg, HaiCrypt_CryptoDir tx)
|
||||
{
|
||||
hcrypt_Session *crypto;
|
||||
unsigned char *mem_buf;
|
||||
size_t mem_siz, inbuf_siz;
|
||||
|
||||
HaiCrypt_DumpConfig(cfg);
|
||||
|
||||
HCRYPT_PRINTKEY(cfg->secret.str, cfg->secret.len, "cfgkey");
|
||||
|
||||
inbuf_siz = 0;
|
||||
inbuf_siz = hcryptMsg_PaddedLen(cfg->data_max_len, 128/8);
|
||||
|
||||
/* Allocate crypto session control struct */
|
||||
mem_siz = sizeof(hcrypt_Session) // structure
|
||||
+ inbuf_siz;
|
||||
|
||||
crypto = malloc(mem_siz);
|
||||
if (NULL == crypto) {
|
||||
HCRYPT_LOG(LOG_ERR, "%s\n", "malloc failed");
|
||||
return NULL;
|
||||
}
|
||||
mem_buf = (unsigned char *)crypto;
|
||||
mem_buf += sizeof(*crypto);
|
||||
memset(crypto, 0, sizeof(*crypto));
|
||||
|
||||
if (inbuf_siz) {
|
||||
crypto->inbuf = mem_buf;
|
||||
crypto->inbuf_siz = inbuf_siz;
|
||||
}
|
||||
|
||||
crypto->cryspr = cfg->cryspr;
|
||||
crypto->cfg.data_max_len = cfg->data_max_len;
|
||||
|
||||
/* Setup transport packet info */
|
||||
switch (cfg->xport) {
|
||||
case HAICRYPT_XPT_STANDALONE:
|
||||
crypto->se = HCRYPT_SE_TSUDP;
|
||||
crypto->msg_info = hcryptMsg_STA_MsgInfo();
|
||||
break;
|
||||
case HAICRYPT_XPT_SRT:
|
||||
crypto->se = HCRYPT_SE_TSSRT;
|
||||
crypto->msg_info = hcryptMsg_SRT_MsgInfo();
|
||||
break;
|
||||
default:
|
||||
HCRYPT_LOG(LOG_ERR, "invalid xport: %d\n", cfg->xport);
|
||||
free(crypto);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
timerclear(&crypto->km.tx_last);
|
||||
crypto->km.tx_period.tv_sec = cfg->km_tx_period_ms / 1000;
|
||||
crypto->km.tx_period.tv_usec = (cfg->km_tx_period_ms % 1000) * 1000;
|
||||
|
||||
crypto->km.refresh_rate = cfg->km_refresh_rate_pkt;
|
||||
crypto->km.pre_announce = cfg->km_pre_announce_pkt;
|
||||
|
||||
/* Indentify each context */
|
||||
crypto->ctx_pair[0].flags = HCRYPT_MSG_F_eSEK | (tx ? HCRYPT_CTX_F_ENCRYPT : 0);
|
||||
crypto->ctx_pair[1].flags = HCRYPT_MSG_F_oSEK | (tx ? HCRYPT_CTX_F_ENCRYPT : 0);
|
||||
/* Point to each other */
|
||||
crypto->ctx_pair[0].alt = &crypto->ctx_pair[1];
|
||||
crypto->ctx_pair[1].alt = &crypto->ctx_pair[0];
|
||||
|
||||
crypto->cryspr_cb = crypto->cryspr->open(crypto->cryspr, cfg->data_max_len);
|
||||
if (NULL == crypto->cryspr_cb) {
|
||||
free(crypto);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return crypto;
|
||||
}
|
||||
|
||||
int HaiCrypt_Create(const HaiCrypt_Cfg *cfg, HaiCrypt_Handle *phhc)
|
||||
{
|
||||
ASSERT(cfg != NULL);
|
||||
ASSERT(phhc != NULL);
|
||||
|
||||
hcrypt_Session *crypto;
|
||||
HaiCrypt_CryptoDir tx = (HaiCrypt_CryptoDir)(HAICRYPT_CFG_F_TX & cfg->flags);
|
||||
|
||||
*phhc = NULL;
|
||||
|
||||
HCRYPT_LOG_INIT();
|
||||
//Test log
|
||||
HCRYPT_LOG(LOG_INFO, "creating crypto context(flags=0x%x)\n", cfg->flags);
|
||||
|
||||
if (!(HAICRYPT_CFG_F_CRYPTO & cfg->flags)) {
|
||||
HCRYPT_LOG(LOG_INFO, "no supported flags set (0x%x)\n", cfg->flags);
|
||||
return(-1);
|
||||
} else if ((16 != cfg->key_len) /* SEK length */
|
||||
&& (24 != cfg->key_len)
|
||||
&& (32 != cfg->key_len)) {
|
||||
HCRYPT_LOG(LOG_ERR, "invalid key length (%d). Expected: 16, 24, 32\n", (int)cfg->key_len);
|
||||
return(-1);
|
||||
} else if ((HAICRYPT_SECTYP_PASSPHRASE == cfg->secret.typ)
|
||||
&& ((0 == cfg->secret.len) || (sizeof(cfg->secret.str) < cfg->secret.len))) { /* KEK length */
|
||||
HCRYPT_LOG(LOG_ERR, "invalid secret passphrase length (%d)\n", (int)cfg->secret.len);
|
||||
return(-1);
|
||||
} else if ((HAICRYPT_SECTYP_PRESHARED == cfg->secret.typ)
|
||||
&& (cfg->key_len > cfg->secret.len)) {
|
||||
HCRYPT_LOG(LOG_ERR, "preshared secret length (%d) smaller than key length (%d)\n",
|
||||
(int)cfg->secret.len, (int)cfg->key_len);
|
||||
return(-1);
|
||||
} else if (NULL == cfg->cryspr) {
|
||||
HCRYPT_LOG(LOG_ERR, "%s\n", "no cryspr specified");
|
||||
return(-1);
|
||||
} else if (0 == cfg->data_max_len) {
|
||||
HCRYPT_LOG(LOG_ERR, "%s\n", "no data_max_len specified");
|
||||
return(-1);
|
||||
}
|
||||
|
||||
crypto = sHaiCrypt_PrepareHandle(cfg, tx);
|
||||
if (!crypto)
|
||||
return -1;
|
||||
|
||||
if (tx) { /* Encoder */
|
||||
/* Configure initial context */
|
||||
if (hcryptCtx_Tx_Init(crypto, &crypto->ctx_pair[0], cfg)
|
||||
|| hcryptCtx_Tx_Init(crypto, &crypto->ctx_pair[1], cfg)) {
|
||||
free(crypto);
|
||||
return(-1);
|
||||
}
|
||||
/* Generate keys for first (default) context */
|
||||
if (hcryptCtx_Tx_Rekey(crypto, &crypto->ctx_pair[0])) {
|
||||
free(crypto);
|
||||
return(-1);
|
||||
}
|
||||
crypto->ctx = &crypto->ctx_pair[0];
|
||||
crypto->ctx->flags |= (HCRYPT_CTX_F_ANNOUNCE | HCRYPT_CTX_F_TTSEND);
|
||||
crypto->ctx->status = HCRYPT_CTX_S_ACTIVE;
|
||||
} else { /* Decoder */
|
||||
/* Configure contexts */
|
||||
if (hcryptCtx_Rx_Init(crypto, &crypto->ctx_pair[0], cfg)
|
||||
|| hcryptCtx_Rx_Init(crypto, &crypto->ctx_pair[1], cfg)) {
|
||||
free(crypto);
|
||||
return(-1);
|
||||
}
|
||||
}
|
||||
|
||||
*phhc = (void *)crypto;
|
||||
return(0);
|
||||
}
|
||||
|
||||
int HaiCrypt_ExtractConfig(HaiCrypt_Handle hhcSrc, HaiCrypt_Cfg* pcfg)
|
||||
{
|
||||
hcrypt_Session *crypto = (hcrypt_Session *)hhcSrc;
|
||||
hcrypt_Ctx* ctx = crypto->ctx;
|
||||
if (!ctx)
|
||||
{
|
||||
// Fall back to the first of the pair;
|
||||
// Should this be not initialized, ignore it.
|
||||
ctx = &crypto->ctx_pair[0];
|
||||
|
||||
// We assume that when ctx != NULL, it is active or keyed anyway.
|
||||
if (ctx->status != HCRYPT_CTX_S_KEYED && ctx->status != HCRYPT_CTX_S_ACTIVE)
|
||||
return -1;
|
||||
}
|
||||
|
||||
pcfg->flags = HAICRYPT_CFG_F_CRYPTO;
|
||||
if ((ctx->flags & HCRYPT_CTX_F_ENCRYPT) == HCRYPT_CTX_F_ENCRYPT)
|
||||
pcfg->flags |= HAICRYPT_CFG_F_TX;
|
||||
|
||||
/* Set this explicitly - this use of this library is SRT only. */
|
||||
pcfg->xport = HAICRYPT_XPT_SRT;
|
||||
pcfg->cryspr = crypto->cryspr;
|
||||
pcfg->key_len = ctx->cfg.key_len;
|
||||
if (pcfg->key_len == 0) // not initialized - usual in RX
|
||||
{
|
||||
pcfg->key_len = ctx->sek_len;
|
||||
}
|
||||
pcfg->data_max_len = crypto->cfg.data_max_len;
|
||||
pcfg->km_tx_period_ms = 0;//No HaiCrypt KM inject period, handled in SRT;
|
||||
|
||||
pcfg->km_refresh_rate_pkt = crypto->km.refresh_rate;
|
||||
pcfg->km_pre_announce_pkt = crypto->km.pre_announce;
|
||||
|
||||
/* As SRT is using only the PASSPHRASE type, never PRESHARED,
|
||||
* this is so assumed here, although there are completely no
|
||||
* premises as to which is currently used by the hhcSrc.
|
||||
*/
|
||||
pcfg->secret.typ = HAICRYPT_SECTYP_PASSPHRASE;
|
||||
pcfg->secret.len = ctx->cfg.pwd_len;
|
||||
memcpy(pcfg->secret.str, ctx->cfg.pwd, pcfg->secret.len);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int HaiCrypt_Clone(HaiCrypt_Handle hhcSrc, HaiCrypt_CryptoDir tx, HaiCrypt_Handle *phhc)
|
||||
{
|
||||
hcrypt_Session *cryptoSrc = (hcrypt_Session *)hhcSrc;
|
||||
hcrypt_Session *cryptoClone;
|
||||
unsigned char *mem_buf;
|
||||
size_t mem_siz, inbuf_siz;
|
||||
|
||||
*phhc = NULL;
|
||||
|
||||
ASSERT(NULL != hhcSrc);
|
||||
|
||||
HCRYPT_LOG(LOG_INFO, "%s\n", "creating CLONED crypto context");
|
||||
|
||||
if (tx) {
|
||||
HaiCrypt_Cfg crypto_config;
|
||||
HaiCrypt_ExtractConfig(hhcSrc, &crypto_config);
|
||||
|
||||
/*
|
||||
* Just invert the direction written in flags and use the
|
||||
* standard way of creating the context, as you already have a config.
|
||||
*/
|
||||
crypto_config.flags |= HAICRYPT_CFG_F_TX;
|
||||
cryptoClone = sHaiCrypt_PrepareHandle(&crypto_config, tx);
|
||||
if (!cryptoClone)
|
||||
return -1;
|
||||
|
||||
/* Configure initial context */
|
||||
if (hcryptCtx_Tx_Init(cryptoClone, &cryptoClone->ctx_pair[0], &crypto_config)
|
||||
|| hcryptCtx_Tx_Init(cryptoClone, &cryptoClone->ctx_pair[1], &crypto_config)) {
|
||||
free(cryptoClone);
|
||||
return(-1);
|
||||
}
|
||||
/* Clone keys for first (default) context from the source RX crypto */
|
||||
if (hcryptCtx_Tx_CloneKey(cryptoClone, &cryptoClone->ctx_pair[0], cryptoSrc)) {
|
||||
free(cryptoClone);
|
||||
return(-1);
|
||||
}
|
||||
cryptoClone->ctx = &cryptoClone->ctx_pair[0];
|
||||
cryptoClone->ctx->flags |= (HCRYPT_CTX_F_ANNOUNCE | HCRYPT_CTX_F_TTSEND);
|
||||
cryptoClone->ctx->status = HCRYPT_CTX_S_ACTIVE;
|
||||
|
||||
} else { /* Receiver */
|
||||
|
||||
/*
|
||||
* If cryspr has no special input buffer alignment requirement,
|
||||
* handle it in the crypto session.
|
||||
*/
|
||||
inbuf_siz = cryptoSrc->inbuf_siz ;
|
||||
|
||||
/* Allocate crypto session control struct */
|
||||
mem_siz = sizeof(hcrypt_Session) // structure
|
||||
+ inbuf_siz;
|
||||
|
||||
cryptoClone = malloc(mem_siz);
|
||||
if (NULL == cryptoClone) {
|
||||
HCRYPT_LOG(LOG_ERR, "%s\n", "malloc failed");
|
||||
return(-1);
|
||||
}
|
||||
mem_buf = (unsigned char *)cryptoClone;
|
||||
mem_buf += sizeof(*cryptoClone);
|
||||
memcpy(cryptoClone, cryptoSrc, sizeof(*cryptoClone));
|
||||
|
||||
if (inbuf_siz) {
|
||||
cryptoClone->inbuf = mem_buf;
|
||||
mem_buf += inbuf_siz;
|
||||
}
|
||||
timerclear(&cryptoClone->km.tx_last);
|
||||
|
||||
/* Adjust pointers pointing into cryproSrc after copy
|
||||
msg_info and crysprs are extern statics so this is ok*/
|
||||
cryptoClone->ctx_pair[0].alt = &cryptoClone->ctx_pair[1];
|
||||
cryptoClone->ctx_pair[1].alt = &cryptoClone->ctx_pair[0];
|
||||
|
||||
/* create a new cryspr (OpenSSL) context */
|
||||
cryptoClone->cryspr_cb = cryptoClone->cryspr->open(cryptoClone->cryspr, cryptoClone->cfg.data_max_len);
|
||||
if (NULL == cryptoClone->cryspr_cb) {
|
||||
//shred
|
||||
free(cryptoClone);
|
||||
return(-1);
|
||||
}
|
||||
|
||||
|
||||
/* Configure contexts */
|
||||
if (hcryptCtx_Rx_Init(cryptoClone, &cryptoClone->ctx_pair[0], NULL)
|
||||
|| hcryptCtx_Rx_Init(cryptoClone, &cryptoClone->ctx_pair[1], NULL)) {
|
||||
free(cryptoClone);
|
||||
return(-1);
|
||||
}
|
||||
|
||||
/* Clear salt to force later regeneration of KEK as AES decrypting key,
|
||||
copyed one is encrypting key */
|
||||
cryptoClone->ctx_pair[0].flags &= ~HCRYPT_CTX_F_ENCRYPT;
|
||||
cryptoClone->ctx_pair[1].flags &= ~HCRYPT_CTX_F_ENCRYPT;
|
||||
memset(cryptoClone->ctx_pair[0].salt, 0, sizeof(cryptoClone->ctx_pair[0].salt));
|
||||
cryptoClone->ctx_pair[0].salt_len = 0;
|
||||
}
|
||||
|
||||
*phhc = (void *)cryptoClone;
|
||||
return(0);
|
||||
}
|
||||
|
||||
int HaiCrypt_Close(HaiCrypt_Handle hhc)
|
||||
{
|
||||
hcrypt_Session *crypto = (hcrypt_Session *)hhc;
|
||||
int rc = -1;
|
||||
|
||||
if (crypto) {
|
||||
if (crypto->cryspr && crypto->cryspr->close) crypto->cryspr->close(crypto->cryspr_cb);
|
||||
free(crypto);
|
||||
rc = 0;
|
||||
}
|
||||
HCRYPT_LOG_EXIT();
|
||||
return rc;
|
||||
}
|
169
trunk/3rdparty/srt-1-fit/haicrypt/hcrypt.h
vendored
Normal file
169
trunk/3rdparty/srt-1-fit/haicrypt/hcrypt.h
vendored
Normal file
|
@ -0,0 +1,169 @@
|
|||
/*
|
||||
* SRT - Secure, Reliable, Transport
|
||||
* Copyright (c) 2018 Haivision Systems Inc.
|
||||
*
|
||||
* 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/.
|
||||
*
|
||||
*/
|
||||
|
||||
/*****************************************************************************
|
||||
written by
|
||||
Haivision Systems Inc.
|
||||
|
||||
2011-06-23 (jdube)
|
||||
HaiCrypt initial implementation.
|
||||
2014-03-11 (jdube)
|
||||
Adaptation for SRT.
|
||||
2014-03-26 (jsantiago)
|
||||
OS-X Build.
|
||||
2014-03-27 (jdube)
|
||||
Remove dependency on internal Crypto API.
|
||||
2016-07-22 (jsantiago)
|
||||
MINGW-W64 Build.
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef HCRYPT_H
|
||||
#define HCRYPT_H
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <winsock2.h>
|
||||
#include <ws2tcpip.h>
|
||||
#if defined(_MSC_VER)
|
||||
#pragma warning(disable:4267)
|
||||
#pragma warning(disable:4018)
|
||||
#endif
|
||||
#else
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
|
||||
#ifdef __GNUC__
|
||||
#define ATR_UNUSED __attribute__((unused))
|
||||
#else
|
||||
#define ATR_UNUSED
|
||||
#endif
|
||||
|
||||
#include "haicrypt.h"
|
||||
#include "hcrypt_msg.h"
|
||||
#include "hcrypt_ctx.h"
|
||||
#include "cryspr.h"
|
||||
|
||||
//#define HCRYPT_DEV 1 /* Development: should not be defined in committed code */
|
||||
|
||||
#ifdef HAICRYPT_SUPPORT_CRYPTO_API
|
||||
/* See CRYPTOFEC_OBJECT in session structure */
|
||||
#define CRYPTO_API_SERVER 1 /* Enable handler's structures */
|
||||
#include "crypto_api.h"
|
||||
#endif /* HAICRYPT_SUPPORT_CRYPTO_API */
|
||||
|
||||
typedef struct hcrypt_Session_str {
|
||||
#ifdef HAICRYPT_SUPPORT_CRYPTO_API
|
||||
/*
|
||||
* Resv matches internal upper layer handle (crypto_api)
|
||||
* They are not used in HaiCrypt.
|
||||
* This make 3 layers using the same handle.
|
||||
* To get rid of this dependency for a portable HaiCrypt,
|
||||
* revise caller (crypto_hc.c) to allocate its own buffer.
|
||||
*/
|
||||
CRYPTOFEC_OBJECT resv; /* See above comment */
|
||||
#endif /* HAICRYPT_SUPPORT_CRYPTO_API */
|
||||
|
||||
hcrypt_Ctx ctx_pair[2]; /* Even(0)/Odd(1) crypto contexts */
|
||||
hcrypt_Ctx * ctx; /* Current context */
|
||||
|
||||
CRYSPR_methods * cryspr;
|
||||
CRYSPR_cb * cryspr_cb;
|
||||
|
||||
unsigned char * inbuf; /* allocated if cipher has no getinbuf() func */
|
||||
size_t inbuf_siz;
|
||||
|
||||
int se; /* Stream Encapsulation (HCRYPT_SE_xxx) */
|
||||
hcrypt_MsgInfo * msg_info;
|
||||
|
||||
struct {
|
||||
size_t data_max_len;
|
||||
}cfg;
|
||||
|
||||
struct {
|
||||
struct timeval tx_period; /* Keying Material tx period (milliseconds) */
|
||||
struct timeval tx_last; /* Keying Material last tx time */
|
||||
unsigned int refresh_rate; /* SEK use period */
|
||||
unsigned int pre_announce; /* Pre/Post next/old SEK announce */
|
||||
}km;
|
||||
} hcrypt_Session;
|
||||
|
||||
#if ENABLE_HAICRYPT_LOGGING
|
||||
#include "haicrypt_log.h"
|
||||
#else
|
||||
|
||||
#define HCRYPT_LOG_INIT()
|
||||
#define HCRYPT_LOG_EXIT()
|
||||
#define HCRYPT_LOG(lvl, fmt, ...)
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef HCRYPT_DEV
|
||||
#define HCRYPT_PRINTKEY(key, len, tag) HCRYPT_LOG(LOG_DEBUG, \
|
||||
"%s[%d]=0x%02x%02x..%02x%02x\n", tag, len, \
|
||||
(key)[0], (key)[1], (key)[(len)-2], (key)[(len)-1])
|
||||
#else /* HCRYPT_DEV */
|
||||
#define HCRYPT_PRINTKEY(key,len,tag)
|
||||
#endif /* HCRYPT_DEV */
|
||||
|
||||
#ifndef ASSERT
|
||||
#include <assert.h>
|
||||
#define ASSERT(c) assert(c)
|
||||
#endif
|
||||
|
||||
|
||||
/* HaiCrypt-TP CTR mode IV (128-bit):
|
||||
* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
|
||||
* +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|
||||
* | 0s | pki | ctr |
|
||||
* +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|
||||
* XOR
|
||||
* +---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|
||||
* | nonce +
|
||||
* +---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|
||||
*
|
||||
* pki (32-bit): packet index
|
||||
* ctr (16-bit): block counter
|
||||
* nonce (112-bit): number used once (salt)
|
||||
*/
|
||||
#define hcrypt_SetCtrIV(pki, nonce, iv) do { \
|
||||
memset(&(iv)[0], 0, 128/8); \
|
||||
memcpy(&(iv)[10], (pki), HCRYPT_PKI_SZ); \
|
||||
hcrypt_XorStream(&(iv)[0], (nonce), 112/8); \
|
||||
} while(0)
|
||||
|
||||
#define hcrypt_XorStream(dst, strm, len) do { \
|
||||
int __XORSTREAMi; \
|
||||
for (__XORSTREAMi = 0 \
|
||||
;__XORSTREAMi < (int)(len) \
|
||||
;__XORSTREAMi += 1) { \
|
||||
(dst)[__XORSTREAMi] ^= (strm)[__XORSTREAMi]; \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
|
||||
int hcryptCtx_SetSecret(hcrypt_Session *crypto, hcrypt_Ctx *ctx, const HaiCrypt_Secret *secret);
|
||||
int hcryptCtx_GenSecret(hcrypt_Session *crypto, hcrypt_Ctx *ctx);
|
||||
|
||||
int hcryptCtx_Tx_Init(hcrypt_Session *crypto, hcrypt_Ctx *ctx, const HaiCrypt_Cfg *cfg);
|
||||
int hcryptCtx_Tx_Rekey(hcrypt_Session *crypto, hcrypt_Ctx *ctx);
|
||||
int hcryptCtx_Tx_CloneKey(hcrypt_Session *crypto, hcrypt_Ctx *ctx, const hcrypt_Session* cryptoSrc);
|
||||
int hcryptCtx_Tx_Refresh(hcrypt_Session *crypto);
|
||||
int hcryptCtx_Tx_PreSwitch(hcrypt_Session *crypto);
|
||||
int hcryptCtx_Tx_Switch(hcrypt_Session *crypto);
|
||||
int hcryptCtx_Tx_PostSwitch(hcrypt_Session *crypto);
|
||||
int hcryptCtx_Tx_AsmKM(hcrypt_Session *crypto, hcrypt_Ctx *ctx, unsigned char *alt_sek);
|
||||
int hcryptCtx_Tx_ManageKM(hcrypt_Session *crypto);
|
||||
int hcryptCtx_Tx_InjectKM(hcrypt_Session *crypto, void *out_p[], size_t out_len_p[], int maxout);
|
||||
|
||||
int hcryptCtx_Rx_Init(hcrypt_Session *crypto, hcrypt_Ctx *ctx, const HaiCrypt_Cfg *cfg);
|
||||
int hcryptCtx_Rx_ParseKM(hcrypt_Session *crypto, unsigned char *msg, size_t msg_len);
|
||||
|
||||
#endif /* HCRYPT_H */
|
97
trunk/3rdparty/srt-1-fit/haicrypt/hcrypt_ctx.h
vendored
Normal file
97
trunk/3rdparty/srt-1-fit/haicrypt/hcrypt_ctx.h
vendored
Normal file
|
@ -0,0 +1,97 @@
|
|||
/*
|
||||
* SRT - Secure, Reliable, Transport
|
||||
* Copyright (c) 2018 Haivision Systems Inc.
|
||||
*
|
||||
* 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/.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
written by
|
||||
Haivision Systems Inc.
|
||||
|
||||
2011-06-23 (jdube)
|
||||
HaiCrypt initial implementation.
|
||||
2014-03-11 (jdube)
|
||||
Adaptation for SRT.
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef HCRYPT_CTX_H
|
||||
#define HCRYPT_CTX_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <sys/types.h>
|
||||
#include "hcrypt.h"
|
||||
|
||||
#if !defined(HAISRT_VERSION_INT)
|
||||
#include "haicrypt.h"
|
||||
#include "hcrypt_msg.h"
|
||||
#else
|
||||
// Included by haisrt.h or similar
|
||||
#include "haisrt/haicrypt.h"
|
||||
#include "haisrt/hcrypt_msg.h"
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
unsigned char *pfx; //Prefix described by transport msg info (in ctx)
|
||||
unsigned char *payload;
|
||||
size_t len; //Payload size
|
||||
}hcrypt_DataDesc;
|
||||
|
||||
|
||||
typedef struct tag_hcrypt_Ctx {
|
||||
struct tag_hcrypt_Ctx * alt; /* Alternative ctx (even/odd) */
|
||||
|
||||
#define HCRYPT_CTX_F_MSG 0x00FF /* Aligned wiht message header flags */
|
||||
#define HCRYPT_CTX_F_eSEK HCRYPT_MSG_F_eSEK
|
||||
#define HCRYPT_CTX_F_oSEK HCRYPT_MSG_F_oSEK
|
||||
#define HCRYPT_CTX_F_xSEK HCRYPT_MSG_F_xSEK
|
||||
|
||||
#define HCRYPT_CTX_F_ENCRYPT 0x0100 /* 0:decrypt 1:encrypt */
|
||||
#define HCRYPT_CTX_F_ANNOUNCE 0x0200 /* Announce KM */
|
||||
#define HCRYPT_CTX_F_TTSEND 0x0400 /* time to send */
|
||||
unsigned flags;
|
||||
#define hcryptCtx_GetKeyFlags(ctx) ((ctx)->flags & HCRYPT_CTX_F_xSEK)
|
||||
#define hcryptCtx_GetKeyIndex(ctx) (((ctx)->flags & HCRYPT_CTX_F_xSEK)>>1)
|
||||
|
||||
#define HCRYPT_CTX_S_INIT 1
|
||||
#define HCRYPT_CTX_S_SARDY 2 /* Security Association (KEK) ready */
|
||||
#define HCRYPT_CTX_S_KEYED 3 /* Media Stream Encrypting Key (SEK) ready */
|
||||
#define HCRYPT_CTX_S_ACTIVE 4 /* Announced and in use */
|
||||
#define HCRYPT_CTX_S_DEPRECATED 5 /* Still announced but no longer used */
|
||||
unsigned status;
|
||||
|
||||
#define HCRYPT_CTX_MODE_CLRTXT 0 /* NULL cipher (for tests) */
|
||||
#define HCRYPT_CTX_MODE_AESECB 1 /* Electronic Code Book mode */
|
||||
#define HCRYPT_CTX_MODE_AESCTR 2 /* Counter mode */
|
||||
#define HCRYPT_CTX_MODE_AESCBC 3 /* Cipher-block chaining mode */
|
||||
unsigned mode;
|
||||
|
||||
struct {
|
||||
size_t key_len;
|
||||
size_t pwd_len;
|
||||
char pwd[HAICRYPT_PWD_MAX_SZ];
|
||||
} cfg;
|
||||
|
||||
size_t salt_len;
|
||||
unsigned char salt[HAICRYPT_SALT_SZ];
|
||||
|
||||
size_t sek_len;
|
||||
unsigned char sek[HAICRYPT_KEY_MAX_SZ];
|
||||
|
||||
hcrypt_MsgInfo * msg_info; /* Transport message handler */
|
||||
unsigned pkt_cnt; /* Key usage counter */
|
||||
|
||||
#define HCRYPT_CTX_MAX_KM_PFX_SZ 16
|
||||
size_t KMmsg_len;
|
||||
unsigned char KMmsg_cache[HCRYPT_CTX_MAX_KM_PFX_SZ + HCRYPT_MSG_KM_MAX_SZ];
|
||||
|
||||
#define HCRYPT_CTX_MAX_MS_PFX_SZ 16
|
||||
unsigned char MSpfx_cache[HCRYPT_CTX_MAX_MS_PFX_SZ];
|
||||
} hcrypt_Ctx;
|
||||
|
||||
|
||||
#endif /* HCRYPT_CTX_H */
|
199
trunk/3rdparty/srt-1-fit/haicrypt/hcrypt_ctx_rx.c
vendored
Normal file
199
trunk/3rdparty/srt-1-fit/haicrypt/hcrypt_ctx_rx.c
vendored
Normal file
|
@ -0,0 +1,199 @@
|
|||
/*
|
||||
* SRT - Secure, Reliable, Transport
|
||||
* Copyright (c) 2018 Haivision Systems Inc.
|
||||
*
|
||||
* 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/.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
written by
|
||||
Haivision Systems Inc.
|
||||
|
||||
2011-06-23 (jdube)
|
||||
HaiCrypt initial implementation.
|
||||
2014-03-11 (jdube)
|
||||
Adaptation for SRT.
|
||||
*****************************************************************************/
|
||||
|
||||
#include <string.h> /* memcpy */
|
||||
#include "hcrypt.h"
|
||||
|
||||
int hcryptCtx_Rx_Init(hcrypt_Session *crypto, hcrypt_Ctx *ctx, const HaiCrypt_Cfg *cfg)
|
||||
{
|
||||
ctx->mode = HCRYPT_CTX_MODE_AESCTR;
|
||||
ctx->status = HCRYPT_CTX_S_INIT;
|
||||
|
||||
ctx->msg_info = crypto->msg_info;
|
||||
|
||||
if (cfg && hcryptCtx_SetSecret(crypto, ctx, &cfg->secret)) {
|
||||
return(-1);
|
||||
}
|
||||
ctx->status = HCRYPT_CTX_S_SARDY;
|
||||
return(0);
|
||||
}
|
||||
|
||||
int hcryptCtx_Rx_Rekey(hcrypt_Session *crypto, hcrypt_Ctx *ctx, unsigned char *sek, size_t sek_len)
|
||||
{
|
||||
if (crypto->cryspr->ms_setkey(crypto->cryspr_cb, ctx, sek, sek_len)) {
|
||||
HCRYPT_LOG(LOG_ERR, "cryspr setkey[%d](sek) failed\n", hcryptCtx_GetKeyIndex(ctx));
|
||||
return(-1);
|
||||
}
|
||||
memcpy(ctx->sek, sek, sek_len);
|
||||
ctx->sek_len = sek_len;
|
||||
|
||||
HCRYPT_LOG(LOG_INFO, "updated context[%d]\n", hcryptCtx_GetKeyIndex(ctx));
|
||||
HCRYPT_PRINTKEY(ctx->sek, ctx->sek_len, "sek");
|
||||
ctx->status = HCRYPT_CTX_S_KEYED;
|
||||
return(0);
|
||||
}
|
||||
|
||||
/* Parse Keying Material message */
|
||||
int hcryptCtx_Rx_ParseKM(hcrypt_Session *crypto, unsigned char *km_msg, size_t msg_len)
|
||||
{
|
||||
size_t sek_len, salt_len;
|
||||
unsigned char seks[HAICRYPT_KEY_MAX_SZ * 2];
|
||||
int sek_cnt;
|
||||
size_t kek_len = 0;
|
||||
hcrypt_Ctx *ctx;
|
||||
int do_pbkdf = 0;
|
||||
|
||||
if (NULL == crypto) {
|
||||
HCRYPT_LOG(LOG_ERR, "Rx_ParseKM: invalid params: crypto=%p\n", crypto);
|
||||
return(-1);
|
||||
}
|
||||
|
||||
/* Validate message content */
|
||||
{
|
||||
if (msg_len <= HCRYPT_MSG_KM_OFS_SALT) {
|
||||
HCRYPT_LOG(LOG_WARNING, "KMmsg length too small (%zd)\n", msg_len);
|
||||
return(-1);
|
||||
}
|
||||
salt_len = hcryptMsg_KM_GetSaltLen(km_msg);
|
||||
sek_len = hcryptMsg_KM_GetSekLen(km_msg);
|
||||
|
||||
if ((salt_len > HAICRYPT_SALT_SZ)
|
||||
|| (sek_len > HAICRYPT_KEY_MAX_SZ)) {
|
||||
HCRYPT_LOG(LOG_WARNING, "%s", "KMmsg unsupported salt/key length\n");
|
||||
return(-1);
|
||||
}
|
||||
if ((16 != sek_len)
|
||||
&& (24 != sek_len)
|
||||
&& (32 != sek_len)) {
|
||||
HCRYPT_LOG(LOG_WARNING, "%s", "KMmsg unsupported key length\n");
|
||||
return(-1);
|
||||
}
|
||||
if (hcryptMsg_KM_HasBothSek(km_msg)) {
|
||||
sek_cnt = 2;
|
||||
} else {
|
||||
sek_cnt = 1;
|
||||
}
|
||||
if (msg_len != (HCRYPT_MSG_KM_OFS_SALT + salt_len + (sek_cnt * sek_len) + HAICRYPT_WRAPKEY_SIGN_SZ)) {
|
||||
HCRYPT_LOG(LOG_WARNING, "KMmsg length inconsistent (%zd,%zd,%zd)\n",
|
||||
salt_len, sek_len, msg_len);
|
||||
return(-1);
|
||||
}
|
||||
|
||||
/* Check options support */
|
||||
if ((HCRYPT_CIPHER_AES_CTR != km_msg[HCRYPT_MSG_KM_OFS_CIPHER])
|
||||
|| (HCRYPT_AUTH_NONE != km_msg[HCRYPT_MSG_KM_OFS_AUTH])) {
|
||||
HCRYPT_LOG(LOG_WARNING, "%s", "KMmsg unsupported option\n");
|
||||
return(-1);
|
||||
}
|
||||
|
||||
if (crypto->se != km_msg[HCRYPT_MSG_KM_OFS_SE]) {
|
||||
HCRYPT_LOG(LOG_WARNING, "%s", "KMmsg invalid SE\n");
|
||||
return(-1);
|
||||
}
|
||||
|
||||
/* Check KEKI here and pick right key */
|
||||
//>>todo
|
||||
/*
|
||||
* We support no key exchange,
|
||||
* KEK is preshared or derived from a passphrase
|
||||
*/
|
||||
}
|
||||
|
||||
/* Pick the context updated by this KMmsg */
|
||||
if (hcryptMsg_KM_HasBothSek(km_msg) && (NULL != crypto->ctx)) {
|
||||
ctx = crypto->ctx->alt; /* 2 SEK KM, start with inactive ctx */
|
||||
} else {
|
||||
ctx = &crypto->ctx_pair[hcryptMsg_KM_GetKeyIndex(km_msg)];
|
||||
}
|
||||
if (NULL == ctx) {
|
||||
HCRYPT_LOG(LOG_WARNING, "%s", "KMmsg invalid flags (no SEK)\n");
|
||||
return(-1);
|
||||
}
|
||||
|
||||
/* Check Salt and get if new */
|
||||
if ((salt_len != ctx->salt_len)
|
||||
|| (0 != memcmp(ctx->salt, &km_msg[HCRYPT_MSG_KM_OFS_SALT], salt_len))) {
|
||||
/* Salt changed (or 1st KMmsg received) */
|
||||
memcpy(ctx->salt, &km_msg[HCRYPT_MSG_KM_OFS_SALT], salt_len);
|
||||
ctx->salt_len = salt_len;
|
||||
do_pbkdf = 1; /* Impact on password derived kek */
|
||||
}
|
||||
|
||||
/* Check SEK length and get if new */
|
||||
if (sek_len != ctx->sek_len) {
|
||||
/* Key length changed or 1st KMmsg received */
|
||||
ctx->sek_len = sek_len;
|
||||
do_pbkdf = 1; /* Impact on password derived kek */
|
||||
}
|
||||
|
||||
/*
|
||||
* Regenerate KEK if it is password derived
|
||||
* and Salt or SEK length changed
|
||||
*/
|
||||
if (ctx->cfg.pwd_len && do_pbkdf) {
|
||||
if (hcryptCtx_GenSecret(crypto, ctx)) {
|
||||
return(-1);
|
||||
}
|
||||
ctx->status = HCRYPT_CTX_S_SARDY;
|
||||
kek_len = sek_len; /* KEK changed */
|
||||
}
|
||||
|
||||
/* Unwrap SEK(s) and set in context */
|
||||
if (0 > crypto->cryspr->km_unwrap(crypto->cryspr_cb, seks,
|
||||
&km_msg[HCRYPT_MSG_KM_OFS_SALT + salt_len],
|
||||
(sek_cnt * sek_len) + HAICRYPT_WRAPKEY_SIGN_SZ)) {
|
||||
HCRYPT_LOG(LOG_WARNING, "%s", "unwrap key failed\n");
|
||||
return(-2); //Report unmatched shared secret
|
||||
}
|
||||
/*
|
||||
* First SEK in KMmsg is eSEK if both SEK present
|
||||
*/
|
||||
hcryptCtx_Rx_Rekey(crypto, ctx,
|
||||
((2 == sek_cnt) && (ctx->flags & HCRYPT_MSG_F_oSEK)) ? &seks[sek_len] : &seks[0],
|
||||
sek_len);
|
||||
|
||||
/*
|
||||
* Refresh KMmsg cache to detect Keying Material changes
|
||||
*/
|
||||
ctx->KMmsg_len = msg_len;
|
||||
memcpy(ctx->KMmsg_cache, km_msg, msg_len);
|
||||
|
||||
/* update other (alternate) context if both SEK provided */
|
||||
if (2 == sek_cnt) {
|
||||
hcrypt_Ctx *alt = ctx->alt;
|
||||
|
||||
memcpy(alt->salt, &km_msg[HCRYPT_MSG_KM_OFS_SALT], salt_len);
|
||||
alt->salt_len = salt_len;
|
||||
|
||||
if (kek_len) { /* New or changed KEK */
|
||||
// memcpy(&alt->aes_kek, &ctx->aes_kek, sizeof(alt->aes_kek));
|
||||
alt->status = HCRYPT_CTX_S_SARDY;
|
||||
}
|
||||
|
||||
hcryptCtx_Rx_Rekey(crypto, alt,
|
||||
((2 == sek_cnt) && (alt->flags & HCRYPT_MSG_F_oSEK)) ? &seks[sek_len] : &seks[0],
|
||||
sek_len);
|
||||
|
||||
alt->KMmsg_len = msg_len;
|
||||
memcpy(alt->KMmsg_cache, km_msg, msg_len);
|
||||
}
|
||||
return(0);
|
||||
}
|
420
trunk/3rdparty/srt-1-fit/haicrypt/hcrypt_ctx_tx.c
vendored
Normal file
420
trunk/3rdparty/srt-1-fit/haicrypt/hcrypt_ctx_tx.c
vendored
Normal file
|
@ -0,0 +1,420 @@
|
|||
/*
|
||||
* SRT - Secure, Reliable, Transport
|
||||
* Copyright (c) 2018 Haivision Systems Inc.
|
||||
*
|
||||
* 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/.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
written by
|
||||
Haivision Systems Inc.
|
||||
|
||||
2011-06-23 (jdube)
|
||||
HaiCrypt initial implementation.
|
||||
2014-03-11 (jdube)
|
||||
Adaptation for SRT.
|
||||
*****************************************************************************/
|
||||
|
||||
#include <string.h> /* memcpy */
|
||||
#ifdef _WIN32
|
||||
#include <winsock2.h>
|
||||
#include <ws2tcpip.h>
|
||||
#include <win/wintime.h>
|
||||
#else
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
#include "hcrypt.h"
|
||||
|
||||
int hcryptCtx_Tx_Init(hcrypt_Session *crypto, hcrypt_Ctx *ctx, const HaiCrypt_Cfg *cfg)
|
||||
{
|
||||
ctx->cfg.key_len = cfg->key_len;
|
||||
|
||||
ctx->mode = HCRYPT_CTX_MODE_AESCTR;
|
||||
ctx->status = HCRYPT_CTX_S_INIT;
|
||||
|
||||
ctx->msg_info = crypto->msg_info;
|
||||
|
||||
if (hcryptCtx_SetSecret(crypto, ctx, &cfg->secret)) {
|
||||
return(-1);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
int hcryptCtx_Tx_Rekey(hcrypt_Session *crypto, hcrypt_Ctx *ctx)
|
||||
{
|
||||
int iret;
|
||||
|
||||
ASSERT(HCRYPT_CTX_S_SARDY <= ctx->status);
|
||||
|
||||
/* Generate Salt */
|
||||
ctx->salt_len = HAICRYPT_SALT_SZ;
|
||||
if (0 > (iret = crypto->cryspr->prng(ctx->salt, ctx->salt_len))) {
|
||||
HCRYPT_LOG(LOG_ERR, "PRNG(salt[%zd]) failed\n", ctx->salt_len);
|
||||
return(iret);
|
||||
}
|
||||
|
||||
/* Generate SEK */
|
||||
ctx->sek_len = ctx->cfg.key_len;
|
||||
if (0 > (iret = crypto->cryspr->prng(ctx->sek, ctx->sek_len))) {
|
||||
HCRYPT_LOG(LOG_ERR, "PRNG(sek[%zd] failed\n", ctx->sek_len);
|
||||
return(iret);
|
||||
}
|
||||
|
||||
/* Set SEK in cryspr */
|
||||
if (crypto->cryspr->ms_setkey(crypto->cryspr_cb, ctx, ctx->sek, ctx->sek_len)) {
|
||||
HCRYPT_LOG(LOG_ERR, "cryspr setkey(sek[%zd]) failed\n", ctx->sek_len);
|
||||
return(-1);
|
||||
}
|
||||
|
||||
HCRYPT_LOG(LOG_NOTICE, "rekeyed crypto context[%d]\n", (ctx->flags & HCRYPT_CTX_F_xSEK)/2);
|
||||
HCRYPT_PRINTKEY(ctx->sek, ctx->sek_len, "sek");
|
||||
|
||||
/* Regenerate KEK if Password-based (uses newly generated salt and sek_len) */
|
||||
if ((0 < ctx->cfg.pwd_len)
|
||||
&& (0 > (iret = hcryptCtx_GenSecret(crypto, ctx)))) {
|
||||
return(iret);
|
||||
}
|
||||
|
||||
/* Assemble the new Keying Material message */
|
||||
if (0 != (iret = hcryptCtx_Tx_AsmKM(crypto, ctx, NULL))) {
|
||||
return(iret);
|
||||
}
|
||||
if ((HCRYPT_CTX_S_KEYED <= ctx->alt->status)
|
||||
&& hcryptMsg_KM_HasBothSek(ctx->alt->KMmsg_cache)) {
|
||||
/*
|
||||
* previous context KM announced in alternate (odd/even) KM,
|
||||
* reassemble it without our KM
|
||||
*/
|
||||
hcryptCtx_Tx_AsmKM(crypto, ctx->alt, NULL);
|
||||
}
|
||||
|
||||
/* Initialize the Media Stream message prefix cache */
|
||||
ctx->msg_info->resetCache(ctx->MSpfx_cache, HCRYPT_MSG_PT_MS, ctx->flags & HCRYPT_CTX_F_xSEK);
|
||||
ctx->pkt_cnt = 1;
|
||||
|
||||
ctx->status = HCRYPT_CTX_S_KEYED;
|
||||
return(0);
|
||||
}
|
||||
|
||||
int hcryptCtx_Tx_CloneKey(hcrypt_Session *crypto, hcrypt_Ctx *ctx, const hcrypt_Session* cryptoSrc)
|
||||
{
|
||||
int iret;
|
||||
|
||||
ASSERT(HCRYPT_CTX_S_SARDY <= ctx->status);
|
||||
|
||||
const hcrypt_Ctx* ctxSrc = cryptoSrc->ctx;
|
||||
if (!ctxSrc)
|
||||
{
|
||||
/* Probbly the context is not yet completely initialized, so
|
||||
* use blindly the first context from the pair
|
||||
*/
|
||||
ctxSrc = &cryptoSrc->ctx_pair[0];
|
||||
}
|
||||
|
||||
/* Copy SALT (instead of generating) */
|
||||
ctx->salt_len = ctxSrc->salt_len;
|
||||
memcpy(ctx->salt, ctxSrc->salt, ctx->salt_len);
|
||||
|
||||
/* Copy SEK */
|
||||
ctx->sek_len = ctxSrc->sek_len;
|
||||
memcpy(ctx->sek, ctxSrc->sek, ctx->sek_len);
|
||||
|
||||
/* Set SEK in cryspr */
|
||||
if (crypto->cryspr->ms_setkey(crypto->cryspr_cb, ctx, ctx->sek, ctx->sek_len)) {
|
||||
HCRYPT_LOG(LOG_ERR, "cryspr setkey(sek[%zd]) failed\n", ctx->sek_len);
|
||||
return(-1);
|
||||
}
|
||||
|
||||
HCRYPT_LOG(LOG_NOTICE, "clone-keyed crypto context[%d]\n", (ctx->flags & HCRYPT_CTX_F_xSEK)/2);
|
||||
HCRYPT_PRINTKEY(ctx->sek, ctx->sek_len, "sek");
|
||||
|
||||
/* Regenerate KEK if Password-based (uses newly generated salt and sek_len) */
|
||||
/* (note for CloneKey imp: it's expected that the same passphrase-salt pair
|
||||
shall generate the same KEK. GenSecret also prints the KEK */
|
||||
if ((0 < ctx->cfg.pwd_len)
|
||||
&& (0 > (iret = hcryptCtx_GenSecret(crypto, ctx)))) {
|
||||
return(iret);
|
||||
}
|
||||
|
||||
/* Assemble the new Keying Material message */
|
||||
if (0 != (iret = hcryptCtx_Tx_AsmKM(crypto, ctx, NULL))) {
|
||||
return(iret);
|
||||
}
|
||||
if ((HCRYPT_CTX_S_KEYED <= ctx->alt->status)
|
||||
&& hcryptMsg_KM_HasBothSek(ctx->alt->KMmsg_cache)) {
|
||||
/*
|
||||
* previous context KM announced in alternate (odd/even) KM,
|
||||
* reassemble it without our KM
|
||||
*/
|
||||
hcryptCtx_Tx_AsmKM(crypto, ctx->alt, NULL);
|
||||
}
|
||||
|
||||
/* Initialize the Media Stream message prefix cache */
|
||||
ctx->msg_info->resetCache(ctx->MSpfx_cache, HCRYPT_MSG_PT_MS, ctx->flags & HCRYPT_CTX_F_xSEK);
|
||||
ctx->pkt_cnt = 1;
|
||||
|
||||
ctx->status = HCRYPT_CTX_S_KEYED;
|
||||
return(0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Refresh the alternate context from the current.
|
||||
* Regenerates the SEK but keep the salt, doing so also
|
||||
* preserve the KEK generated from secret password and salt.
|
||||
*/
|
||||
|
||||
int hcryptCtx_Tx_Refresh(hcrypt_Session *crypto)
|
||||
{
|
||||
hcrypt_Ctx *ctx = crypto->ctx;
|
||||
hcrypt_Ctx *new_ctx;
|
||||
int iret;
|
||||
|
||||
ASSERT(NULL != ctx);
|
||||
ASSERT(HCRYPT_CTX_S_ACTIVE == ctx->status);
|
||||
|
||||
/* Pick the alternative (inactive) context */
|
||||
new_ctx = ctx->alt;
|
||||
|
||||
ASSERT(HCRYPT_CTX_S_SARDY <= new_ctx->status);
|
||||
|
||||
/* Keep same KEK, configuration, and salt */
|
||||
// memcpy(&new_ctx->aes_kek, &ctx->aes_kek, sizeof(new_ctx->aes_kek));
|
||||
memcpy(&new_ctx->cfg, &ctx->cfg, sizeof(new_ctx->cfg));
|
||||
|
||||
new_ctx->salt_len = ctx->salt_len;
|
||||
memcpy(new_ctx->salt, ctx->salt, HAICRYPT_SALT_SZ);
|
||||
|
||||
/* Generate new SEK */
|
||||
new_ctx->sek_len = new_ctx->cfg.key_len;
|
||||
|
||||
HCRYPT_LOG(LOG_DEBUG, "refresh/generate SEK. salt_len=%d sek_len=%d\n", (int)new_ctx->salt_len, (int)new_ctx->sek_len);
|
||||
|
||||
if (0 > crypto->cryspr->prng(new_ctx->sek, new_ctx->sek_len)) {
|
||||
HCRYPT_LOG(LOG_ERR, "PRNG(sek[%zd] failed\n", new_ctx->sek_len);
|
||||
return(-1);
|
||||
}
|
||||
/* Cryspr's dependent key */
|
||||
if (crypto->cryspr->ms_setkey(crypto->cryspr_cb, new_ctx, new_ctx->sek, new_ctx->sek_len)) {
|
||||
HCRYPT_LOG(LOG_ERR, "refresh cryspr setkey(sek[%d]) failed\n", new_ctx->sek_len);
|
||||
return(-1);
|
||||
}
|
||||
|
||||
HCRYPT_PRINTKEY(new_ctx->sek, new_ctx->sek_len, "sek");
|
||||
|
||||
/* Assemble the new KMmsg with new and current SEK */
|
||||
if (0 != (iret = hcryptCtx_Tx_AsmKM(crypto, new_ctx, ctx->sek))) {
|
||||
return(iret);
|
||||
}
|
||||
|
||||
/* Initialize the message prefix cache */
|
||||
new_ctx->msg_info->resetCache(new_ctx->MSpfx_cache, HCRYPT_MSG_PT_MS, new_ctx->flags & HCRYPT_MSG_F_xSEK);
|
||||
new_ctx->pkt_cnt = 0;
|
||||
|
||||
new_ctx->status = HCRYPT_CTX_S_KEYED;
|
||||
return(0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Prepare context switch
|
||||
* both odd & even keys announced
|
||||
*/
|
||||
int hcryptCtx_Tx_PreSwitch(hcrypt_Session *crypto)
|
||||
{
|
||||
hcrypt_Ctx *ctx = crypto->ctx;
|
||||
|
||||
ASSERT(NULL != ctx);
|
||||
ASSERT(HCRYPT_CTX_S_ACTIVE == ctx->status);
|
||||
ASSERT(HCRYPT_CTX_S_KEYED == ctx->alt->status);
|
||||
|
||||
ctx->alt->flags |= HCRYPT_CTX_F_ANNOUNCE;
|
||||
ctx->alt->flags |= HCRYPT_CTX_F_TTSEND; //Send now
|
||||
|
||||
/* Stop announcing current context if next one contains its key */
|
||||
if (hcryptMsg_KM_HasBothSek(ctx->alt->KMmsg_cache)) {
|
||||
ctx->flags &= ~HCRYPT_CTX_F_ANNOUNCE;
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
int hcryptCtx_Tx_Switch(hcrypt_Session *crypto)
|
||||
{
|
||||
hcrypt_Ctx *ctx = crypto->ctx;
|
||||
|
||||
ASSERT(HCRYPT_CTX_S_KEYED <= ctx->alt->status);
|
||||
|
||||
ctx->status = HCRYPT_CTX_S_DEPRECATED;
|
||||
ctx->alt->status = HCRYPT_CTX_S_ACTIVE;
|
||||
|
||||
ctx->alt->flags |= HCRYPT_CTX_F_ANNOUNCE; // Already cleared if new KM has both SEK
|
||||
crypto->ctx = ctx->alt;
|
||||
return(0);
|
||||
}
|
||||
|
||||
int hcryptCtx_Tx_PostSwitch(hcrypt_Session *crypto)
|
||||
{
|
||||
hcrypt_Ctx *ctx = crypto->ctx;
|
||||
hcrypt_Ctx *old_ctx = ctx->alt;
|
||||
|
||||
/* Stop announcing old context (if announced) */
|
||||
old_ctx->flags &= ~HCRYPT_CTX_F_ANNOUNCE;
|
||||
old_ctx->status = HCRYPT_CTX_S_SARDY;
|
||||
|
||||
/* If current context KM announce both, reassemble it */
|
||||
if (hcryptMsg_KM_HasBothSek(ctx->KMmsg_cache)) {
|
||||
hcryptCtx_Tx_AsmKM(crypto, ctx, NULL);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
/* Assemble Keying Material message */
|
||||
int hcryptCtx_Tx_AsmKM(hcrypt_Session *crypto, hcrypt_Ctx *ctx, unsigned char *alt_sek)
|
||||
{
|
||||
unsigned char *km_msg;
|
||||
size_t msg_len;
|
||||
int sek_cnt = (NULL == alt_sek ? 1 : 2);
|
||||
unsigned char sek_buf[HAICRYPT_KEY_MAX_SZ * 2];
|
||||
unsigned char *seks;
|
||||
|
||||
if (NULL == ctx) {
|
||||
HCRYPT_LOG(LOG_ERR, "%s", "crypto context undefined\n");
|
||||
return(-1);
|
||||
}
|
||||
|
||||
msg_len = HCRYPT_MSG_KM_OFS_SALT
|
||||
+ ctx->salt_len
|
||||
+ (ctx->sek_len * sek_cnt)
|
||||
+ HAICRYPT_WRAPKEY_SIGN_SZ;
|
||||
|
||||
km_msg = &ctx->KMmsg_cache[0];
|
||||
ctx->KMmsg_len = 0;
|
||||
|
||||
memset(km_msg, 0, msg_len);
|
||||
ctx->msg_info->resetCache(km_msg, HCRYPT_MSG_PT_KM,
|
||||
2 == sek_cnt ? HCRYPT_MSG_F_xSEK : (ctx->flags & HCRYPT_MSG_F_xSEK));
|
||||
|
||||
/* crypto->KMmsg_cache[4..7]: KEKI=0 */
|
||||
km_msg[HCRYPT_MSG_KM_OFS_CIPHER] = HCRYPT_CIPHER_AES_CTR;
|
||||
km_msg[HCRYPT_MSG_KM_OFS_AUTH] = HCRYPT_AUTH_NONE;
|
||||
km_msg[HCRYPT_MSG_KM_OFS_SE] = crypto->se;
|
||||
hcryptMsg_KM_SetSaltLen(km_msg, ctx->salt_len);
|
||||
hcryptMsg_KM_SetSekLen(km_msg, ctx->sek_len);
|
||||
|
||||
memcpy(&km_msg[HCRYPT_MSG_KM_OFS_SALT], ctx->salt, ctx->salt_len);
|
||||
|
||||
if (2 == sek_cnt) {
|
||||
/* Even SEK first in dual SEK KMmsg */
|
||||
if (HCRYPT_MSG_F_eSEK & ctx->flags) {
|
||||
memcpy(&sek_buf[0], ctx->sek, ctx->sek_len);
|
||||
memcpy(&sek_buf[ctx->sek_len], alt_sek, ctx->sek_len);
|
||||
} else {
|
||||
memcpy(&sek_buf[0], alt_sek, ctx->sek_len);
|
||||
memcpy(&sek_buf[ctx->sek_len], ctx->sek, ctx->sek_len);
|
||||
}
|
||||
seks = sek_buf;
|
||||
} else {
|
||||
seks = ctx->sek;
|
||||
}
|
||||
if (0 > crypto->cryspr->km_wrap(crypto->cryspr_cb,
|
||||
&km_msg[HCRYPT_MSG_KM_OFS_SALT + ctx->salt_len],
|
||||
seks, sek_cnt * ctx->sek_len)) {
|
||||
|
||||
HCRYPT_LOG(LOG_ERR, "%s", "wrap key failed\n");
|
||||
return(-1);
|
||||
}
|
||||
ctx->KMmsg_len = msg_len;
|
||||
return(0);
|
||||
}
|
||||
|
||||
int hcryptCtx_Tx_ManageKM(hcrypt_Session *crypto)
|
||||
{
|
||||
hcrypt_Ctx *ctx = crypto->ctx;
|
||||
|
||||
ASSERT(NULL != ctx);
|
||||
|
||||
HCRYPT_LOG(LOG_DEBUG, "KM[%d] KEY STATUS: pkt_cnt=%u against ref.rate=%u and pre.announce=%u\n",
|
||||
(ctx->alt->flags & HCRYPT_CTX_F_xSEK)/2,
|
||||
ctx->pkt_cnt, crypto->km.refresh_rate, crypto->km.pre_announce);
|
||||
|
||||
if ((ctx->pkt_cnt > crypto->km.refresh_rate)
|
||||
|| (ctx->pkt_cnt == 0)) { //rolled over
|
||||
/*
|
||||
* End of crypto period for current SEK,
|
||||
* switch to other (even/odd) SEK
|
||||
*/
|
||||
HCRYPT_LOG(LOG_INFO, "KM[%d] Activated\n",
|
||||
(ctx->alt->flags & HCRYPT_CTX_F_xSEK)/2);
|
||||
|
||||
hcryptCtx_Tx_Switch(crypto);
|
||||
|
||||
} else
|
||||
if ((ctx->pkt_cnt > (crypto->km.refresh_rate - crypto->km.pre_announce))
|
||||
&& !(ctx->alt->flags & HCRYPT_CTX_F_ANNOUNCE)) {
|
||||
/*
|
||||
* End of crypto period approach for this SEK,
|
||||
* prepare next SEK for announcement
|
||||
*/
|
||||
hcryptCtx_Tx_Refresh(crypto);
|
||||
|
||||
HCRYPT_LOG(LOG_INFO, "KM[%d] Pre-announced\n",
|
||||
(ctx->alt->flags & HCRYPT_CTX_F_xSEK)/2);
|
||||
|
||||
hcryptCtx_Tx_PreSwitch(crypto);
|
||||
|
||||
} else
|
||||
if ((ctx->alt->status == HCRYPT_CTX_S_DEPRECATED)
|
||||
&& (ctx->pkt_cnt > crypto->km.pre_announce)) {
|
||||
/*
|
||||
* Deprecated SEK is no longer needed (for late packets),
|
||||
* decommission it
|
||||
*/
|
||||
HCRYPT_LOG(LOG_INFO, "KM[%d] Deprecated\n",
|
||||
(ctx->alt->flags & HCRYPT_CTX_F_xSEK)/2);
|
||||
|
||||
hcryptCtx_Tx_PostSwitch(crypto);
|
||||
}
|
||||
|
||||
/* Check if it is time to send Keying Material */
|
||||
if (timerisset(&crypto->km.tx_period)) { /* tx_period=0.0 -> out-of-stream Keying Material distribution */
|
||||
struct timeval now, nxt_tx;
|
||||
|
||||
gettimeofday(&now, NULL);
|
||||
timeradd(&crypto->km.tx_last, &crypto->km.tx_period, &nxt_tx);
|
||||
if (timercmp(&now, &nxt_tx, >)) {
|
||||
if (crypto->ctx_pair[0].flags & HCRYPT_CTX_F_ANNOUNCE) crypto->ctx_pair[0].flags |= HCRYPT_CTX_F_TTSEND;
|
||||
if (crypto->ctx_pair[1].flags & HCRYPT_CTX_F_ANNOUNCE) crypto->ctx_pair[1].flags |= HCRYPT_CTX_F_TTSEND;
|
||||
}
|
||||
}
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
int hcryptCtx_Tx_InjectKM(hcrypt_Session *crypto,
|
||||
void *out_p[], size_t out_len_p[], int maxout ATR_UNUSED)
|
||||
{
|
||||
int i, nbout = 0;
|
||||
|
||||
ASSERT(maxout >= 2);
|
||||
for (i=0; i<2; i++) {
|
||||
if (crypto->ctx_pair[i].flags & HCRYPT_CTX_F_TTSEND) { /* Time To Send */
|
||||
HCRYPT_LOG(LOG_DEBUG, "Send KMmsg[%d] len=%zd\n", i,
|
||||
crypto->ctx_pair[i].KMmsg_len);
|
||||
/* Send Keying Material */
|
||||
out_p[nbout] = crypto->ctx_pair[i].KMmsg_cache;
|
||||
out_len_p[nbout] = crypto->ctx_pair[i].KMmsg_len;
|
||||
nbout++;
|
||||
crypto->ctx_pair[i].flags &= ~HCRYPT_CTX_F_TTSEND;
|
||||
}
|
||||
}
|
||||
if (nbout) {
|
||||
struct timeval now;
|
||||
gettimeofday(&now, NULL);
|
||||
crypto->km.tx_last = now;
|
||||
}
|
||||
return(nbout);
|
||||
}
|
||||
|
||||
|
155
trunk/3rdparty/srt-1-fit/haicrypt/hcrypt_msg.h
vendored
Normal file
155
trunk/3rdparty/srt-1-fit/haicrypt/hcrypt_msg.h
vendored
Normal file
|
@ -0,0 +1,155 @@
|
|||
/*
|
||||
* SRT - Secure, Reliable, Transport
|
||||
* Copyright (c) 2018 Haivision Systems Inc.
|
||||
*
|
||||
* 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/.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
written by
|
||||
Haivision Systems Inc.
|
||||
|
||||
2011-06-23 (jdube)
|
||||
HaiCrypt initial implementation.
|
||||
2014-03-11 (jdube)
|
||||
Adaptation for SRT.
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef HCRYPT_MSG_H
|
||||
#define HCRYPT_MSG_H
|
||||
|
||||
/*
|
||||
* HaiCrypt Transport Message Header info
|
||||
*/
|
||||
|
||||
|
||||
#ifndef HCRYPT_DSP
|
||||
#include <sys/types.h>
|
||||
|
||||
typedef uint32_t hcrypt_Pki;
|
||||
#endif /* HCRYPT_DSP */
|
||||
|
||||
|
||||
#define HCRYPT_MSG_VERSION 1 /* Current HaiCrypt version */
|
||||
|
||||
#define HCRYPT_MSG_SIGN (('H'-'@')<<10 | ('A'-'@')<<5 | ('I'-'@')) /* Haivision PnP Mfr ID 'HAI' */
|
||||
|
||||
#define HCRYPT_PKI_SZ 4 /* Packet Index size (CTR mode cipher) */
|
||||
|
||||
#define HCRYPT_MSG_PT_MS 1 /* Media stream */
|
||||
#define HCRYPT_MSG_PT_KM 2 /* Keying Material */
|
||||
#define HCRYPT_MSG_PT_RESV7 7 /* Reserved to dicriminate MPEG-TS packet (SyncByte=0x47) */
|
||||
|
||||
|
||||
#define HCRYPT_MSG_F_eSEK 0x01 /* Even Stream Encrypting Key */
|
||||
#define HCRYPT_MSG_F_oSEK 0x02 /* Odd Stream Encrypting Key */
|
||||
#define HCRYPT_MSG_F_xSEK 0x03 /* Both Stream Encrypting Keys */
|
||||
|
||||
typedef struct {
|
||||
int hdr_len; // data and control common prefix portion
|
||||
int pfx_len; // Message Prefix len. Also payload offset
|
||||
unsigned (*getKeyFlags)(unsigned char *msg);
|
||||
hcrypt_Pki (*getPki)(unsigned char *msg, int nwko);
|
||||
void (*setPki)(unsigned char *msg, hcrypt_Pki);
|
||||
void (*resetCache)(unsigned char *pfx_cache, unsigned pkt_type, unsigned flags);
|
||||
void (*indexMsg)(unsigned char *msg, unsigned char *pfx_cache);
|
||||
int (*parseMsg)(unsigned char *msg);
|
||||
}hcrypt_MsgInfo;
|
||||
|
||||
|
||||
#define hcryptMsg_GetKeyIndex(mi,msg) ((mi)->getKeyFlags(msg)>>1)
|
||||
#define hcryptMsg_GetPki(mi,msg,nwko) ((mi)->getPki(msg,nwko))
|
||||
#define hcryptMsg_SetPki(mi,msg,pki) (mi)->setPki(msg, pki)
|
||||
|
||||
#define hcryptMsg_HasEvenSek(mi,msg) ((mi)->getKeyFlags(msg) & HCRYPT_MSG_F_eSEK)
|
||||
#define hcryptMsg_HasOddSek(mi,msg) ((mi)->getKeyFlags(msg) & HCRYPT_MSG_F_oSEK)
|
||||
#define hcryptMsg_HasBothSek(mi,msg) (HCRYPT_MSG_F_xSEK == ((mi)->getKeyFlags(msg) & HCRYPT_MSG_F_xSEK))
|
||||
#define hcryptMsg_HasNoSek(mi,msg) (0 == ((mi)->getKeyFlags(msg) & HCRYPT_MSG_F_xSEK))
|
||||
|
||||
#define hcryptMsg_PaddedLen(len, fact) ((((len)+(fact)-1)/(fact))*(fact))
|
||||
|
||||
|
||||
/*
|
||||
* HaiCrypt KMmsg (Keying Material):
|
||||
*
|
||||
* 0 1 2 3
|
||||
* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||
* +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+
|
||||
*+0x00 |0|Vers | PT | Sign | resv |KF |
|
||||
* +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+
|
||||
*+0x04 | KEKI |
|
||||
* +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+
|
||||
*+0x08 | Cipher | Auth | SE | Resv1 |
|
||||
* +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+
|
||||
*+0x0C | Resv2 | Slen/4 | Klen/4 |
|
||||
* +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+
|
||||
*+0x10 | Salt |
|
||||
* | ... |
|
||||
* +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+
|
||||
* | Wrap |
|
||||
* | ... |
|
||||
* +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#define HCRYPT_MSG_KM_OFS_VERSION 0
|
||||
#define HCRYPT_MSG_KM_OFS_PT 0
|
||||
#define HCRYPT_MSG_KM_OFS_SIGN 1
|
||||
#define HCRYPT_MSG_KM_OFS_KFLGS 3
|
||||
#define HCRYPT_MSG_KM_RSH_KFLGS 0 /* Right shift (in byte) */
|
||||
|
||||
#define HCRYPT_MSG_KM_OFS_KEKI 4
|
||||
#define HCRYPT_MSG_KM_OFS_CIPHER 8
|
||||
#define HCRYPT_MSG_KM_OFS_AUTH 9
|
||||
#define HCRYPT_MSG_KM_OFS_SE 10
|
||||
#define HCRYPT_MSG_KM_OFS_RESV2 12
|
||||
#define HCRYPT_MSG_KM_OFS_SLEN 14
|
||||
#define HCRYPT_MSG_KM_OFS_KLEN 15
|
||||
#define HCRYPT_MSG_KM_OFS_SALT 16
|
||||
|
||||
#define HCRYPT_MSG_KM_MAX_SZ (0 \
|
||||
+ HCRYPT_MSG_KM_OFS_SALT \
|
||||
+ HAICRYPT_SALT_SZ \
|
||||
+ (HAICRYPT_KEY_MAX_SZ * 2) \
|
||||
+ HAICRYPT_WRAPKEY_SIGN_SZ)
|
||||
|
||||
#define HCRYPT_CIPHER_NONE 0
|
||||
#define HCRYPT_CIPHER_AES_ECB 1
|
||||
#define HCRYPT_CIPHER_AES_CTR 2
|
||||
#define HCRYPT_CIPHER_AES_CBC 3
|
||||
|
||||
#define HCRYPT_AUTH_NONE 0
|
||||
|
||||
#define HCRYPT_SE_TSUDP 1
|
||||
hcrypt_MsgInfo * hcryptMsg_STA_MsgInfo(void);
|
||||
#define HCRYPT_SE_TSSRT 2
|
||||
hcrypt_MsgInfo * hcryptMsg_SRT_MsgInfo(void);
|
||||
|
||||
#define hcryptMsg_KM_GetVersion(msg) (((msg)[HCRYPT_MSG_KM_OFS_VERSION]>>4)& 0xF)
|
||||
#define hcryptMsg_KM_GetPktType(msg) (((msg)[HCRYPT_MSG_KM_OFS_PT]) & 0xF)
|
||||
#define hcryptMsg_KM_GetSign(msg) (((msg)[HCRYPT_MSG_KM_OFS_SIGN]<<8) | (msg)[HCRYPT_MSG_KM_OFS_SIGN+1])
|
||||
|
||||
#define hcryptMsg_KM_GetKeyIndex(msg) (((msg)[HCRYPT_MSG_KM_OFS_KFLGS] & HCRYPT_MSG_F_xSEK)>>1)
|
||||
|
||||
#define hcryptMsg_KM_HasEvenSek(msg) ((msg)[HCRYPT_MSG_KM_OFS_KFLGS] & HCRYPT_MSG_F_eSEK)
|
||||
#define hcryptMsg_KM_HasOddSek(msg) ((msg)[HCRYPT_MSG_KM_OFS_KFLGS] & HCRYPT_MSG_F_oSEK)
|
||||
#define hcryptMsg_KM_HasBothSek(msg) (HCRYPT_MSG_F_xSEK == ((msg)[HCRYPT_MSG_KM_OFS_KFLGS] & HCRYPT_MSG_F_xSEK))
|
||||
#define hcryptMsg_KM_HasNoSek(msg) (0 == ((msg)[HCRYPT_MSG_KM_OFS_KFLGS] & HCRYPT_MSG_F_xSEK))
|
||||
|
||||
#define hcryptMsg_KM_GetCipher(msg) ((msg)[HCRYPT_MSG_KM_OFS_CIPHER])
|
||||
#define hcryptMsg_KM_GetAuth(msg) ((msg)[HCRYPT_MSG_KM_OFS_AUTH])
|
||||
#define hcryptMsg_KM_GetSE(msg) ((msg)[HCRYPT_MSG_KM_OFS_SE])
|
||||
|
||||
#define hcryptMsg_KM_GetSaltLen(msg) (size_t)((msg)[HCRYPT_MSG_KM_OFS_SLEN] * 4)
|
||||
#define hcryptMsg_KM_GetSekLen(msg) (size_t)((msg)[HCRYPT_MSG_KM_OFS_KLEN] * 4)
|
||||
|
||||
#define hcryptMsg_KM_SetSaltLen(msg,len)do {(msg)[HCRYPT_MSG_KM_OFS_SLEN] = (len)/4;} while(0)
|
||||
#define hcryptMsg_KM_SetSekLen(msg,len) do {(msg)[HCRYPT_MSG_KM_OFS_KLEN] = (len)/4;} while(0)
|
||||
|
||||
|
||||
#endif /* HCRYPT_MSG_H */
|
146
trunk/3rdparty/srt-1-fit/haicrypt/hcrypt_rx.c
vendored
Normal file
146
trunk/3rdparty/srt-1-fit/haicrypt/hcrypt_rx.c
vendored
Normal file
|
@ -0,0 +1,146 @@
|
|||
/*
|
||||
* SRT - Secure, Reliable, Transport
|
||||
* Copyright (c) 2018 Haivision Systems Inc.
|
||||
*
|
||||
* 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/.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
written by
|
||||
Haivision Systems Inc.
|
||||
|
||||
2011-06-23 (jdube)
|
||||
HaiCrypt initial implementation.
|
||||
2014-03-11 (jdube)
|
||||
Adaptation for SRT.
|
||||
*****************************************************************************/
|
||||
|
||||
#include <stdlib.h> /* NULL */
|
||||
#include <string.h> /* memcmp */
|
||||
#include "hcrypt.h"
|
||||
|
||||
int HaiCrypt_Rx_Data(HaiCrypt_Handle hhc,
|
||||
unsigned char *in_pfx, unsigned char *data, size_t data_len)
|
||||
{
|
||||
hcrypt_Session *crypto = (hcrypt_Session *)hhc;
|
||||
hcrypt_Ctx *ctx;
|
||||
int nb = -1;
|
||||
|
||||
if ((NULL == crypto)
|
||||
|| (NULL == data)) {
|
||||
HCRYPT_LOG(LOG_ERR, "%s", "invalid parameters\n");
|
||||
return(nb);
|
||||
}
|
||||
|
||||
ctx = &crypto->ctx_pair[hcryptMsg_GetKeyIndex(crypto->msg_info, in_pfx)];
|
||||
|
||||
ASSERT(NULL != ctx); /* Header check should prevent this error */
|
||||
ASSERT(NULL != crypto->cryspr); /* Header check should prevent this error */
|
||||
|
||||
crypto->ctx = ctx; /* Context of last received msg */
|
||||
if (NULL == crypto->cryspr->ms_decrypt) {
|
||||
HCRYPT_LOG(LOG_ERR, "%s", "cryspr had no decryptor\n");
|
||||
} else if (ctx->status >= HCRYPT_CTX_S_KEYED) {
|
||||
hcrypt_DataDesc indata;
|
||||
indata.pfx = in_pfx;
|
||||
indata.payload = data;
|
||||
indata.len = data_len;
|
||||
|
||||
if (0 > (nb = crypto->cryspr->ms_decrypt(crypto->cryspr_cb, ctx, &indata, 1, NULL, NULL, NULL))) {
|
||||
HCRYPT_LOG(LOG_ERR, "%s", "ms_decrypt failed\n");
|
||||
} else {
|
||||
nb = indata.len;
|
||||
}
|
||||
} else { /* No key received yet */
|
||||
nb = 0;
|
||||
}
|
||||
return(nb);
|
||||
}
|
||||
|
||||
int HaiCrypt_Rx_Process(HaiCrypt_Handle hhc,
|
||||
unsigned char *in_msg, size_t in_len,
|
||||
void *out_p[], size_t out_len_p[], int maxout)
|
||||
{
|
||||
hcrypt_Session *crypto = (hcrypt_Session *)hhc;
|
||||
hcrypt_Ctx *ctx;
|
||||
int nbout = maxout;
|
||||
int msg_type;
|
||||
|
||||
if ((NULL == crypto)
|
||||
|| (NULL == in_msg)) {
|
||||
|
||||
HCRYPT_LOG(LOG_ERR, "%s", "invalid parameters\n");
|
||||
return(-1);
|
||||
}
|
||||
|
||||
/* Validate HaiCrypt message */
|
||||
if (0 > (msg_type = crypto->msg_info->parseMsg(in_msg))) {
|
||||
return(-1);
|
||||
}
|
||||
|
||||
switch(msg_type) {
|
||||
case HCRYPT_MSG_PT_MS: /* MSmsg */
|
||||
ctx = &crypto->ctx_pair[hcryptMsg_GetKeyIndex(crypto->msg_info, in_msg)];
|
||||
|
||||
if ((NULL == out_p)
|
||||
|| (NULL == out_len_p)) {
|
||||
HCRYPT_LOG(LOG_ERR, "%s", "invalid parameters\n");
|
||||
return(-1);
|
||||
}
|
||||
ASSERT(NULL != ctx); /* Header check should prevent this error */
|
||||
ASSERT(NULL != crypto->cryspr); /* Header check should prevent this error */
|
||||
|
||||
crypto->ctx = ctx; /* Context of last received msg */
|
||||
if (NULL == crypto->cryspr->ms_decrypt) {
|
||||
HCRYPT_LOG(LOG_ERR, "%s", "cryspr had no decryptor\n");
|
||||
nbout = -1;
|
||||
} else if (ctx->status >= HCRYPT_CTX_S_KEYED) {
|
||||
hcrypt_DataDesc indata;
|
||||
indata.pfx = in_msg;
|
||||
indata.payload = &in_msg[crypto->msg_info->pfx_len];
|
||||
indata.len = in_len - crypto->msg_info->pfx_len;
|
||||
|
||||
if (crypto->cryspr->ms_decrypt(crypto->cryspr_cb, ctx, &indata, 1, out_p, out_len_p, &nbout)) {
|
||||
HCRYPT_LOG(LOG_ERR, "%s", "ms_decrypt failed\n");
|
||||
nbout = -1;
|
||||
}
|
||||
} else { /* No key received yet */
|
||||
nbout = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case HCRYPT_MSG_PT_KM: /* KMmsg */
|
||||
/* Even or Both SEKs check with even context */
|
||||
ctx = &crypto->ctx_pair[hcryptMsg_GetKeyIndex(crypto->msg_info, in_msg)];
|
||||
|
||||
ASSERT(NULL != ctx); /* Header check should prevent this error */
|
||||
|
||||
if ((ctx->status < HCRYPT_CTX_S_KEYED) /* No key deciphered yet */
|
||||
|| (in_len != ctx->KMmsg_len) /* or not same size */
|
||||
|| (0 != memcmp(ctx->KMmsg_cache, in_msg, in_len))) { /* or different */
|
||||
|
||||
nbout = hcryptCtx_Rx_ParseKM(crypto, in_msg, in_len);
|
||||
//-2: unmatched shared secret
|
||||
//-1: other failures
|
||||
//0: success
|
||||
} else {
|
||||
nbout = 0;
|
||||
}
|
||||
if (NULL != out_p) out_p[0] = NULL;
|
||||
if (NULL != out_len_p) out_len_p[0] = 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
HCRYPT_LOG(LOG_WARNING, "%s", "unknown packet type\n");
|
||||
nbout = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
return(nbout);
|
||||
}
|
||||
|
||||
|
96
trunk/3rdparty/srt-1-fit/haicrypt/hcrypt_sa.c
vendored
Normal file
96
trunk/3rdparty/srt-1-fit/haicrypt/hcrypt_sa.c
vendored
Normal file
|
@ -0,0 +1,96 @@
|
|||
/*
|
||||
* SRT - Secure, Reliable, Transport
|
||||
* Copyright (c) 2018 Haivision Systems Inc.
|
||||
*
|
||||
* 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/.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
written by
|
||||
Haivision Systems Inc.
|
||||
|
||||
2011-06-23 (jdube)
|
||||
HaiCrypt initial implementation.
|
||||
*****************************************************************************/
|
||||
|
||||
/*
|
||||
* For now:
|
||||
* Pre-shared or password derived KEK (Key Encrypting Key)
|
||||
* Future:
|
||||
* Certificate-based association
|
||||
*/
|
||||
#include <string.h> /* memcpy */
|
||||
#include "hcrypt.h"
|
||||
|
||||
int hcryptCtx_SetSecret(hcrypt_Session *crypto, hcrypt_Ctx *ctx, const HaiCrypt_Secret *secret)
|
||||
{
|
||||
int iret;
|
||||
(void)crypto;
|
||||
|
||||
switch(secret->typ) {
|
||||
case HAICRYPT_SECTYP_PRESHARED:
|
||||
ASSERT(secret->len <= HAICRYPT_KEY_MAX_SZ);
|
||||
ctx->cfg.pwd_len = 0;
|
||||
/* KEK: Key Encrypting Key */
|
||||
if (0 > (iret = crypto->cryspr->km_setkey(crypto->cryspr_cb,
|
||||
(HCRYPT_CTX_F_ENCRYPT & ctx->flags ? true : false),
|
||||
secret->str, secret->len))) {
|
||||
HCRYPT_LOG(LOG_ERR, "km_setkey(pdkek[%zd]) failed (rc=%d)\n", secret->len, iret);
|
||||
return(-1);
|
||||
}
|
||||
ctx->status = HCRYPT_CTX_S_SARDY;
|
||||
break;
|
||||
|
||||
case HAICRYPT_SECTYP_PASSPHRASE:
|
||||
ASSERT(secret->len <= sizeof(ctx->cfg.pwd));
|
||||
memcpy(ctx->cfg.pwd, secret->str, secret->len);
|
||||
ctx->cfg.pwd_len = secret->len;
|
||||
/* KEK will be derived from password with Salt */
|
||||
ctx->status = HCRYPT_CTX_S_SARDY;
|
||||
break;
|
||||
|
||||
default:
|
||||
HCRYPT_LOG(LOG_ERR, "Unknown secret type %d\n",
|
||||
secret->typ);
|
||||
return(-1);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
int hcryptCtx_GenSecret(hcrypt_Session *crypto, hcrypt_Ctx *ctx)
|
||||
{
|
||||
/*
|
||||
* KEK need same length as the key it protects (SEK)
|
||||
* KEK = PBKDF2(Pwd, LSB(64, Salt), Iter, Klen)
|
||||
*/
|
||||
unsigned char kek[HAICRYPT_KEY_MAX_SZ];
|
||||
size_t kek_len = ctx->sek_len;
|
||||
size_t pbkdf_salt_len = (ctx->salt_len >= HAICRYPT_PBKDF2_SALT_LEN
|
||||
? HAICRYPT_PBKDF2_SALT_LEN
|
||||
: ctx->salt_len);
|
||||
int iret = 0;
|
||||
(void)crypto;
|
||||
|
||||
iret = crypto->cryspr->km_pbkdf2(crypto->cryspr_cb, ctx->cfg.pwd, ctx->cfg.pwd_len,
|
||||
&ctx->salt[ctx->salt_len - pbkdf_salt_len], pbkdf_salt_len,
|
||||
HAICRYPT_PBKDF2_ITER_CNT, kek_len, kek);
|
||||
|
||||
if(iret) {
|
||||
HCRYPT_LOG(LOG_ERR, "km_pbkdf2() failed (rc=%d)\n", iret);
|
||||
return(-1);
|
||||
}
|
||||
HCRYPT_PRINTKEY(ctx->cfg.pwd, ctx->cfg.pwd_len, "pwd");
|
||||
HCRYPT_PRINTKEY(kek, kek_len, "kek");
|
||||
|
||||
/* KEK: Key Encrypting Key */
|
||||
if (0 > (iret = crypto->cryspr->km_setkey(crypto->cryspr_cb, (HCRYPT_CTX_F_ENCRYPT & ctx->flags ? true : false), kek, kek_len))) {
|
||||
HCRYPT_LOG(LOG_ERR, "km_setkey(pdkek[%zd]) failed (rc=%d)\n", kek_len, iret);
|
||||
return(-1);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
174
trunk/3rdparty/srt-1-fit/haicrypt/hcrypt_tx.c
vendored
Normal file
174
trunk/3rdparty/srt-1-fit/haicrypt/hcrypt_tx.c
vendored
Normal file
|
@ -0,0 +1,174 @@
|
|||
/*
|
||||
* SRT - Secure, Reliable, Transport
|
||||
* Copyright (c) 2018 Haivision Systems Inc.
|
||||
*
|
||||
* 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/.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
written by
|
||||
Haivision Systems Inc.
|
||||
|
||||
2011-06-23 (jdube)
|
||||
HaiCrypt initial implementation.
|
||||
2014-03-11 (jdube)
|
||||
Adaptation for SRT.
|
||||
*****************************************************************************/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <stdlib.h> /* NULL */
|
||||
#include <string.h> /* memcpy */
|
||||
#ifdef _WIN32
|
||||
#include <winsock2.h>
|
||||
#include <ws2tcpip.h>
|
||||
#include <stdint.h>
|
||||
#else
|
||||
#include <arpa/inet.h> /* htonl */
|
||||
#endif
|
||||
#include "hcrypt.h"
|
||||
|
||||
int HaiCrypt_Tx_GetBuf(HaiCrypt_Handle hhc, size_t data_len, unsigned char **in_pp)
|
||||
{
|
||||
hcrypt_Session *crypto = (hcrypt_Session *)hhc;
|
||||
|
||||
ASSERT(NULL != crypto);
|
||||
ASSERT(NULL != crypto->cryspr);
|
||||
|
||||
int pad_factor = (HCRYPT_CTX_MODE_AESECB == crypto->ctx->mode ? 128/8 : 1);
|
||||
|
||||
#ifndef _WIN32
|
||||
ASSERT(crypto->inbuf != NULL);
|
||||
#endif
|
||||
size_t in_len = crypto->msg_info->pfx_len + hcryptMsg_PaddedLen(data_len, pad_factor);
|
||||
*in_pp = crypto->inbuf;
|
||||
if (in_len > crypto->inbuf_siz) {
|
||||
*in_pp = NULL;
|
||||
return(-1);
|
||||
}
|
||||
return(crypto->msg_info->pfx_len);
|
||||
}
|
||||
|
||||
int HaiCrypt_Tx_ManageKeys(HaiCrypt_Handle hhc, void *out_p[], size_t out_len_p[], int maxout)
|
||||
{
|
||||
hcrypt_Session *crypto = (hcrypt_Session *)hhc;
|
||||
hcrypt_Ctx *ctx = NULL;
|
||||
int nbout = 0;
|
||||
|
||||
if ((NULL == crypto)
|
||||
|| (NULL == (ctx = crypto->ctx))
|
||||
|| (NULL == out_p)
|
||||
|| (NULL == out_len_p)) {
|
||||
HCRYPT_LOG(LOG_ERR, "ManageKeys: invalid params: crypto=%p crypto->ctx=%p\n", crypto, ctx);
|
||||
return(-1);
|
||||
}
|
||||
|
||||
/* Manage Key Material (refresh, announce, decommission) */
|
||||
hcryptCtx_Tx_ManageKM(crypto);
|
||||
|
||||
if (NULL == (ctx = crypto->ctx)) {
|
||||
HCRYPT_LOG(LOG_ERR, "%s", "crypto context not defined\n");
|
||||
return(-1);
|
||||
}
|
||||
ASSERT(ctx->status == HCRYPT_CTX_S_ACTIVE);
|
||||
|
||||
nbout = hcryptCtx_Tx_InjectKM(crypto, out_p, out_len_p, maxout);
|
||||
return(nbout);
|
||||
}
|
||||
|
||||
int HaiCrypt_Tx_GetKeyFlags(HaiCrypt_Handle hhc)
|
||||
{
|
||||
hcrypt_Session *crypto = (hcrypt_Session *)hhc;
|
||||
hcrypt_Ctx *ctx = NULL;
|
||||
|
||||
if ((NULL == crypto)
|
||||
|| (NULL == (ctx = crypto->ctx))){
|
||||
HCRYPT_LOG(LOG_ERR, "GetKeyFlags: invalid params: crypto=%p crypto->ctx=%p\n", crypto, ctx);
|
||||
return(-1);
|
||||
}
|
||||
return(hcryptCtx_GetKeyFlags(ctx));
|
||||
}
|
||||
|
||||
int HaiCrypt_Tx_Data(HaiCrypt_Handle hhc,
|
||||
unsigned char *in_pfx, unsigned char *in_data, size_t in_len)
|
||||
{
|
||||
hcrypt_Session *crypto = (hcrypt_Session *)hhc;
|
||||
hcrypt_Ctx *ctx = NULL;
|
||||
int nbout = 0;
|
||||
|
||||
if ((NULL == crypto)
|
||||
|| (NULL == (ctx = crypto->ctx))){
|
||||
HCRYPT_LOG(LOG_ERR, "Tx_Data: invalid params: crypto=%p crypto->ctx=%p\n", crypto, ctx);
|
||||
return(-1);
|
||||
}
|
||||
/* Get/Set packet index */
|
||||
ctx->msg_info->indexMsg(in_pfx, ctx->MSpfx_cache);
|
||||
|
||||
/* Encrypt */
|
||||
{
|
||||
hcrypt_DataDesc indata;
|
||||
indata.pfx = in_pfx;
|
||||
indata.payload = in_data;
|
||||
indata.len = in_len;
|
||||
|
||||
if (0 > (nbout = crypto->cryspr->ms_encrypt(crypto->cryspr_cb, ctx, &indata, 1, NULL, NULL, NULL))) {
|
||||
HCRYPT_LOG(LOG_ERR, "%s", "ms_encrypt failed\n");
|
||||
return(nbout);
|
||||
}
|
||||
}
|
||||
ctx->pkt_cnt++;
|
||||
|
||||
return(nbout);
|
||||
}
|
||||
|
||||
int HaiCrypt_Tx_Process(HaiCrypt_Handle hhc,
|
||||
unsigned char *in_msg, size_t in_len,
|
||||
void *out_p[], size_t out_len_p[], int maxout)
|
||||
{
|
||||
hcrypt_Session *crypto = (hcrypt_Session *)hhc;
|
||||
hcrypt_Ctx *ctx = NULL;
|
||||
int nb, nbout = 0;
|
||||
|
||||
if ((NULL == crypto)
|
||||
|| (NULL == (ctx = crypto->ctx))
|
||||
|| (NULL == out_p)
|
||||
|| (NULL == out_len_p)) {
|
||||
HCRYPT_LOG(LOG_ERR, "Tx_Process: invalid params: crypto=%p crypto->ctx=%p\n", crypto, ctx);
|
||||
return(-1);
|
||||
}
|
||||
|
||||
/* Manage Key Material (refresh, announce, decommission) */
|
||||
hcryptCtx_Tx_ManageKM(crypto);
|
||||
|
||||
if (NULL == (ctx = crypto->ctx)) {
|
||||
HCRYPT_LOG(LOG_ERR, "%s", "crypto context not defined\n");
|
||||
return(-1);
|
||||
}
|
||||
ASSERT(ctx->status == HCRYPT_CTX_S_ACTIVE);
|
||||
|
||||
nbout += hcryptCtx_Tx_InjectKM(crypto, out_p, out_len_p, maxout);
|
||||
|
||||
/* Get packet index */
|
||||
ctx->msg_info->indexMsg(in_msg, ctx->MSpfx_cache);
|
||||
|
||||
/* Encrypt */
|
||||
nb = maxout - nbout;
|
||||
{
|
||||
hcrypt_DataDesc indata;
|
||||
indata.pfx = in_msg;
|
||||
indata.payload = &in_msg[ctx->msg_info->pfx_len];
|
||||
indata.len = in_len - ctx->msg_info->pfx_len;
|
||||
|
||||
if (crypto->cryspr->ms_encrypt(crypto->cryspr_cb, ctx, &indata, 1, &out_p[nbout], &out_len_p[nbout], &nb)) {
|
||||
HCRYPT_LOG(LOG_ERR, "%s", "ms_encrypt failed\n");
|
||||
return(nbout);
|
||||
}
|
||||
}
|
||||
nbout += nb;
|
||||
ctx->pkt_cnt++;
|
||||
|
||||
return(nbout);
|
||||
}
|
224
trunk/3rdparty/srt-1-fit/haicrypt/hcrypt_ut.c
vendored
Normal file
224
trunk/3rdparty/srt-1-fit/haicrypt/hcrypt_ut.c
vendored
Normal file
|
@ -0,0 +1,224 @@
|
|||
/*
|
||||
* SRT - Secure, Reliable, Transport
|
||||
* Copyright (c) 2018 Haivision Systems Inc.
|
||||
*
|
||||
* 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/.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
written by
|
||||
Haivision Systems Inc.
|
||||
|
||||
2011-07-11 (jdube)
|
||||
HaiCrypt initial implementation.
|
||||
*****************************************************************************/
|
||||
|
||||
#include <string.h> /* memcpy */
|
||||
#include <stdio.h>
|
||||
#include <haicrypt.h>
|
||||
#include "hcrypt.h"
|
||||
|
||||
#ifndef _WIN32
|
||||
|
||||
/* RFC6070 PBKDF2 Tests Vectors */
|
||||
|
||||
static struct TestVector {
|
||||
size_t pwd_len;
|
||||
const char *pwd;
|
||||
size_t salt_len;
|
||||
const unsigned char *salt;
|
||||
int cnt;
|
||||
size_t dk_len;
|
||||
unsigned char dk[32];
|
||||
} tv[] = {
|
||||
{ /* 1 */
|
||||
.pwd_len = 8, .pwd = "password",
|
||||
.salt_len = 4, .salt = (unsigned char *)"salt",
|
||||
.cnt = 1,
|
||||
.dk_len = 20,
|
||||
.dk = {
|
||||
0x0c, 0x60, 0xc8, 0x0f, 0x96, 0x1f, 0x0e, 0x71,
|
||||
0xf3, 0xa9, 0xb5, 0x24, 0xaf, 0x60, 0x12, 0x06,
|
||||
0x2f, 0xe0, 0x37, 0xa6
|
||||
}
|
||||
},
|
||||
{ /* 2 */
|
||||
.pwd_len = 8, .pwd = "password",
|
||||
.salt_len = 4, .salt = (unsigned char *)"salt",
|
||||
.cnt = 2,
|
||||
.dk_len = 20,
|
||||
.dk = {
|
||||
0xea, 0x6c, 0x01, 0x4d, 0xc7, 0x2d, 0x6f, 0x8c,
|
||||
0xcd, 0x1e, 0xd9, 0x2a, 0xce, 0x1d, 0x41, 0xf0,
|
||||
0xd8, 0xde, 0x89, 0x57
|
||||
}
|
||||
},
|
||||
{ /* 3 */
|
||||
.pwd_len = 8, .pwd = "password",
|
||||
.salt_len = 4, .salt = (unsigned char *)"salt",
|
||||
.cnt = 4096,
|
||||
.dk_len = 20,
|
||||
.dk = {
|
||||
0x4b, 0x00, 0x79, 0x01, 0xb7, 0x65, 0x48, 0x9a,
|
||||
0xbe, 0xad, 0x49, 0xd9, 0x26, 0xf7, 0x21, 0xd0,
|
||||
0x65, 0xa4, 0x29, 0xc1
|
||||
}
|
||||
},
|
||||
{ /* 4 */
|
||||
.pwd_len = 8, .pwd = "password",
|
||||
.salt_len = 4, .salt = (unsigned char *)"salt",
|
||||
.cnt = 16777216,
|
||||
.dk_len = 20,
|
||||
.dk = {
|
||||
0xee, 0xfe, 0x3d, 0x61, 0xcd, 0x4d, 0xa4, 0xe4,
|
||||
0xe9, 0x94, 0x5b, 0x3d, 0x6b, 0xa2, 0x15, 0x8c,
|
||||
0x26, 0x34, 0xe9, 0x84
|
||||
}
|
||||
},
|
||||
{ /* 5 */
|
||||
.pwd_len = 24, .pwd = "passwordPASSWORDpassword",
|
||||
.salt_len = 36, .salt = (unsigned char *)"saltSALTsaltSALTsaltSALTsaltSALTsalt",
|
||||
.cnt = 4096,
|
||||
.dk_len = 25,
|
||||
.dk = {
|
||||
0x3d, 0x2e, 0xec, 0x4f, 0xe4, 0x1c, 0x84, 0x9b,
|
||||
0x80, 0xc8, 0xd8, 0x36, 0x62, 0xc0, 0xe4, 0x4a,
|
||||
0x8b, 0x29, 0x1a, 0x96, 0x4c, 0xf2, 0xf0, 0x70,
|
||||
0x38
|
||||
}
|
||||
},
|
||||
{ /* 6 */
|
||||
.pwd_len = 9, .pwd = "pass\0word",
|
||||
.salt_len = 5, .salt = (unsigned char *)"sa\0lt",
|
||||
.cnt = 4096,
|
||||
.dk_len = 16,
|
||||
.dk = {
|
||||
0x56, 0xfa, 0x6a, 0xa7, 0x55, 0x48, 0x09, 0x9d,
|
||||
0xcc, 0x37, 0xd7, 0xf0, 0x34, 0x25, 0xe0, 0xc3
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
#include <sys/time.h>
|
||||
|
||||
static int hc_ut_pbkdf2(unsigned verbose)
|
||||
{
|
||||
int i;
|
||||
int nbt = sizeof(tv)/sizeof(tv[0]);
|
||||
int nbe = 0;
|
||||
unsigned char dk[32];
|
||||
struct timeval tstart, tstop, tdiff;
|
||||
|
||||
for (i=0; i<nbt; i++) {
|
||||
if (verbose) {
|
||||
printf("PBKDF2 test vector %d", i+1);
|
||||
fflush(stdout);
|
||||
gettimeofday(&tstart, NULL);
|
||||
}
|
||||
|
||||
hcrypt_pbkdf2_hmac_sha1(tv[i].pwd, tv[i].pwd_len,
|
||||
tv[i].salt, tv[i].salt_len,
|
||||
tv[i].cnt, tv[i].dk_len, dk);
|
||||
|
||||
if (verbose) {
|
||||
gettimeofday(&tstop, NULL);
|
||||
timersub(&tstop, &tstart, &tdiff);
|
||||
}
|
||||
|
||||
if(memcmp(dk, tv[i].dk, tv[i].dk_len)) {
|
||||
if (verbose) {
|
||||
printf(": failed in %lu.%06lu sec\n", tdiff.tv_sec, (unsigned long)tdiff.tv_usec);
|
||||
} else {
|
||||
printf("PBKDF2 test vector %d: failed\n", i+1);
|
||||
}
|
||||
nbe++;
|
||||
} else if (verbose) {
|
||||
printf(": passed in %lu.%06lu sec\n", tdiff.tv_sec, (unsigned long)tdiff.tv_usec);
|
||||
}
|
||||
}
|
||||
return(nbe);
|
||||
}
|
||||
|
||||
int hc_ut_encrypt_ctr_speed(void)
|
||||
{
|
||||
static HaiCrypt_Secret secret = {
|
||||
.typ = HAICRYPT_SECTYP_PASSPHRASE,
|
||||
.len = 12,
|
||||
.str = "000000000000"
|
||||
};
|
||||
HaiCrypt_Cfg crypto_cfg;
|
||||
HaiCrypt_Handle hcrypto;
|
||||
struct timeval tstart, tstop, tdiff;
|
||||
unsigned char pkt[1500];
|
||||
int nbe = 0;
|
||||
int i;
|
||||
#ifdef HAICRYPT_USE_OPENSSL_EVP_CBC
|
||||
HaiCrypt_Cipher HaiCryptCipher_OpenSSL_EVP_CBC(void); /* OpenSSL EVP interface CBC mode*/
|
||||
#endif
|
||||
|
||||
memset(&crypto_cfg, 0, sizeof(crypto_cfg));
|
||||
|
||||
crypto_cfg.flags = HAICRYPT_CFG_F_CRYPTO | HAICRYPT_CFG_F_TX;
|
||||
crypto_cfg.xport = HAICRYPT_XPT_SRT;
|
||||
#ifdef HAICRYPT_USE_OPENSSL_EVP_CBC
|
||||
crypto_cfg.cipher = HaiCryptCipher_OpenSSL_EVP_CBC();
|
||||
#else
|
||||
crypto_cfg.cipher = HaiCryptCipher_Get_Instance();
|
||||
#endif
|
||||
crypto_cfg.key_len = (size_t)128/8;
|
||||
crypto_cfg.data_max_len = HAICRYPT_DEF_DATA_MAX_LENGTH; //MTU
|
||||
crypto_cfg.km_tx_period_ms = 0;//No HaiCrypt KM inject period, handled in SRT;
|
||||
crypto_cfg.km_refresh_rate_pkt = HAICRYPT_DEF_KM_REFRESH_RATE;
|
||||
crypto_cfg.km_pre_announce_pkt = 0x10000; //HAICRYPT_DEF_KM_PRE_ANNOUNCE;
|
||||
|
||||
memcpy(&crypto_cfg.secret, &secret, sizeof(crypto_cfg.secret));
|
||||
|
||||
if (HaiCrypt_Create(&crypto_cfg, &hcrypto)) {
|
||||
fprintf(stderr, "haicrypt: HaiCrypt_Create failed\n");
|
||||
return(1);
|
||||
}
|
||||
|
||||
for (i=0; i<1500; i++) {
|
||||
pkt[i] = i & 0xff;
|
||||
}
|
||||
|
||||
#define UT_NBPKTS 100000L
|
||||
#define UT_PKTSZ (7*188)
|
||||
|
||||
gettimeofday(&tstart, NULL);
|
||||
for (i=0; i<UT_NBPKTS; i++) {
|
||||
if (0 > HaiCrypt_Tx_Data(hcrypto, &pkt[0], &pkt[16], UT_PKTSZ)) nbe++;
|
||||
if (0 == (i % 1000)) {
|
||||
printf("\b\b\b\b\b\b%6d", i);
|
||||
fflush(stdout);
|
||||
}
|
||||
}
|
||||
gettimeofday(&tstop, NULL);
|
||||
timersub(&tstop, &tstart, &tdiff);
|
||||
printf("\nhaicrypt: encrypted %ld packets in %lu.%06lu sec (%ld.%03ld kbps)\n",
|
||||
UT_NBPKTS, tdiff.tv_sec, (unsigned long)tdiff.tv_usec,
|
||||
(((UT_NBPKTS * UT_PKTSZ*10)/((tdiff.tv_sec*10) + (tdiff.tv_usec/100))) / 1000),
|
||||
(((UT_NBPKTS * UT_PKTSZ*10)/((tdiff.tv_sec*10) + (tdiff.tv_usec/100))) % 1000));
|
||||
|
||||
HaiCrypt_Close(hcrypto);
|
||||
return(nbe);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
|
||||
int nbe = 0;
|
||||
(void)argc;
|
||||
(void)argv;
|
||||
nbe += hc_ut_encrypt_ctr_speed();
|
||||
nbe += hc_ut_pbkdf2(1);
|
||||
|
||||
printf("haicrypt unit test %s: %d errors found\n", nbe ? "failed" : "passed", nbe);
|
||||
return(nbe);
|
||||
}
|
||||
|
||||
#endif // _WIN32
|
171
trunk/3rdparty/srt-1-fit/haicrypt/hcrypt_xpt_srt.c
vendored
Normal file
171
trunk/3rdparty/srt-1-fit/haicrypt/hcrypt_xpt_srt.c
vendored
Normal file
|
@ -0,0 +1,171 @@
|
|||
/*
|
||||
* SRT - Secure, Reliable, Transport
|
||||
* Copyright (c) 2018 Haivision Systems Inc.
|
||||
*
|
||||
* 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/.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
written by
|
||||
Haivision Systems Inc.
|
||||
|
||||
2014-03-11 (jdube)
|
||||
Adaptation for SRT.
|
||||
*****************************************************************************/
|
||||
|
||||
#include <string.h> /* memset, memcpy */
|
||||
#ifdef _WIN32
|
||||
#include <winsock2.h>
|
||||
#include <ws2tcpip.h>
|
||||
#else
|
||||
#include <arpa/inet.h> /* htonl, ntohl */
|
||||
#endif
|
||||
#include "hcrypt.h"
|
||||
|
||||
/*
|
||||
* HaiCrypt SRT (Secure Reliable Transport) Media Stream (MS) Msg Prefix:
|
||||
* This is UDT data header with Crypto Key Flags (KF) added.
|
||||
* Header is in 32bit host order words in the context of the functions of this handler.
|
||||
*
|
||||
* 0 1 2 3
|
||||
* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||
* +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+
|
||||
* 0x00 |0| Packet Sequence Number (pki) |
|
||||
* +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+
|
||||
* 0x04 |FF |o|KF | Message Number |
|
||||
* +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+
|
||||
* 0x08 | Time Stamp |
|
||||
* +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+
|
||||
* 0x0C | Destination Socket ID) |
|
||||
* +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+
|
||||
* | Payload... |
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* HaiCrypt Standalone Transport Keying Material (KM) Msg header kept in SRT
|
||||
* Message and cache maintained in network order
|
||||
*
|
||||
* 0 1 2 3
|
||||
* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||
* +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+
|
||||
* 0x00 |0|Vers | PT | Sign | resv |
|
||||
* +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+
|
||||
* ... .
|
||||
*/
|
||||
|
||||
#define HCRYPT_MSG_SRT_HDR_SZ 16
|
||||
#define HCRYPT_MSG_SRT_PFX_SZ 16
|
||||
|
||||
#define HCRYPT_MSG_SRT_OFS_PKI 0
|
||||
#define HCRYPT_MSG_SRT_OFS_MSGNO 4
|
||||
#define HCRYPT_MSG_SRT_SHF_KFLGS 27 //shift
|
||||
|
||||
static hcrypt_MsgInfo _hcMsg_SRT_MsgInfo;
|
||||
|
||||
static unsigned hcryptMsg_SRT_GetKeyFlags(unsigned char *msg)
|
||||
{
|
||||
uint32_t msgno;
|
||||
memcpy(&msgno, &msg[HCRYPT_MSG_SRT_OFS_MSGNO], sizeof(msgno)); //header is in host order
|
||||
return((unsigned)((msgno >> HCRYPT_MSG_SRT_SHF_KFLGS) & HCRYPT_MSG_F_xSEK));
|
||||
}
|
||||
|
||||
static hcrypt_Pki hcryptMsg_SRT_GetPki(unsigned char *msg, int nwkorder)
|
||||
{
|
||||
hcrypt_Pki pki;
|
||||
memcpy(&pki, &msg[HCRYPT_MSG_SRT_OFS_PKI], sizeof(pki)); //header is in host order
|
||||
return (nwkorder ? htonl(pki) : pki);
|
||||
}
|
||||
|
||||
static void hcryptMsg_SRT_SetPki(unsigned char *msg, hcrypt_Pki pki)
|
||||
{
|
||||
memcpy(&msg[HCRYPT_MSG_SRT_OFS_PKI], &pki, sizeof(pki)); //header is in host order
|
||||
}
|
||||
|
||||
static void hcryptMsg_SRT_ResetCache(unsigned char *pfx_cache, unsigned pkt_type, unsigned kflgs)
|
||||
{
|
||||
switch(pkt_type) {
|
||||
case HCRYPT_MSG_PT_MS: /* Media Stream */
|
||||
/* Nothing to do, header filled by protocol */
|
||||
break;
|
||||
case HCRYPT_MSG_PT_KM: /* Keying Material */
|
||||
pfx_cache[HCRYPT_MSG_KM_OFS_VERSION] = (unsigned char)((HCRYPT_MSG_VERSION << 4) | pkt_type); // version || PT
|
||||
pfx_cache[HCRYPT_MSG_KM_OFS_SIGN] = (unsigned char)((HCRYPT_MSG_SIGN >> 8) & 0xFF); // Haivision PnP Mfr ID
|
||||
pfx_cache[HCRYPT_MSG_KM_OFS_SIGN+1] = (unsigned char)(HCRYPT_MSG_SIGN & 0xFF);
|
||||
pfx_cache[HCRYPT_MSG_KM_OFS_KFLGS] = (unsigned char)kflgs; //HCRYPT_MSG_F_xxx
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void hcryptMsg_SRT_IndexMsg(unsigned char *msg, unsigned char *pfx_cache)
|
||||
{
|
||||
(void)msg;
|
||||
(void)pfx_cache;
|
||||
return; //nothing to do, header and index maintained by SRT
|
||||
}
|
||||
|
||||
static int hcryptMsg_SRT_ParseMsg(unsigned char *msg)
|
||||
{
|
||||
int rc;
|
||||
|
||||
if ((HCRYPT_MSG_VERSION == hcryptMsg_KM_GetVersion(msg)) /* Version 1 */
|
||||
&& (HCRYPT_MSG_PT_KM == hcryptMsg_KM_GetPktType(msg)) /* Keying Material */
|
||||
&& (HCRYPT_MSG_SIGN == hcryptMsg_KM_GetSign(msg))) { /* 'HAI' PnP Mfr ID */
|
||||
rc = HCRYPT_MSG_PT_KM;
|
||||
} else {
|
||||
//Assume it's data.
|
||||
//SRT does not call this for MS msg
|
||||
rc = HCRYPT_MSG_PT_MS;
|
||||
}
|
||||
|
||||
switch(rc) {
|
||||
case HCRYPT_MSG_PT_MS:
|
||||
if (hcryptMsg_HasNoSek(&_hcMsg_SRT_MsgInfo, msg)
|
||||
|| hcryptMsg_HasBothSek(&_hcMsg_SRT_MsgInfo, msg)) {
|
||||
HCRYPT_LOG(LOG_ERR, "invalid MS msg flgs: %02x\n",
|
||||
hcryptMsg_GetKeyIndex(&_hcMsg_SRT_MsgInfo, msg));
|
||||
return(-1);
|
||||
}
|
||||
break;
|
||||
case HCRYPT_MSG_PT_KM:
|
||||
if (HCRYPT_SE_TSSRT != hcryptMsg_KM_GetSE(msg)) { //Check Stream Encapsulation (SE)
|
||||
HCRYPT_LOG(LOG_ERR, "invalid KM msg SE: %d\n",
|
||||
hcryptMsg_KM_GetSE(msg));
|
||||
return(-1);
|
||||
}
|
||||
if (hcryptMsg_KM_HasNoSek(msg)) {
|
||||
HCRYPT_LOG(LOG_ERR, "invalid KM msg flgs: %02x\n",
|
||||
hcryptMsg_KM_GetKeyIndex(msg));
|
||||
return(-1);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
HCRYPT_LOG(LOG_ERR, "invalid pkt type: %d\n", rc);
|
||||
rc = 0; /* unknown packet type */
|
||||
break;
|
||||
}
|
||||
return(rc); /* -1: error, 0: unknown: >0: PT */
|
||||
}
|
||||
|
||||
static hcrypt_MsgInfo _hcMsg_SRT_MsgInfo;
|
||||
|
||||
hcrypt_MsgInfo *hcryptMsg_SRT_MsgInfo(void)
|
||||
{
|
||||
_hcMsg_SRT_MsgInfo.hdr_len = HCRYPT_MSG_SRT_HDR_SZ;
|
||||
_hcMsg_SRT_MsgInfo.pfx_len = HCRYPT_MSG_SRT_PFX_SZ;
|
||||
_hcMsg_SRT_MsgInfo.getKeyFlags = hcryptMsg_SRT_GetKeyFlags;
|
||||
_hcMsg_SRT_MsgInfo.getPki = hcryptMsg_SRT_GetPki;
|
||||
_hcMsg_SRT_MsgInfo.setPki = hcryptMsg_SRT_SetPki;
|
||||
_hcMsg_SRT_MsgInfo.resetCache = hcryptMsg_SRT_ResetCache;
|
||||
_hcMsg_SRT_MsgInfo.indexMsg = hcryptMsg_SRT_IndexMsg;
|
||||
_hcMsg_SRT_MsgInfo.parseMsg = hcryptMsg_SRT_ParseMsg;
|
||||
|
||||
return(&_hcMsg_SRT_MsgInfo);
|
||||
}
|
||||
|
180
trunk/3rdparty/srt-1-fit/haicrypt/hcrypt_xpt_sta.c
vendored
Normal file
180
trunk/3rdparty/srt-1-fit/haicrypt/hcrypt_xpt_sta.c
vendored
Normal file
|
@ -0,0 +1,180 @@
|
|||
/*
|
||||
* SRT - Secure, Reliable, Transport
|
||||
* Copyright (c) 2018 Haivision Systems Inc.
|
||||
*
|
||||
* 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/.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
written by
|
||||
Haivision Systems Inc.
|
||||
|
||||
2011-06-23 (jdube)
|
||||
HaiCrypt initial implementation.
|
||||
2014-03-11 (jdube)
|
||||
Adaptation for SRT.
|
||||
*****************************************************************************/
|
||||
|
||||
#include <string.h> /* memset, memcpy */
|
||||
#include <time.h> /* time() */
|
||||
#ifdef _WIN32
|
||||
#include <winsock2.h>
|
||||
#include <ws2tcpip.h>
|
||||
#else
|
||||
#include <arpa/inet.h> /* htonl, ntohl */
|
||||
#endif
|
||||
#include "hcrypt.h"
|
||||
|
||||
/*
|
||||
* HaiCrypt Standalone Transport Media Stream (MS) Data Msg Prefix:
|
||||
* Cache maintained in network order
|
||||
*
|
||||
* 0 1 2 3
|
||||
* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||
* +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+
|
||||
* 0x00 |0|Vers | PT | Sign | resv |KF |
|
||||
* +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+
|
||||
* 0x04 | pki |
|
||||
* +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+
|
||||
* | payload... |
|
||||
*/
|
||||
|
||||
/*
|
||||
* HaiCrypt Standalone Transport Keying Material (KM) Msg (no prefix, use KM Msg directly):
|
||||
* Cache maintained in network order
|
||||
*
|
||||
* 0 1 2 3
|
||||
* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||
* +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+
|
||||
* 0x00 |0|Vers | PT | Sign | resv |
|
||||
* +-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-+
|
||||
* ... .
|
||||
*/
|
||||
|
||||
#define HCRYPT_MSG_STA_HDR_SZ 4
|
||||
#define HCRYPT_MSG_STA_PKI_SZ 4
|
||||
#define HCRYPT_MSG_STA_PFX_SZ (HCRYPT_MSG_STA_HDR_SZ + HCRYPT_MSG_STA_PKI_SZ)
|
||||
|
||||
#define HCRYPT_MSG_STA_OFS_VERSION HCRYPT_MSG_KM_OFS_VERSION
|
||||
#define HCRYPT_MSG_STA_OFS_PT HCRYPT_MSG_KM_OFS_PT
|
||||
#define HCRYPT_MSG_STA_OFS_SIGN HCRYPT_MSG_KM_OFS_SIGN
|
||||
#define HCRYPT_MSG_STA_OFS_KFLGS HCRYPT_MSG_KM_OFS_KFLGS
|
||||
|
||||
#define HCRYPT_MSG_STA_OFS_PKI HCRYPT_MSG_STA_HDR_SZ
|
||||
|
||||
#define hcryptMsg_STA_GetVersion(msg) (((msg)[HCRYPT_MSG_STA_OFS_VERSION]>>4)& 0xF)
|
||||
#define hcryptMsg_STA_GetPktType(msg) (((msg)[HCRYPT_MSG_STA_OFS_PT]) & 0xF)
|
||||
#define hcryptMsg_STA_GetSign(msg) (((msg)[HCRYPT_MSG_STA_OFS_SIGN]<<8) | (msg)[HCRYPT_MSG_STA_OFS_SIGN+1])
|
||||
|
||||
static hcrypt_MsgInfo _hcMsg_STA_MsgInfo;
|
||||
|
||||
static unsigned hcryptMsg_STA_GetKeyFlags(unsigned char *msg)
|
||||
{
|
||||
return((unsigned)(msg[HCRYPT_MSG_STA_OFS_KFLGS] & HCRYPT_MSG_F_xSEK));
|
||||
}
|
||||
|
||||
static hcrypt_Pki hcryptMsg_STA_GetPki(unsigned char *msg, int nwkorder)
|
||||
{
|
||||
hcrypt_Pki pki;
|
||||
memcpy(&pki, &msg[HCRYPT_MSG_STA_OFS_PKI], sizeof(pki)); //header is in host order
|
||||
return (nwkorder ? pki : ntohl(pki));
|
||||
}
|
||||
|
||||
static void hcryptMsg_STA_SetPki(unsigned char *msg, hcrypt_Pki pki)
|
||||
{
|
||||
hcrypt_Pki nwk_pki = htonl(pki);
|
||||
memcpy(&msg[HCRYPT_MSG_STA_OFS_PKI], &nwk_pki, sizeof(nwk_pki)); //header is in host order
|
||||
}
|
||||
|
||||
static void hcryptMsg_STA_ResetCache(unsigned char *pfx_cache, unsigned pkt_type, unsigned kflgs)
|
||||
{
|
||||
pfx_cache[HCRYPT_MSG_STA_OFS_VERSION] = (unsigned char)((HCRYPT_MSG_VERSION << 4) | pkt_type); // version || PT
|
||||
pfx_cache[HCRYPT_MSG_STA_OFS_SIGN] = (unsigned char)((HCRYPT_MSG_SIGN >> 8) & 0xFF); // Haivision PnP Mfr ID
|
||||
pfx_cache[HCRYPT_MSG_STA_OFS_SIGN+1] = (unsigned char)(HCRYPT_MSG_SIGN & 0xFF);
|
||||
|
||||
switch(pkt_type) {
|
||||
case HCRYPT_MSG_PT_MS:
|
||||
pfx_cache[HCRYPT_MSG_STA_OFS_KFLGS] = (unsigned char)kflgs; //HCRYPT_MSG_F_xxx
|
||||
hcryptMsg_STA_SetPki(pfx_cache, 0);
|
||||
break;
|
||||
case HCRYPT_MSG_PT_KM:
|
||||
pfx_cache[HCRYPT_MSG_KM_OFS_KFLGS] = (unsigned char)kflgs; //HCRYPT_MSG_F_xxx
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void hcryptMsg_STA_IndexMsg(unsigned char *msg, unsigned char *pfx_cache)
|
||||
{
|
||||
hcrypt_Pki pki = hcryptMsg_STA_GetPki(pfx_cache, 0); //Get in host order
|
||||
memcpy(msg, pfx_cache, HCRYPT_MSG_STA_PFX_SZ);
|
||||
hcryptMsg_SetPki(&_hcMsg_STA_MsgInfo, pfx_cache, ++pki);
|
||||
}
|
||||
|
||||
static time_t _tLastLogTime = 0;
|
||||
|
||||
static int hcryptMsg_STA_ParseMsg(unsigned char *msg)
|
||||
{
|
||||
int rc;
|
||||
|
||||
if ((HCRYPT_MSG_VERSION != hcryptMsg_STA_GetVersion(msg)) /* Version 1 */
|
||||
|| (HCRYPT_MSG_SIGN != hcryptMsg_STA_GetSign(msg))) { /* 'HAI' PnP Mfr ID */
|
||||
time_t tCurrentTime = time(NULL);
|
||||
// invalid data
|
||||
if ((tCurrentTime - _tLastLogTime) >= 2 || (0 == _tLastLogTime))
|
||||
{
|
||||
_tLastLogTime = tCurrentTime;
|
||||
HCRYPT_LOG(LOG_ERR, "invalid msg hdr: 0x%02x %02x%02x %02x\n",
|
||||
msg[0], msg[1], msg[2], msg[3]);
|
||||
}
|
||||
return(-1); /* Invalid packet */
|
||||
}
|
||||
rc = hcryptMsg_STA_GetPktType(msg);
|
||||
switch(rc) {
|
||||
case HCRYPT_MSG_PT_MS:
|
||||
if (hcryptMsg_HasNoSek(&_hcMsg_STA_MsgInfo, msg)
|
||||
|| hcryptMsg_HasBothSek(&_hcMsg_STA_MsgInfo, msg)) {
|
||||
HCRYPT_LOG(LOG_ERR, "invalid MS msg flgs: %02x\n",
|
||||
hcryptMsg_GetKeyIndex(&_hcMsg_STA_MsgInfo, msg));
|
||||
return(-1);
|
||||
}
|
||||
break;
|
||||
case HCRYPT_MSG_PT_KM:
|
||||
if (HCRYPT_SE_TSUDP != hcryptMsg_KM_GetSE(msg)) {
|
||||
HCRYPT_LOG(LOG_ERR, "invalid KM msg SE: %d\n",
|
||||
hcryptMsg_KM_GetSE(msg));
|
||||
} else if (hcryptMsg_KM_HasNoSek(msg)) {
|
||||
HCRYPT_LOG(LOG_ERR, "invalid KM msg flgs: %02x\n",
|
||||
hcryptMsg_KM_GetKeyIndex(msg));
|
||||
return(-1);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
HCRYPT_LOG(LOG_ERR, "invalid pkt type: %d\n", rc);
|
||||
rc = 0; /* unknown packet type */
|
||||
break;
|
||||
}
|
||||
return(rc); /* -1: error, 0: unknown: >0: PT */
|
||||
}
|
||||
|
||||
static hcrypt_MsgInfo _hcMsg_STA_MsgInfo;
|
||||
|
||||
hcrypt_MsgInfo *hcryptMsg_STA_MsgInfo(void)
|
||||
{
|
||||
_hcMsg_STA_MsgInfo.hdr_len = HCRYPT_MSG_STA_HDR_SZ;
|
||||
_hcMsg_STA_MsgInfo.pfx_len = HCRYPT_MSG_STA_PFX_SZ;
|
||||
_hcMsg_STA_MsgInfo.getKeyFlags = hcryptMsg_STA_GetKeyFlags;
|
||||
_hcMsg_STA_MsgInfo.getPki = hcryptMsg_STA_GetPki;
|
||||
_hcMsg_STA_MsgInfo.setPki = hcryptMsg_STA_SetPki;
|
||||
_hcMsg_STA_MsgInfo.resetCache = hcryptMsg_STA_ResetCache;
|
||||
_hcMsg_STA_MsgInfo.indexMsg = hcryptMsg_STA_IndexMsg;
|
||||
_hcMsg_STA_MsgInfo.parseMsg = hcryptMsg_STA_ParseMsg;
|
||||
|
||||
return(&_hcMsg_STA_MsgInfo);
|
||||
}
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue