@brief Verify OTA authentication response @param password Password to verify against @param nonce Server nonce (64 chars hex) @param cnonce Client nonce from response @param response Client response to verify @return true if authentication successful
| 942 | /// @param response Client response to verify |
| 943 | /// @return true if authentication successful |
| 944 | static bool verifyAuth(const char* password, const char* nonce, |
| 945 | const char* cnonce, const char* response) { |
| 946 | // Compute password hash (SHA256) |
| 947 | unsigned char pass_hash[32]; |
| 948 | mbedtls_sha256((unsigned char*)password, strlen(password), pass_hash, 0); |
| 949 | |
| 950 | // Convert password hash to hex |
| 951 | char pass_hash_hex[65]; |
| 952 | for (int i = 0; i < 32; i++) { |
| 953 | fl::snprintf(pass_hash_hex + i * 2, 3, "%02x", pass_hash[i]); |
| 954 | } |
| 955 | pass_hash_hex[64] = '\0'; |
| 956 | |
| 957 | // Derive key using simple iteration (simplified PBKDF2-like) |
| 958 | unsigned char derived_key[32]; |
| 959 | fl::memcpy(derived_key, pass_hash, 32); |
| 960 | for (int i = 0; i < 1000; i++) { // 1000 iterations (lighter than 10000) |
| 961 | mbedtls_sha256(derived_key, 32, derived_key, 0); |
| 962 | } |
| 963 | |
| 964 | // Convert derived key to hex |
| 965 | char derived_key_hex[65]; |
| 966 | for (int i = 0; i < 32; i++) { |
| 967 | fl::snprintf(derived_key_hex + i * 2, 3, "%02x", derived_key[i]); |
| 968 | } |
| 969 | derived_key_hex[64] = '\0'; |
| 970 | |
| 971 | // Compute expected response: SHA256(derived_key_hex:nonce:cnonce) |
| 972 | char auth_string[256]; |
| 973 | fl::snprintf(auth_string, sizeof(auth_string), "%s:%s:%s", |
| 974 | derived_key_hex, nonce, cnonce); |
| 975 | |
| 976 | unsigned char expected_hash[32]; |
| 977 | mbedtls_sha256((unsigned char*)auth_string, strlen(auth_string), |
| 978 | expected_hash, 0); |
| 979 | |
| 980 | char expected_response[65]; |
| 981 | for (int i = 0; i < 32; i++) { |
| 982 | fl::snprintf(expected_response + i * 2, 3, "%02x", expected_hash[i]); |
| 983 | } |
| 984 | expected_response[64] = '\0'; |
| 985 | |
| 986 | return strcmp(response, expected_response) == 0; |
| 987 | } |
| 988 | |
| 989 | /// @brief Handle TCP firmware upload after successful invitation/auth |
| 990 | /// @param client_addr UDP client address |