fix(protocomm): invalidate SRP session on proof-verify failure

handle_session_command1() left the session in SESSION_STATE_CMD1 with a
live esp_srp handle (ephemeral b/B and derived session key intact) when
the client SRP proof failed to validate. A client could therefore keep
sending Command1 messages with different guessed proofs against a single
handshake, turning the SRP exchange into an unlimited online dictionary
attack on the proof-of-possession.

Tear down the SRP context and reset the session back to
SESSION_STATE_CMD0 on proof-verify failure so that every guess now
requires a fresh, expensive Command0 handshake (new ephemeral). The
session id is preserved so the transport session stays valid for a
legitimate retry, and the credential-mismatch event still fires for
application-level lockout policies.

Closes SEC-620
This commit is contained in:
Aditya Patwardhan
2026-09-21 11:42:02 +05:30
parent f0d7736076
commit 4ba8c5efc3
@@ -247,6 +247,18 @@ static esp_err_t handle_session_command1(session_t *cur_session,
if (esp_srp_exchange_proofs(cur_session->srp_hd, cur_session->username, cur_session->username_len, (char * ) in->sc1->client_proof.data, device_proof) != ESP_OK) {
ESP_LOGE(TAG, "Failed to authenticate client proof!");
free(device_proof);
if (cur_session->srp_hd) {
esp_srp_free(cur_session->srp_hd);
cur_session->srp_hd = NULL;
}
cur_session->session_key = NULL;
cur_session->session_key_len = 0;
free(cur_session->username);
cur_session->username = NULL;
cur_session->username_len = 0;
cur_session->state = SESSION_STATE_CMD0;
if (esp_event_post(PROTOCOMM_SECURITY_SESSION_EVENT, PROTOCOMM_SECURITY_SESSION_CREDENTIALS_MISMATCH, NULL, 0, portMAX_DELAY) != ESP_OK) {
ESP_LOGE(TAG, "Failed to post credential mismatch event");
}