1
0
mirror of https://github.com/taigrr/arduinolibs synced 2025-01-18 04:33:12 -08:00

Test cases for the transport phase of Noise sessions

This commit is contained in:
Rhys Weatherley 2018-06-18 05:24:27 +10:00
parent e04733b8a5
commit 5db9e834f2
7 changed files with 42 additions and 62 deletions

View File

@ -226,23 +226,21 @@ static NoiseHandshakeState *create_handshake(const char *protocol)
*/ */
static void test_connection(const TestVector *vec) static void test_connection(const TestVector *vec)
{ {
NoiseHandshakeState *initiator = 0; NoiseHandshakeState *initiator;
NoiseHandshakeState *responder = 0; NoiseHandshakeState *responder;
NoiseHandshakeState *send; NoiseHandshakeState *send;
NoiseHandshakeState *recv; NoiseHandshakeState *recv;
#if 0
NoiseCipherState *c1init; NoiseCipherState *c1init;
NoiseCipherState *c2init; NoiseCipherState *c2init;
NoiseCipherState *c1resp; NoiseCipherState *c1resp;
NoiseCipherState *c2resp; NoiseCipherState *c2resp;
NoiseCipherState *csend; NoiseCipherState *csend;
NoiseCipherState *crecv; NoiseCipherState *crecv;
#endif
uint8_t message[MAX_MESSAGE_SIZE]; uint8_t message[MAX_MESSAGE_SIZE];
uint8_t payload[MAX_MESSAGE_SIZE]; uint8_t payload[MAX_MESSAGE_SIZE];
int result; int result;
size_t index; size_t index;
//size_t mac_len; size_t mac_len;
Noise::Party role; Noise::Party role;
/* Create the two ends of the connection */ /* Create the two ends of the connection */
@ -338,72 +336,58 @@ static void test_connection(const TestVector *vec)
vec->messages[index].payload_len); vec->messages[index].payload_len);
} }
#if 0
/* Handshake finished. Check the handshake hash values */ /* Handshake finished. Check the handshake hash values */
#if 0
if (vec->handshake_hash_len) { if (vec->handshake_hash_len) {
memset(payload, 0xAA, sizeof(payload)); memset(payload, 0xAA, sizeof(payload));
compare(noise_handshakestate_get_handshake_hash verify(initiator->getHandshakeHash(payload, vec->handshake_hash_len));
(initiator, payload, vec->handshake_hash_len),
NOISE_ERROR_NONE);
compare_blocks("handshake_hash", payload, vec->handshake_hash_len, compare_blocks("handshake_hash", payload, vec->handshake_hash_len,
vec->handshake_hash, vec->handshake_hash_len); vec->handshake_hash, vec->handshake_hash_len);
memset(payload, 0xAA, sizeof(payload)); memset(payload, 0xAA, sizeof(payload));
compare(noise_handshakestate_get_handshake_hash verify(responder->getHandshakeHash(payload, vec->handshake_hash_len));
(responder, payload, vec->handshake_hash_len),
NOISE_ERROR_NONE);
compare_blocks("handshake_hash", payload, vec->handshake_hash_len, compare_blocks("handshake_hash", payload, vec->handshake_hash_len,
vec->handshake_hash, vec->handshake_hash_len); vec->handshake_hash, vec->handshake_hash_len);
} }
#endif
/* Now handle the data transport */ /* Now handle the data transport */
compare(noise_handshakestate_split(initiator, &c1init, &c2init), verify(initiator->split(&c1init, &c2init));
NOISE_ERROR_NONE); verify(responder->split(&c2resp, &c1resp));
compare(noise_handshakestate_split(responder, &c2resp, &c1resp), mac_len = 16;
NOISE_ERROR_NONE);
mac_len = noise_cipherstate_get_mac_length(c1init);
for (; index < vec->num_messages; ++index) { for (; index < vec->num_messages; ++index) {
if (role == NOISE_ROLE_INITIATOR) { if (role == Noise::Initiator) {
/* Send on the initiator, receive on the responder */ /* Send on the initiator, receive on the responder */
csend = c1init; csend = c1init;
crecv = c1resp; crecv = c1resp;
if (!is_one_way) role = Noise::Responder;
role = NOISE_ROLE_RESPONDER;
} else { } else {
/* Send on the responder, receive on the initiator */ /* Send on the responder, receive on the initiator */
csend = c2resp; csend = c2resp;
crecv = c2init; crecv = c2init;
role = NOISE_ROLE_INITIATOR; role = Noise::Initiator;
} }
verify(sizeof(message) >= (vec->messages[index].payload_len + mac_len)); verify(sizeof(message) >= (vec->messages[index].payload_len + mac_len));
memcpy(message, vec->messages[index].payload, verify(sizeof(payload) >= (vec->messages[index].payload_len + mac_len));
vec->messages[index].payload_len); result = csend->encryptPacket
noise_buffer_set_inout(mbuf, message, vec->messages[index].payload_len, (message, sizeof(message),
sizeof(message)); vec->messages[index].payload, vec->messages[index].payload_len);
compare(noise_cipherstate_encrypt(csend, &mbuf), verify(result >= 0);
NOISE_ERROR_NONE); compare_blocks("ciphertext", message, (size_t)result,
compare_blocks("ciphertext", mbuf.data, mbuf.size,
vec->messages[index].ciphertext, vec->messages[index].ciphertext,
vec->messages[index].ciphertext_len); vec->messages[index].ciphertext_len);
compare(noise_cipherstate_decrypt(crecv, &mbuf), result = crecv->decryptPacket
NOISE_ERROR_NONE); (payload, sizeof(payload), message, result);
compare_blocks("plaintext", mbuf.data, mbuf.size, verify(result >= 0);
compare_blocks("plaintext", payload, (size_t)result,
vec->messages[index].payload, vec->messages[index].payload,
vec->messages[index].payload_len); vec->messages[index].payload_len);
} }
#endif
/* Clean up */ /* Clean up */
delete initiator; delete initiator;
delete responder; delete responder;
delete c1init;
#if 0 delete c2init;
compare(noise_cipherstate_free(c1init), NOISE_ERROR_NONE); delete c1resp;
compare(noise_cipherstate_free(c2init), NOISE_ERROR_NONE); delete c2resp;
compare(noise_cipherstate_free(c1resp), NOISE_ERROR_NONE);
compare(noise_cipherstate_free(c2resp), NOISE_ERROR_NONE);
#endif
} }
/** /**

View File

@ -77,11 +77,11 @@ int NoiseCipherState_AESGCM::decryptPacket
return -1; return -1;
uint8_t iv[12]; uint8_t iv[12];
noiseAESGCMFormatIV(iv, n); noiseAESGCMFormatIV(iv, n);
cipher.setIV((const uint8_t *)&iv, sizeof(iv)); cipher.setIV(iv, sizeof(iv));
cipher.decrypt((uint8_t *)output, (const uint8_t *)input, outputSize); cipher.decrypt((uint8_t *)output, (const uint8_t *)input, inputSize - 16);
if (cipher.checkTag(((const uint8_t *)input) + outputSize, 16)) { if (cipher.checkTag(((const uint8_t *)input) + inputSize - 16, 16)) {
++n; ++n;
return outputSize; return inputSize - 16;
} }
memset(output, 0, outputSize); // Destroy the output if the tag is invalid. memset(output, 0, outputSize); // Destroy the output if the tag is invalid.
return -1; return -1;

View File

@ -73,12 +73,11 @@ int NoiseCipherState_ChaChaPoly::decryptPacket
if (inputSize < 16 || outputSize < (inputSize - 16)) if (inputSize < 16 || outputSize < (inputSize - 16))
return -1; return -1;
uint64_t iv = htole64(n); uint64_t iv = htole64(n);
outputSize = inputSize - 16;
cipher.setIV((const uint8_t *)&iv, sizeof(iv)); cipher.setIV((const uint8_t *)&iv, sizeof(iv));
cipher.decrypt((uint8_t *)output, (const uint8_t *)input, outputSize); cipher.decrypt((uint8_t *)output, (const uint8_t *)input, inputSize - 16);
if (cipher.checkTag(((const uint8_t *)input) + outputSize, 16)) { if (cipher.checkTag(((const uint8_t *)input) + inputSize - 16, 16)) {
++n; ++n;
return outputSize; return inputSize - 16;
} }
memset(output, 0, outputSize); // Destroy the output if the tag is invalid. memset(output, 0, outputSize); // Destroy the output if the tag is invalid.
return -1; return -1;

View File

@ -353,7 +353,7 @@ int NoiseHandshakeState::read
* \return Returns true if the cipher objects were split out, or false if * \return Returns true if the cipher objects were split out, or false if
* state() is not NoiseHandshakeState::Split. * state() is not NoiseHandshakeState::Split.
* *
* If \a tx or \a rx are NULL, the the respective cipher object will not * If \a tx or \a rx are NULL, then the respective cipher object will not
* be created. This is useful for one-way patterns. * be created. This is useful for one-way patterns.
* *
* The application is responsible for destroying the \a tx and \a rx * The application is responsible for destroying the \a tx and \a rx

View File

@ -174,16 +174,15 @@ int NoiseSymmetricState_AESGCM_SHA256::decryptAndHash
if (st.hasKey) { if (st.hasKey) {
if (inputSize < 16 || outputSize < (inputSize - 16)) if (inputSize < 16 || outputSize < (inputSize - 16))
return -1; return -1;
outputSize = inputSize - 16;
uint8_t iv[12]; uint8_t iv[12];
noiseAESGCMFormatIV(iv, st.n); noiseAESGCMFormatIV(iv, st.n);
cipher.setIV(iv, sizeof(iv)); cipher.setIV(iv, sizeof(iv));
cipher.addAuthData(st.h, sizeof(st.h)); cipher.addAuthData(st.h, sizeof(st.h));
mixHash(input, inputSize); mixHash(input, inputSize);
cipher.decrypt(output, input, outputSize); cipher.decrypt(output, input, inputSize -16);
if (cipher.checkTag(input + outputSize, 16)) { if (cipher.checkTag(input + inputSize - 16, 16)) {
++st.n; ++st.n;
return outputSize; return inputSize -16;
} }
memset(output, 0, outputSize); // Destroy output if tag is incorrect. memset(output, 0, outputSize); // Destroy output if tag is incorrect.
return -1; return -1;

View File

@ -148,17 +148,16 @@ int NoiseSymmetricState_ChaChaPoly_BLAKE2s::decryptAndHash
if (st.hasKey) { if (st.hasKey) {
if (inputSize < 16 || outputSize < (inputSize - 16)) if (inputSize < 16 || outputSize < (inputSize - 16))
return -1; return -1;
outputSize = inputSize - 16;
ChaChaPoly cipher; ChaChaPoly cipher;
uint64_t iv = htole64(st.n); uint64_t iv = htole64(st.n);
cipher.setKey(st.key, 32); cipher.setKey(st.key, 32);
cipher.setIV((const uint8_t *)&iv, sizeof(iv)); cipher.setIV((const uint8_t *)&iv, sizeof(iv));
cipher.addAuthData(st.h, sizeof(st.h)); cipher.addAuthData(st.h, sizeof(st.h));
mixHash(input, inputSize); mixHash(input, inputSize);
cipher.decrypt(output, input, outputSize); cipher.decrypt(output, input, inputSize - 16);
if (cipher.checkTag(input + outputSize, 16)) { if (cipher.checkTag(input + inputSize - 16, 16)) {
++st.n; ++st.n;
return outputSize; return inputSize - 16;
} }
memset(output, 0, outputSize); // Destroy output if tag is incorrect. memset(output, 0, outputSize); // Destroy output if tag is incorrect.
return -1; return -1;

View File

@ -148,17 +148,16 @@ int NoiseSymmetricState_ChaChaPoly_SHA256::decryptAndHash
if (st.hasKey) { if (st.hasKey) {
if (inputSize < 16 || outputSize < (inputSize - 16)) if (inputSize < 16 || outputSize < (inputSize - 16))
return -1; return -1;
outputSize = inputSize - 16;
ChaChaPoly cipher; ChaChaPoly cipher;
uint64_t iv = htole64(st.n); uint64_t iv = htole64(st.n);
cipher.setKey(st.key, 32); cipher.setKey(st.key, 32);
cipher.setIV((const uint8_t *)&iv, sizeof(iv)); cipher.setIV((const uint8_t *)&iv, sizeof(iv));
cipher.addAuthData(st.h, sizeof(st.h)); cipher.addAuthData(st.h, sizeof(st.h));
mixHash(input, inputSize); mixHash(input, inputSize);
cipher.decrypt(output, input, outputSize); cipher.decrypt(output, input, inputSize - 16);
if (cipher.checkTag(input + outputSize, 16)) { if (cipher.checkTag(input + inputSize - 16, 16)) {
++st.n; ++st.n;
return outputSize; return inputSize - 16;
} }
memset(output, 0, outputSize); // Destroy output if tag is incorrect. memset(output, 0, outputSize); // Destroy output if tag is incorrect.
return -1; return -1;