@@ -3352,6 +3352,99 @@ static int test_MsgHighwater(void)
33523352 return result;
33533353}
33543354
3355+ /* Sibling of test_MsgHighwater for the byte-count branch of HighwaterCheck
3356+ * (RFC 4253 Section 9 keystream/IV bound). Covers:
3357+ * - Threshold boundary: mark-1 does not fire, mark fires (>= not >)
3358+ * - Callback fires exactly once per epoch (highwaterFlag gates re-firing)
3359+ * - Receive side fires independently after an epoch reset
3360+ * - highwaterMark == 0 disables the byte check */
3361+ static int test_ByteHighwater(void)
3362+ {
3363+ WOLFSSH_CTX* ctx = NULL;
3364+ WOLFSSH* ssh = NULL;
3365+ HwTestCtx hc;
3366+ int result = 0;
3367+
3368+ ctx = wolfSSH_CTX_new(WOLFSSH_ENDPOINT_SERVER, NULL);
3369+ if (ctx == NULL)
3370+ return -820;
3371+
3372+ WMEMSET(&hc, 0, sizeof(hc));
3373+ wolfSSH_SetHighwaterCb(ctx, 1024, HwTestCb);
3374+
3375+ ssh = wolfSSH_new(ctx);
3376+ if (ssh == NULL) {
3377+ result = -821;
3378+ goto done;
3379+ }
3380+ wolfSSH_SetHighwaterCtx(ssh, &hc);
3381+ /* Disable the packet-count branch so only the byte branch is under
3382+ * test. */
3383+ wolfSSH_SetMsgHighwater(ssh, 0);
3384+
3385+ if (wolfSSH_GetHighwater(ssh) != 1024) {
3386+ result = -822;
3387+ goto done;
3388+ }
3389+
3390+ /* One byte under the mark on both sides: must not fire. */
3391+ ssh->txCount = 1023;
3392+ ssh->rxCount = 1023;
3393+ if (wolfSSH_TestHighwaterCheck(ssh, WOLFSSH_HWSIDE_TRANSMIT) != WS_SUCCESS
3394+ || hc.count != 0) {
3395+ result = -823;
3396+ goto done;
3397+ }
3398+
3399+ /* At the mark: fires, with the transmit side reported. */
3400+ ssh->txCount = 1024;
3401+ if (wolfSSH_TestHighwaterCheck(ssh, WOLFSSH_HWSIDE_TRANSMIT) != WS_SUCCESS
3402+ || hc.count != 1
3403+ || hc.lastSide != WOLFSSH_HWSIDE_TRANSMIT) {
3404+ result = -824;
3405+ goto done;
3406+ }
3407+
3408+ /* Flag-gated: more bytes in the same epoch must not re-fire. */
3409+ ssh->txCount = 4096;
3410+ if (wolfSSH_TestHighwaterCheck(ssh, WOLFSSH_HWSIDE_TRANSMIT) != WS_SUCCESS
3411+ || hc.count != 1) {
3412+ result = -825;
3413+ goto done;
3414+ }
3415+
3416+ /* Fresh key epoch (highwaterFlag and tx/rxCount are reset by
3417+ * DoNewKeys/SendNewKeys): the receive side fires on its own. */
3418+ ssh->highwaterFlag = 0;
3419+ ssh->txCount = 0;
3420+ ssh->rxCount = 1024;
3421+ if (wolfSSH_TestHighwaterCheck(ssh, WOLFSSH_HWSIDE_RECEIVE) != WS_SUCCESS
3422+ || hc.count != 2
3423+ || hc.lastSide != WOLFSSH_HWSIDE_RECEIVE) {
3424+ result = -826;
3425+ goto done;
3426+ }
3427+
3428+ /* mark == 0 disables the byte check entirely. */
3429+ if (wolfSSH_SetHighwater(ssh, 0) != WS_SUCCESS) {
3430+ result = -827;
3431+ goto done;
3432+ }
3433+ ssh->highwaterFlag = 0;
3434+ ssh->txCount = 0xFFFFFFFFu;
3435+ ssh->rxCount = 0xFFFFFFFFu;
3436+ if (wolfSSH_TestHighwaterCheck(ssh, WOLFSSH_HWSIDE_TRANSMIT) != WS_SUCCESS
3437+ || hc.count != 2) {
3438+ result = -828;
3439+ goto done;
3440+ }
3441+
3442+ done:
3443+ wolfSSH_free(ssh);
3444+ wolfSSH_CTX_free(ctx);
3445+ return result;
3446+ }
3447+
33553448static int test_DoChannelSuccess(void)
33563449{
33573450 WOLFSSH_CTX* ctx = NULL;
@@ -14514,6 +14607,10 @@ int wolfSSH_UnitTest(int argc, char** argv)
1451414607 printf("MsgHighwater: %s\n", (unitResult == 0 ? "SUCCESS" : "FAILED"));
1451514608 testResult = testResult || unitResult;
1451614609
14610+ unitResult = test_ByteHighwater();
14611+ printf("ByteHighwater: %s\n", (unitResult == 0 ? "SUCCESS" : "FAILED"));
14612+ testResult = testResult || unitResult;
14613+
1451714614 unitResult = test_DoUserAuthRequest_serviceName();
1451814615 printf("DoUserAuthRequest_serviceName: %s\n",
1451914616 (unitResult == 0 ? "SUCCESS" : "FAILED"));
0 commit comments