Skip to content

Commit

Permalink
feat: add constant time comparison for grpc authentication (#5902)
Browse files Browse the repository at this point in the history
Description
---
- Added constant-time username comparison for gRPC authentication. This
will largely mitigate side-channel attacks to uncover the gRPC username.
(See `BasicAuthCredentials::constant_time_compare_username`)

- **Edit:** Credential validation for the combined username and password
will now also run in constant time and not return if the username did
not match as it did previously.

- **Edit:** Fixed an issue where the `BasicAuthCredentials` from header
did not pass validation, impacted in `fn it_generates_a_valid_header()`
and `it_decodes_from_well_formed_header`.

(Closes #5810)

Motivation and Context
---
See #5810

How Has This Been Tested?
---
- Added two unit tests to compare constant time performance with varying
length username guesses. The unit test was performed in release mode
with a no-load and fully loaded CPU.
- `fn it_compares_user_names_in_constant_time()` 
```
        // This unit test asserts that the minimum variance is less than 10% (chosen to be robust for running the unit
        // test with CI), indicating that the function behaves within acceptable constant-time constraints.
        //
        // Some consecutive results running in release mode on a Core i7-12700H (with no other processes running):
        //
        // Minimum variance:                          0.247 %
        // Average variance:                          4.65738 %
        // Average short username time:               1.17486 microseconds
        // Average long username time:                1.17344 microseconds
        // Average actual username time:              1.18388 microseconds
        //
        // Minimum variance:                          0.10214 %
        // Average variance:                          4.32226 %
        // Average short username time:               1.1619 microseconds
        // Average long username time:                1.16591 microseconds
        // Average actual username time:              1.18157 microseconds
        //
        // Minimum variance:                          0.17953 %
        // Average variance:                          5.51519 %
        // Average short username time:               1.17974 microseconds
        // Average long username time:                1.19232 microseconds
        // Average actual username time:              1.18709 microseconds
        //
        // Some consecutive results running in release mode on a Core i7-12700H (while entire CPU fully stressed):
        //
        // Minimum variance:                          0.60357 %
        // Average variance:                          6.30167 %
        // Average short username time:               1.81708 microseconds
        // Average long username time:                1.77562 microseconds
        // Average actual username time:              1.74824 microseconds
        //
        // Minimum variance:                          0.28176 %
        // Average variance:                          6.47136 %
        // Average short username time:               1.8317 microseconds
        // Average long username time:                1.8304 microseconds
        // Average actual username time:              1.80362 microseconds
        //
        // Minimum variance:                          0.53593 %
        // Average variance:                          6.99394 %
        // Average short username time:               1.82322 microseconds
        // Average long username time:                1.81431 microseconds
        // Average actual username time:              1.78002 microseconds
```
- `fn it_compares_credentials_in_constant_time()`
```
        // This unit test asserts that the minimum variance is less than 10% (chosen to be robust for running the unit
        // test with CI), indicating that the function behaves within acceptable constant-time constraints.
        //
        // Some consecutive results running in release mode on a Core i7-12700H (with no other processes running):
        //
        // Minimum variance:                          0.43478 %
        // Average variance:                          2.08995 %
        // Average short username time:               34.580 microseconds
        // Average long username time:                34.315 microseconds
        // Average actual username time:              34.260 microseconds
        //
        // Minimum variance:                          0.43731 %
        // Average variance:                          1.77209 %
        // Average short username time:               34.560 microseconds
        // Average long username time:                34.755 microseconds
        // Average actual username time:              34.690 microseconds
        //
        // Minimum variance:                          0.43988 %
        // Average variance:                          1.61299 %
        // Average short username time:               34.33999 microseconds
        // Average long username time:                34.38500 microseconds
        // Average actual username time:              34.28500 microseconds
        //
        // Some consecutive results running in release mode on a Core i7-12700H (while entire CPU fully stressed):
        //
        // Minimum variance:                          0.30326 %
        // Average variance:                          2.29341 %
        // Average short username time:               64.87500 microseconds
        // Average long username time:                65.55499 microseconds
        // Average actual username time:              65.81000 microseconds
        //
        // Minimum variance:                          1.18168 %
        // Average variance:                          2.99206 %
        // Average short username time:               67.970 microseconds
        // Average long username time:                68.000 microseconds
        // Average actual username time:              68.005 microseconds
        //
        // Minimum variance:                          1.01083 %
        // Average variance:                          2.31316 %
        // Average short username time:               68.715 microseconds
        // Average long username time:                69.675 microseconds
        // Average actual username time:              69.715 microseconds
```

What process can a PR reviewer use to test or verify this change?
---
Code walk through
Run the unit tests

<!-- Checklist -->
<!-- 1. Is the title of your PR in the form that would make nice release
notes? The title, excluding the conventional commit
tag, will be included exactly as is in the CHANGELOG, so please think
about it carefully. -->


Breaking Changes
---

- [x] None
- [ ] Requires data directory on base node to be deleted
- [ ] Requires hard fork
- [ ] Other - Please specify

<!-- Does this include a breaking change? If so, include this line as a
footer -->
<!-- BREAKING CHANGE: Description what the user should do, e.g. delete a
database, resync the chain -->
  • Loading branch information
hansieodendaal committed Nov 10, 2023
1 parent 27f78de commit 2fe44db
Show file tree
Hide file tree
Showing 4 changed files with 432 additions and 29 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions applications/minotari_app_grpc/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ rand = "0.8"
thiserror = "1"
tonic = "0.6.2"
zeroize = "1"
subtle = { version = "2.5.0", features = ["core_hint_black_box"] }

[build-dependencies]
tonic-build = "0.6.2"
Expand Down
Loading

0 comments on commit 2fe44db

Please sign in to comment.