From 4ba8c5efc3a0d03968ca2924efbad2a4a30dde3a Mon Sep 17 00:00:00 2001 From: Aditya Patwardhan Date: Mon, 29 Jun 2026 13:49:58 +0530 Subject: [PATCH] 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 --- components/protocomm/src/security/security2.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/components/protocomm/src/security/security2.c b/components/protocomm/src/security/security2.c index 437148ec977..a8e36174589 100644 --- a/components/protocomm/src/security/security2.c +++ b/components/protocomm/src/security/security2.c @@ -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"); }