-
Notifications
You must be signed in to change notification settings - Fork 56
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Let's DOIT: Add support for DOIT-instruction list in (S)CT checkers #736
Conversation
I have just now noticed #608, which reorganizes the (S)CT checkers and introduces some of the functionality that this PR duplicates, namely the "checkCTafter" CLI option. What is the plan with that PR @bgregoir? Will it get merged soon? Should this get rebased on top of it? I plan to cleanup the commits in this PR and would like to know which branch to base it on. |
5b897c7
to
fbec7b1
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have not taken the time to read all of the PR.
But two small remarks:
- Can you propagate the change also in SCT ?
- Clearly the changelog needs to be updated.
Forgot about the first I was stupid, it is done |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For the option checkCTafter should we use it always when we want to do doit?
Thank a lot for this PR, I am globally impressed by what you did. |
Yeah, it does not make sense to use |
30fd559
to
7ac5e20
Compare
I implemented changes based on the review:
One thing that needs to be done (and I do not know how to do it) is to properly print the ARM instructions in the
|
I rebased this branch on top of current main. That means that now the |
@@ -15,6 +15,12 @@ bin = ./scripts/check-cct | |||
okdirs = !CCT/success | |||
kodirs = !CCT/fail | |||
|
|||
[test-CCT-DOIT] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we add also a SCT DOIT?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure, let me add that.
(when the `-doit` flag is used) check that secrets are only used with | ||
guaranteed constant time instructions (DOIT for Intel, DIT for ARM). This option | ||
only makes sense when done after the lowering compiler pass, which can be ensured | ||
with the new `-after` option. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
for -doit, did we have a default pass ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What do you mean by a default pass? There are two ways I guess:
- Passing the
-doit
option also sets the compiler pass to be after inline propagation. If someone also uses the-after
option they get an error? Or maybe they get an error only if the pass is before lowering? - Passing the
-doit
option does nothing to the compiler pass set, it needs to be set using the-after
option and that will check that the set pass is after lowering. This is currently implemented (and I like it more, but I am open to suggestions).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was more in favor of the first one, with
the solution "Or maybe they get an error only if the pass is before lowering?". I think the user don't need
to know the name of the pass.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, makes sense.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have added some extra small comment. Excepted those I think we will be ok.
(when the `-doit` flag is used) check that secrets are only used with | ||
guaranteed constant time instructions (DOIT for Intel, DIT for ARM). This option | ||
only makes sense when done after the lowering compiler pass, which can be ensured | ||
with the new `-after` option. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was more in favor of the first one, with
the solution "Or maybe they get an error only if the pass is before lowering?". I think the user don't need
to know the name of the pass.
@@ -1,8 +1,9 @@ | |||
fn add_H_L_L(#secret reg u64 x, #public reg u64 ya) -> #public reg u64 { | |||
export fn add_H_L_L(#secret reg u64 x, #public reg u64 ya) -> #public reg u64 { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you explain why you have change all the tests.
What is the motivation of adding the export.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If they are not marked export
they are not present at the later compiler passes where DOIT checking happens :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Then those programs are not suited for testing the new functionality.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well, AFAIK the export
does not change anything about them with regards to the CT checking (the ordinary tests would have caught that) so I believe these can be reused for DOIT checking. They should be reused to see that unless specific non-DOIT instructions are used DOIT checking is the same as CT checking.
This brings me to a broader point that DOIT-specific tests should be added, which I will work on.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Did you manually inspect the error messages of the CT checker before and after your change to validate that they are still the same? Do you expect the reviewers of your PR to do this boring work?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would expect the tests (and some understanding of what the export
keyword does) to ensure that. Nevertheless I just manually checked and there is no change in the ordinary CT checker output.
@@ -172,7 +172,7 @@ let pp_kind fmt k = | |||
if k = Flexible then Format.fprintf fmt "#%s " (string_of_lvl_kind k) | |||
|
|||
let pp_arg fmt (x, (k, lvl)) = | |||
Format.fprintf fmt "%a%a %a" pp_kind k Lvl.pp lvl (Printer.pp_var ~debug:false) x | |||
Format.fprintf fmt "%a%a %a" pp_kind k Lvl.pp lvl (Printer.pp_var ~debug:!Glob_options.debug) x |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems to be not the correct fix.
Debug may print many other infos that are usually used
to debug the compiler.
For doit, I am agree that it is important to print the info
(it is done after lower spill), name clashes can occur. But either replace this by just a true or a boolean
depending on the pass.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see, if this is set depending on the pass then the pass would need to be passed through to the checker. I think this will be quite cumbersome.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Indeed, fixing this is non trivial and mostly unrelated to this PR. Therefore please:
- open an issue
- drop this commit from this PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done: #810.
When it is run after lowering (where it neess to be done for the DOIT option), the variables have ids that distinguish them and those are important to see in debug output.
Adds a CCT-DOIT test group that contains the normal CCT tests in the success condition and the failure condition as well as DOIT-specific tests in the failure condition. The DOIT-specific tests use the two non-DOIT instructions ROL and XCHG. Reusing the CCT tests required making their main functions "export" to make sure they are kept at the later compiler passes where DOIT checking needs to be done.
I’ve taken to PR #811 some changes from this PR. Notable changes are that for armv7, instructions LDR, STR, and MOVT have been marked as secure. The rationale for memory accesses is that the documentation explicitly mentions that timing may only depend on the address (which is generically handled by the checker otherwise) and not on the exchanged data. For MOVT, the guess is that this instruction is not listed as a secure instruction of armv8 because it is not an instruction of armv8 in the first place. |
I believe that all the tooling proposed in this PR, namely data extraction from manufacturer’s websites and data extraction from Jasmin, may be moved to a different repository (e.g., attached to a publication related this work). |
Future steps might be:
|
Now that PR #736 has been merged, I suggest to close this one. |
This PR will add support for ensuring that secret values only go into guaranteed constant-time instructions (Intel DOITM, ARM DIT).
Currently it does the following:
-help-instructions
to the compiler that is similar to the-help-instrinsics
one but prints all of the instructions for the given architecture that Jasmin understands along with their expanded variants. This is necessary for the automated extraction of the DIT/DOIT instructions that Jasmin supports. Example of output:-doit
to thejazzct
tool that switches the CT checker list of constant-time instructions from "all but DIV/MOD" to "only those in the DOIT/DIT" lists. This CLI option also checks that the compiler pass selected is during or after lowering, because the mode otherwise does not make sense.Which compiler pass to run with
It needs to be done at least after lowering, to have the instructions.
When run right after lowering, the CT checker can have false positives in case of lines like:
if (_LT(of, cf, sf, zf)) {
because it will consider all of the flags, even though the _LT operator only actually considers some.
If run after inline variable propagation this problem disappears, because the expression will be replaced with one that contains only the used flags.