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