From 6a71e60d85d0d90ab0b292759963c37a760354b0 Mon Sep 17 00:00:00 2001 From: Rhys Weatherley Date: Thu, 21 Jun 2018 19:28:52 +1000 Subject: [PATCH] Hashing of prologues in sections --- host/Crypto/noise/test-vector.cpp | 4 +-- .../NoiseProtocol/src/NoiseHandshakeState.cpp | 27 ++++++++++++-- .../NoiseProtocol/src/NoiseHandshakeState.h | 4 +-- .../NoiseProtocol/src/NoiseSymmetricState.cpp | 14 ++++++++ .../NoiseProtocol/src/NoiseSymmetricState.h | 2 ++ .../src/NoiseSymmetricState_AESGCM_SHA256.cpp | 35 ++++++++++++++++--- .../src/NoiseSymmetricState_AESGCM_SHA256.h | 12 +++++-- ...NoiseSymmetricState_ChaChaPoly_BLAKE2s.cpp | 34 +++++++++++++++--- .../NoiseSymmetricState_ChaChaPoly_BLAKE2s.h | 12 +++++-- .../NoiseSymmetricState_ChaChaPoly_SHA256.cpp | 34 +++++++++++++++--- .../NoiseSymmetricState_ChaChaPoly_SHA256.h | 12 +++++-- 11 files changed, 166 insertions(+), 24 deletions(-) diff --git a/host/Crypto/noise/test-vector.cpp b/host/Crypto/noise/test-vector.cpp index ebb5ad7c..ac371fb5 100644 --- a/host/Crypto/noise/test-vector.cpp +++ b/host/Crypto/noise/test-vector.cpp @@ -250,8 +250,8 @@ static void test_connection(const TestVector *vec) /* Should be able to start the handshake now on both sides */ initiator->start (Noise::Initiator, vec->init_prologue, vec->init_prologue_len); - responder->start - (Noise::Responder, vec->resp_prologue, vec->resp_prologue_len); + responder->start(Noise::Responder); + responder->addPrologue(vec->resp_prologue, vec->resp_prologue_len); compare(initiator->state(), Noise::Write); compare(responder->state(), Noise::Read); diff --git a/libraries/NoiseProtocol/src/NoiseHandshakeState.cpp b/libraries/NoiseProtocol/src/NoiseHandshakeState.cpp index e7423214..e5de9d8b 100644 --- a/libraries/NoiseProtocol/src/NoiseHandshakeState.cpp +++ b/libraries/NoiseProtocol/src/NoiseHandshakeState.cpp @@ -85,7 +85,11 @@ NoiseHandshakeState::~NoiseHandshakeState() * the application should call split() to obtain the cipher objects to use * to encrypt and decrypt transport messages. * - * \sa state(), write(), read(), split() + * If the prologue is split into multiple sections, then start() can be + * followed by calls to addPrologue() to add the additional sections + * prior to calling write() or read() for the first time. + * + * \sa state(), write(), read(), split(), addPrologue() */ void NoiseHandshakeState::start (Noise::Party party, const void *prologue, size_t prologueLen) @@ -95,7 +99,26 @@ void NoiseHandshakeState::start msgnum = 0; removeKeys(); symmetricState()->initialize(protoName); - symmetricState()->mixHash(prologue, prologueLen); + symmetricState()->mixPrologue(prologue, prologueLen); +} + +/** + * \brief Adds additional prologue data to the handshake. + * + * \param prologue Points to the additional prologue data. + * \param prologueLen Length of the prologue additional data in bytes. + * + * \return Returns true if the data was added, or false if the handshake + * is not in the state just after start(). Once the first write() or read() + * occurs, no further prologue data can be added. + * + * \sa start() + */ +bool NoiseHandshakeState::addPrologue(const void *prologue, size_t prologueLen) +{ + if (st != Noise::Write && st != Noise::Read) + return false; + return symmetricState()->mixPrologue(prologue, prologueLen); } /** diff --git a/libraries/NoiseProtocol/src/NoiseHandshakeState.h b/libraries/NoiseProtocol/src/NoiseHandshakeState.h index 86af8b18..fd66af22 100644 --- a/libraries/NoiseProtocol/src/NoiseHandshakeState.h +++ b/libraries/NoiseProtocol/src/NoiseHandshakeState.h @@ -33,8 +33,8 @@ class NoiseHandshakeState public: virtual ~NoiseHandshakeState(); - virtual void start - (Noise::Party party, const void *prologue = 0, size_t prologueLen = 0); + void start(Noise::Party party, const void *prologue = 0, size_t prologueLen = 0); + bool addPrologue(const void *prologue, size_t prologueLen); Noise::Party party() const { return pty; } Noise::HandshakeState state() const { return st; } diff --git a/libraries/NoiseProtocol/src/NoiseSymmetricState.cpp b/libraries/NoiseProtocol/src/NoiseSymmetricState.cpp index 18a02771..b29f61e5 100644 --- a/libraries/NoiseProtocol/src/NoiseSymmetricState.cpp +++ b/libraries/NoiseProtocol/src/NoiseSymmetricState.cpp @@ -72,6 +72,20 @@ size_t NoiseSymmetricState::macLen() const return 16; } +/** + * \fn bool NoiseSymmetricState::mixPrologue(const void *data, size_t size) + * \brief Mixes input data into the prologue. + * + * \param data Points to the data to be mixed in. + * \param size Number of bytes to mix in. + * + * \return Returns true if the data was mixed, or false if the prologue + * phase has ended (or never began). + * + * This function must be called just after initialize and before any + * other mixing or encryption operation. + */ + /** * \fn void NoiseSymmetricState::mixKey(const void *data, size_t size) * \brief Mixes input data into the chaining key. diff --git a/libraries/NoiseProtocol/src/NoiseSymmetricState.h b/libraries/NoiseProtocol/src/NoiseSymmetricState.h index a1e72d3e..7afc951e 100644 --- a/libraries/NoiseProtocol/src/NoiseSymmetricState.h +++ b/libraries/NoiseProtocol/src/NoiseSymmetricState.h @@ -39,6 +39,8 @@ public: virtual bool hasKey() const = 0; virtual size_t macLen() const; + virtual bool mixPrologue(const void *data, size_t size) = 0; + virtual void mixKey(const void *data, size_t size) = 0; virtual void mixHash(const void *data, size_t size) = 0; virtual void mixKeyAndHash(const void *data, size_t size) = 0; diff --git a/libraries/NoiseProtocol/src/NoiseSymmetricState_AESGCM_SHA256.cpp b/libraries/NoiseProtocol/src/NoiseSymmetricState_AESGCM_SHA256.cpp index f451f95e..0c61bae3 100644 --- a/libraries/NoiseProtocol/src/NoiseSymmetricState_AESGCM_SHA256.cpp +++ b/libraries/NoiseProtocol/src/NoiseSymmetricState_AESGCM_SHA256.cpp @@ -22,7 +22,6 @@ #include "NoiseSymmetricState_AESGCM_SHA256.h" #include "NoiseCipherState_AESGCM.h" -#include "SHA256.h" #include "Crypto.h" #include @@ -38,6 +37,7 @@ NoiseSymmetricState_AESGCM_SHA256::NoiseSymmetricState_AESGCM_SHA256() { st.n = 0; st.hasKey = false; + st.inPrologue = false; } /** @@ -56,12 +56,15 @@ void NoiseSymmetricState_AESGCM_SHA256::initialize memcpy(st.h, protocolName, len); memset(st.h + len, 0, 32 - len); } else { - SHA256 hash; + hash.reset(); hash.update(protocolName, len); hash.finalize(st.h, 32); } memcpy(st.ck, st.h, 32); st.hasKey = false; + hash.reset(); + hash.update(st.h, sizeof(st.h)); + st.inPrologue = true; } bool NoiseSymmetricState_AESGCM_SHA256::hasKey() const @@ -69,10 +72,20 @@ bool NoiseSymmetricState_AESGCM_SHA256::hasKey() const return st.hasKey; } +bool NoiseSymmetricState_AESGCM_SHA256::mixPrologue + (const void *data, size_t size) +{ + if (!st.inPrologue) + return false; + hash.update(data, size); + return true; +} + void NoiseSymmetricState_AESGCM_SHA256::mixKey (const void *data, size_t size) { uint8_t key[32]; + endPrologue(); hmac(key, st.ck, data, size, 0); hmac(st.ck, key, 0, 0, 1); hmac(key, key, st.ck, 32, 2); @@ -85,7 +98,8 @@ void NoiseSymmetricState_AESGCM_SHA256::mixKey void NoiseSymmetricState_AESGCM_SHA256::mixHash (const void *data, size_t size) { - SHA256 hash; + endPrologue(); + hash.reset(); hash.update(st.h, sizeof(st.h)); hash.update(data, size); hash.finalize(st.h, sizeof(st.h)); @@ -96,6 +110,7 @@ void NoiseSymmetricState_AESGCM_SHA256::mixKeyAndHash { uint8_t key[32]; uint8_t temph[32]; + endPrologue(); hmac(key, st.ck, data, size, 0); hmac(st.ck, key, 0, 0, 1); hmac(temph, key, st.ck, 32, 2); @@ -111,6 +126,7 @@ void NoiseSymmetricState_AESGCM_SHA256::mixKeyAndHash void NoiseSymmetricState_AESGCM_SHA256::getHandshakeHash (void *data, size_t size) { + endPrologue(); if (size <= 32) { memcpy(data, st.h, size); } else { @@ -146,6 +162,7 @@ int NoiseSymmetricState_AESGCM_SHA256::encryptAndHash (uint8_t *output, size_t outputSize, const uint8_t *input, size_t inputSize) { + endPrologue(); if (st.hasKey) { if (outputSize < 16 || (outputSize - 16) < inputSize) return -1; @@ -171,6 +188,7 @@ int NoiseSymmetricState_AESGCM_SHA256::decryptAndHash (uint8_t *output, size_t outputSize, const uint8_t *input, size_t inputSize) { + endPrologue(); if (st.hasKey) { if (inputSize < 16 || outputSize < (inputSize - 16)) return -1; @@ -200,6 +218,7 @@ void NoiseSymmetricState_AESGCM_SHA256::split { uint8_t k1[32]; uint8_t k2[32]; + endPrologue(); hmac(k2, st.ck, 0, 0, 0); hmac(k1, k2, 0, 0, 1); hmac(k2, k2, k1, 32, 2); @@ -213,16 +232,24 @@ void NoiseSymmetricState_AESGCM_SHA256::split void NoiseSymmetricState_AESGCM_SHA256::clear() { + cipher.clear(); + hash.clear(); clean(st); st.n = 0; st.hasKey = false; + st.inPrologue = false; +} + +void NoiseSymmetricState_AESGCM_SHA256::doEndPrologue() +{ + st.inPrologue = false; + hash.finalize(st.h, sizeof(st.h)); } void NoiseSymmetricState_AESGCM_SHA256::hmac (uint8_t *output, const uint8_t *key, const void *data, size_t size, uint8_t tag) { - SHA256 hash; hash.resetHMAC(key, 32); hash.update(data, size); if (tag != 0) diff --git a/libraries/NoiseProtocol/src/NoiseSymmetricState_AESGCM_SHA256.h b/libraries/NoiseProtocol/src/NoiseSymmetricState_AESGCM_SHA256.h index de169308..9eb96a41 100644 --- a/libraries/NoiseProtocol/src/NoiseSymmetricState_AESGCM_SHA256.h +++ b/libraries/NoiseProtocol/src/NoiseSymmetricState_AESGCM_SHA256.h @@ -26,6 +26,7 @@ #include "NoiseSymmetricState.h" #include "AES.h" #include "GCM.h" +#include "SHA256.h" class NoiseSymmetricState_AESGCM_SHA256 : public NoiseSymmetricState { @@ -37,6 +38,8 @@ public: bool hasKey() const; + bool mixPrologue(const void *data, size_t size); + void mixKey(const void *data, size_t size); void mixHash(const void *data, size_t size); void mixKeyAndHash(const void *data, size_t size); @@ -56,15 +59,20 @@ public: private: GCM cipher; + SHA256 hash; struct { uint8_t ck[32]; uint8_t h[32]; uint64_t n; bool hasKey; + bool inPrologue; } st; - static void hmac(uint8_t *output, const uint8_t *key, - const void *data, size_t size, uint8_t tag); + void doEndPrologue(); + void endPrologue() { if (st.inPrologue) doEndPrologue(); } + + void hmac(uint8_t *output, const uint8_t *key, + const void *data, size_t size, uint8_t tag); }; #endif diff --git a/libraries/NoiseProtocol/src/NoiseSymmetricState_ChaChaPoly_BLAKE2s.cpp b/libraries/NoiseProtocol/src/NoiseSymmetricState_ChaChaPoly_BLAKE2s.cpp index f3f15d79..58e00dd5 100644 --- a/libraries/NoiseProtocol/src/NoiseSymmetricState_ChaChaPoly_BLAKE2s.cpp +++ b/libraries/NoiseProtocol/src/NoiseSymmetricState_ChaChaPoly_BLAKE2s.cpp @@ -23,7 +23,6 @@ #include "NoiseSymmetricState_ChaChaPoly_BLAKE2s.h" #include "NoiseCipherState_ChaChaPoly.h" #include "ChaChaPoly.h" -#include "BLAKE2s.h" #include "Crypto.h" #include "utility/EndianUtil.h" #include @@ -40,6 +39,7 @@ NoiseSymmetricState_ChaChaPoly_BLAKE2s::NoiseSymmetricState_ChaChaPoly_BLAKE2s() { st.n = 0; st.hasKey = false; + st.inPrologue = false; } /** @@ -58,12 +58,15 @@ void NoiseSymmetricState_ChaChaPoly_BLAKE2s::initialize memcpy(st.h, protocolName, len); memset(st.h + len, 0, 32 - len); } else { - BLAKE2s hash; + hash.reset(); hash.update(protocolName, len); hash.finalize(st.h, 32); } memcpy(st.ck, st.h, 32); st.hasKey = false; + hash.reset(); + hash.update(st.h, sizeof(st.h)); + st.inPrologue = true; } bool NoiseSymmetricState_ChaChaPoly_BLAKE2s::hasKey() const @@ -71,9 +74,19 @@ bool NoiseSymmetricState_ChaChaPoly_BLAKE2s::hasKey() const return st.hasKey; } +bool NoiseSymmetricState_ChaChaPoly_BLAKE2s::mixPrologue + (const void *data, size_t size) +{ + if (!st.inPrologue) + return false; + hash.update(data, size); + return true; +} + void NoiseSymmetricState_ChaChaPoly_BLAKE2s::mixKey (const void *data, size_t size) { + endPrologue(); hmac(st.key, st.ck, data, size, 0); hmac(st.ck, st.key, 0, 0, 1); hmac(st.key, st.key, st.ck, 32, 2); @@ -84,7 +97,8 @@ void NoiseSymmetricState_ChaChaPoly_BLAKE2s::mixKey void NoiseSymmetricState_ChaChaPoly_BLAKE2s::mixHash (const void *data, size_t size) { - BLAKE2s hash; + endPrologue(); + hash.reset(); hash.update(st.h, sizeof(st.h)); hash.update(data, size); hash.finalize(st.h, sizeof(st.h)); @@ -94,6 +108,7 @@ void NoiseSymmetricState_ChaChaPoly_BLAKE2s::mixKeyAndHash (const void *data, size_t size) { uint8_t temph[32]; + endPrologue(); hmac(st.key, st.ck, data, size, 0); hmac(st.ck, st.key, 0, 0, 1); hmac(temph, st.key, st.ck, 32, 2); @@ -107,6 +122,7 @@ void NoiseSymmetricState_ChaChaPoly_BLAKE2s::mixKeyAndHash void NoiseSymmetricState_ChaChaPoly_BLAKE2s::getHandshakeHash (void *data, size_t size) { + endPrologue(); if (size <= 32) { memcpy(data, st.h, size); } else { @@ -119,6 +135,7 @@ int NoiseSymmetricState_ChaChaPoly_BLAKE2s::encryptAndHash (uint8_t *output, size_t outputSize, const uint8_t *input, size_t inputSize) { + endPrologue(); if (st.hasKey) { if (outputSize < 16 || (outputSize - 16) < inputSize) return -1; @@ -145,6 +162,7 @@ int NoiseSymmetricState_ChaChaPoly_BLAKE2s::decryptAndHash (uint8_t *output, size_t outputSize, const uint8_t *input, size_t inputSize) { + endPrologue(); if (st.hasKey) { if (inputSize < 16 || outputSize < (inputSize - 16)) return -1; @@ -175,6 +193,7 @@ void NoiseSymmetricState_ChaChaPoly_BLAKE2s::split { uint8_t k1[32]; uint8_t k2[32]; + endPrologue(); hmac(k2, st.ck, 0, 0, 0); hmac(k1, k2, 0, 0, 1); hmac(k2, k2, k1, 32, 2); @@ -188,16 +207,23 @@ void NoiseSymmetricState_ChaChaPoly_BLAKE2s::split void NoiseSymmetricState_ChaChaPoly_BLAKE2s::clear() { + hash.clear(); clean(st); st.n = 0; st.hasKey = false; + st.inPrologue = false; +} + +void NoiseSymmetricState_ChaChaPoly_BLAKE2s::doEndPrologue() +{ + st.inPrologue = false; + hash.finalize(st.h, sizeof(st.h)); } void NoiseSymmetricState_ChaChaPoly_BLAKE2s::hmac (uint8_t *output, const uint8_t *key, const void *data, size_t size, uint8_t tag) { - BLAKE2s hash; hash.resetHMAC(key, 32); hash.update(data, size); if (tag != 0) diff --git a/libraries/NoiseProtocol/src/NoiseSymmetricState_ChaChaPoly_BLAKE2s.h b/libraries/NoiseProtocol/src/NoiseSymmetricState_ChaChaPoly_BLAKE2s.h index 1861d14c..fac61b93 100644 --- a/libraries/NoiseProtocol/src/NoiseSymmetricState_ChaChaPoly_BLAKE2s.h +++ b/libraries/NoiseProtocol/src/NoiseSymmetricState_ChaChaPoly_BLAKE2s.h @@ -24,6 +24,7 @@ #define NOISE_SYMMETRIC_STATE_CHACHAPOLY_BLAKE2S_H #include "NoiseSymmetricState.h" +#include "BLAKE2s.h" class NoiseSymmetricState_ChaChaPoly_BLAKE2s : public NoiseSymmetricState { @@ -35,6 +36,8 @@ public: bool hasKey() const; + bool mixPrologue(const void *data, size_t size); + void mixKey(const void *data, size_t size); void mixHash(const void *data, size_t size); void mixKeyAndHash(const void *data, size_t size); @@ -53,16 +56,21 @@ public: void clear(); private: + BLAKE2s hash; struct { uint8_t ck[32]; uint8_t h[32]; uint8_t key[32]; uint64_t n; bool hasKey; + bool inPrologue; } st; - static void hmac(uint8_t *output, const uint8_t *key, - const void *data, size_t size, uint8_t tag); + void doEndPrologue(); + void endPrologue() { if (st.inPrologue) doEndPrologue(); } + + void hmac(uint8_t *output, const uint8_t *key, + const void *data, size_t size, uint8_t tag); }; #endif diff --git a/libraries/NoiseProtocol/src/NoiseSymmetricState_ChaChaPoly_SHA256.cpp b/libraries/NoiseProtocol/src/NoiseSymmetricState_ChaChaPoly_SHA256.cpp index f19bd3e9..46b399aa 100644 --- a/libraries/NoiseProtocol/src/NoiseSymmetricState_ChaChaPoly_SHA256.cpp +++ b/libraries/NoiseProtocol/src/NoiseSymmetricState_ChaChaPoly_SHA256.cpp @@ -23,7 +23,6 @@ #include "NoiseSymmetricState_ChaChaPoly_SHA256.h" #include "NoiseCipherState_ChaChaPoly.h" #include "ChaChaPoly.h" -#include "SHA256.h" #include "Crypto.h" #include "utility/EndianUtil.h" #include @@ -40,6 +39,7 @@ NoiseSymmetricState_ChaChaPoly_SHA256::NoiseSymmetricState_ChaChaPoly_SHA256() { st.n = 0; st.hasKey = false; + st.inPrologue = false; } /** @@ -58,12 +58,15 @@ void NoiseSymmetricState_ChaChaPoly_SHA256::initialize memcpy(st.h, protocolName, len); memset(st.h + len, 0, 32 - len); } else { - SHA256 hash; + hash.reset(); hash.update(protocolName, len); hash.finalize(st.h, 32); } memcpy(st.ck, st.h, 32); st.hasKey = false; + hash.reset(); + hash.update(st.h, sizeof(st.h)); + st.inPrologue = true; } bool NoiseSymmetricState_ChaChaPoly_SHA256::hasKey() const @@ -71,9 +74,19 @@ bool NoiseSymmetricState_ChaChaPoly_SHA256::hasKey() const return st.hasKey; } +bool NoiseSymmetricState_ChaChaPoly_SHA256::mixPrologue + (const void *data, size_t size) +{ + if (!st.inPrologue) + return false; + hash.update(data, size); + return true; +} + void NoiseSymmetricState_ChaChaPoly_SHA256::mixKey (const void *data, size_t size) { + endPrologue(); hmac(st.key, st.ck, data, size, 0); hmac(st.ck, st.key, 0, 0, 1); hmac(st.key, st.key, st.ck, 32, 2); @@ -84,7 +97,8 @@ void NoiseSymmetricState_ChaChaPoly_SHA256::mixKey void NoiseSymmetricState_ChaChaPoly_SHA256::mixHash (const void *data, size_t size) { - SHA256 hash; + endPrologue(); + hash.reset(); hash.update(st.h, sizeof(st.h)); hash.update(data, size); hash.finalize(st.h, sizeof(st.h)); @@ -94,6 +108,7 @@ void NoiseSymmetricState_ChaChaPoly_SHA256::mixKeyAndHash (const void *data, size_t size) { uint8_t temph[32]; + endPrologue(); hmac(st.key, st.ck, data, size, 0); hmac(st.ck, st.key, 0, 0, 1); hmac(temph, st.key, st.ck, 32, 2); @@ -107,6 +122,7 @@ void NoiseSymmetricState_ChaChaPoly_SHA256::mixKeyAndHash void NoiseSymmetricState_ChaChaPoly_SHA256::getHandshakeHash (void *data, size_t size) { + endPrologue(); if (size <= 32) { memcpy(data, st.h, size); } else { @@ -119,6 +135,7 @@ int NoiseSymmetricState_ChaChaPoly_SHA256::encryptAndHash (uint8_t *output, size_t outputSize, const uint8_t *input, size_t inputSize) { + endPrologue(); if (st.hasKey) { if (outputSize < 16 || (outputSize - 16) < inputSize) return -1; @@ -145,6 +162,7 @@ int NoiseSymmetricState_ChaChaPoly_SHA256::decryptAndHash (uint8_t *output, size_t outputSize, const uint8_t *input, size_t inputSize) { + endPrologue(); if (st.hasKey) { if (inputSize < 16 || outputSize < (inputSize - 16)) return -1; @@ -175,6 +193,7 @@ void NoiseSymmetricState_ChaChaPoly_SHA256::split { uint8_t k1[32]; uint8_t k2[32]; + endPrologue(); hmac(k2, st.ck, 0, 0, 0); hmac(k1, k2, 0, 0, 1); hmac(k2, k2, k1, 32, 2); @@ -188,16 +207,23 @@ void NoiseSymmetricState_ChaChaPoly_SHA256::split void NoiseSymmetricState_ChaChaPoly_SHA256::clear() { + hash.clear(); clean(st); st.n = 0; st.hasKey = false; + st.inPrologue = false; +} + +void NoiseSymmetricState_ChaChaPoly_SHA256::doEndPrologue() +{ + st.inPrologue = false; + hash.finalize(st.h, sizeof(st.h)); } void NoiseSymmetricState_ChaChaPoly_SHA256::hmac (uint8_t *output, const uint8_t *key, const void *data, size_t size, uint8_t tag) { - SHA256 hash; hash.resetHMAC(key, 32); hash.update(data, size); if (tag != 0) diff --git a/libraries/NoiseProtocol/src/NoiseSymmetricState_ChaChaPoly_SHA256.h b/libraries/NoiseProtocol/src/NoiseSymmetricState_ChaChaPoly_SHA256.h index b66ddb8d..d941413b 100644 --- a/libraries/NoiseProtocol/src/NoiseSymmetricState_ChaChaPoly_SHA256.h +++ b/libraries/NoiseProtocol/src/NoiseSymmetricState_ChaChaPoly_SHA256.h @@ -24,6 +24,7 @@ #define NOISE_SYMMETRIC_STATE_CHACHAPOLY_SHA256_H #include "NoiseSymmetricState.h" +#include "SHA256.h" class NoiseSymmetricState_ChaChaPoly_SHA256 : public NoiseSymmetricState { @@ -35,6 +36,8 @@ public: bool hasKey() const; + bool mixPrologue(const void *data, size_t size); + void mixKey(const void *data, size_t size); void mixHash(const void *data, size_t size); void mixKeyAndHash(const void *data, size_t size); @@ -53,16 +56,21 @@ public: void clear(); private: + SHA256 hash; struct { uint8_t ck[32]; uint8_t h[32]; uint8_t key[32]; uint64_t n; bool hasKey; + bool inPrologue; } st; - static void hmac(uint8_t *output, const uint8_t *key, - const void *data, size_t size, uint8_t tag); + void doEndPrologue(); + void endPrologue() { if (st.inPrologue) doEndPrologue(); } + + void hmac(uint8_t *output, const uint8_t *key, + const void *data, size_t size, uint8_t tag); }; #endif