create next tagset

This commit is contained in:
orignal 2020-04-26 19:27:31 -04:00
parent 7f859978dd
commit 51e3d5f7bc
2 changed files with 72 additions and 7 deletions

View file

@ -38,7 +38,11 @@ namespace garlic
{
i2p::crypto::HKDF (m_KeyData.GetSessTagCK (), m_SessTagConstant, 32, "SessionTagKeyGen", m_KeyData.buf); // [sessTag_ck, tag] = HKDF(sessTag_chainkey, SESSTAG_CONSTANT, "SessionTagKeyGen", 64)
m_NextIndex++;
if (m_NextIndex >= 65535) m_NextIndex = 0; // TODO: dirty hack, should create new tagset
if (m_NextIndex >= 65535)
{
LogPrint (eLogError, "Garlic: Tagset ", GetTagSetID (), " is empty");
return 0;
}
return m_KeyData.GetTag ();
}
@ -251,7 +255,26 @@ namespace garlic
uint8_t flag = buf[0]; buf++; // flag
if (flag & ECIESX25519_NEXT_KEY_REVERSE_KEY_FLAG)
{
// TODO: implement
if (!m_NextSendRatchet) return;
uint16_t keyID = bufbe16toh (buf); buf += 2; // keyID
if (((!m_NextSendRatchet->newKey || !m_NextSendRatchet->keyID) && keyID == m_NextSendRatchet->keyID) ||
(m_NextSendRatchet->newKey && keyID == m_NextSendRatchet->keyID -1))
{
if (flag & ECIESX25519_NEXT_KEY_REQUEST_REVERSE_KEY_FLAG)
memcpy (m_NextSendRatchet->remote, buf, 32);
uint8_t sharedSecret[32], tagsetKey[32];
m_NextSendRatchet->key.Agree (m_NextSendRatchet->remote, sharedSecret);
i2p::crypto::HKDF (sharedSecret, nullptr, 0, "XDHRatchetTagSet", tagsetKey, 32); // tagsetKey = HKDF(sharedSecret, ZEROLEN, "XDHRatchetTagSet", 32)
auto newTagset = std::make_shared<RatchetTagSet> (shared_from_this ());
newTagset->SetTagSetID (1 + m_NextSendRatchet->keyID + keyID);
newTagset->DHInitialize (m_SendTagset->GetNextRootKey (), tagsetKey);
newTagset->NextSessionTagRatchet ();
m_SendTagset = newTagset;
m_SendForwardKey = false;
LogPrint (eLogDebug, "Garlic: next send tagset ", newTagset->GetTagSetID (), " created");
}
else
LogPrint (eLogDebug, "Garlic: Unexpected next key ", keyID);
}
else
{
@ -292,6 +315,26 @@ namespace garlic
LogPrint (eLogDebug, "Garlic: next receive tagset ", tagsetID, " created");
}
}
void ECIESX25519AEADRatchetSession::NewNextSendRatchet ()
{
auto newTagset = new DHRatchet ();
if (m_NextSendRatchet)
{
newTagset->keyID = m_NextSendRatchet->keyID;
if (!newTagset->newKey || !newTagset->keyID)
{
newTagset->keyID++;
newTagset->newKey = true;
}
else
newTagset->newKey = false;
}
if (newTagset->newKey)
newTagset->key.GenerateKeys ();
m_NextSendRatchet.reset (newTagset);
m_SendForwardKey = true;
}
bool ECIESX25519AEADRatchetSession::NewOutgoingSessionMessage (const uint8_t * payload, size_t len, uint8_t * out, size_t outLen)
{
@ -487,7 +530,9 @@ namespace garlic
{
LogPrint (eLogWarning, "Garlic: Payload section AEAD encryption failed");
return false;
}
}
if (index >= ECIESX25519_TAGSET_MAX_NUM_TAGS && !m_SendForwardKey)
NewNextSendRatchet ();
return true;
}
@ -601,6 +646,11 @@ namespace garlic
payloadLen += 6;
if (m_NextReceiveRatchet->newKey) payloadLen += 32;
}
if (m_SendForwardKey)
{
payloadLen += 6;
if (m_NextSendRatchet->newKey) payloadLen += 32;
}
uint8_t paddingSize;
RAND_bytes (&paddingSize, 1);
paddingSize &= 0x0F; paddingSize++; // 1 - 16
@ -662,6 +712,20 @@ namespace garlic
}
m_SendReverseKey = false;
}
if (m_SendForwardKey)
{
v[offset] = eECIESx25519BlkNextKey; offset++;
htobe16buf (v.data () + offset, m_NextSendRatchet->newKey ? 35 : 3); offset += 2;
v[offset] = m_NextSendRatchet->newKey ? ECIESX25519_NEXT_KEY_KEY_PRESENT_FLAG : ECIESX25519_NEXT_KEY_REQUEST_REVERSE_KEY_FLAG;
if (!m_NextSendRatchet->keyID) v[offset] |= ECIESX25519_NEXT_KEY_REQUEST_REVERSE_KEY_FLAG; // for first key only
offset++; // flag
htobe16buf (v.data () + offset, m_NextSendRatchet->keyID); offset += 2; // keyid
if (m_NextSendRatchet->newKey)
{
memcpy (v.data () + offset, m_NextSendRatchet->key.GetPublicKey (), 32);
offset += 32; // public key
}
}
// padding
v[offset] = eECIESx25519BlkPadding; offset++;
htobe16buf (v.data () + offset, paddingSize); offset += 2;