Skip to content
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

Make ge25519_cmove_stride4b constant time #4428

Merged
merged 1 commit into from
Dec 16, 2024
Merged

Conversation

onvej-sl
Copy link
Contributor

@onvej-sl onvej-sl commented Dec 6, 2024

This pull request builds on top of #4374, it fixes #4393. I don't know if we want to update the version of gcc once the issue is fixed, so I kept it the same as the version of gcc-arm-embedded. Which means you need to update gcc to version 14 to verify if this pull request indeed resolves the issue.

Copy link

github-actions bot commented Dec 6, 2024

core UI changes device test click test persistence test
T2T1 Model T test(screens) main(screens) test(screens) main(screens) test(screens) main(screens)
T3B1 Safe 3 test(screens) main(screens) test(screens) main(screens) test(screens) main(screens)
T3T1 Safe 5 test(screens) main(screens) test(screens) main(screens) test(screens) main(screens)
All main(screens)

@onvej-sl
Copy link
Contributor Author

onvej-sl commented Dec 6, 2024

I also checked the binary of the core firmware (make build_firmware). If I read it correctly, the function ge25519_cmove_stride4 is inlined in ge25519_move_conditional_pniels_array and this pull request removes conditional branching from the part of the function that appears to corresponds to ge25519_cmove_stride4. See this.

@onvej-sl onvej-sl marked this pull request as ready for review December 6, 2024 13:47
@onvej-sl onvej-sl requested review from mmilata and removed request for prusnak and andrewkozlik December 6, 2024 13:47
Comment on lines 401 to 408
const long mask_y = -flag;
const long mask_x = ~mask_y;

// x = flag ? y : x
x0 = (y0 & mask_y) | (x0 & mask_x);
x1 = (y1 & mask_y) | (x1 & mask_x);
x2 = (y2 & mask_y) | (x2 & mask_x);
x3 = (y3 & mask_y) | (x3 & mask_x);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking at this I feel a little uneasy about the bitwise operations on signed integers, but it's probably correct.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's a good point. I think we can use unsigned long instead of long.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in 7f359b1.

@mmilata
Copy link
Member

mmilata commented Dec 10, 2024

Thanks for looking into this!

removes conditional branching from the part of the function [...] See this.

Doesn't it slow ed25519 signing/verification though? The "old" assembly listing had movne instructions which if I understand correctly are not really branching and should be OK wrt constant time? The "new" assembly is OK too.

If the bitwise version is slower we can only use it for x86_64 and keep the old one for firmware.

@onvej-sl
Copy link
Contributor Author

Doesn't it slow ed25519 signing/verification though?

I did a benchmark on trezor T and the times seem to be the same before and after this pull request:

function time
publickey 11.8 ms
sign 23.8 ms
verify 10.9 ms

The "old" assembly listing had movne instructions which if I understand correctly are not really branching and should be OK wrt constant time?

I am not sure how the movne instruction is interpreted internally, but I would guess that if the condition is not met, skipping the instruction takes less time compared to executing it.

Copy link
Member

@mmilata mmilata left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Feel free to rebase on main and merge, or I can do it once #4374 is merged.

But please fix style first:

crypto/ed25519-donna/ed25519-donna-impl-base.c:
	400: Trailing whitespace
	403: Trailing whitespace
	425: Trailing whitespace
	428: Trailing whitespace

@onvej-sl onvej-sl force-pushed the onvej-sl/constant-time-fix branch from 7f359b1 to 5cc3849 Compare December 11, 2024 13:45
@onvej-sl onvej-sl merged commit ecc38f2 into main Dec 16, 2024
93 of 94 checks passed
@onvej-sl onvej-sl deleted the onvej-sl/constant-time-fix branch December 16, 2024 11:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: Approved
Development

Successfully merging this pull request may close these issues.

GCC 14 makes ed25519 not constant-time on x86_64
3 participants