Create separate SRTP and SRTCP objects for each MediaStream
This commit is contained in:
parent
9cb5b9fe45
commit
85bb4c6eef
|
@ -75,14 +75,14 @@ namespace uvg_rtp {
|
|||
struct {
|
||||
uint8_t enc_key[AES_KEY_LENGTH];
|
||||
uint8_t auth_key[AES_KEY_LENGTH];
|
||||
uint8_t salt_key[SALT_LENGTH];
|
||||
uint8_t salt_key[AES_KEY_LENGTH]; /* TODO: make sure this is correct */
|
||||
} local;
|
||||
|
||||
/* Used to decrypt/Authenticate packets sent by remote */
|
||||
struct {
|
||||
uint8_t enc_key[AES_KEY_LENGTH];
|
||||
uint8_t auth_key[AES_KEY_LENGTH];
|
||||
uint8_t salt_key[SALT_LENGTH];
|
||||
uint8_t salt_key[AES_KEY_LENGTH];
|
||||
} remote;
|
||||
|
||||
} srtp_key_ctx_t;
|
||||
|
@ -142,13 +142,7 @@ namespace uvg_rtp {
|
|||
bool authenticate_rtp();
|
||||
|
||||
/* Get reference to the SRTP context (including session keys) */
|
||||
srtp_ctx_t& get_ctx();
|
||||
|
||||
/* Decrypt the payload and verify authentication tag (if enabled) */
|
||||
static rtp_error_t recv_packet_handler(void *arg, int flags, frame::rtp_frame **out);
|
||||
|
||||
/* Encrypt the payload and add authentication tag (if enabled) */
|
||||
static rtp_error_t send_packet_handler(void *arg, buf_vec& buffers);
|
||||
srtp_ctx_t *get_ctx();
|
||||
#endif
|
||||
|
||||
protected:
|
||||
|
@ -164,8 +158,8 @@ namespace uvg_rtp {
|
|||
/* Internal init method that initialize the SRTP context using values in key_ctx_.master */
|
||||
rtp_error_t init(int type, int flags);
|
||||
#endif
|
||||
|
||||
srtp_ctx_t srtp_ctx_;
|
||||
/* SRTP context containing all session information and keys */
|
||||
srtp_ctx_t *srtp_ctx_;
|
||||
|
||||
/* If NULL cipher is enabled, it means that RTP packets are not
|
||||
* encrypted but other security mechanisms described in RFC 3711 may be used */
|
||||
|
|
|
@ -9,6 +9,7 @@ namespace uvg_rtp {
|
|||
srtp();
|
||||
~srtp();
|
||||
|
||||
#ifdef __RTP_CRYPTO__
|
||||
/* TODO: */
|
||||
rtp_error_t encrypt(uint32_t ssrc, uint16_t seq, uint8_t *buffer, size_t len);
|
||||
|
||||
|
@ -20,5 +21,6 @@ namespace uvg_rtp {
|
|||
|
||||
/* Encrypt the payload of an RTP packet and add authentication tag (if enabled) */
|
||||
static rtp_error_t send_packet_handler(void *arg, buf_vec& buffers);
|
||||
#endif
|
||||
};
|
||||
};
|
||||
|
|
|
@ -188,7 +188,7 @@ rtp_error_t uvg_rtp::media_stream::init(uvg_rtp::zrtp *zrtp)
|
|||
return ret;
|
||||
}
|
||||
|
||||
if ((srtp_ = new uvg_rtp::srtp()) == nullptr)
|
||||
if (!(srtp_ = new uvg_rtp::srtp()))
|
||||
return RTP_MEMORY_ERROR;
|
||||
|
||||
if ((ret = srtp_->init_zrtp(SRTP, ctx_config_.flags, rtp_, zrtp)) != RTP_OK) {
|
||||
|
@ -196,8 +196,11 @@ rtp_error_t uvg_rtp::media_stream::init(uvg_rtp::zrtp *zrtp)
|
|||
return ret;
|
||||
}
|
||||
|
||||
if (!(srtcp_ = new uvg_rtp::srtcp()))
|
||||
return RTP_MEMORY_ERROR;
|
||||
|
||||
if ((ret = srtcp_->init_zrtp(SRTCP, ctx_config_.flags, rtp_, zrtp)) != RTP_OK) {
|
||||
LOG_ERROR("Failed to initialize SRTP for media stream!");
|
||||
LOG_ERROR("Failed to initialize SRTCP for media stream!");
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -272,7 +275,7 @@ rtp_error_t uvg_rtp::media_stream::add_srtp_ctx(uint8_t *key, uint8_t *salt)
|
|||
return RTP_MEMORY_ERROR;
|
||||
}
|
||||
|
||||
if ((srtp_ = new uvg_rtp::srtp()) == nullptr)
|
||||
if (!(srtp_ = new uvg_rtp::srtp()))
|
||||
return RTP_MEMORY_ERROR;
|
||||
|
||||
if ((ret = srtp_->init_user(SRTP, ctx_config_.flags, key, salt)) != RTP_OK) {
|
||||
|
@ -280,6 +283,14 @@ rtp_error_t uvg_rtp::media_stream::add_srtp_ctx(uint8_t *key, uint8_t *salt)
|
|||
return ret;
|
||||
}
|
||||
|
||||
if (!(srtcp_ = new uvg_rtp::srtcp()))
|
||||
return RTP_MEMORY_ERROR;
|
||||
|
||||
if ((ret = srtcp_->init_user(SRTCP, ctx_config_.flags, key, salt)) != RTP_OK) {
|
||||
LOG_WARN("Failed to initialize SRTCP for media stream!");
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (!(rtcp_ = new uvg_rtp::rtcp(rtp_, srtcp_, ctx_config_.flags))) {
|
||||
delete rtp_;
|
||||
delete pkt_dispatcher_;
|
||||
|
|
|
@ -30,10 +30,17 @@ uvg_rtp::rtcp::rtcp(uvg_rtp::rtp *rtp, int flags):
|
|||
clock_start_ = 0;
|
||||
rtp_ts_start_ = 0;
|
||||
runner_ = nullptr;
|
||||
srtcp_ = nullptr;
|
||||
|
||||
zero_stats(&our_stats);
|
||||
}
|
||||
|
||||
uvg_rtp::rtcp::rtcp(uvg_rtp::rtp *rtp, uvg_rtp::srtcp *srtcp, int flags):
|
||||
rtcp(rtp, flags)
|
||||
{
|
||||
srtcp_ = srtcp;
|
||||
}
|
||||
|
||||
uvg_rtp::rtcp::~rtcp()
|
||||
{
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
#endif
|
||||
|
||||
uvg_rtp::base_srtp::base_srtp():
|
||||
srtp_ctx_(),
|
||||
srtp_ctx_(new uvg_rtp::srtp_ctx_t),
|
||||
use_null_cipher_(false),
|
||||
authenticate_rtp_(false)
|
||||
{
|
||||
|
@ -30,7 +30,7 @@ bool uvg_rtp::base_srtp::authenticate_rtp()
|
|||
return authenticate_rtp_;
|
||||
}
|
||||
|
||||
uvg_rtp::srtp_ctx_t& uvg_rtp::base_srtp::get_ctx()
|
||||
uvg_rtp::srtp_ctx_t *uvg_rtp::base_srtp::get_ctx()
|
||||
{
|
||||
return srtp_ctx_;
|
||||
}
|
||||
|
@ -72,24 +72,24 @@ rtp_error_t uvg_rtp::base_srtp::create_iv(uint8_t *out, uint32_t ssrc, uint64_t
|
|||
|
||||
rtp_error_t uvg_rtp::base_srtp::init(int type, int flags)
|
||||
{
|
||||
srtp_ctx_.roc = 0;
|
||||
srtp_ctx_.type = type;
|
||||
srtp_ctx_.enc = AES_128;
|
||||
srtp_ctx_.hmac = HMAC_SHA1;
|
||||
srtp_ctx_->roc = 0;
|
||||
srtp_ctx_->type = type;
|
||||
srtp_ctx_->enc = AES_128;
|
||||
srtp_ctx_->hmac = HMAC_SHA1;
|
||||
|
||||
srtp_ctx_.mki_size = 0;
|
||||
srtp_ctx_.mki_present = false;
|
||||
srtp_ctx_.mki = nullptr;
|
||||
srtp_ctx_->mki_size = 0;
|
||||
srtp_ctx_->mki_present = false;
|
||||
srtp_ctx_->mki = nullptr;
|
||||
|
||||
srtp_ctx_.master_key = srtp_ctx_.key_ctx.master.local_key;
|
||||
srtp_ctx_.master_salt = srtp_ctx_.key_ctx.master.local_salt;
|
||||
srtp_ctx_.mk_cnt = 0;
|
||||
srtp_ctx_->master_key = srtp_ctx_->key_ctx.master.local_key;
|
||||
srtp_ctx_->master_salt = srtp_ctx_->key_ctx.master.local_salt;
|
||||
srtp_ctx_->mk_cnt = 0;
|
||||
|
||||
srtp_ctx_.n_e = AES_KEY_LENGTH;
|
||||
srtp_ctx_.n_a = HMAC_KEY_LENGTH;
|
||||
srtp_ctx_->n_e = AES_KEY_LENGTH;
|
||||
srtp_ctx_->n_a = HMAC_KEY_LENGTH;
|
||||
|
||||
srtp_ctx_.s_l = 0;
|
||||
srtp_ctx_.replay = nullptr;
|
||||
srtp_ctx_->s_l = 0;
|
||||
srtp_ctx_->replay = nullptr;
|
||||
|
||||
use_null_cipher_ = !!(flags & RCE_SRTP_NULL_CIPHER);
|
||||
authenticate_rtp_ = !!(flags & RCE_SRTP_AUTHENTICATE_RTP);
|
||||
|
@ -111,46 +111,46 @@ rtp_error_t uvg_rtp::base_srtp::init(int type, int flags)
|
|||
/* Local aka encryption keys */
|
||||
(void)derive_key(
|
||||
label_enc,
|
||||
srtp_ctx_.key_ctx.master.local_key,
|
||||
srtp_ctx_.key_ctx.master.local_salt,
|
||||
srtp_ctx_.key_ctx.local.enc_key,
|
||||
srtp_ctx_->key_ctx.master.local_key,
|
||||
srtp_ctx_->key_ctx.master.local_salt,
|
||||
srtp_ctx_->key_ctx.local.enc_key,
|
||||
AES_KEY_LENGTH
|
||||
);
|
||||
(void)derive_key(
|
||||
label_auth,
|
||||
srtp_ctx_.key_ctx.master.local_key,
|
||||
srtp_ctx_.key_ctx.master.local_salt,
|
||||
srtp_ctx_.key_ctx.local.auth_key,
|
||||
srtp_ctx_->key_ctx.master.local_key,
|
||||
srtp_ctx_->key_ctx.master.local_salt,
|
||||
srtp_ctx_->key_ctx.local.auth_key,
|
||||
AES_KEY_LENGTH
|
||||
);
|
||||
(void)derive_key(
|
||||
label_salt,
|
||||
srtp_ctx_.key_ctx.master.local_key,
|
||||
srtp_ctx_.key_ctx.master.local_salt,
|
||||
srtp_ctx_.key_ctx.local.salt_key,
|
||||
srtp_ctx_->key_ctx.master.local_key,
|
||||
srtp_ctx_->key_ctx.master.local_salt,
|
||||
srtp_ctx_->key_ctx.local.salt_key,
|
||||
SALT_LENGTH
|
||||
);
|
||||
|
||||
/* Remote aka decryption keys */
|
||||
(void)derive_key(
|
||||
label_enc,
|
||||
srtp_ctx_.key_ctx.master.remote_key,
|
||||
srtp_ctx_.key_ctx.master.remote_salt,
|
||||
srtp_ctx_.key_ctx.remote.enc_key,
|
||||
srtp_ctx_->key_ctx.master.remote_key,
|
||||
srtp_ctx_->key_ctx.master.remote_salt,
|
||||
srtp_ctx_->key_ctx.remote.enc_key,
|
||||
AES_KEY_LENGTH
|
||||
);
|
||||
(void)derive_key(
|
||||
label_auth,
|
||||
srtp_ctx_.key_ctx.master.remote_key,
|
||||
srtp_ctx_.key_ctx.master.remote_salt,
|
||||
srtp_ctx_.key_ctx.remote.auth_key,
|
||||
srtp_ctx_->key_ctx.master.remote_key,
|
||||
srtp_ctx_->key_ctx.master.remote_salt,
|
||||
srtp_ctx_->key_ctx.remote.auth_key,
|
||||
AES_KEY_LENGTH
|
||||
);
|
||||
(void)derive_key(
|
||||
label_salt,
|
||||
srtp_ctx_.key_ctx.master.remote_key,
|
||||
srtp_ctx_.key_ctx.master.remote_salt,
|
||||
srtp_ctx_.key_ctx.remote.salt_key,
|
||||
srtp_ctx_->key_ctx.master.remote_key,
|
||||
srtp_ctx_->key_ctx.master.remote_salt,
|
||||
srtp_ctx_->key_ctx.remote.salt_key,
|
||||
SALT_LENGTH
|
||||
);
|
||||
|
||||
|
@ -166,10 +166,10 @@ rtp_error_t uvg_rtp::base_srtp::init_zrtp(int type, int flags, uvg_rtp::rtp *rtp
|
|||
|
||||
/* ZRTP key derivation function expects the keys lengths to be given in bits */
|
||||
rtp_error_t ret = zrtp->get_srtp_keys(
|
||||
srtp_ctx_.key_ctx.master.local_key, AES_KEY_LENGTH * 8,
|
||||
srtp_ctx_.key_ctx.master.remote_key, AES_KEY_LENGTH * 8,
|
||||
srtp_ctx_.key_ctx.master.local_salt, SALT_LENGTH * 8,
|
||||
srtp_ctx_.key_ctx.master.remote_salt, SALT_LENGTH * 8
|
||||
srtp_ctx_->key_ctx.master.local_key, AES_KEY_LENGTH * 8,
|
||||
srtp_ctx_->key_ctx.master.remote_key, AES_KEY_LENGTH * 8,
|
||||
srtp_ctx_->key_ctx.master.local_salt, SALT_LENGTH * 8,
|
||||
srtp_ctx_->key_ctx.master.remote_salt, SALT_LENGTH * 8
|
||||
);
|
||||
|
||||
if (ret != RTP_OK) {
|
||||
|
@ -185,12 +185,11 @@ rtp_error_t uvg_rtp::base_srtp::init_user(int type, int flags, uint8_t *key, uin
|
|||
if (!key || !salt)
|
||||
return RTP_INVALID_VALUE;
|
||||
|
||||
memcpy(srtp_ctx_.key_ctx.master.local_key, key, AES_KEY_LENGTH);
|
||||
memcpy(srtp_ctx_.key_ctx.master.remote_key, key, AES_KEY_LENGTH);
|
||||
memcpy(srtp_ctx_.key_ctx.master.local_salt, salt, SALT_LENGTH);
|
||||
memcpy(srtp_ctx_.key_ctx.master.remote_salt, salt, SALT_LENGTH);
|
||||
memcpy(srtp_ctx_->key_ctx.master.local_key, key, AES_KEY_LENGTH);
|
||||
memcpy(srtp_ctx_->key_ctx.master.remote_key, key, AES_KEY_LENGTH);
|
||||
memcpy(srtp_ctx_->key_ctx.master.local_salt, salt, SALT_LENGTH);
|
||||
memcpy(srtp_ctx_->key_ctx.master.remote_salt, salt, SALT_LENGTH);
|
||||
|
||||
/* TODO: why srtp keys are derived using zrtp kdf? */
|
||||
return init(type, flags);
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -24,12 +24,12 @@ rtp_error_t uvg_rtp::srtcp::encrypt(uint32_t ssrc, uint16_t seq, uint8_t *buffer
|
|||
|
||||
uint8_t iv[16] = { 0 };
|
||||
|
||||
if (create_iv(iv, ssrc, seq, srtp_ctx_.key_ctx.local.salt_key) != RTP_OK) {
|
||||
if (create_iv(iv, ssrc, seq, srtp_ctx_->key_ctx.local.salt_key) != RTP_OK) {
|
||||
LOG_ERROR("Failed to create IV, unable to encrypt the RTP packet!");
|
||||
return RTP_INVALID_VALUE;
|
||||
}
|
||||
|
||||
uvg_rtp::crypto::aes::ctr ctr(srtp_ctx_.key_ctx.local.enc_key, sizeof(srtp_ctx_.key_ctx.local.enc_key), iv);
|
||||
uvg_rtp::crypto::aes::ctr ctr(srtp_ctx_->key_ctx.local.enc_key, sizeof(srtp_ctx_->key_ctx.local.enc_key), iv);
|
||||
ctr.encrypt(buffer, buffer, len);
|
||||
|
||||
return RTP_OK;
|
||||
|
@ -40,16 +40,16 @@ rtp_error_t uvg_rtp::srtcp::decrypt(uint32_t ssrc, uint32_t seq, uint8_t *buffer
|
|||
uint8_t iv[16] = { 0 };
|
||||
uint64_t digest = 0;
|
||||
|
||||
if (create_iv(iv, ssrc, seq, srtp_ctx_.key_ctx.remote.salt_key) != RTP_OK) {
|
||||
if (create_iv(iv, ssrc, seq, srtp_ctx_->key_ctx.remote.salt_key) != RTP_OK) {
|
||||
LOG_ERROR("Failed to create IV, unable to encrypt the RTP packet!");
|
||||
return RTP_INVALID_VALUE;
|
||||
}
|
||||
|
||||
uvg_rtp::crypto::aes::ctr ctr(srtp_ctx_.key_ctx.remote.enc_key, sizeof(srtp_ctx_.key_ctx.remote.enc_key), iv);
|
||||
uvg_rtp::crypto::aes::ctr ctr(srtp_ctx_->key_ctx.remote.enc_key, sizeof(srtp_ctx_->key_ctx.remote.enc_key), iv);
|
||||
|
||||
/* ... otherwise calculate authentication tag for the packet
|
||||
* and compare it against the one we received */
|
||||
auto hmac_sha1 = uvg_rtp::crypto::hmac::sha1(srtp_ctx_.key_ctx.remote.auth_key, AES_KEY_LENGTH);
|
||||
auto hmac_sha1 = uvg_rtp::crypto::hmac::sha1(srtp_ctx_->key_ctx.remote.auth_key, AES_KEY_LENGTH);
|
||||
|
||||
hmac_sha1.update(buffer, size - AUTH_TAG_LENGTH - SRTCP_INDEX_LENGTH);
|
||||
hmac_sha1.final((uint8_t *)&digest);
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
#include <cstring>
|
||||
#include <iostream>
|
||||
|
||||
/* #include "srtp.hh" */
|
||||
#include "srtp/base.hh"
|
||||
#include "srtp/srtp.hh"
|
||||
|
||||
|
@ -25,18 +24,18 @@ rtp_error_t uvg_rtp::srtp::encrypt(uint32_t ssrc, uint16_t seq, uint8_t *buffer,
|
|||
return RTP_OK;
|
||||
|
||||
uint8_t iv[16] = { 0 };
|
||||
uint64_t index = (((uint64_t)srtp_ctx_.roc) << 16) + seq;
|
||||
uint64_t index = (((uint64_t)srtp_ctx_->roc) << 16) + seq;
|
||||
|
||||
/* Sequence number has wrapped around, update Roll-over Counter */
|
||||
if (seq == 0xffff)
|
||||
srtp_ctx_.roc++;
|
||||
srtp_ctx_->roc++;
|
||||
|
||||
if (create_iv(iv, ssrc, index, srtp_ctx_.key_ctx.local.salt_key) != RTP_OK) {
|
||||
if (create_iv(iv, ssrc, index, srtp_ctx_->key_ctx.local.salt_key) != RTP_OK) {
|
||||
LOG_ERROR("Failed to create IV, unable to encrypt the RTP packet!");
|
||||
return RTP_INVALID_VALUE;
|
||||
}
|
||||
|
||||
uvg_rtp::crypto::aes::ctr ctr(srtp_ctx_.key_ctx.local.enc_key, sizeof(srtp_ctx_.key_ctx.local.enc_key), iv);
|
||||
uvg_rtp::crypto::aes::ctr ctr(srtp_ctx_->key_ctx.local.enc_key, sizeof(srtp_ctx_->key_ctx.local.enc_key), iv);
|
||||
ctr.encrypt(buffer, buffer, len);
|
||||
|
||||
return RTP_OK;
|
||||
|
@ -47,7 +46,7 @@ rtp_error_t uvg_rtp::srtp::recv_packet_handler(void *arg, int flags, frame::rtp_
|
|||
(void)flags;
|
||||
|
||||
uvg_rtp::srtp *srtp = (uvg_rtp::srtp *)arg;
|
||||
uvg_rtp::srtp_ctx_t ctx = srtp->get_ctx();
|
||||
uvg_rtp::srtp_ctx_t *ctx = srtp->get_ctx();
|
||||
uvg_rtp::frame::rtp_frame *frame = *out;
|
||||
|
||||
if (srtp->use_null_cipher())
|
||||
|
@ -56,19 +55,19 @@ rtp_error_t uvg_rtp::srtp::recv_packet_handler(void *arg, int flags, frame::rtp_
|
|||
uint8_t iv[16] = { 0 };
|
||||
uint16_t seq = frame->header.seq;
|
||||
uint32_t ssrc = frame->header.ssrc;
|
||||
uint64_t index = (((uint64_t)ctx.roc) << 16) + seq;
|
||||
uint64_t index = (((uint64_t)ctx->roc) << 16) + seq;
|
||||
uint64_t digest = 0;
|
||||
|
||||
/* Sequence number has wrapped around, update Roll-over Counter */
|
||||
if (seq == 0xffff)
|
||||
ctx.roc++;
|
||||
ctx->roc++;
|
||||
|
||||
if (srtp->create_iv(iv, ssrc, index, ctx.key_ctx.remote.salt_key) != RTP_OK) {
|
||||
if (srtp->create_iv(iv, ssrc, index, ctx->key_ctx.remote.salt_key) != RTP_OK) {
|
||||
LOG_ERROR("Failed to create IV, unable to encrypt the RTP packet!");
|
||||
return RTP_INVALID_VALUE;
|
||||
}
|
||||
|
||||
uvg_rtp::crypto::aes::ctr ctr(ctx.key_ctx.remote.enc_key, sizeof(ctx.key_ctx.remote.enc_key), iv);
|
||||
uvg_rtp::crypto::aes::ctr ctr(ctx->key_ctx.remote.enc_key, sizeof(ctx->key_ctx.remote.enc_key), iv);
|
||||
|
||||
/* exit early if RTP packet authentication is disabled... */
|
||||
if (!srtp->authenticate_rtp()) {
|
||||
|
@ -78,10 +77,10 @@ rtp_error_t uvg_rtp::srtp::recv_packet_handler(void *arg, int flags, frame::rtp_
|
|||
|
||||
/* ... otherwise calculate authentication tag for the packet
|
||||
* and compare it against the one we received */
|
||||
auto hmac_sha1 = uvg_rtp::crypto::hmac::sha1(ctx.key_ctx.remote.auth_key, AES_KEY_LENGTH);
|
||||
auto hmac_sha1 = uvg_rtp::crypto::hmac::sha1(ctx->key_ctx.remote.auth_key, AES_KEY_LENGTH);
|
||||
|
||||
hmac_sha1.update((uint8_t *)frame, frame->payload_len - AUTH_TAG_LENGTH);
|
||||
hmac_sha1.update((uint8_t *)&ctx.roc, sizeof(ctx.roc));
|
||||
hmac_sha1.update((uint8_t *)&ctx->roc, sizeof(ctx->roc));
|
||||
hmac_sha1.final((uint8_t *)&digest);
|
||||
|
||||
if (memcmp(&digest, &frame[frame->payload_len - AUTH_TAG_LENGTH], AUTH_TAG_LENGTH)) {
|
||||
|
@ -122,12 +121,12 @@ rtp_error_t uvg_rtp::srtp::send_packet_handler(void *arg, uvg_rtp::buf_vec& buff
|
|||
return RTP_OK;
|
||||
|
||||
/* create authentication tag for the packet and push it to the vector buffer */
|
||||
auto hmac_sha1 = uvg_rtp::crypto::hmac::sha1(ctx.key_ctx.local.auth_key, AES_KEY_LENGTH);
|
||||
auto hmac_sha1 = uvg_rtp::crypto::hmac::sha1(ctx->key_ctx.local.auth_key, AES_KEY_LENGTH);
|
||||
|
||||
for (size_t i = 0; i < buffers.size() - 1; ++i)
|
||||
hmac_sha1.update((uint8_t *)buffers[i].second, buffers[i].first);
|
||||
|
||||
hmac_sha1.update((uint8_t *)&ctx.roc, sizeof(ctx.roc));
|
||||
hmac_sha1.update((uint8_t *)&ctx->roc, sizeof(ctx->roc));
|
||||
hmac_sha1.final((uint8_t *)buffers[buffers.size() - 1].second);
|
||||
|
||||
return ret;
|
||||
|
|
Loading…
Reference in New Issue