Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Applied fixes for crypto in RX-to-TX cloning #365

Merged
merged 16 commits into from
Jun 12, 2018

Conversation

ethouris
Copy link
Collaborator

@ethouris ethouris commented Apr 30, 2018

Fixes:

  1. The HaiCrypt_Create function was extracted the major part, common for RX and TX direction into a new function sHaiCrypt_PrepareHandle.
  2. Added a function that extracts the HaiCrypt_Cfg type object from the RX crypto after it is initialized by KMREQ message.
  3. Added a function, hcrypt_Tx_CloneKey, which is almost a full copy of hcrypt_Tx_Rekey, except that instead of generating a random byte sequence for SEK and SALT, it copies them from the given RX crypto. The KEK generation based on SALT and passphrase, as well as all other initialization activities remain as they were in Rekey function.
  4. The HaiCrypt_Clone function for a case when target is a TX crypto, uses the following method:
    • Creates the extracted configuration from RX
    • Calls sHaiCrypt_PrepareHandle, which is the most common part with HaiCrypt_Create, except the last part that is direction-specific
    • The rest of TX crypto initialization part was copied from that in HaiCrypt_Clone, with the exception that the hcrypt_Tx_Rekey call was replaced with hcrypt_Tx_CloneKey
  5. Fixed in sendKeysToPeer so that this may be called also when the agent is HSD_RESPONDER, as long as the regen is REGEN_KM, which means that this is done while transmission, not during the handshake
  6. When running in handshake mode (bidirectional), after successful processing into RX and cloning into TX, the incoming KMX message is recorded in m_SndKmMsg so that it can be used later to craft KMRSP message without having the incoming KMREQ at hand

@@ -100,6 +100,67 @@ int hcryptCtx_Tx_Rekey(hcrypt_Session *crypto, hcrypt_Ctx *ctx)
return(0);
}

int hcryptCtx_Tx_CloneKey(hcrypt_Session *crypto, hcrypt_Ctx *ctx, const hcrypt_Session* cryptoSrc)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tabs vs spaces throughout this function.

@@ -129,13 +190,16 @@ int hcryptCtx_Tx_Refresh(hcrypt_Session *crypto)

/* 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);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tabs vs spaces

@@ -271,6 +335,10 @@ int hcryptCtx_Tx_ManageKM(hcrypt_Session *crypto)

ASSERT(NULL != ctx);

HCRYPT_LOG(LOG_DEBUG, "KM[%d] KEY STATUS: pkt_cnt=%u against ref.rate=%u and pre.announce=%u\n",
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tabs vs spaces

srtcore/crypto.h Outdated
@@ -118,16 +118,26 @@ class CCryptoControl

const unsigned char* getKmMsg_data(size_t ki) const { return m_SndKmMsg[ki].Msg; }
size_t getKmMsg_size(size_t ki) const { return m_SndKmMsg[ki].MsgLen; }
bool getKmMsg_needSend(size_t ki) const
bool getKmMsg_needSend(size_t ki, bool runtime) const
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

'runtime' is always false?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The plan was to use these functions also in CCryptoControl::sendKeysToPeer and then move this whole function to CUDT in order to avoid reverse-call to CUDT::sendSrtMsg (another refactoring put aside). As this function is in CCryptoControl, it can use direct access to the "KmMsg" things instead of this function, but when moved to CUDT it will have to use them, and then the runtime parameter would have to be true. I could remove this parameter and associated code, but I really wouldn't like to lose it because if there happens next time the need to use them at the "during transmission" stage, the developer may forget the correct use of it in this situation and cause another hard to find bug.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK. Could you please add a comment explaining the function of the 'runtime' parameter for now? Its name alone does not give enough insight to what the parameter does or how it needs to be configured.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure.

srtcore/crypto.h Outdated
}

void getKmMsg_markSent(size_t ki)
void getKmMsg_markSent(size_t ki, bool runtime)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

'runtime' is always false?

int HaiCrypt_Create(const HaiCrypt_Cfg *cfg, HaiCrypt_Handle *phhc)
static const char* DumpCfgFlags(int flags)
{
static char buf[4096];
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please avoid returning non-const static buffers from a function. There is really no need for this: just pass destination buffer and its length as arguments.

@@ -41,18 +41,16 @@ int HaiCrypt_SetLogLevel(int level, int logfa)

#if ENABLE_HAICRYPT_LOGGING

static const char* DumpCfgFlags(int flags)
static const char* DumpCfgFlags(int flags, char* buf)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The buffer length needs to be passed as well and checked for buffer overruns on buffer access.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not a public function, and it's predicted to be used only for logging purposes, and logging in this FA must be turned on explicitly by a distinct option (that is, this function will not be used, unless someone makes a special build for development purposes only, with a special option, that is also warned about security concerns when used).

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, as this is shared with #359, the problem will be solved there, and this PR remerged after this fix, so this problem should disappear.

Copy link

@StephaneStH StephaneStH left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess the comments below were never sent out... Let's see if this triggers the sending....

hcrypt_Session *crypto;
HaiCrypt_CryptoDir tx = (HaiCrypt_CryptoDir)(HAICRYPT_CFG_F_TX & cfg->flags);

*phhc = NULL;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since we have assert on cfg not being NULL, maybe an assert for phhc before writing to it would be good too.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right. Moreover, the assertion for cfg is kinda useless if done after the use. Fixing.

HCRYPT_LOG(LOG_ERR, "invalid secret passphrase length (%d)\n", (int)cfg->secret.len);
return(-1);
} else if ((HAICRYPT_SECTYP_PRESHARED == cfg->secret.typ)
&& (16 != cfg->key_len) /* SEK length */

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unless I am missing something, this test appears redundant with what is at line 221...

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is an old code, so I paid no attention on it. Yes, it looks like this condition will be always false (stating that any true part in the key length checking has been caught in this previous one). Removing.

} else { /* Receiver */
mem_buf = (unsigned char *)cryptoClone;
mem_buf += sizeof(*cryptoClone);
memset(cryptoClone, 0, sizeof(*cryptoClone));

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

memset looks superfluous since there is a memcpy over the same exact area right after.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right. memset probably was earlier for something else, or copying was not exactly to the whole object.

size_t maxlen = 1024 - (pbuf - buf_secret) - 5;
if (cfg->secret.len > maxlen)
{
memcpy(pbuf, (char*)cfg->secret.str, maxlen);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The cast here is not needed, you have a similar memcpy a few lines later without it.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function has been rewritten to C++, so it's no longer a problem.

@@ -41,18 +41,16 @@ int HaiCrypt_SetLogLevel(int level, int logfa)

#if ENABLE_HAICRYPT_LOGGING

static const char* DumpCfgFlags(int flags)
static const char* DumpCfgFlags(int flags, char* buf)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The idea was I believe to pass a buffer AND it's length/size. DumpCfgFlags has now no idea of the limits when writing to that buf.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, the idea was to pass the buffer that is always large enough to hold a string spanning for one line. Yes, it looks ugly, so the whole function has been rewritten to C++, it uses std::ostringstream and so the buffer size checking is off head.

@rndi rndi merged commit febe51f into Haivision:master Jun 12, 2018
@ethouris ethouris deleted the dev-fix-rendezvous-processing-crypto branch January 23, 2019 12:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants