Code change:
extension will result in a new ClientHello to process, so even the client's TLS version preferences may have changed. <del> The ClientECH value is said to match a known ECHConfig if there exists an ECHConfig that can be used to successfully decrypt ClientECH.payload.  This matching procedure should be done using one of the following two checks: </del> <ins> First, the server collects a set of candidate ECHConfigs.  This set is determined by one of the two following methods: </ins> <del> Compare ClientECH.config_id against identifiers of known ECHConfig and choose the one that matches. </del> <ins> Compare ClientECH.config_id against identifiers of known ECHConfigs and select the one that matches, if any, as a candidate. </ins> <del> Use trial decryption of ClientECH.payload with known ECHConfig and choose the one that succeeds. </del> <ins> Collect all known ECHConfigs as candidates, with trial decryption below determining the final selection. </ins> Some uses of ECH, such as local discovery mode, may omit the ClientECH.config_id since it can be used as a tracking vector.  In <del> such cases, trial decryption should be used for matching ClientECH to known ECHConfig.  Unless specified by the application using (D)TLS or externally configured on both sides, implementations MUST use the first method. If the ClientECH value does not match any known ECHConfig structure, it MUST ignore the extension and proceed with the connection, with the following added behavior: It MUST include the "encrypted_client_hello" extension in its EncryptedExtensions with the "retry_configs" field set to one or more ECHConfig structures with up-to-date keys.  Servers MAY supply multiple ECHConfig values of different versions.  This allows a server to support multiple versions at once. If offered, the server MUST ignore the "pre_shared_key" extension in the ClientHello. Note that an unrecognized ClientECH.config_id value may be a GREASE ECH extension (see grease-extensions), so it is necessary for servers to proceed with the connection and rely on the client to abort if ECH was required.  In particular, the unrecognized value alone does not indicate a misconfigured ECH advertisement (misconfiguration). Instead, servers can measure occurrences of the "ech_required" alert to detect this case. </del> <ins> such cases, the second method should be used for matching ClientECH to known ECHConfig.  See optional-configs.  Unless specified by the application using (D)TLS or externally configured on both sides, implementations MUST use the first method. The server then iterates over all candidate ECHConfigs, attempting to decrypt the "encrypted_client_hello" extension: </ins> <del> Once a suitable ECHConfig is found, the server verifies that the ECHConfig supports the cipher suite indicated by ClientECH.cipher_suite and that the version of ECH indicated by the client matches the ECHConfig.version.  If not, then the server MUST abort with an "illegal_parameter" alert.  Otherwise, the server decrypts ClientECH.payload, using the private key skR corresponding to ECHConfig, as follows: </del> <ins> The server verifies that the ECHConfig supports the cipher suite indicated by the ClientECH.cipher_suite and that the version of ECH indicated by the client matches the ECHConfig.version.  If not, the server continues to the next candidate ECHConfig. Next, the server decrypts ClientECH.payload, using the private key skR corresponding to ECHConfig, as follows: </ins> ClientHelloOuterAAD is computed from ClientHelloOuter as described in <del> authenticating-outer.  If decryption fails, the server MUST abort the connection with a "decrypt_error" alert.  Otherwise, the server reconstructs ClientHelloInner from EncodedClientHelloInner, as described in encoding-inner. </del> <ins> authenticating-outer.  The "info" parameter to SetupBaseS is the concatenation "tls ech", a zero byte, and the serialized ECHConfig. If decryption fails, the server continues to the next candidate ECHConfig.  Otherwise, the server reconstructs ClientHelloInner from EncodedClientHelloInner, as described in encoding-inner.  It then stops consider candidate ECHConfigs. </ins> Upon determining the ClientHelloInner, the client-facing server then forwards the ClientHelloInner to the appropriate backend server,

Related discussion:
text: The spec describes an optional trial decryption mode, but most of the text contradicts it. This PR fixes the text up and tries to unify their processing models. In doing so, it flips the error handling from decrypterror to fallback to be consistent. This, combined with the ClientHelloOuterAAD change, plugs an active sticking out attack for free. It also makes easier because GREASE configid collisions with real configids are now harmless. Along the way, NAME and NAME observed that we're not authenticating the ECHConfig at all. (It used to be authenticated by way of the configid, which was a digest.) Instead, just pass the ECHConfig into the info field of the HPKE context. They also noticed the server rule about PSKs on ClientHelloOuter didn't work with GREASE. Instead, we can simply remove it.
This matches the acceptance signal length, and we've already accepted that probability of collision.