{"action":"created","comment":{"url":"https://api.github.com/repos/ekr/base-drafts/pulls/comments/189701048","pull_request_review_id":121922710,"id":189701048,"diff_hunk":"@@ -667,73 +600,85 @@ Early data within the TLS connection MUST NOT be used.  As it is for other TLS\n application data, a server MUST treat receiving early data on the TLS connection\n as a connection error of type PROTOCOL_VIOLATION.\n \n+## Rejecting 0-RTT\n \n-## QUIC Key Expansion {#key-expansion}\n+A server rejects 0-RTT by rejecting 0-RTT at the TLS layer.  This results in\n+early exporter keys being unavailable, thereby preventing the use of 0-RTT for\n+QUIC.\n \n-QUIC uses a system of packet protection secrets, keys and IVs that are modelled\n-on the system used in TLS {{!TLS13}}.  The secrets that QUIC uses\n-as the basis of its key schedule are obtained using TLS exporters (see Section\n-7.5 of {{!TLS13}}).\n+A client that attempts 0-RTT MUST also consider 0-RTT to be rejected if it\n+receives a Version Negotiation packet.\n \n+When 0-RTT is rejected, all connection characteristics that the client assumed\n+might be incorrect.  This includes the choice of application protocol, transport\n+parameters, and any application configuration.  The client therefore MUST reset\n+the state of all streams, including application state bound to those streams.\n \n-### QHKDF-Expand\n+## HelloRetryRequest\n \n-QUIC uses the Hash-based Key Derivation Function (HKDF) {{!HKDF=RFC5869}} with\n-the same hash function negotiated by TLS for key derivation.  For example, if\n-TLS is using the TLS_AES_128_GCM_SHA256, the SHA-256 hash function is used.\n+In TLS over TCP, the HelloRetryRequest feature ({{TLS13}; Section\n+4.1.4) can be used to correct a client's incorrect KeyShare extension\n+as well as for a stateless round trip check. From the perspective of\n+QUIC, this just looks like additional messages carried in the Initial\n+encryption level. Although it is in principle possible to use this\n+feature for address verification in QUIC, QUIC implementations SHOULD\n+instead use the RETRY feature ([TODO: REF]).\n \n-Most key derivations in this document use the QHKDF-Expand function, which uses\n-the HKDF expand function and is modelled on the HKDF-Expand-Label function from\n-TLS 1.3 (see Section 7.1 of {{!TLS13}}). QHKDF-Expand differs from\n-HKDF-Expand-Label in that it uses a different base label and omits the Context\n-argument.\n \n-~~~\n-QHKDF-Expand(Secret, Label, Length) =\n-   HKDF-Expand(Secret, QhkdfExpandInfo, Length)\n-~~~\n+## TLS Errors\n \n-The HKDF-Expand function used by QHKDF-Expand uses the PRF hash function\n-negotiated by TLS, except for handshake secrets and keys derived from them (see\n-{{handshake-secrets}}).\n+If TLS experiences an error, it MUST generate an appropriate alert\n+as defined in {{TLS13}}; Section 6) and then provide it to QUIC,\n+which sends the alert in a CRYPTO_CLOSE frame. All such alerts are\n+\"fatal\".\n \n-Where the `info` parameter of HKDF-Expand is an encoded `QhkdfExpandInfo`\n-structure:\n \n-~~~\n-struct {\n-   uint16 length = Length;\n-   opaque label<6..255> = \"QUIC \" + Label;\n-} QhkdfExpandInfo;\n-~~~\n+# QUIC Packet Protection {#packet-protection}\n+\n+As with TLS over TCP QUIC encrypts packets with keys derived from the TLS\n+handshake, using the AEAD algorithm negotiated by TLS.\n \n-For example, assuming a hash function with a 32 octet output, derivation for a\n-client packet protection key would use HKDF-Expand with an `info` parameter of\n-0x00200851554943206b6579.\n \n+## QUIC Packet Encryption Keys {#encryption-keys}\n \n-### Handshake Secrets {#handshake-secrets}\n+QUIC derives packet encryption keys in the same way as TLS 1.3:\n+Each encryption level/direction pair has a secret value, which\n+is then used to derive the traffic keys using as described\n+in {{TLS13}}; Section 7.3.\n \n-Packets that carry the TLS handshake (Initial, Retry, and Handshake) are\n-protected with a secret derived from the Destination Connection ID field from\n-the client's Initial packet.  Specifically:\n+The keys for the Initial encryption level are computed based on\n+the client's first Destination Connection Id, as described in\n+{{initial-secrets}}.\n+\n+The keys for the remaining encryption level are computed in the same\n+fashion as the corresponding TLS keys (see {{TLS13}}; Section 7),\n+except that the label for HKDF-Expand-Label uses the prefix \"quic \"\n+rather than \"tls 13\". The purpose of this change is to provide key\n+separation between TLS and QUIC, so that TLS stacks can avoid\n+exposing TLS record protection keys.\n+\n+### Initial Secrets {#initial-secrets}\n+\n+Packets that carry the TLS handshake (Initial and Handshake) are protected with","path":"draft-ietf-quic-tls.md","position":770,"original_position":770,"commit_id":"cc04e4e520b3a27eeac5b9aded7a90bc1a859ded","original_commit_id":"cc04e4e520b3a27eeac5b9aded7a90bc1a859ded","user":{"login":"MikeBishop","id":4273797,"avatar_url":"https://avatars0.githubusercontent.com/u/4273797?v=4","gravatar_id":"","url":"https://api.github.com/users/MikeBishop","html_url":"https://github.com/MikeBishop","followers_url":"https://api.github.com/users/MikeBishop/followers","following_url":"https://api.github.com/users/MikeBishop/following{/other_user}","gists_url":"https://api.github.com/users/MikeBishop/gists{/gist_id}","starred_url":"https://api.github.com/users/MikeBishop/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/MikeBishop/subscriptions","organizations_url":"https://api.github.com/users/MikeBishop/orgs","repos_url":"https://api.github.com/users/MikeBishop/repos","events_url":"https://api.github.com/users/MikeBishop/events{/privacy}","received_events_url":"https://api.github.com/users/MikeBishop/received_events","type":"User","site_admin":false},"body":"Wait, Handshake packets are protected with the Initial key, and not with the Handshake key?  Then what packet type uses the Handshake key?  If Handshake packets can be protected with either key, how does the receiver differentiate again?\r\n\r\nI'm hoping the simplest answer is correct, and Handshake shouldn't be in this section.","created_at":"2018-05-21T20:17:05Z","updated_at":"2018-05-21T20:38:12Z","html_url":"https://github.com/ekr/base-drafts/pull/9#discussion_r189701048","pull_request_url":"https://api.github.com/repos/ekr/base-drafts/pulls/9","author_association":"NONE","_links":{"self":{"href":"https://api.github.com/repos/ekr/base-drafts/pulls/comments/189701048"},"html":{"href":"https://github.com/ekr/base-drafts/pull/9#discussion_r189701048"},"pull_request":{"href":"https://api.github.com/repos/ekr/base-drafts/pulls/9"}}},"pull_request":{"url":"https://api.github.com/repos/ekr/base-drafts/pulls/9","id":188754994,"html_url":"https://github.com/ekr/base-drafts/pull/9","diff_url":"https://github.com/ekr/base-drafts/pull/9.diff","patch_url":"https://github.com/ekr/base-drafts/pull/9.patch","issue_url":"https://api.github.com/repos/ekr/base-drafts/issues/9","number":9,"state":"open","locked":false,"title":"Stream0 dt output","user":{"login":"ekr","id":1111457,"avatar_url":"https://avatars0.githubusercontent.com/u/1111457?v=4","gravatar_id":"","url":"https://api.github.com/users/ekr","html_url":"https://github.com/ekr","followers_url":"https://api.github.com/users/ekr/followers","following_url":"https://api.github.com/users/ekr/following{/other_user}","gists_url":"https://api.github.com/users/ekr/gists{/gist_id}","starred_url":"https://api.github.com/users/ekr/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ekr/subscriptions","organizations_url":"https://api.github.com/users/ekr/orgs","repos_url":"https://api.github.com/users/ekr/repos","events_url":"https://api.github.com/users/ekr/events{/privacy}","received_events_url":"https://api.github.com/users/ekr/received_events","type":"User","site_admin":false},"body":"This is the consolidated PR.","created_at":"2018-05-17T14:24:30Z","updated_at":"2018-05-21T20:38:12Z","closed_at":null,"merged_at":null,"merge_commit_sha":"4f8faaba24f62c2b28a290bddc95317a5d4c3f79","assignee":null,"assignees":[],"requested_reviewers":[],"requested_teams":[],"labels":[],"milestone":null,"commits_url":"https://api.github.com/repos/ekr/base-drafts/pulls/9/commits","review_comments_url":"https://api.github.com/repos/ekr/base-drafts/pulls/9/comments","review_comment_url":"https://api.github.com/repos/ekr/base-drafts/pulls/comments{/number}","comments_url":"https://api.github.com/repos/ekr/base-drafts/issues/9/comments","statuses_url":"https://api.github.com/repos/ekr/base-drafts/statuses/cc04e4e520b3a27eeac5b9aded7a90bc1a859ded","head":{"label":"ekr:stream0_dt_output","ref":"stream0_dt_output","sha":"cc04e4e520b3a27eeac5b9aded7a90bc1a859ded","user":{"login":"ekr","id":1111457,"avatar_url":"https://avatars0.githubusercontent.com/u/1111457?v=4","gravatar_id":"","url":"https://api.github.com/users/ekr","html_url":"https://github.com/ekr","followers_url":"https://api.github.com/users/ekr/followers","following_url":"https://api.github.com/users/ekr/following{/other_user}","gists_url":"https://api.github.com/users/ekr/gists{/gist_id}","starred_url":"https://api.github.com/users/ekr/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ekr/subscriptions","organizations_url":"https://api.github.com/users/ekr/orgs","repos_url":"https://api.github.com/users/ekr/repos","events_url":"https://api.github.com/users/ekr/events{/privacy}","received_events_url":"https://api.github.com/users/ekr/received_events","type":"User","site_admin":false},"repo":{"id":74522960,"name":"base-drafts","full_name":"ekr/base-drafts","owner":{"login":"ekr","id":1111457,"avatar_url":"https://avatars0.githubusercontent.com/u/1111457?v=4","gravatar_id":"","url":"https://api.github.com/users/ekr","html_url":"https://github.com/ekr","followers_url":"https://api.github.com/users/ekr/followers","following_url":"https://api.github.com/users/ekr/following{/other_user}","gists_url":"https://api.github.com/users/ekr/gists{/gist_id}","starred_url":"https://api.github.com/users/ekr/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ekr/subscriptions","organizations_url":"https://api.github.com/users/ekr/orgs","repos_url":"https://api.github.com/users/ekr/repos","events_url":"https://api.github.com/users/ekr/events{/privacy}","received_events_url":"https://api.github.com/users/ekr/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/ekr/base-drafts","description":" Internet-Drafts that make up the base QUIC specification","fork":true,"url":"https://api.github.com/repos/ekr/base-drafts","forks_url":"https://api.github.com/repos/ekr/base-drafts/forks","keys_url":"https://api.github.com/repos/ekr/base-drafts/keys{/key_id}","collaborators_url":"https://api.github.com/repos/ekr/base-drafts/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/ekr/base-drafts/teams","hooks_url":"https://api.github.com/repos/ekr/base-drafts/hooks","issue_events_url":"https://api.github.com/repos/ekr/base-drafts/issues/events{/number}","events_url":"https://api.github.com/repos/ekr/base-drafts/events","assignees_url":"https://api.github.com/repos/ekr/base-drafts/assignees{/user}","branches_url":"https://api.github.com/repos/ekr/base-drafts/branches{/branch}","tags_url":"https://api.github.com/repos/ekr/base-drafts/tags","blobs_url":"https://api.github.com/repos/ekr/base-drafts/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/ekr/base-drafts/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/ekr/base-drafts/git/refs{/sha}","trees_url":"https://api.github.com/repos/ekr/base-drafts/git/trees{/sha}","statuses_url":"https://api.github.com/repos/ekr/base-drafts/statuses/{sha}","languages_url":"https://api.github.com/repos/ekr/base-drafts/languages","stargazers_url":"https://api.github.com/repos/ekr/base-drafts/stargazers","contributors_url":"https://api.github.com/repos/ekr/base-drafts/contributors","subscribers_url":"https://api.github.com/repos/ekr/base-drafts/subscribers","subscription_url":"https://api.github.com/repos/ekr/base-drafts/subscription","commits_url":"https://api.github.com/repos/ekr/base-drafts/commits{/sha}","git_commits_url":"https://api.github.com/repos/ekr/base-drafts/git/commits{/sha}","comments_url":"https://api.github.com/repos/ekr/base-drafts/comments{/number}","issue_comment_url":"https://api.github.com/repos/ekr/base-drafts/issues/comments{/number}","contents_url":"https://api.github.com/repos/ekr/base-drafts/contents/{+path}","compare_url":"https://api.github.com/repos/ekr/base-drafts/compare/{base}...{head}","merges_url":"https://api.github.com/repos/ekr/base-drafts/merges","archive_url":"https://api.github.com/repos/ekr/base-drafts/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/ekr/base-drafts/downloads","issues_url":"https://api.github.com/repos/ekr/base-drafts/issues{/number}","pulls_url":"https://api.github.com/repos/ekr/base-drafts/pulls{/number}","milestones_url":"https://api.github.com/repos/ekr/base-drafts/milestones{/number}","notifications_url":"https://api.github.com/repos/ekr/base-drafts/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/ekr/base-drafts/labels{/name}","releases_url":"https://api.github.com/repos/ekr/base-drafts/releases{/id}","deployments_url":"https://api.github.com/repos/ekr/base-drafts/deployments","created_at":"2016-11-22T23:42:49Z","updated_at":"2018-05-17T14:25:07Z","pushed_at":"2018-05-18T20:56:04Z","git_url":"git://github.com/ekr/base-drafts.git","ssh_url":"git@github.com:ekr/base-drafts.git","clone_url":"https://github.com/ekr/base-drafts.git","svn_url":"https://github.com/ekr/base-drafts","homepage":null,"size":4624,"stargazers_count":1,"watchers_count":1,"language":"Python","has_issues":false,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":2,"mirror_url":null,"archived":false,"open_issues_count":1,"license":null,"forks":2,"open_issues":1,"watchers":1,"default_branch":"master"}},"base":{"label":"ekr:master","ref":"master","sha":"3060c471f0015bde65d7b1a4eca1edbc8bd1cf45","user":{"login":"ekr","id":1111457,"avatar_url":"https://avatars0.githubusercontent.com/u/1111457?v=4","gravatar_id":"","url":"https://api.github.com/users/ekr","html_url":"https://github.com/ekr","followers_url":"https://api.github.com/users/ekr/followers","following_url":"https://api.github.com/users/ekr/following{/other_user}","gists_url":"https://api.github.com/users/ekr/gists{/gist_id}","starred_url":"https://api.github.com/users/ekr/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ekr/subscriptions","organizations_url":"https://api.github.com/users/ekr/orgs","repos_url":"https://api.github.com/users/ekr/repos","events_url":"https://api.github.com/users/ekr/events{/privacy}","received_events_url":"https://api.github.com/users/ekr/received_events","type":"User","site_admin":false},"repo":{"id":74522960,"name":"base-drafts","full_name":"ekr/base-drafts","owner":{"login":"ekr","id":1111457,"avatar_url":"https://avatars0.githubusercontent.com/u/1111457?v=4","gravatar_id":"","url":"https://api.github.com/users/ekr","html_url":"https://github.com/ekr","followers_url":"https://api.github.com/users/ekr/followers","following_url":"https://api.github.com/users/ekr/following{/other_user}","gists_url":"https://api.github.com/users/ekr/gists{/gist_id}","starred_url":"https://api.github.com/users/ekr/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ekr/subscriptions","organizations_url":"https://api.github.com/users/ekr/orgs","repos_url":"https://api.github.com/users/ekr/repos","events_url":"https://api.github.com/users/ekr/events{/privacy}","received_events_url":"https://api.github.com/users/ekr/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/ekr/base-drafts","description":" Internet-Drafts that make up the base QUIC specification","fork":true,"url":"https://api.github.com/repos/ekr/base-drafts","forks_url":"https://api.github.com/repos/ekr/base-drafts/forks","keys_url":"https://api.github.com/repos/ekr/base-drafts/keys{/key_id}","collaborators_url":"https://api.github.com/repos/ekr/base-drafts/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/ekr/base-drafts/teams","hooks_url":"https://api.github.com/repos/ekr/base-drafts/hooks","issue_events_url":"https://api.github.com/repos/ekr/base-drafts/issues/events{/number}","events_url":"https://api.github.com/repos/ekr/base-drafts/events","assignees_url":"https://api.github.com/repos/ekr/base-drafts/assignees{/user}","branches_url":"https://api.github.com/repos/ekr/base-drafts/branches{/branch}","tags_url":"https://api.github.com/repos/ekr/base-drafts/tags","blobs_url":"https://api.github.com/repos/ekr/base-drafts/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/ekr/base-drafts/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/ekr/base-drafts/git/refs{/sha}","trees_url":"https://api.github.com/repos/ekr/base-drafts/git/trees{/sha}","statuses_url":"https://api.github.com/repos/ekr/base-drafts/statuses/{sha}","languages_url":"https://api.github.com/repos/ekr/base-drafts/languages","stargazers_url":"https://api.github.com/repos/ekr/base-drafts/stargazers","contributors_url":"https://api.github.com/repos/ekr/base-drafts/contributors","subscribers_url":"https://api.github.com/repos/ekr/base-drafts/subscribers","subscription_url":"https://api.github.com/repos/ekr/base-drafts/subscription","commits_url":"https://api.github.com/repos/ekr/base-drafts/commits{/sha}","git_commits_url":"https://api.github.com/repos/ekr/base-drafts/git/commits{/sha}","comments_url":"https://api.github.com/repos/ekr/base-drafts/comments{/number}","issue_comment_url":"https://api.github.com/repos/ekr/base-drafts/issues/comments{/number}","contents_url":"https://api.github.com/repos/ekr/base-drafts/contents/{+path}","compare_url":"https://api.github.com/repos/ekr/base-drafts/compare/{base}...{head}","merges_url":"https://api.github.com/repos/ekr/base-drafts/merges","archive_url":"https://api.github.com/repos/ekr/base-drafts/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/ekr/base-drafts/downloads","issues_url":"https://api.github.com/repos/ekr/base-drafts/issues{/number}","pulls_url":"https://api.github.com/repos/ekr/base-drafts/pulls{/number}","milestones_url":"https://api.github.com/repos/ekr/base-drafts/milestones{/number}","notifications_url":"https://api.github.com/repos/ekr/base-drafts/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/ekr/base-drafts/labels{/name}","releases_url":"https://api.github.com/repos/ekr/base-drafts/releases{/id}","deployments_url":"https://api.github.com/repos/ekr/base-drafts/deployments","created_at":"2016-11-22T23:42:49Z","updated_at":"2018-05-17T14:25:07Z","pushed_at":"2018-05-18T20:56:04Z","git_url":"git://github.com/ekr/base-drafts.git","ssh_url":"git@github.com:ekr/base-drafts.git","clone_url":"https://github.com/ekr/base-drafts.git","svn_url":"https://github.com/ekr/base-drafts","homepage":null,"size":4624,"stargazers_count":1,"watchers_count":1,"language":"Python","has_issues":false,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":2,"mirror_url":null,"archived":false,"open_issues_count":1,"license":null,"forks":2,"open_issues":1,"watchers":1,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/ekr/base-drafts/pulls/9"},"html":{"href":"https://github.com/ekr/base-drafts/pull/9"},"issue":{"href":"https://api.github.com/repos/ekr/base-drafts/issues/9"},"comments":{"href":"https://api.github.com/repos/ekr/base-drafts/issues/9/comments"},"review_comments":{"href":"https://api.github.com/repos/ekr/base-drafts/pulls/9/comments"},"review_comment":{"href":"https://api.github.com/repos/ekr/base-drafts/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/ekr/base-drafts/pulls/9/commits"},"statuses":{"href":"https://api.github.com/repos/ekr/base-drafts/statuses/cc04e4e520b3a27eeac5b9aded7a90bc1a859ded"}},"author_association":"OWNER"}}
{"actor":{"display_login":"MikeBishop"}}