Page MenuHomeFreeBSD

ktls: Add simple transmit tests of kernel TLS.
ClosedPublic

Authored by jhb on Oct 26 2021, 12:52 AM.
Tags
None
Referenced Files
F106142498: D32652.id97507.diff
Thu, Dec 26, 2:36 AM
F106115485: D32652.diff
Wed, Dec 25, 3:49 PM
Unknown Object (File)
Sun, Dec 15, 10:58 AM
Unknown Object (File)
Sun, Dec 8, 5:45 AM
Unknown Object (File)
Nov 21 2024, 7:44 AM
Unknown Object (File)
Nov 15 2024, 12:40 PM
Unknown Object (File)
Nov 13 2024, 10:51 PM
Unknown Object (File)
Nov 12 2024, 7:38 AM

Details

Summary

Note that these tests test the kernel TLS functionality directly.
Rather than using OpenSSL to perform negotiation and generate keys,
these tests generate random keys send data over a pair of TCP sockets
manually decrypting the TLS records generated by the kernel.

Sponsored by: Netflix

Diff Detail

Repository
rS FreeBSD src repository - subversion
Lint
Lint Passed
Unit
No Test Coverage
Build Status
Buildable 42356
Build 39244: arc lint + arc unit

Event Timeline

jhb requested review of this revision.Oct 26 2021, 12:52 AM

These result of all these macros are to test all the cipher suites we currently support on transmit:

ktls_test:ktls_transmit_aes128_cbc_1_0_sha1_control
ktls_test:ktls_transmit_aes128_cbc_1_0_sha1_long
ktls_test:ktls_transmit_aes128_cbc_1_0_sha1_short
ktls_test:ktls_transmit_aes128_cbc_1_1_sha1_control
ktls_test:ktls_transmit_aes128_cbc_1_1_sha1_long
ktls_test:ktls_transmit_aes128_cbc_1_1_sha1_short
ktls_test:ktls_transmit_aes128_cbc_1_2_sha1_control
ktls_test:ktls_transmit_aes128_cbc_1_2_sha1_long
ktls_test:ktls_transmit_aes128_cbc_1_2_sha1_short
ktls_test:ktls_transmit_aes128_cbc_1_2_sha256_control
ktls_test:ktls_transmit_aes128_cbc_1_2_sha256_long
ktls_test:ktls_transmit_aes128_cbc_1_2_sha256_short
ktls_test:ktls_transmit_aes128_cbc_1_2_sha384_control
ktls_test:ktls_transmit_aes128_cbc_1_2_sha384_long
ktls_test:ktls_transmit_aes128_cbc_1_2_sha384_short
ktls_test:ktls_transmit_aes128_gcm_1_2_control
ktls_test:ktls_transmit_aes128_gcm_1_2_long
ktls_test:ktls_transmit_aes128_gcm_1_2_short
ktls_test:ktls_transmit_aes128_gcm_1_3_control
ktls_test:ktls_transmit_aes128_gcm_1_3_long
ktls_test:ktls_transmit_aes128_gcm_1_3_short
ktls_test:ktls_transmit_aes256_cbc_1_0_sha1_control
ktls_test:ktls_transmit_aes256_cbc_1_0_sha1_long
ktls_test:ktls_transmit_aes256_cbc_1_0_sha1_short
ktls_test:ktls_transmit_aes256_cbc_1_1_sha1_control
ktls_test:ktls_transmit_aes256_cbc_1_1_sha1_long
ktls_test:ktls_transmit_aes256_cbc_1_1_sha1_short
ktls_test:ktls_transmit_aes256_cbc_1_2_sha1_control
ktls_test:ktls_transmit_aes256_cbc_1_2_sha1_long
ktls_test:ktls_transmit_aes256_cbc_1_2_sha1_short
ktls_test:ktls_transmit_aes256_cbc_1_2_sha256_control
ktls_test:ktls_transmit_aes256_cbc_1_2_sha256_long
ktls_test:ktls_transmit_aes256_cbc_1_2_sha256_short
ktls_test:ktls_transmit_aes256_cbc_1_2_sha384_control
ktls_test:ktls_transmit_aes256_cbc_1_2_sha384_long
ktls_test:ktls_transmit_aes256_cbc_1_2_sha384_short
ktls_test:ktls_transmit_aes256_gcm_1_2_control
ktls_test:ktls_transmit_aes256_gcm_1_2_long
ktls_test:ktls_transmit_aes256_gcm_1_2_short
ktls_test:ktls_transmit_aes256_gcm_1_3_control
ktls_test:ktls_transmit_aes256_gcm_1_3_long
ktls_test:ktls_transmit_aes256_gcm_1_3_short
ktls_test:ktls_transmit_chacha20_poly1305_1_2_control
ktls_test:ktls_transmit_chacha20_poly1305_1_2_long
ktls_test:ktls_transmit_chacha20_poly1305_1_2_short
ktls_test:ktls_transmit_chacha20_poly1305_1_3_control
ktls_test:ktls_transmit_chacha20_poly1305_1_3_long
ktls_test:ktls_transmit_chacha20_poly1305_1_3_short

The *_control variants use the control message to send a single message with a specific record type. The *_short variants send 64 bytes of application data (probably fit in a single record). The *_long variants send 64 KB of application data (more than one TLS record).

There are probably some more special cases that can be added (e.g. TLS 1.0 empty fragments, and perhaps invalid combinations that should fail like using AES-CBC for TLS 1.3). I also plan on adding receive side tests for AEAD ciphers.

These currently all pass when I run them, but as I started writing this message I realized I have a bug in my TLS 1.0 decryption (it doesn't update the IV), so the TLS 1.0 "long" tests should be failing. I need to debug why they aren't failing currently.

Ah, I had forgot to enable the sysctl and they were all passing as "skipped". The MTE tests for AES-CBC now all fail so I'll have to fix those.

tests/sys/kern/ktls_test.c
64

So normally you'd set allow_sysctl_side_effects in the test metadata and then the test would automatically enable ktls (or be skipped because the test was run without it).

This has the disadvantage that you need to run kyua -v test_suites.FreeBSD.allow_sysctl_side_effects=1 test each time, even if ktls is already enabled, I think. OTOH, anyone running the test suite as part of a CI system would only need to specify that flag, and they wouldn't have to modify the host sysctl.conf.

1072

IMO it'd be good to have a comment explaining roughly what this is testing for each cipher mode. It's a bit difficult to follow the macro expansions.

tests/sys/kern/ktls_test.c
64

Hmm, I had copied this from how the POSIX AIO tests handle the "safe" knob which works without needing the verbose -v option. I wonder if there's a way to tell CI to flip the knob for the test but still let it be sane when run standalone?

tests/sys/kern/ktls_test.c
64

Our CI sets a "ci" configuration variable that can fetched to determine if the test is running in the CI context.

I suppose we could have logic here to fetch the value of allow_sysctl_side_effects, and toggle the sysctl value if it's set, otherwise skip the test. Typically tests will include metadata which declares whether or not they need to be able to toggle sysctls, but I believe that metadata has to be fixed at compile time.

In any case, if the AIO tests already do something like this then I don't object. It would be nice if our tests were more consistent with this kind of things (whether or not to load KLDs is another one), but it's not worth blocking the review over.

tests/sys/kern/ktls_test.c
64

Our CI sets a "ci" configuration variable that can fetched to determine if the test is running in the CI context.

I suppose we could have logic here to fetch the value of allow_sysctl_side_effects, and toggle the sysctl value if it's set, otherwise skip the test. Typically tests will include metadata which declares whether or not they need to be able to toggle sysctls, but I believe that metadata has to be fixed at compile time.

In any case, if the AIO tests already do something like this then I don't object. It would be nice if our tests were more consistent with this kind of things (whether or not to load KLDs is another one), but it's not worth blocking the review over.

I agree consistency would be good. Does CI always set allow_sysctl_side_effects or does it only set that if a test says it requires it in its require.config? If the former, then I think I would like what you propose of force-enabling it in the test if the setting is present. Might be nice to have a helper function for this perhaps and AIO could be updated to do this as well.

  • Add a comment.
  • Add a dummy auth alg to the GCM and CHACHA20 tables to permit reducing duplication (e.g. the MTE and AEAD macros are now collapsed, and the two build_*_tls_enable functions are now collapsed into a single function).
  • Fix bugs in CBC decryption (padding was off by one, and TLS 1.0 needed to update the implicit IV).

All of the tests now pass once the dependent kernel fix is applied.

tests/sys/kern/ktls_test.c
956

I suppose I could make this into a standalone function that takes the various values as arguments, or alternatively, I could push some of the logic such as setting up the tls_enable structures into test_ktls_transmit_app_data() and test_ktls_transmit_control(). This would make the macro-generated functions one-liners. If that is more readable I can take that approach. It is a bit of a shame one has to use the C pre-processor to generate multiple test cases rather than being able to use, say, a C for loop over an array of structs to declare the tests and run them.

This is a test I'd like to add:
https://github.com/markjdb/freebsd/commit/66264b1209914bd6f4f9ec57c89974dd700b2e6a

On older kernels it triggers a panic due to an mbuf double free. I'll work on integrating it here once this is committed.

tests/sys/kern/ktls_test.c
64

The CI always sets it, it's a global configuration parameter. What roughly happens is that kyua interrogates each test to determine whether it requires that parameter to run. Tests that require it are run only if allow_sysctl_side_effects is configured by the kyua runner, either with -v or in a configuration file.

See https://github.com/freebsd/freebsd-ci/blob/master/scripts/build/config-head/testvm/append/etc/kyua/kyua.conf

956

I don't have a strong feeling either way. The macros aren't too hard to decipher after staring for a few minutes.

Strictly speaking, you don't have to use ATF for this. TAP would be ok, though then you lose the ability to attach metadata like allow_sysctl_side_effects, I believe.

This revision is now accepted and ready to land.Oct 28 2021, 9:23 PM
This revision was automatically updated to reflect the committed changes.