Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions src/internal.c
Original file line number Diff line number Diff line change
Expand Up @@ -10475,6 +10475,13 @@ int DoReceive(WOLFSSH* ssh)
return ret;
}

#ifdef WOLFSSH_TEST_INTERNAL
int wolfSSH_TestDoReceive(WOLFSSH* ssh)
{
return DoReceive(ssh);
}
#endif


int DoProtoId(WOLFSSH* ssh)
{
Expand Down
6 changes: 3 additions & 3 deletions tests/include.am
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ check_PROGRAMS += tests/unit.test tests/api.test \
tests/regress.test

tests_unit_test_SOURCES = tests/unit.c tests/unit.h
tests_unit_test_CPPFLAGS = -DNO_MAIN_DRIVER $(AM_CPPFLAGS)
tests_unit_test_LDADD = src/libwolfssh.la
tests_unit_test_DEPENDENCIES = src/libwolfssh.la
tests_unit_test_CPPFLAGS = -DNO_MAIN_DRIVER -DWOLFSSH_TEST_INTERNAL $(AM_CPPFLAGS)
tests_unit_test_LDADD = src/libwolfssh_test.la
tests_unit_test_DEPENDENCIES = src/libwolfssh_test.la

tests_api_test_SOURCES = tests/api.c tests/api.h \
examples/echoserver/echoserver.c
Expand Down
159 changes: 159 additions & 0 deletions tests/unit.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
#include <wolfssh/ssh.h>
#include <wolfssh/keygen.h>
#include <wolfssh/internal.h>
#include <wolfssl/wolfcrypt/hmac.h>

#define WOLFSSH_TEST_HEX2BIN
#include <wolfssh/test.h>
Expand Down Expand Up @@ -285,6 +286,153 @@ static int test_Ed25519KeyGen(void)
#endif


#if defined(WOLFSSH_TEST_INTERNAL) && \
(!defined(WOLFSSH_NO_HMAC_SHA1) || \
!defined(WOLFSSH_NO_HMAC_SHA1_96) || \
!defined(WOLFSSH_NO_HMAC_SHA2_256) || \
!defined(WOLFSSH_NO_HMAC_SHA2_512))

/* Minimal SSH binary packet: uint32 length, padding_length, msgId, padding.
* Same layout as tests/regress.c BuildPacket (8-byte aligned body). */
static word32 BuildMacTestPacketPrefix(byte msgId, byte* out, word32 outSz)
{
byte padLen = 6;
word32 packetLen = (word32)(1 + 1 + padLen);
word32 need = UINT32_SZ + packetLen;

if (outSz < need)
return 0;
out[0] = (byte)(packetLen >> 24);
out[1] = (byte)(packetLen >> 16);
out[2] = (byte)(packetLen >> 8);
out[3] = (byte)(packetLen);
out[4] = padLen;
out[5] = msgId;
WMEMSET(out + 6, 0, padLen);
return need;
}


static int test_DoReceive_VerifyMacFailure(void)
{
WOLFSSH_CTX* ctx = NULL;
WOLFSSH* ssh = NULL;
int ret = WS_SUCCESS;
int result = 0;
byte flatSeq[LENGTH_SZ];
byte macKey[MAX_HMAC_SZ];
Hmac hmac;
word32 prefixLen;
word32 totalLen;
byte pkt[UINT32_SZ + 8 + MAX_HMAC_SZ];
int i;
struct {
byte macId;
int hmacType;
byte macSz;
byte keySz;
} cases[] = {
#ifndef WOLFSSH_NO_HMAC_SHA1
{ ID_HMAC_SHA1, WC_SHA, WC_SHA_DIGEST_SIZE, WC_SHA_DIGEST_SIZE },
#endif
#ifndef WOLFSSH_NO_HMAC_SHA1_96
{ ID_HMAC_SHA1_96, WC_SHA, SHA1_96_SZ, WC_SHA_DIGEST_SIZE },
#endif
#ifndef WOLFSSH_NO_HMAC_SHA2_256
{ ID_HMAC_SHA2_256, WC_SHA256, WC_SHA256_DIGEST_SIZE,
WC_SHA256_DIGEST_SIZE },
#endif
#ifndef WOLFSSH_NO_HMAC_SHA2_512
{ ID_HMAC_SHA2_512, WC_SHA512, WC_SHA512_DIGEST_SIZE,
WC_SHA512_DIGEST_SIZE },
#endif
};

ctx = wolfSSH_CTX_new(WOLFSSH_ENDPOINT_CLIENT, NULL);
if (ctx == NULL)
return -200;
ssh = wolfSSH_new(ctx);
if (ssh == NULL) {
wolfSSH_CTX_free(ctx);
return -201;
}

WMEMSET(macKey, 0xA5, sizeof(macKey));

for (i = 0; i < (int)(sizeof(cases) / sizeof(cases[0])); i++) {
prefixLen = BuildMacTestPacketPrefix(MSGID_IGNORE, pkt, sizeof(pkt));
if (prefixLen == 0) {
result = -202;
goto done;
}
totalLen = prefixLen + cases[i].macSz;

ssh->peerEncryptId = ID_NONE;
ssh->peerAeadMode = 0;
ssh->peerBlockSz = MIN_BLOCK_SZ;
ssh->peerMacId = cases[i].macId;
ssh->peerMacSz = cases[i].macSz;
WMEMCPY(ssh->peerKeys.macKey, macKey, cases[i].keySz);
ssh->peerKeys.macKeySz = cases[i].keySz;
ssh->peerSeq = 0;
ssh->curSz = 0;
ssh->processReplyState = PROCESS_INIT;
ssh->error = 0;

flatSeq[0] = (byte)(ssh->peerSeq >> 24);
flatSeq[1] = (byte)(ssh->peerSeq >> 16);
flatSeq[2] = (byte)(ssh->peerSeq >> 8);
flatSeq[3] = (byte)(ssh->peerSeq);
ret = wc_HmacInit(&hmac, ssh->ctx->heap, INVALID_DEVID);
if (ret != WS_SUCCESS) {
result = -203;
goto done;
}
ret = wc_HmacSetKey(&hmac, cases[i].hmacType,
ssh->peerKeys.macKey, ssh->peerKeys.macKeySz);
if (ret == WS_SUCCESS)
ret = wc_HmacUpdate(&hmac, flatSeq, sizeof(flatSeq));
if (ret == WS_SUCCESS)
ret = wc_HmacUpdate(&hmac, pkt, prefixLen);
if (ret == WS_SUCCESS)
ret = wc_HmacFinal(&hmac, pkt + prefixLen);
wc_HmacFree(&hmac);
if (ret != WS_SUCCESS) {
result = -204;
goto done;
}

pkt[prefixLen] ^= 0x01;

ShrinkBuffer(&ssh->inputBuffer, 1);
ret = GrowBuffer(&ssh->inputBuffer, totalLen);
if (ret != WS_SUCCESS) {
result = -205;
goto done;
}
WMEMCPY(ssh->inputBuffer.buffer, pkt, totalLen);
ssh->inputBuffer.length = totalLen;
ssh->inputBuffer.idx = 0;

ret = wolfSSH_TestDoReceive(ssh);
if (ret != WS_FATAL_ERROR) {
result = -206;
goto done;
}
if (ssh->error != WS_VERIFY_MAC_E) {
result = -207;
goto done;
}
}

done:
wolfSSH_free(ssh);
wolfSSH_CTX_free(ctx);
return result;
}
#endif /* WOLFSSH_TEST_INTERNAL && any HMAC SHA variant enabled */


/* Error Code And Message Test */

static int test_Errors(void)
Expand Down Expand Up @@ -356,6 +504,17 @@ int wolfSSH_UnitTest(int argc, char** argv)
printf("KDF: %s\n", (unitResult == 0 ? "SUCCESS" : "FAILED"));
testResult = testResult || unitResult;

#if defined(WOLFSSH_TEST_INTERNAL) && \
(!defined(WOLFSSH_NO_HMAC_SHA1) || \
!defined(WOLFSSH_NO_HMAC_SHA1_96) || \
!defined(WOLFSSH_NO_HMAC_SHA2_256) || \
!defined(WOLFSSH_NO_HMAC_SHA2_512))
unitResult = test_DoReceive_VerifyMacFailure();
printf("DoReceiveVerifyMac: %s\n",
(unitResult == 0 ? "SUCCESS" : "FAILED"));
testResult = testResult || unitResult;
#endif

#ifdef WOLFSSH_KEYGEN
#ifndef WOLFSSH_NO_RSA
unitResult = test_RsaKeyGen();
Expand Down
1 change: 1 addition & 0 deletions wolfssh/internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -1323,6 +1323,7 @@ enum WS_MessageIdLimits {
#ifdef WOLFSSH_TEST_INTERNAL
WOLFSSH_API int wolfSSH_TestIsMessageAllowed(WOLFSSH* ssh, byte msg,
byte state);
WOLFSSH_API int wolfSSH_TestDoReceive(WOLFSSH* ssh);
#endif

/* dynamic memory types */
Expand Down
Loading