mirror of
https://github.com/taigrr/arduinolibs
synced 2025-01-18 04:33:12 -08:00
Hashing of prologues in sections
This commit is contained in:
parent
3e3e90b19e
commit
6a71e60d85
@ -250,8 +250,8 @@ static void test_connection(const TestVector *vec)
|
|||||||
/* Should be able to start the handshake now on both sides */
|
/* Should be able to start the handshake now on both sides */
|
||||||
initiator->start
|
initiator->start
|
||||||
(Noise::Initiator, vec->init_prologue, vec->init_prologue_len);
|
(Noise::Initiator, vec->init_prologue, vec->init_prologue_len);
|
||||||
responder->start
|
responder->start(Noise::Responder);
|
||||||
(Noise::Responder, vec->resp_prologue, vec->resp_prologue_len);
|
responder->addPrologue(vec->resp_prologue, vec->resp_prologue_len);
|
||||||
compare(initiator->state(), Noise::Write);
|
compare(initiator->state(), Noise::Write);
|
||||||
compare(responder->state(), Noise::Read);
|
compare(responder->state(), Noise::Read);
|
||||||
|
|
||||||
|
@ -85,7 +85,11 @@ NoiseHandshakeState::~NoiseHandshakeState()
|
|||||||
* the application should call split() to obtain the cipher objects to use
|
* the application should call split() to obtain the cipher objects to use
|
||||||
* to encrypt and decrypt transport messages.
|
* 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
|
void NoiseHandshakeState::start
|
||||||
(Noise::Party party, const void *prologue, size_t prologueLen)
|
(Noise::Party party, const void *prologue, size_t prologueLen)
|
||||||
@ -95,7 +99,26 @@ void NoiseHandshakeState::start
|
|||||||
msgnum = 0;
|
msgnum = 0;
|
||||||
removeKeys();
|
removeKeys();
|
||||||
symmetricState()->initialize(protoName);
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -33,8 +33,8 @@ class NoiseHandshakeState
|
|||||||
public:
|
public:
|
||||||
virtual ~NoiseHandshakeState();
|
virtual ~NoiseHandshakeState();
|
||||||
|
|
||||||
virtual void start
|
void start(Noise::Party party, const void *prologue = 0, size_t prologueLen = 0);
|
||||||
(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::Party party() const { return pty; }
|
||||||
Noise::HandshakeState state() const { return st; }
|
Noise::HandshakeState state() const { return st; }
|
||||||
|
@ -72,6 +72,20 @@ size_t NoiseSymmetricState::macLen() const
|
|||||||
return 16;
|
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)
|
* \fn void NoiseSymmetricState::mixKey(const void *data, size_t size)
|
||||||
* \brief Mixes input data into the chaining key.
|
* \brief Mixes input data into the chaining key.
|
||||||
|
@ -39,6 +39,8 @@ public:
|
|||||||
virtual bool hasKey() const = 0;
|
virtual bool hasKey() const = 0;
|
||||||
virtual size_t macLen() const;
|
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 mixKey(const void *data, size_t size) = 0;
|
||||||
virtual void mixHash(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;
|
virtual void mixKeyAndHash(const void *data, size_t size) = 0;
|
||||||
|
@ -22,7 +22,6 @@
|
|||||||
|
|
||||||
#include "NoiseSymmetricState_AESGCM_SHA256.h"
|
#include "NoiseSymmetricState_AESGCM_SHA256.h"
|
||||||
#include "NoiseCipherState_AESGCM.h"
|
#include "NoiseCipherState_AESGCM.h"
|
||||||
#include "SHA256.h"
|
|
||||||
#include "Crypto.h"
|
#include "Crypto.h"
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
@ -38,6 +37,7 @@ NoiseSymmetricState_AESGCM_SHA256::NoiseSymmetricState_AESGCM_SHA256()
|
|||||||
{
|
{
|
||||||
st.n = 0;
|
st.n = 0;
|
||||||
st.hasKey = false;
|
st.hasKey = false;
|
||||||
|
st.inPrologue = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -56,12 +56,15 @@ void NoiseSymmetricState_AESGCM_SHA256::initialize
|
|||||||
memcpy(st.h, protocolName, len);
|
memcpy(st.h, protocolName, len);
|
||||||
memset(st.h + len, 0, 32 - len);
|
memset(st.h + len, 0, 32 - len);
|
||||||
} else {
|
} else {
|
||||||
SHA256 hash;
|
hash.reset();
|
||||||
hash.update(protocolName, len);
|
hash.update(protocolName, len);
|
||||||
hash.finalize(st.h, 32);
|
hash.finalize(st.h, 32);
|
||||||
}
|
}
|
||||||
memcpy(st.ck, st.h, 32);
|
memcpy(st.ck, st.h, 32);
|
||||||
st.hasKey = false;
|
st.hasKey = false;
|
||||||
|
hash.reset();
|
||||||
|
hash.update(st.h, sizeof(st.h));
|
||||||
|
st.inPrologue = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NoiseSymmetricState_AESGCM_SHA256::hasKey() const
|
bool NoiseSymmetricState_AESGCM_SHA256::hasKey() const
|
||||||
@ -69,10 +72,20 @@ bool NoiseSymmetricState_AESGCM_SHA256::hasKey() const
|
|||||||
return st.hasKey;
|
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
|
void NoiseSymmetricState_AESGCM_SHA256::mixKey
|
||||||
(const void *data, size_t size)
|
(const void *data, size_t size)
|
||||||
{
|
{
|
||||||
uint8_t key[32];
|
uint8_t key[32];
|
||||||
|
endPrologue();
|
||||||
hmac(key, st.ck, data, size, 0);
|
hmac(key, st.ck, data, size, 0);
|
||||||
hmac(st.ck, key, 0, 0, 1);
|
hmac(st.ck, key, 0, 0, 1);
|
||||||
hmac(key, key, st.ck, 32, 2);
|
hmac(key, key, st.ck, 32, 2);
|
||||||
@ -85,7 +98,8 @@ void NoiseSymmetricState_AESGCM_SHA256::mixKey
|
|||||||
void NoiseSymmetricState_AESGCM_SHA256::mixHash
|
void NoiseSymmetricState_AESGCM_SHA256::mixHash
|
||||||
(const void *data, size_t size)
|
(const void *data, size_t size)
|
||||||
{
|
{
|
||||||
SHA256 hash;
|
endPrologue();
|
||||||
|
hash.reset();
|
||||||
hash.update(st.h, sizeof(st.h));
|
hash.update(st.h, sizeof(st.h));
|
||||||
hash.update(data, size);
|
hash.update(data, size);
|
||||||
hash.finalize(st.h, sizeof(st.h));
|
hash.finalize(st.h, sizeof(st.h));
|
||||||
@ -96,6 +110,7 @@ void NoiseSymmetricState_AESGCM_SHA256::mixKeyAndHash
|
|||||||
{
|
{
|
||||||
uint8_t key[32];
|
uint8_t key[32];
|
||||||
uint8_t temph[32];
|
uint8_t temph[32];
|
||||||
|
endPrologue();
|
||||||
hmac(key, st.ck, data, size, 0);
|
hmac(key, st.ck, data, size, 0);
|
||||||
hmac(st.ck, key, 0, 0, 1);
|
hmac(st.ck, key, 0, 0, 1);
|
||||||
hmac(temph, key, st.ck, 32, 2);
|
hmac(temph, key, st.ck, 32, 2);
|
||||||
@ -111,6 +126,7 @@ void NoiseSymmetricState_AESGCM_SHA256::mixKeyAndHash
|
|||||||
void NoiseSymmetricState_AESGCM_SHA256::getHandshakeHash
|
void NoiseSymmetricState_AESGCM_SHA256::getHandshakeHash
|
||||||
(void *data, size_t size)
|
(void *data, size_t size)
|
||||||
{
|
{
|
||||||
|
endPrologue();
|
||||||
if (size <= 32) {
|
if (size <= 32) {
|
||||||
memcpy(data, st.h, size);
|
memcpy(data, st.h, size);
|
||||||
} else {
|
} else {
|
||||||
@ -146,6 +162,7 @@ int NoiseSymmetricState_AESGCM_SHA256::encryptAndHash
|
|||||||
(uint8_t *output, size_t outputSize,
|
(uint8_t *output, size_t outputSize,
|
||||||
const uint8_t *input, size_t inputSize)
|
const uint8_t *input, size_t inputSize)
|
||||||
{
|
{
|
||||||
|
endPrologue();
|
||||||
if (st.hasKey) {
|
if (st.hasKey) {
|
||||||
if (outputSize < 16 || (outputSize - 16) < inputSize)
|
if (outputSize < 16 || (outputSize - 16) < inputSize)
|
||||||
return -1;
|
return -1;
|
||||||
@ -171,6 +188,7 @@ int NoiseSymmetricState_AESGCM_SHA256::decryptAndHash
|
|||||||
(uint8_t *output, size_t outputSize,
|
(uint8_t *output, size_t outputSize,
|
||||||
const uint8_t *input, size_t inputSize)
|
const uint8_t *input, size_t inputSize)
|
||||||
{
|
{
|
||||||
|
endPrologue();
|
||||||
if (st.hasKey) {
|
if (st.hasKey) {
|
||||||
if (inputSize < 16 || outputSize < (inputSize - 16))
|
if (inputSize < 16 || outputSize < (inputSize - 16))
|
||||||
return -1;
|
return -1;
|
||||||
@ -200,6 +218,7 @@ void NoiseSymmetricState_AESGCM_SHA256::split
|
|||||||
{
|
{
|
||||||
uint8_t k1[32];
|
uint8_t k1[32];
|
||||||
uint8_t k2[32];
|
uint8_t k2[32];
|
||||||
|
endPrologue();
|
||||||
hmac(k2, st.ck, 0, 0, 0);
|
hmac(k2, st.ck, 0, 0, 0);
|
||||||
hmac(k1, k2, 0, 0, 1);
|
hmac(k1, k2, 0, 0, 1);
|
||||||
hmac(k2, k2, k1, 32, 2);
|
hmac(k2, k2, k1, 32, 2);
|
||||||
@ -213,16 +232,24 @@ void NoiseSymmetricState_AESGCM_SHA256::split
|
|||||||
|
|
||||||
void NoiseSymmetricState_AESGCM_SHA256::clear()
|
void NoiseSymmetricState_AESGCM_SHA256::clear()
|
||||||
{
|
{
|
||||||
|
cipher.clear();
|
||||||
|
hash.clear();
|
||||||
clean(st);
|
clean(st);
|
||||||
st.n = 0;
|
st.n = 0;
|
||||||
st.hasKey = false;
|
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
|
void NoiseSymmetricState_AESGCM_SHA256::hmac
|
||||||
(uint8_t *output, const uint8_t *key,
|
(uint8_t *output, const uint8_t *key,
|
||||||
const void *data, size_t size, uint8_t tag)
|
const void *data, size_t size, uint8_t tag)
|
||||||
{
|
{
|
||||||
SHA256 hash;
|
|
||||||
hash.resetHMAC(key, 32);
|
hash.resetHMAC(key, 32);
|
||||||
hash.update(data, size);
|
hash.update(data, size);
|
||||||
if (tag != 0)
|
if (tag != 0)
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
#include "NoiseSymmetricState.h"
|
#include "NoiseSymmetricState.h"
|
||||||
#include "AES.h"
|
#include "AES.h"
|
||||||
#include "GCM.h"
|
#include "GCM.h"
|
||||||
|
#include "SHA256.h"
|
||||||
|
|
||||||
class NoiseSymmetricState_AESGCM_SHA256 : public NoiseSymmetricState
|
class NoiseSymmetricState_AESGCM_SHA256 : public NoiseSymmetricState
|
||||||
{
|
{
|
||||||
@ -37,6 +38,8 @@ public:
|
|||||||
|
|
||||||
bool hasKey() const;
|
bool hasKey() const;
|
||||||
|
|
||||||
|
bool mixPrologue(const void *data, size_t size);
|
||||||
|
|
||||||
void mixKey(const void *data, size_t size);
|
void mixKey(const void *data, size_t size);
|
||||||
void mixHash(const void *data, size_t size);
|
void mixHash(const void *data, size_t size);
|
||||||
void mixKeyAndHash(const void *data, size_t size);
|
void mixKeyAndHash(const void *data, size_t size);
|
||||||
@ -56,14 +59,19 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
GCM<AES256> cipher;
|
GCM<AES256> cipher;
|
||||||
|
SHA256 hash;
|
||||||
struct {
|
struct {
|
||||||
uint8_t ck[32];
|
uint8_t ck[32];
|
||||||
uint8_t h[32];
|
uint8_t h[32];
|
||||||
uint64_t n;
|
uint64_t n;
|
||||||
bool hasKey;
|
bool hasKey;
|
||||||
|
bool inPrologue;
|
||||||
} st;
|
} st;
|
||||||
|
|
||||||
static void hmac(uint8_t *output, const uint8_t *key,
|
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);
|
const void *data, size_t size, uint8_t tag);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -23,7 +23,6 @@
|
|||||||
#include "NoiseSymmetricState_ChaChaPoly_BLAKE2s.h"
|
#include "NoiseSymmetricState_ChaChaPoly_BLAKE2s.h"
|
||||||
#include "NoiseCipherState_ChaChaPoly.h"
|
#include "NoiseCipherState_ChaChaPoly.h"
|
||||||
#include "ChaChaPoly.h"
|
#include "ChaChaPoly.h"
|
||||||
#include "BLAKE2s.h"
|
|
||||||
#include "Crypto.h"
|
#include "Crypto.h"
|
||||||
#include "utility/EndianUtil.h"
|
#include "utility/EndianUtil.h"
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@ -40,6 +39,7 @@ NoiseSymmetricState_ChaChaPoly_BLAKE2s::NoiseSymmetricState_ChaChaPoly_BLAKE2s()
|
|||||||
{
|
{
|
||||||
st.n = 0;
|
st.n = 0;
|
||||||
st.hasKey = false;
|
st.hasKey = false;
|
||||||
|
st.inPrologue = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -58,12 +58,15 @@ void NoiseSymmetricState_ChaChaPoly_BLAKE2s::initialize
|
|||||||
memcpy(st.h, protocolName, len);
|
memcpy(st.h, protocolName, len);
|
||||||
memset(st.h + len, 0, 32 - len);
|
memset(st.h + len, 0, 32 - len);
|
||||||
} else {
|
} else {
|
||||||
BLAKE2s hash;
|
hash.reset();
|
||||||
hash.update(protocolName, len);
|
hash.update(protocolName, len);
|
||||||
hash.finalize(st.h, 32);
|
hash.finalize(st.h, 32);
|
||||||
}
|
}
|
||||||
memcpy(st.ck, st.h, 32);
|
memcpy(st.ck, st.h, 32);
|
||||||
st.hasKey = false;
|
st.hasKey = false;
|
||||||
|
hash.reset();
|
||||||
|
hash.update(st.h, sizeof(st.h));
|
||||||
|
st.inPrologue = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NoiseSymmetricState_ChaChaPoly_BLAKE2s::hasKey() const
|
bool NoiseSymmetricState_ChaChaPoly_BLAKE2s::hasKey() const
|
||||||
@ -71,9 +74,19 @@ bool NoiseSymmetricState_ChaChaPoly_BLAKE2s::hasKey() const
|
|||||||
return st.hasKey;
|
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
|
void NoiseSymmetricState_ChaChaPoly_BLAKE2s::mixKey
|
||||||
(const void *data, size_t size)
|
(const void *data, size_t size)
|
||||||
{
|
{
|
||||||
|
endPrologue();
|
||||||
hmac(st.key, st.ck, data, size, 0);
|
hmac(st.key, st.ck, data, size, 0);
|
||||||
hmac(st.ck, st.key, 0, 0, 1);
|
hmac(st.ck, st.key, 0, 0, 1);
|
||||||
hmac(st.key, st.key, st.ck, 32, 2);
|
hmac(st.key, st.key, st.ck, 32, 2);
|
||||||
@ -84,7 +97,8 @@ void NoiseSymmetricState_ChaChaPoly_BLAKE2s::mixKey
|
|||||||
void NoiseSymmetricState_ChaChaPoly_BLAKE2s::mixHash
|
void NoiseSymmetricState_ChaChaPoly_BLAKE2s::mixHash
|
||||||
(const void *data, size_t size)
|
(const void *data, size_t size)
|
||||||
{
|
{
|
||||||
BLAKE2s hash;
|
endPrologue();
|
||||||
|
hash.reset();
|
||||||
hash.update(st.h, sizeof(st.h));
|
hash.update(st.h, sizeof(st.h));
|
||||||
hash.update(data, size);
|
hash.update(data, size);
|
||||||
hash.finalize(st.h, sizeof(st.h));
|
hash.finalize(st.h, sizeof(st.h));
|
||||||
@ -94,6 +108,7 @@ void NoiseSymmetricState_ChaChaPoly_BLAKE2s::mixKeyAndHash
|
|||||||
(const void *data, size_t size)
|
(const void *data, size_t size)
|
||||||
{
|
{
|
||||||
uint8_t temph[32];
|
uint8_t temph[32];
|
||||||
|
endPrologue();
|
||||||
hmac(st.key, st.ck, data, size, 0);
|
hmac(st.key, st.ck, data, size, 0);
|
||||||
hmac(st.ck, st.key, 0, 0, 1);
|
hmac(st.ck, st.key, 0, 0, 1);
|
||||||
hmac(temph, st.key, st.ck, 32, 2);
|
hmac(temph, st.key, st.ck, 32, 2);
|
||||||
@ -107,6 +122,7 @@ void NoiseSymmetricState_ChaChaPoly_BLAKE2s::mixKeyAndHash
|
|||||||
void NoiseSymmetricState_ChaChaPoly_BLAKE2s::getHandshakeHash
|
void NoiseSymmetricState_ChaChaPoly_BLAKE2s::getHandshakeHash
|
||||||
(void *data, size_t size)
|
(void *data, size_t size)
|
||||||
{
|
{
|
||||||
|
endPrologue();
|
||||||
if (size <= 32) {
|
if (size <= 32) {
|
||||||
memcpy(data, st.h, size);
|
memcpy(data, st.h, size);
|
||||||
} else {
|
} else {
|
||||||
@ -119,6 +135,7 @@ int NoiseSymmetricState_ChaChaPoly_BLAKE2s::encryptAndHash
|
|||||||
(uint8_t *output, size_t outputSize,
|
(uint8_t *output, size_t outputSize,
|
||||||
const uint8_t *input, size_t inputSize)
|
const uint8_t *input, size_t inputSize)
|
||||||
{
|
{
|
||||||
|
endPrologue();
|
||||||
if (st.hasKey) {
|
if (st.hasKey) {
|
||||||
if (outputSize < 16 || (outputSize - 16) < inputSize)
|
if (outputSize < 16 || (outputSize - 16) < inputSize)
|
||||||
return -1;
|
return -1;
|
||||||
@ -145,6 +162,7 @@ int NoiseSymmetricState_ChaChaPoly_BLAKE2s::decryptAndHash
|
|||||||
(uint8_t *output, size_t outputSize,
|
(uint8_t *output, size_t outputSize,
|
||||||
const uint8_t *input, size_t inputSize)
|
const uint8_t *input, size_t inputSize)
|
||||||
{
|
{
|
||||||
|
endPrologue();
|
||||||
if (st.hasKey) {
|
if (st.hasKey) {
|
||||||
if (inputSize < 16 || outputSize < (inputSize - 16))
|
if (inputSize < 16 || outputSize < (inputSize - 16))
|
||||||
return -1;
|
return -1;
|
||||||
@ -175,6 +193,7 @@ void NoiseSymmetricState_ChaChaPoly_BLAKE2s::split
|
|||||||
{
|
{
|
||||||
uint8_t k1[32];
|
uint8_t k1[32];
|
||||||
uint8_t k2[32];
|
uint8_t k2[32];
|
||||||
|
endPrologue();
|
||||||
hmac(k2, st.ck, 0, 0, 0);
|
hmac(k2, st.ck, 0, 0, 0);
|
||||||
hmac(k1, k2, 0, 0, 1);
|
hmac(k1, k2, 0, 0, 1);
|
||||||
hmac(k2, k2, k1, 32, 2);
|
hmac(k2, k2, k1, 32, 2);
|
||||||
@ -188,16 +207,23 @@ void NoiseSymmetricState_ChaChaPoly_BLAKE2s::split
|
|||||||
|
|
||||||
void NoiseSymmetricState_ChaChaPoly_BLAKE2s::clear()
|
void NoiseSymmetricState_ChaChaPoly_BLAKE2s::clear()
|
||||||
{
|
{
|
||||||
|
hash.clear();
|
||||||
clean(st);
|
clean(st);
|
||||||
st.n = 0;
|
st.n = 0;
|
||||||
st.hasKey = false;
|
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
|
void NoiseSymmetricState_ChaChaPoly_BLAKE2s::hmac
|
||||||
(uint8_t *output, const uint8_t *key,
|
(uint8_t *output, const uint8_t *key,
|
||||||
const void *data, size_t size, uint8_t tag)
|
const void *data, size_t size, uint8_t tag)
|
||||||
{
|
{
|
||||||
BLAKE2s hash;
|
|
||||||
hash.resetHMAC(key, 32);
|
hash.resetHMAC(key, 32);
|
||||||
hash.update(data, size);
|
hash.update(data, size);
|
||||||
if (tag != 0)
|
if (tag != 0)
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
#define NOISE_SYMMETRIC_STATE_CHACHAPOLY_BLAKE2S_H
|
#define NOISE_SYMMETRIC_STATE_CHACHAPOLY_BLAKE2S_H
|
||||||
|
|
||||||
#include "NoiseSymmetricState.h"
|
#include "NoiseSymmetricState.h"
|
||||||
|
#include "BLAKE2s.h"
|
||||||
|
|
||||||
class NoiseSymmetricState_ChaChaPoly_BLAKE2s : public NoiseSymmetricState
|
class NoiseSymmetricState_ChaChaPoly_BLAKE2s : public NoiseSymmetricState
|
||||||
{
|
{
|
||||||
@ -35,6 +36,8 @@ public:
|
|||||||
|
|
||||||
bool hasKey() const;
|
bool hasKey() const;
|
||||||
|
|
||||||
|
bool mixPrologue(const void *data, size_t size);
|
||||||
|
|
||||||
void mixKey(const void *data, size_t size);
|
void mixKey(const void *data, size_t size);
|
||||||
void mixHash(const void *data, size_t size);
|
void mixHash(const void *data, size_t size);
|
||||||
void mixKeyAndHash(const void *data, size_t size);
|
void mixKeyAndHash(const void *data, size_t size);
|
||||||
@ -53,15 +56,20 @@ public:
|
|||||||
void clear();
|
void clear();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
BLAKE2s hash;
|
||||||
struct {
|
struct {
|
||||||
uint8_t ck[32];
|
uint8_t ck[32];
|
||||||
uint8_t h[32];
|
uint8_t h[32];
|
||||||
uint8_t key[32];
|
uint8_t key[32];
|
||||||
uint64_t n;
|
uint64_t n;
|
||||||
bool hasKey;
|
bool hasKey;
|
||||||
|
bool inPrologue;
|
||||||
} st;
|
} st;
|
||||||
|
|
||||||
static void hmac(uint8_t *output, const uint8_t *key,
|
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);
|
const void *data, size_t size, uint8_t tag);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -23,7 +23,6 @@
|
|||||||
#include "NoiseSymmetricState_ChaChaPoly_SHA256.h"
|
#include "NoiseSymmetricState_ChaChaPoly_SHA256.h"
|
||||||
#include "NoiseCipherState_ChaChaPoly.h"
|
#include "NoiseCipherState_ChaChaPoly.h"
|
||||||
#include "ChaChaPoly.h"
|
#include "ChaChaPoly.h"
|
||||||
#include "SHA256.h"
|
|
||||||
#include "Crypto.h"
|
#include "Crypto.h"
|
||||||
#include "utility/EndianUtil.h"
|
#include "utility/EndianUtil.h"
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@ -40,6 +39,7 @@ NoiseSymmetricState_ChaChaPoly_SHA256::NoiseSymmetricState_ChaChaPoly_SHA256()
|
|||||||
{
|
{
|
||||||
st.n = 0;
|
st.n = 0;
|
||||||
st.hasKey = false;
|
st.hasKey = false;
|
||||||
|
st.inPrologue = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -58,12 +58,15 @@ void NoiseSymmetricState_ChaChaPoly_SHA256::initialize
|
|||||||
memcpy(st.h, protocolName, len);
|
memcpy(st.h, protocolName, len);
|
||||||
memset(st.h + len, 0, 32 - len);
|
memset(st.h + len, 0, 32 - len);
|
||||||
} else {
|
} else {
|
||||||
SHA256 hash;
|
hash.reset();
|
||||||
hash.update(protocolName, len);
|
hash.update(protocolName, len);
|
||||||
hash.finalize(st.h, 32);
|
hash.finalize(st.h, 32);
|
||||||
}
|
}
|
||||||
memcpy(st.ck, st.h, 32);
|
memcpy(st.ck, st.h, 32);
|
||||||
st.hasKey = false;
|
st.hasKey = false;
|
||||||
|
hash.reset();
|
||||||
|
hash.update(st.h, sizeof(st.h));
|
||||||
|
st.inPrologue = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NoiseSymmetricState_ChaChaPoly_SHA256::hasKey() const
|
bool NoiseSymmetricState_ChaChaPoly_SHA256::hasKey() const
|
||||||
@ -71,9 +74,19 @@ bool NoiseSymmetricState_ChaChaPoly_SHA256::hasKey() const
|
|||||||
return st.hasKey;
|
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
|
void NoiseSymmetricState_ChaChaPoly_SHA256::mixKey
|
||||||
(const void *data, size_t size)
|
(const void *data, size_t size)
|
||||||
{
|
{
|
||||||
|
endPrologue();
|
||||||
hmac(st.key, st.ck, data, size, 0);
|
hmac(st.key, st.ck, data, size, 0);
|
||||||
hmac(st.ck, st.key, 0, 0, 1);
|
hmac(st.ck, st.key, 0, 0, 1);
|
||||||
hmac(st.key, st.key, st.ck, 32, 2);
|
hmac(st.key, st.key, st.ck, 32, 2);
|
||||||
@ -84,7 +97,8 @@ void NoiseSymmetricState_ChaChaPoly_SHA256::mixKey
|
|||||||
void NoiseSymmetricState_ChaChaPoly_SHA256::mixHash
|
void NoiseSymmetricState_ChaChaPoly_SHA256::mixHash
|
||||||
(const void *data, size_t size)
|
(const void *data, size_t size)
|
||||||
{
|
{
|
||||||
SHA256 hash;
|
endPrologue();
|
||||||
|
hash.reset();
|
||||||
hash.update(st.h, sizeof(st.h));
|
hash.update(st.h, sizeof(st.h));
|
||||||
hash.update(data, size);
|
hash.update(data, size);
|
||||||
hash.finalize(st.h, sizeof(st.h));
|
hash.finalize(st.h, sizeof(st.h));
|
||||||
@ -94,6 +108,7 @@ void NoiseSymmetricState_ChaChaPoly_SHA256::mixKeyAndHash
|
|||||||
(const void *data, size_t size)
|
(const void *data, size_t size)
|
||||||
{
|
{
|
||||||
uint8_t temph[32];
|
uint8_t temph[32];
|
||||||
|
endPrologue();
|
||||||
hmac(st.key, st.ck, data, size, 0);
|
hmac(st.key, st.ck, data, size, 0);
|
||||||
hmac(st.ck, st.key, 0, 0, 1);
|
hmac(st.ck, st.key, 0, 0, 1);
|
||||||
hmac(temph, st.key, st.ck, 32, 2);
|
hmac(temph, st.key, st.ck, 32, 2);
|
||||||
@ -107,6 +122,7 @@ void NoiseSymmetricState_ChaChaPoly_SHA256::mixKeyAndHash
|
|||||||
void NoiseSymmetricState_ChaChaPoly_SHA256::getHandshakeHash
|
void NoiseSymmetricState_ChaChaPoly_SHA256::getHandshakeHash
|
||||||
(void *data, size_t size)
|
(void *data, size_t size)
|
||||||
{
|
{
|
||||||
|
endPrologue();
|
||||||
if (size <= 32) {
|
if (size <= 32) {
|
||||||
memcpy(data, st.h, size);
|
memcpy(data, st.h, size);
|
||||||
} else {
|
} else {
|
||||||
@ -119,6 +135,7 @@ int NoiseSymmetricState_ChaChaPoly_SHA256::encryptAndHash
|
|||||||
(uint8_t *output, size_t outputSize,
|
(uint8_t *output, size_t outputSize,
|
||||||
const uint8_t *input, size_t inputSize)
|
const uint8_t *input, size_t inputSize)
|
||||||
{
|
{
|
||||||
|
endPrologue();
|
||||||
if (st.hasKey) {
|
if (st.hasKey) {
|
||||||
if (outputSize < 16 || (outputSize - 16) < inputSize)
|
if (outputSize < 16 || (outputSize - 16) < inputSize)
|
||||||
return -1;
|
return -1;
|
||||||
@ -145,6 +162,7 @@ int NoiseSymmetricState_ChaChaPoly_SHA256::decryptAndHash
|
|||||||
(uint8_t *output, size_t outputSize,
|
(uint8_t *output, size_t outputSize,
|
||||||
const uint8_t *input, size_t inputSize)
|
const uint8_t *input, size_t inputSize)
|
||||||
{
|
{
|
||||||
|
endPrologue();
|
||||||
if (st.hasKey) {
|
if (st.hasKey) {
|
||||||
if (inputSize < 16 || outputSize < (inputSize - 16))
|
if (inputSize < 16 || outputSize < (inputSize - 16))
|
||||||
return -1;
|
return -1;
|
||||||
@ -175,6 +193,7 @@ void NoiseSymmetricState_ChaChaPoly_SHA256::split
|
|||||||
{
|
{
|
||||||
uint8_t k1[32];
|
uint8_t k1[32];
|
||||||
uint8_t k2[32];
|
uint8_t k2[32];
|
||||||
|
endPrologue();
|
||||||
hmac(k2, st.ck, 0, 0, 0);
|
hmac(k2, st.ck, 0, 0, 0);
|
||||||
hmac(k1, k2, 0, 0, 1);
|
hmac(k1, k2, 0, 0, 1);
|
||||||
hmac(k2, k2, k1, 32, 2);
|
hmac(k2, k2, k1, 32, 2);
|
||||||
@ -188,16 +207,23 @@ void NoiseSymmetricState_ChaChaPoly_SHA256::split
|
|||||||
|
|
||||||
void NoiseSymmetricState_ChaChaPoly_SHA256::clear()
|
void NoiseSymmetricState_ChaChaPoly_SHA256::clear()
|
||||||
{
|
{
|
||||||
|
hash.clear();
|
||||||
clean(st);
|
clean(st);
|
||||||
st.n = 0;
|
st.n = 0;
|
||||||
st.hasKey = false;
|
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
|
void NoiseSymmetricState_ChaChaPoly_SHA256::hmac
|
||||||
(uint8_t *output, const uint8_t *key,
|
(uint8_t *output, const uint8_t *key,
|
||||||
const void *data, size_t size, uint8_t tag)
|
const void *data, size_t size, uint8_t tag)
|
||||||
{
|
{
|
||||||
SHA256 hash;
|
|
||||||
hash.resetHMAC(key, 32);
|
hash.resetHMAC(key, 32);
|
||||||
hash.update(data, size);
|
hash.update(data, size);
|
||||||
if (tag != 0)
|
if (tag != 0)
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
#define NOISE_SYMMETRIC_STATE_CHACHAPOLY_SHA256_H
|
#define NOISE_SYMMETRIC_STATE_CHACHAPOLY_SHA256_H
|
||||||
|
|
||||||
#include "NoiseSymmetricState.h"
|
#include "NoiseSymmetricState.h"
|
||||||
|
#include "SHA256.h"
|
||||||
|
|
||||||
class NoiseSymmetricState_ChaChaPoly_SHA256 : public NoiseSymmetricState
|
class NoiseSymmetricState_ChaChaPoly_SHA256 : public NoiseSymmetricState
|
||||||
{
|
{
|
||||||
@ -35,6 +36,8 @@ public:
|
|||||||
|
|
||||||
bool hasKey() const;
|
bool hasKey() const;
|
||||||
|
|
||||||
|
bool mixPrologue(const void *data, size_t size);
|
||||||
|
|
||||||
void mixKey(const void *data, size_t size);
|
void mixKey(const void *data, size_t size);
|
||||||
void mixHash(const void *data, size_t size);
|
void mixHash(const void *data, size_t size);
|
||||||
void mixKeyAndHash(const void *data, size_t size);
|
void mixKeyAndHash(const void *data, size_t size);
|
||||||
@ -53,15 +56,20 @@ public:
|
|||||||
void clear();
|
void clear();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
SHA256 hash;
|
||||||
struct {
|
struct {
|
||||||
uint8_t ck[32];
|
uint8_t ck[32];
|
||||||
uint8_t h[32];
|
uint8_t h[32];
|
||||||
uint8_t key[32];
|
uint8_t key[32];
|
||||||
uint64_t n;
|
uint64_t n;
|
||||||
bool hasKey;
|
bool hasKey;
|
||||||
|
bool inPrologue;
|
||||||
} st;
|
} st;
|
||||||
|
|
||||||
static void hmac(uint8_t *output, const uint8_t *key,
|
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);
|
const void *data, size_t size, uint8_t tag);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user