diff --git a/.github/workflows/daily-tests.yml b/.github/workflows/daily-tests.yml index df4c0c16..9dc7bb65 100644 --- a/.github/workflows/daily-tests.yml +++ b/.github/workflows/daily-tests.yml @@ -130,3 +130,61 @@ jobs: shell: bash run: | grep 'sni=encrypted' ech-test.log + + prefer-pq: + name: "Post-quantum (${{ matrix.os }})" + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [ ubuntu-latest, macos-latest, windows-latest ] + + steps: + - name: Checkout sources + uses: actions/checkout@v4 + with: + persist-credentials: false + + - name: Install nightly toolchain + uses: dtolnay/rust-toolchain@nightly + + - name: Install cargo-c (Ubuntu) + if: matrix.os == 'ubuntu-latest' + env: + LINK: https://github.com/lu-zero/cargo-c/releases/latest/download + CARGO_C_FILE: cargo-c-x86_64-unknown-linux-musl.tar.gz + run: | + curl -L $LINK/$CARGO_C_FILE | tar xz -C ~/.cargo/bin + - name: Install cargo-c (macOS) + if: matrix.os == 'macos-latest' + env: + LINK: https://github.com/lu-zero/cargo-c/releases/latest/download + CARGO_C_FILE: cargo-c-macos.zip + run: | + curl -L $LINK/$CARGO_C_FILE -o cargo-c-macos.zip + unzip cargo-c-macos.zip -d ~/.cargo/bin + - name: Install cargo-c (Windows) + if: matrix.os == 'windows-latest' + env: + LINK: https://github.com/lu-zero/cargo-c/releases/latest/download + CARGO_C_FILE: cargo-c-windows-msvc.zip + run: | + curl -L "$env:LINK/$env:CARGO_C_FILE" -o cargo-c-windows-msvc.zip + powershell -Command "Expand-Archive -Path cargo-c-windows-msvc.zip -DestinationPath $env:USERPROFILE\\.cargo\\bin -Force" + - name: Setup cmake build + run: | + cmake ${{ + matrix.os != 'windows-latest' && '-DCMAKE_BUILD_TYPE=Release -DPREFER_POST_QUANTUM=on\' || '-DPREFER_POST_QUANTUM=on' + }} ${{ + matrix.os == 'macos-latest' && '-DCMAKE_OSX_DEPLOYMENT_TARGET=14.5' || '' + }} -S librustls -B build + - name: Run PQ connect test + # NOTE: uses bash as the shell to allow for easy no-powershell tee/grep pipeline. + shell: bash + run: | + cmake --build build --target prefer-pq-test ${{ + matrix.os == 'windows-latest' && '--config Release' || '' + }} | tee pq-test.log + - name: Verify PQ status + shell: bash + run: | + grep 'kex=X25519MLKEM768' pq-test.log diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 6835ebbc..b78e50d5 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -12,7 +12,7 @@ on: jobs: build: - name: "Build+Test (${{ matrix.os }}, ${{ matrix.cc }}, ${{ matrix.rust }}, ${{ matrix.crypto }}${{ matrix.cert_compression == 'on' && ', cert compression' || '' }}${{ matrix.dyn_link == 'on' && ', dynamic linking' || '' }})" + name: "Build+Test (${{ matrix.os }}, ${{ matrix.cc }}, ${{ matrix.rust }}, ${{ matrix.crypto }}${{ matrix.cert_compression == 'on' && ', cert compression' || '' }}${{ matrix.prefer-pq == 'on' && ', prefer-post-quantum' || '' }}${{ matrix.dyn_link == 'on' && ', dynamic linking' || '' }})" runs-on: ${{ matrix.os }} strategy: matrix: @@ -42,6 +42,12 @@ jobs: crypto: aws-lc-rs rust: stable cert_compression: on + # Linux prefer-pq build + - os: ubuntu-latest + cc: clang + crypto: aws-lc-rs + rust: stable + prefer-pq: on # MacOS standard build - os: macos-latest cc: clang @@ -60,6 +66,12 @@ jobs: crypto: aws-lc-rs rust: stable cert_compression: on + # MacOS prefer-pq build + - os: macos-latest + cc: clang + crypto: aws-lc-rs + rust: stable + prefer-pq: on steps: - name: Checkout sources uses: actions/checkout@v4 @@ -97,6 +109,7 @@ jobs: cmake \ -DCRYPTO_PROVIDER=${{matrix.crypto}} \ -DCERT_COMPRESSION=${{matrix.cert_compression}} \ + -DPREFER_POST_QUANTUM=${{matrix.prefer-pq}} \ -DDYN_LINK=${{matrix.dyn_link}} \ -DCMAKE_BUILD_TYPE=Debug \ ${{ matrix.os == 'macos-latest' && '-DCMAKE_OSX_DEPLOYMENT_TARGET=14.5' || '' }} \ @@ -117,7 +130,7 @@ jobs: - name: Build release binaries run: | cmake --build build -- clean - CC=${{matrix.cc}} CXX=${{matrix.cc}} cmake -S librustls -B build -DCRYPTO_PROVIDER=${{matrix.crypto}} -DCMAKE_BUILD_TYPE=Release + CC=${{matrix.cc}} CXX=${{matrix.cc}} cmake -S librustls -B build -DCRYPTO_PROVIDER=${{matrix.crypto}} -DPREFER_POST_QUANTUM=${{matrix.prefer-pq}} -DCMAKE_BUILD_TYPE=Release cmake --build build - name: Verify release builds were not using ASAN @@ -189,7 +202,7 @@ jobs: run: cmake --build build --target integration-test test-windows: - name: "Windows (${{ matrix.crypto }}, ${{ matrix.config }}${{ matrix.cert_compression == 'on' && ', cert compression' || '' }}${{ matrix.dyn_link == 'on' && ', dynamic linking' || '' }})" + name: "Windows (${{ matrix.crypto }}, ${{ matrix.config }}${{ matrix.cert_compression == 'on' && ', cert compression' || '' }}${{ matrix.prefer-pq == 'on' && ', prefer-post-quantum' || '' }}${{ matrix.dyn_link == 'on' && ', dynamic linking' || '' }})" runs-on: windows-latest strategy: matrix: @@ -206,6 +219,10 @@ jobs: - crypto: aws-lc-rs config: Release cert_compression: on + # One build with prefer-pq. + - crypto: aws-lc-rs + config: Release + prefer-pq: on steps: - uses: actions/checkout@v4 with: @@ -233,7 +250,7 @@ jobs: powershell -Command "Expand-Archive -Path cargo-c-windows-msvc.zip -DestinationPath $env:USERPROFILE\\.cargo\\bin -Force" - name: Configure CMake - run: cmake -DCRYPTO_PROVIDER="${{ matrix.crypto }}" -DCERT_COMPRESSION="${{ matrix.cert_compression }}" -DDYN_LINK="${{ matrix.dyn_link }}" -S librustls -B build + run: cmake -DCRYPTO_PROVIDER="${{ matrix.crypto }}" -DCERT_COMPRESSION="${{ matrix.cert_compression }}" -DPREFER_POST_QUANTUM="${{ matrix.prefer-pq }}" -DDYN_LINK="${{ matrix.dyn_link }}" -S librustls -B build - name: Build run: cmake --build build --config "${{ matrix.config }}" diff --git a/README.md b/README.md index d2569e5b..5e2a855d 100644 --- a/README.md +++ b/README.md @@ -98,6 +98,17 @@ platforms see the upstream documentation: [`*ring*`]: https://crates.io/crates/ring [`*ring*` supported platforms]: https://github.com/briansmith/ring/blob/2e8363b433fa3b3962c877d9ed2e9145612f3160/include/ring-core/target.h#L18-L64 +#### Post-Quantum X25519MLKEM768 Key Exchange + +Post-quantum-secure key exchange using [X25519MLKEM768][] is supported when using the `aws-lc-rs` +cryptography provider. At this time default support places `X25519MLKEM768` at a lower negotiation priority. + +By enabling the `prefer-post-quantum` feature flag the `X25519MLKEM768` key exchange will be used as the most +preferred key exchange algorithm. We expect to add this feature to the crate's default features in a future +release. + +[X25519MLKEM768]: https://datatracker.ietf.org/doc/draft-kwiatkowski-tls-ecdhe-mlkem + #### Certificate Compression You can optionally enable [RFC 8879](https://www.rfc-editor.org/rfc/rfc8879) diff --git a/librustls/Cargo.toml b/librustls/Cargo.toml index 7512b419..a8c7fbf4 100644 --- a/librustls/Cargo.toml +++ b/librustls/Cargo.toml @@ -25,6 +25,7 @@ ring = ["rustls/ring", "webpki/ring"] aws-lc-rs = ["rustls/aws-lc-rs", "webpki/aws_lc_rs"] cert_compression = ["rustls/brotli", "rustls/zlib"] fips = ["aws-lc-rs", "rustls/fips"] +prefer-post-quantum = ["aws-lc-rs", "rustls/prefer-post-quantum"] [dependencies] # Keep in sync with RUSTLS_CRATE_VERSION in build.rs diff --git a/librustls/cmake/options.cmake b/librustls/cmake/options.cmake index c021fa62..c9058398 100644 --- a/librustls/cmake/options.cmake +++ b/librustls/cmake/options.cmake @@ -20,6 +20,11 @@ option( option(FIPS "Whether to enable aws-lc-rs and FIPS support") +option( + PREFER_POST_QUANTUM + "Whether to enable aws-lc-rs and prefer post-quantum key exchange support" +) + option(DYN_LINK "Use dynamic linking for rustls library" OFF) if(DYN_LINK AND FIPS AND (APPLE OR WIN32)) @@ -45,6 +50,10 @@ if(FIPS) list(APPEND CARGO_FEATURES --features=fips) endif() +if(PREFER_POST_QUANTUM) + list(APPEND CARGO_FEATURES --features=prefer-post-quantum) +endif() + # By default w/ Makefile or Ninja generators (e.g. Linux/MacOS CLI) # the `CMAKE_BUILD_TYPE` is "" when using the C/C++ project tooling. # diff --git a/librustls/cmake/rust.cmake b/librustls/cmake/rust.cmake index 2f2a08d2..ab6b6a93 100644 --- a/librustls/cmake/rust.cmake +++ b/librustls/cmake/rust.cmake @@ -98,3 +98,24 @@ add_custom_command( $ cloudflare-ech.com 443 /cdn-cgi/trace WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" ) + +add_custom_target(prefer-pq-test DEPENDS client) + +if(WIN32 AND DYN_LINK) + add_custom_command( + TARGET prefer-pq-test + PRE_BUILD + COMMAND + ${CMAKE_COMMAND} -E copy "${CMAKE_BINARY_DIR}/rust/bin/rustls.dll" + "${CMAKE_BINARY_DIR}\\tests\\$\\" + ) +endif() + +add_custom_command( + TARGET prefer-pq-test + POST_BUILD + COMMAND + ${CMAKE_COMMAND} -E env RUSTLS_PLATFORM_VERIFIER=1 $ + pq.cloudflareresearch.com 443 /cdn-cgi/trace + WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" +)