1
0
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:
Rhys Weatherley
2018-06-17 14:48:35 +10:00
parent fa1400ea83
commit 8fd4a994dc
15 changed files with 1559 additions and 22 deletions

View File

@@ -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);

View File

@@ -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.

View File

@@ -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:

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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);

View File

@@ -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);