#ifndef INC_SRT_HCRYPT_H
#define INC_SRT_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"
#ifdef HAICRYPT_SUPPORT_CRYPTO_API
#define CRYPTO_API_SERVER 1
#include "crypto_api.h"
#endif
typedef struct hcrypt_Session_str {
#ifdef HAICRYPT_SUPPORT_CRYPTO_API
CRYPTOFEC_OBJECT resv;
#endif
hcrypt_Ctx ctx_pair[2];
hcrypt_Ctx * ctx;
CRYSPR_methods * cryspr;
CRYSPR_cb * cryspr_cb;
unsigned char * inbuf;
size_t inbuf_siz;
int se;
hcrypt_MsgInfo * msg_info;
struct {
size_t data_max_len;
}cfg;
struct {
struct timeval tx_period;
struct timeval tx_last;
unsigned int refresh_rate;
unsigned int pre_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
#define HCRYPT_PRINTKEY(key,len,tag)
#endif
#ifndef ASSERT
#include <assert.h>
#define ASSERT(c) assert(c)
#endif
#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