Skip to content

Commit b6652e6

Browse files
authored
Merge pull request #912 from yosuke-wolfssl/f_2482
Add unit test for VerifyMac
2 parents b71670f + aa4c9ff commit b6652e6

File tree

4 files changed

+176
-3
lines changed

4 files changed

+176
-3
lines changed

src/internal.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10502,6 +10502,13 @@ int DoReceive(WOLFSSH* ssh)
1050210502
return ret;
1050310503
}
1050410504

10505+
#ifdef WOLFSSH_TEST_INTERNAL
10506+
int wolfSSH_TestDoReceive(WOLFSSH* ssh)
10507+
{
10508+
return DoReceive(ssh);
10509+
}
10510+
#endif
10511+
1050510512

1050610513
int DoProtoId(WOLFSSH* ssh)
1050710514
{

tests/include.am

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@ check_PROGRAMS += tests/unit.test tests/api.test \
77
tests/regress.test
88

99
tests_unit_test_SOURCES = tests/unit.c tests/unit.h
10-
tests_unit_test_CPPFLAGS = -DNO_MAIN_DRIVER $(AM_CPPFLAGS)
11-
tests_unit_test_LDADD = src/libwolfssh.la
12-
tests_unit_test_DEPENDENCIES = src/libwolfssh.la
10+
tests_unit_test_CPPFLAGS = -DNO_MAIN_DRIVER -DWOLFSSH_TEST_INTERNAL $(AM_CPPFLAGS)
11+
tests_unit_test_LDADD = src/libwolfssh_test.la
12+
tests_unit_test_DEPENDENCIES = src/libwolfssh_test.la
1313

1414
tests_api_test_SOURCES = tests/api.c tests/api.h \
1515
examples/echoserver/echoserver.c

tests/unit.c

Lines changed: 165 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@
3131
#include <stdio.h>
3232
#include <wolfssh/ssh.h>
3333
#include <wolfssh/keygen.h>
34+
#include <wolfssh/internal.h>
35+
#include <wolfssl/wolfcrypt/hmac.h>
3436

3537
#define WOLFSSH_TEST_HEX2BIN
3638
#include <wolfssh/test.h>
@@ -285,6 +287,158 @@ static int test_Ed25519KeyGen(void)
285287
#endif
286288

287289

290+
#if defined(WOLFSSH_TEST_INTERNAL) && \
291+
(!defined(WOLFSSH_NO_HMAC_SHA1) || \
292+
!defined(WOLFSSH_NO_HMAC_SHA1_96) || \
293+
!defined(WOLFSSH_NO_HMAC_SHA2_256) || \
294+
!defined(WOLFSSH_NO_HMAC_SHA2_512))
295+
296+
/* Minimal SSH binary packet: uint32 length, padding_length, msgId, padding.
297+
* Same layout as tests/regress.c BuildPacket (8-byte aligned body). */
298+
static word32 BuildMacTestPacketPrefix(byte msgId, byte* out, word32 outSz)
299+
{
300+
byte padLen = 6;
301+
word32 packetLen = (word32)(1 + 1 + padLen);
302+
word32 need = UINT32_SZ + packetLen;
303+
304+
if (outSz < need)
305+
return 0;
306+
out[0] = (byte)(packetLen >> 24);
307+
out[1] = (byte)(packetLen >> 16);
308+
out[2] = (byte)(packetLen >> 8);
309+
out[3] = (byte)(packetLen);
310+
out[4] = padLen;
311+
out[5] = msgId;
312+
WMEMSET(out + 6, 0, padLen);
313+
return need;
314+
}
315+
316+
317+
static int test_DoReceive_VerifyMacFailure(void)
318+
{
319+
WOLFSSH_CTX* ctx = NULL;
320+
WOLFSSH* ssh = NULL;
321+
int ret = WS_SUCCESS;
322+
int result = 0;
323+
byte flatSeq[LENGTH_SZ];
324+
byte macKey[MAX_HMAC_SZ];
325+
Hmac hmac;
326+
word32 prefixLen;
327+
word32 totalLen;
328+
byte pkt[UINT32_SZ + 8 + MAX_HMAC_SZ];
329+
int i;
330+
struct {
331+
byte macId;
332+
int hmacType;
333+
byte macSz;
334+
byte keySz;
335+
} cases[] = {
336+
#ifndef WOLFSSH_NO_HMAC_SHA1
337+
{ ID_HMAC_SHA1, WC_SHA, WC_SHA_DIGEST_SIZE, WC_SHA_DIGEST_SIZE },
338+
#endif
339+
#ifndef WOLFSSH_NO_HMAC_SHA1_96
340+
{ ID_HMAC_SHA1_96, WC_SHA, SHA1_96_SZ, WC_SHA_DIGEST_SIZE },
341+
#endif
342+
#ifndef WOLFSSH_NO_HMAC_SHA2_256
343+
{ ID_HMAC_SHA2_256, WC_SHA256, WC_SHA256_DIGEST_SIZE,
344+
WC_SHA256_DIGEST_SIZE },
345+
#endif
346+
#ifndef WOLFSSH_NO_HMAC_SHA2_512
347+
{ ID_HMAC_SHA2_512, WC_SHA512, WC_SHA512_DIGEST_SIZE,
348+
WC_SHA512_DIGEST_SIZE },
349+
#endif
350+
};
351+
352+
ctx = wolfSSH_CTX_new(WOLFSSH_ENDPOINT_CLIENT, NULL);
353+
if (ctx == NULL)
354+
return -200;
355+
ssh = wolfSSH_new(ctx);
356+
if (ssh == NULL) {
357+
wolfSSH_CTX_free(ctx);
358+
return -201;
359+
}
360+
361+
WMEMSET(macKey, 0xA5, sizeof(macKey));
362+
363+
for (i = 0; i < (int)(sizeof(cases) / sizeof(cases[0])); i++) {
364+
prefixLen = BuildMacTestPacketPrefix(MSGID_IGNORE, pkt, sizeof(pkt));
365+
if (prefixLen == 0) {
366+
result = -202;
367+
goto done;
368+
}
369+
totalLen = prefixLen + cases[i].macSz;
370+
371+
ssh->peerEncryptId = ID_NONE;
372+
ssh->peerAeadMode = 0;
373+
ssh->peerBlockSz = MIN_BLOCK_SZ;
374+
ssh->peerMacId = cases[i].macId;
375+
ssh->peerMacSz = cases[i].macSz;
376+
WMEMCPY(ssh->peerKeys.macKey, macKey, cases[i].keySz);
377+
ssh->peerKeys.macKeySz = cases[i].keySz;
378+
ssh->peerSeq = 0;
379+
ssh->curSz = 0;
380+
ssh->processReplyState = PROCESS_INIT;
381+
ssh->error = 0;
382+
383+
flatSeq[0] = (byte)(ssh->peerSeq >> 24);
384+
flatSeq[1] = (byte)(ssh->peerSeq >> 16);
385+
flatSeq[2] = (byte)(ssh->peerSeq >> 8);
386+
flatSeq[3] = (byte)(ssh->peerSeq);
387+
ret = wc_HmacInit(&hmac, ssh->ctx->heap, INVALID_DEVID);
388+
if (ret != WS_SUCCESS) {
389+
result = -203;
390+
goto done;
391+
}
392+
{
393+
byte digest[WC_MAX_DIGEST_SIZE];
394+
ret = wc_HmacSetKey(&hmac, cases[i].hmacType,
395+
ssh->peerKeys.macKey, ssh->peerKeys.macKeySz);
396+
if (ret == WS_SUCCESS)
397+
ret = wc_HmacUpdate(&hmac, flatSeq, sizeof(flatSeq));
398+
if (ret == WS_SUCCESS)
399+
ret = wc_HmacUpdate(&hmac, pkt, prefixLen);
400+
if (ret == WS_SUCCESS)
401+
ret = wc_HmacFinal(&hmac, digest);
402+
wc_HmacFree(&hmac);
403+
if (ret == WS_SUCCESS)
404+
WMEMCPY(pkt + prefixLen, digest, cases[i].macSz);
405+
}
406+
if (ret != WS_SUCCESS) {
407+
result = -204;
408+
goto done;
409+
}
410+
411+
pkt[prefixLen] ^= 0x01;
412+
413+
ShrinkBuffer(&ssh->inputBuffer, 1);
414+
ret = GrowBuffer(&ssh->inputBuffer, totalLen);
415+
if (ret != WS_SUCCESS) {
416+
result = -205;
417+
goto done;
418+
}
419+
WMEMCPY(ssh->inputBuffer.buffer, pkt, totalLen);
420+
ssh->inputBuffer.length = totalLen;
421+
ssh->inputBuffer.idx = 0;
422+
423+
ret = wolfSSH_TestDoReceive(ssh);
424+
if (ret != WS_FATAL_ERROR) {
425+
result = -206;
426+
goto done;
427+
}
428+
if (ssh->error != WS_VERIFY_MAC_E) {
429+
result = -207;
430+
goto done;
431+
}
432+
}
433+
434+
done:
435+
wolfSSH_free(ssh);
436+
wolfSSH_CTX_free(ctx);
437+
return result;
438+
}
439+
#endif /* WOLFSSH_TEST_INTERNAL && any HMAC SHA variant enabled */
440+
441+
288442
/* Error Code And Message Test */
289443

290444
static int test_Errors(void)
@@ -355,6 +509,17 @@ int wolfSSH_UnitTest(int argc, char** argv)
355509
printf("KDF: %s\n", (unitResult == 0 ? "SUCCESS" : "FAILED"));
356510
testResult = testResult || unitResult;
357511

512+
#if defined(WOLFSSH_TEST_INTERNAL) && \
513+
(!defined(WOLFSSH_NO_HMAC_SHA1) || \
514+
!defined(WOLFSSH_NO_HMAC_SHA1_96) || \
515+
!defined(WOLFSSH_NO_HMAC_SHA2_256) || \
516+
!defined(WOLFSSH_NO_HMAC_SHA2_512))
517+
unitResult = test_DoReceive_VerifyMacFailure();
518+
printf("DoReceiveVerifyMac: %s\n",
519+
(unitResult == 0 ? "SUCCESS" : "FAILED"));
520+
testResult = testResult || unitResult;
521+
#endif
522+
358523
#ifdef WOLFSSH_KEYGEN
359524
#ifndef WOLFSSH_NO_RSA
360525
unitResult = test_RsaKeyGen();

wolfssh/internal.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1323,6 +1323,7 @@ enum WS_MessageIdLimits {
13231323
#ifdef WOLFSSH_TEST_INTERNAL
13241324
WOLFSSH_API int wolfSSH_TestIsMessageAllowed(WOLFSSH* ssh, byte msg,
13251325
byte state);
1326+
WOLFSSH_API int wolfSSH_TestDoReceive(WOLFSSH* ssh);
13261327
#endif
13271328

13281329
/* dynamic memory types */

0 commit comments

Comments
 (0)