mirror of
https://github.com/taigrr/arduinolibs
synced 2025-01-18 04:33:12 -08:00
Test cases and bug fixes for Noise handshakes
This commit is contained in:
@@ -458,7 +458,7 @@ bool NoiseDHState_Curve25519::hashPublicKey
|
||||
case Noise::RemoteStatic25519PublicKey:
|
||||
if (!(st.flags & HAVE_25519_REMOTE_STATIC_PUBLIC))
|
||||
break;
|
||||
sym->mixHash(st.re, sizeof(st.re));
|
||||
sym->mixHash(st2.rs, sizeof(st2.rs));
|
||||
return true;
|
||||
default:
|
||||
return NoiseDHState_Curve25519_EphemOnly::hashPublicKey(sym, id);
|
||||
|
||||
@@ -632,8 +632,10 @@ void NoiseHandshakeState::write_ee(NoiseHandshakeState::Packet &packet)
|
||||
*/
|
||||
void NoiseHandshakeState::write_es(NoiseHandshakeState::Packet &packet)
|
||||
{
|
||||
if (!dhState()->hasParameter(Noise::RemoteStaticPublicKey)) {
|
||||
// We don't have a remote static key. It probably should have
|
||||
if (!dhState()->hasParameter
|
||||
(pty == Noise::Initiator ? Noise::RemoteStaticPublicKey
|
||||
: Noise::LocalStaticPublicKey)) {
|
||||
// We don't have the relevent static key. It probably should have
|
||||
// been provided ahead of time when the handshake started.
|
||||
packet.error = true;
|
||||
return;
|
||||
@@ -657,8 +659,10 @@ void NoiseHandshakeState::write_es(NoiseHandshakeState::Packet &packet)
|
||||
*/
|
||||
void NoiseHandshakeState::write_se(NoiseHandshakeState::Packet &packet)
|
||||
{
|
||||
if (!dhState()->hasParameter(Noise::LocalStaticPrivateKey)) {
|
||||
// We don't have a local static key. It probably should have
|
||||
if (!dhState()->hasParameter
|
||||
(pty == Noise::Initiator ? Noise::LocalStaticPublicKey
|
||||
: Noise::RemoteStaticPublicKey)) {
|
||||
// We don't have a relevant static key. It probably should have
|
||||
// been provided ahead of time when the handshake started.
|
||||
packet.error = true;
|
||||
return;
|
||||
@@ -744,7 +748,7 @@ void NoiseHandshakeState::read_s(NoiseHandshakeState::Packet &packet)
|
||||
int size = symmetricState()->decryptAndHash
|
||||
(s, len, packet.data + packet.posn, fullLen);
|
||||
if (size > 0) {
|
||||
packet.posn += size;
|
||||
packet.posn += fullLen;
|
||||
if (!dhState()->setParameter(Noise::RemoteStaticPublicKey, s, len))
|
||||
packet.error = true;
|
||||
} else {
|
||||
@@ -804,6 +808,28 @@ void NoiseHandshakeState::read_s(NoiseHandshakeState::Packet &packet)
|
||||
* \sa write_ss()
|
||||
*/
|
||||
|
||||
/**
|
||||
* \brief Hashes a public key from the pre-message.
|
||||
*
|
||||
* \param packet The handshake packet that is being processed.
|
||||
* \param initiator The public key to hash if party() is Noise::Initiator.
|
||||
* \param responder The public key to hash if party() is Noise::Responder.
|
||||
*
|
||||
* The handshake will fail if the required key is not present.
|
||||
*
|
||||
* This function should be called within the subclass's writeTokens() and
|
||||
* readTokens() implementations when message number 0 is processed.
|
||||
*/
|
||||
void NoiseHandshakeState::premessage
|
||||
(NoiseHandshakeState::Packet &packet,
|
||||
Noise::Parameter initiator, Noise::Parameter responder)
|
||||
{
|
||||
if (pty == Noise::Responder)
|
||||
initiator = responder;
|
||||
if (!dhState()->hashPublicKey(symmetricState(), initiator))
|
||||
packet.error = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* \fn void NoiseHandshakeState::setState(Noise::HandshakeState state)
|
||||
* \brief Sets the state of this handshake.
|
||||
|
||||
@@ -107,6 +107,10 @@ protected:
|
||||
void read_se(NoiseHandshakeState::Packet &packet) { write_se(packet); }
|
||||
void read_ss(NoiseHandshakeState::Packet &packet) { write_ss(packet); }
|
||||
|
||||
void premessage
|
||||
(NoiseHandshakeState::Packet &packet,
|
||||
Noise::Parameter initiator, Noise::Parameter responder);
|
||||
|
||||
void setState(Noise::HandshakeState state) { st = state; }
|
||||
|
||||
private:
|
||||
|
||||
@@ -149,9 +149,10 @@ int NoiseSymmetricState_AESGCM_SHA256::encryptAndHash
|
||||
if (st.hasKey) {
|
||||
if (outputSize < 16 || (outputSize - 16) < inputSize)
|
||||
return -1;
|
||||
uint8_t iv[24];
|
||||
uint8_t iv[12];
|
||||
noiseAESGCMFormatIV(iv, st.n);
|
||||
cipher.setIV(iv, sizeof(iv));
|
||||
cipher.addAuthData(st.h, sizeof(st.h));
|
||||
cipher.encrypt(output, input, inputSize);
|
||||
cipher.computeTag(output + inputSize, 16);
|
||||
mixHash(output, inputSize + 16);
|
||||
@@ -174,10 +175,11 @@ int NoiseSymmetricState_AESGCM_SHA256::decryptAndHash
|
||||
if (inputSize < 16 || outputSize < (inputSize - 16))
|
||||
return -1;
|
||||
outputSize = inputSize - 16;
|
||||
mixHash(input, inputSize);
|
||||
uint8_t iv[24];
|
||||
uint8_t iv[12];
|
||||
noiseAESGCMFormatIV(iv, st.n);
|
||||
cipher.setIV(iv, sizeof(iv));
|
||||
cipher.addAuthData(st.h, sizeof(st.h));
|
||||
mixHash(input, inputSize);
|
||||
cipher.decrypt(output, input, outputSize);
|
||||
if (cipher.checkTag(input + outputSize, 16)) {
|
||||
++st.n;
|
||||
|
||||
@@ -126,6 +126,7 @@ int NoiseSymmetricState_ChaChaPoly_BLAKE2s::encryptAndHash
|
||||
uint64_t iv = htole64(st.n);
|
||||
cipher.setKey(st.key, 32);
|
||||
cipher.setIV((const uint8_t *)&iv, sizeof(iv));
|
||||
cipher.addAuthData(st.h, sizeof(st.h));
|
||||
cipher.encrypt(output, input, inputSize);
|
||||
cipher.computeTag(output + inputSize, 16);
|
||||
mixHash(output, inputSize + 16);
|
||||
@@ -148,11 +149,12 @@ int NoiseSymmetricState_ChaChaPoly_BLAKE2s::decryptAndHash
|
||||
if (inputSize < 16 || outputSize < (inputSize - 16))
|
||||
return -1;
|
||||
outputSize = inputSize - 16;
|
||||
mixHash(input, inputSize);
|
||||
ChaChaPoly cipher;
|
||||
uint64_t iv = htole64(st.n);
|
||||
cipher.setKey(st.key, 32);
|
||||
cipher.setIV((const uint8_t *)&iv, sizeof(iv));
|
||||
cipher.addAuthData(st.h, sizeof(st.h));
|
||||
mixHash(input, inputSize);
|
||||
cipher.decrypt(output, input, outputSize);
|
||||
if (cipher.checkTag(input + outputSize, 16)) {
|
||||
++st.n;
|
||||
|
||||
@@ -126,6 +126,7 @@ int NoiseSymmetricState_ChaChaPoly_SHA256::encryptAndHash
|
||||
uint64_t iv = htole64(st.n);
|
||||
cipher.setKey(st.key, 32);
|
||||
cipher.setIV((const uint8_t *)&iv, sizeof(iv));
|
||||
cipher.addAuthData(st.h, sizeof(st.h));
|
||||
cipher.encrypt(output, input, inputSize);
|
||||
cipher.computeTag(output + inputSize, 16);
|
||||
mixHash(output, inputSize + 16);
|
||||
@@ -148,11 +149,12 @@ int NoiseSymmetricState_ChaChaPoly_SHA256::decryptAndHash
|
||||
if (inputSize < 16 || outputSize < (inputSize - 16))
|
||||
return -1;
|
||||
outputSize = inputSize - 16;
|
||||
mixHash(input, inputSize);
|
||||
ChaChaPoly cipher;
|
||||
uint64_t iv = htole64(st.n);
|
||||
cipher.setKey(st.key, 32);
|
||||
cipher.setIV((const uint8_t *)&iv, sizeof(iv));
|
||||
cipher.addAuthData(st.h, sizeof(st.h));
|
||||
mixHash(input, inputSize);
|
||||
cipher.decrypt(output, input, outputSize);
|
||||
if (cipher.checkTag(input + outputSize, 16)) {
|
||||
++st.n;
|
||||
|
||||
@@ -54,6 +54,8 @@ void NoiseHandshakeState_IK::writeTokens
|
||||
(NoiseHandshakeState::Packet &packet, uint8_t msgnum)
|
||||
{
|
||||
if (msgnum == 0) {
|
||||
premessage(packet, Noise::RemoteStaticPublicKey,
|
||||
Noise::LocalStaticPublicKey);
|
||||
write_e(packet);
|
||||
write_es(packet);
|
||||
write_s(packet);
|
||||
@@ -70,6 +72,8 @@ void NoiseHandshakeState_IK::readTokens
|
||||
(NoiseHandshakeState::Packet &packet, uint8_t msgnum)
|
||||
{
|
||||
if (msgnum == 0) {
|
||||
premessage(packet, Noise::RemoteStaticPublicKey,
|
||||
Noise::LocalStaticPublicKey);
|
||||
read_e(packet);
|
||||
read_es(packet);
|
||||
read_s(packet);
|
||||
|
||||
@@ -69,12 +69,6 @@ bool NoiseHandshakeState_XXfallback::startFallback
|
||||
// Start the new handshake.
|
||||
start(party, prologue, prologueLen);
|
||||
|
||||
// Hash the initiator's ephemeral public key from the pre-message.
|
||||
if (party == Noise::Initiator)
|
||||
thisDH->hashPublicKey(symmetricState(), Noise::LocalEphemPublicKey);
|
||||
else
|
||||
thisDH->hashPublicKey(symmetricState(), Noise::RemoteEphemPublicKey);
|
||||
|
||||
// The responder writes first in a XXfallback handshake.
|
||||
setState(party == Noise::Initiator ? Noise::Read : Noise::Write);
|
||||
return true;
|
||||
@@ -91,6 +85,8 @@ void NoiseHandshakeState_XXfallback::writeTokens
|
||||
(NoiseHandshakeState::Packet &packet, uint8_t msgnum)
|
||||
{
|
||||
if (msgnum == 0) {
|
||||
premessage(packet, Noise::LocalEphemPublicKey,
|
||||
Noise::RemoteEphemPublicKey);
|
||||
write_e(packet);
|
||||
write_ee(packet);
|
||||
write_s(packet);
|
||||
@@ -106,6 +102,8 @@ void NoiseHandshakeState_XXfallback::readTokens
|
||||
(NoiseHandshakeState::Packet &packet, uint8_t msgnum)
|
||||
{
|
||||
if (msgnum == 0) {
|
||||
premessage(packet, Noise::LocalEphemPublicKey,
|
||||
Noise::RemoteEphemPublicKey);
|
||||
read_e(packet);
|
||||
read_ee(packet);
|
||||
read_s(packet);
|
||||
|
||||
Reference in New Issue
Block a user