QUICでinitial packetを送る前に client/server initial key, IV, header protection key の6つの鍵を作成する必要があります。これらの鍵を作成するためにclient_initial_secret, server_initial_secretを作成する必要があります。そしてそれらを作成するためにinitial_secretを作成する必要があり、initial_secretを作成するためにinitial_saltとクライアントが送る initial Destination Connection ID(8 bytes of random data)を使用します。
以下のように鍵を生成します。
HKDF-Extract はソルトと数バイトの鍵素材を与えると、256ビット(32バイト)の新しい鍵素材を作成するもので
RFC 5869: HMAC-based Extract-and-Expand Key Derivation Function (HKDF) section2.2 で説明されています。
HKDF-Expand-Labelは鍵素材、ラベル、コンテキストデータを入力から、要求された長さの新しい鍵を作成するもので、
RFC 8446: The Transport Layer Security (TLS) Protocol Version 1.3 section7.1で説明されています。
initical salt については以下のように書かれています。
Future versions of QUIC SHOULD generate a new salt value, thus ensuring that the keys are different for each version of QUIC. This prevents a middlebox that recognizes only one version of QUIC from seeing or modifying the contents of packets from future versions.
RFC 9001 - Using TLS to Secure QUIC
訳
QUICの将来のバージョンは新しいソルト値を生成すべきであり[SHOULD]、 その結果、鍵はQUICの各バージョンで異なることが保証される。これは、QUICの一つのバージョンだけを認識するミドルボックスが、 将来のバージョンからのパケットのコンテンツを見たり修正したりすることを防ぐ。
つまり将来のQUICの硬直化(ossification)の問題を緩和するために格バージョンごとにソルト値を変えます。将来新しいバージョンのQUICが出た時、そのバージョンに対応していない(そのバージョンのソルトを知らない)実装は、初期パケットを読めないようにしています。
QUIC version 2 では新しいソルトの値を記しています。
3.3. Cryptography changes 3.3.1. Initial Salt The salt used to derive Initial keys in Section 5.2 of [QUIC-TLS] changes to: initial_salt = 0xa707c203a59b47184a1d62ca570406ea7ae3e5d3
QUIC Version 2やQUICの硬直化の対策について詳しくはゆきさんのブログで。
RFC9001 に書かれているQUIC v1 のソルトは
initial_salt = 38762cf7f55934b34d179ae6a4c80cadccbb7f0a
ですが、この値"38762cf7f55934b34d179ae6a4c80cadccbb7f0a"はGoogleが見つけた初めてのSHA1衝突の値らしいです。
QUIC が RFCとして標準化せれる前のdraft段階ではdraftごとに変更が入っていました。
RFC9001の元となったdraft draft-ietf-quic-tlsの変更履歴をgithub上で眺めるとsaltが変更されているのがわかります。
Dec 8, 2020 現在のsaltになる。
draft29 draft-ietf-quic-http-29 で変更
C.5. Since draft-ietf-quic-tls-28
* Defined limits on the number of packets that can be protected with
a single key and limits on the number of packets that can fail
authentication (#3619, #3620)* Update Initial salt, Retry keys, and samples (#3711)
https://datatracker.ietf.org/doc/html/draft-ietf-quic-tls-34#appendix-C.5
draft23 で変更
C.11. Since draft-ietf-quic-tls-22
* Update the salt used for Initial secrets (#2887, #2980)
https://datatracker.ietf.org/doc/html/draft-ietf-quic-tls-34#appendix-C.11
draft21 で変更
C.13. Since draft-ietf-quic-tls-20
* Mandate the use of the QUIC transport parameters extension (#2528,
#2560)* Define handshake completion and confirmation; define clearer rules
when it encryption keys should be discarded (#2214, #2267, #2673)
https://datatracker.ietf.org/doc/html/draft-ietf-quic-tls-34#appendix-C.13
draft17
* Update the salt used for Initial secrets (#1970)
https://datatracker.ietf.org/doc/html/draft-ietf-quic-tls-34#appendix-C.16
draft13
(たくさんこの一つのコミットで変更が入ってる)
* Changes to integration of the TLS handshake (#829, #1018, #1094,
#1165, #1190, #1233, #1242, #1252, #1450)
https://datatracker.ietf.org/doc/html/draft-ietf-quic-tls-34#appendix-C.18
draft9
C.21. Since draft-ietf-quic-tls-09
* Cleaned up key schedule and updated the salt used for handshake
packet protection (#1077)
https://datatracker.ietf.org/doc/html/draft-ietf-quic-tls-34#appendix-C.21
draft7
面白いことに上記のコミットのコミットメッセージから分かる通り、今回のソルト
はdraft06のコミットハッシュです。
https://github.com/quicwg/base-drafts/commit/afc824ec5fc77eca1e9d36f37fb2d46518c36639
draftを追いながらQUICを実装していた方々はinitial saltに変更があるたびに変更を入れていたようです。
google/quicheを眺めると
drart29, RFC QUIC v1, QUIC v2 draft の initial saltが設定されています。