[TLS] KeyUpdate storms from buggy update_requested logic

David Benjamin <davidben@chromium.org> Mon, 25 March 2024 18:29 UTC

Return-Path: <davidben@google.com>
X-Original-To: tls@ietfa.amsl.com
Delivered-To: tls@ietfa.amsl.com
Received: from localhost (localhost [127.0.0.1]) by ietfa.amsl.com (Postfix) with ESMTP id 27665C151998 for <tls@ietfa.amsl.com>; Mon, 25 Mar 2024 11:29:55 -0700 (PDT)
X-Virus-Scanned: amavisd-new at amsl.com
X-Spam-Flag: NO
X-Spam-Score: -9.258
X-Spam-Level:
X-Spam-Status: No, score=-9.258 tagged_above=-999 required=5 tests=[BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, HEADER_FROM_DIFFERENT_DOMAINS=0.249, HTML_MESSAGE=0.001, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_ZEN_BLOCKED_OPENDNS=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01, URIBL_DBL_BLOCKED_OPENDNS=0.001, URIBL_ZEN_BLOCKED_OPENDNS=0.001, USER_IN_DEF_SPF_WL=-7.5] autolearn=no autolearn_force=no
Authentication-Results: ietfa.amsl.com (amavisd-new); dkim=pass (1024-bit key) header.d=chromium.org
Received: from mail.ietf.org ([50.223.129.194]) by localhost (ietfa.amsl.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id Mg17QTZ_hjQd for <tls@ietfa.amsl.com>; Mon, 25 Mar 2024 11:29:51 -0700 (PDT)
Received: from mail-yw1-x1130.google.com (mail-yw1-x1130.google.com [IPv6:2607:f8b0:4864:20::1130]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by ietfa.amsl.com (Postfix) with ESMTPS id 49834C14F5F7 for <tls@ietf.org>; Mon, 25 Mar 2024 11:29:51 -0700 (PDT)
Received: by mail-yw1-x1130.google.com with SMTP id 00721157ae682-609fd5fbe50so52568027b3.0 for <tls@ietf.org>; Mon, 25 Mar 2024 11:29:51 -0700 (PDT)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; t=1711391390; x=1711996190; darn=ietf.org; h=cc:to:subject:message-id:date:from:mime-version:from:to:cc:subject :date:message-id:reply-to; bh=XVDLgcUKgXwIlGq18TPG2Q8iIdBOWKdHeeJvL87B+so=; b=YqlvTkOwfGErDUd09xuT5nyCGTumrbkDXANgSh6BotPrQbqpAPBIjFRlBCnZgjp7+c 87TAYjnIkBb1hqqmQbohsltXwjfuts2V8+AoX8IAQkkINuospvC1N1/T2/JCPyRMJdG2 a/mepivFLkMk7rzxbrP7Hno86ZYg45bBZneRg=
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1711391390; x=1711996190; h=cc:to:subject:message-id:date:from:mime-version:x-gm-message-state :from:to:cc:subject:date:message-id:reply-to; bh=XVDLgcUKgXwIlGq18TPG2Q8iIdBOWKdHeeJvL87B+so=; b=dMtn8LuxVj8eBKCT+DQF4ltczwuAoK1TpnEocYz6lDqod5Zw4Q3C7lL4ZsZBiDxODh B5YRxFrLaFuNeBqd3Q4D1hIU6mbOxKSjXuM6I5+JZn6PXEfVwZgHXkHJRPEDrH2zx7gk X2KdiWZjgUqs+wN05275dfY2gBjiY/X5HB77essQm3KHIIfDiLHqfAZa7E8JHX/Db+8R KucQG6ST//Ndmwf6HkaBP/GLlj+oFJfeAqRwrwO84iYTkAURxkOjj+vkn07ocvf2ZEHm KeypeOyJGUoe4PRa35pTlJMYWEw8/wOInLPOFEf5nxJbxJYuyFp8CGTsWgiPLKDnSPZ+ T6ww==
X-Gm-Message-State: AOJu0YzrglNUEFeCDVTug9TVV6pkExICTtXMD4aCfNUtW/fQnQd6f0by c157Rq6GPjBOvdN5MtIDLTt9fjIUPjcJhD3O5AFvopDl/7oRzoxl+/1cGKumkjyKwm2zc1uys3z W+B0SECAx2x4qmJPyzu1XawePnpvmyIt6sRh2b5+JhDoK8zzehjc=
X-Google-Smtp-Source: AGHT+IFyLgNdMRVoqm/xt+5gf6WpAPGlAabCxHLVUOGR1wYuMa0myFH9cO2iXUl79JZ6kUrmrva3KDGvUgZl243cU40=
X-Received: by 2002:a25:2984:0:b0:dcc:5a25:ae88 with SMTP id p126-20020a252984000000b00dcc5a25ae88mr193701ybp.19.1711391389575; Mon, 25 Mar 2024 11:29:49 -0700 (PDT)
MIME-Version: 1.0
From: David Benjamin <davidben@chromium.org>
Date: Mon, 25 Mar 2024 14:29:30 -0400
Message-ID: <CAF8qwaAxBZUPFDOuNq2_R3XYtqCLKPJ8Tcb2NuFB7+n7oejJQw@mail.gmail.com>
To: "<tls@ietf.org>" <tls@ietf.org>
Content-Type: multipart/alternative; boundary="000000000000d9521a0614805b90"
Archived-At: <https://mailarchive.ietf.org/arch/msg/tls/nV2YZjl7joBchIClVoqqxOhA1Vc>
Subject: [TLS] KeyUpdate storms from buggy update_requested logic
X-BeenThere: tls@ietf.org
X-Mailman-Version: 2.1.39
Precedence: list
List-Id: "This is the mailing list for the Transport Layer Security working group of the IETF." <tls.ietf.org>
List-Unsubscribe: <https://www.ietf.org/mailman/options/tls>, <mailto:tls-request@ietf.org?subject=unsubscribe>
List-Archive: <https://mailarchive.ietf.org/arch/browse/tls/>
List-Post: <mailto:tls@ietf.org>
List-Help: <mailto:tls-request@ietf.org?subject=help>
List-Subscribe: <https://www.ietf.org/mailman/listinfo/tls>, <mailto:tls-request@ietf.org?subject=subscribe>
X-List-Received-Date: Mon, 25 Mar 2024 18:29:55 -0000

Hi all,

MT and I were discussing KeyUpdate at the meeting, and I realized I never
got around to writing up an issue we'd observed in real world TLS 1.3
deployments. rfc8446bis is pretty far along now, but MT suggested I write
this up anyway:

We ran into a fun bug with a major TLS implementation that would send an
update_requested KeyUpdate once the other side sent more than N records.
However, they were broken and *sent it on every record that came in after
the threshold was crossed*. Now, imagine the channel is asymmetric and you
are sending at a much faster rate than the buggy peer. Or, even worse,
imagine if this is a simple, non-multiplexed request/response application
protocol, and you're in the middle of sending a very, very large response.
You won't read from the peer until you're done with that response.

In the time it takes for you to finish sending your response, resume
reading, pick up the KeyUpdate, and reply, there will have been many, many
record's past the peer's threshold. Once you go back to reading, you wake
up to a huge storm of KeyUpdates. That's assuming the peer hasn't managed
to deadlock itself by filling the TCP send buffer with KeyUpdates and
blocking, or DoS itself by buffering those writes up instead and burning
memory on queued writes.

This is clearly undesirable. There is no point in sending an
update_requested past the first one because repeat requests won't change
anything. The spec already has text that says:

> Note that implementations may receive an arbitrary
> number of messages between sending a KeyUpdate with request_update set
> to "update_requested" and receiving the
> peer's KeyUpdate, because those messages may already be in flight.

However, one needs to read between the lines to then realize "and therefore
I should not keep sending request_update because it's pointless". I've
filed https://github.com/tlswg/tls13-spec/issues/1341 describing the issue
and uploaded a PR at https://github.com/tlswg/tls13-spec/pull/1343 to
clarify this point.

Thoughts?

David