Skip to content

Commit b776b4f

Browse files
h-filalivogelpi
authored andcommitted
[sw,cryptolib] Fix trigger_fault_if_fg-1 functions
The trigger_fault_if_fg0 functions had a bug where we never trigger a fault. This new implementation should now correctly trigger the fault. For the case where no fault is triggered, we load address 0 into w31. For the error case we try to load address 0 into w39 (which doesn't exist), which triggers a ILLEGAL_INSN error. Signed-off-by: Hakim Filali <[email protected]>
1 parent 7533439 commit b776b4f

File tree

8 files changed

+59
-58
lines changed

8 files changed

+59
-58
lines changed

sw/device/lib/crypto/impl/ecc/p256.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -82,12 +82,12 @@ enum {
8282
/*
8383
* The expected instruction counts for constant time functions.
8484
*/
85-
kModeKeygenInsCnt = 574237,
86-
kModeKeygenSideloadInsCnt = 574122,
87-
kModeEcdhInsCnt = 581920,
88-
kModeEcdhSideloadInsCnt = 581980,
89-
kModeEcdsaSignInsCnt = 607411,
90-
kModeEcdsaSignSideloadInsCnt = 607471,
85+
kModeKeygenInsCnt = 573915,
86+
kModeKeygenSideloadInsCnt = 573800,
87+
kModeEcdhInsCnt = 581598,
88+
kModeEcdhSideloadInsCnt = 581658,
89+
kModeEcdsaSignInsCnt = 607087,
90+
kModeEcdsaSignSideloadInsCnt = 607147,
9191
};
9292

9393
static status_t p256_masked_scalar_write(p256_masked_scalar_t *src,

sw/otbn/crypto/boot.s

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@ attestation_keygen:
168168
The check fails if both sides are not equal.
169169
FG0.Z <= (y^2) mod p == (x^2 + ax + b) mod p */
170170
bn.cmp w18, w19
171-
jal x1, trigger_fault_if_fg0_not_z
171+
jal x1, trigger_fault_if_fg0_z
172172

173173
ecall
174174

sw/otbn/crypto/p256_base.s

Lines changed: 24 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -43,33 +43,27 @@
4343
* sensitive; since aborting the program will be quicker than completing it,
4444
* the flag's value is likely clearly visible to an attacker through timing.
4545
*
46-
* @param[in] w31: all-zero
47-
* @param[in] FG0.Z: boolean indicating fault condition
46+
* @param[in] FG0.Z: boolean indicating fault condition when 1
4847
*
49-
* clobbered registers: x2
48+
* clobbered registers: x2, w31
5049
* clobbered flag groups: none
5150
*/
52-
trigger_fault_if_fg0_z:
51+
trigger_fault_if_fg0_not_z:
5352
/* Read the FG0.Z flag (position 3).
5453
x2 <= FG0.Z */
5554
csrrw x2, FG0, x0
5655
andi x2, x2, 8
57-
srli x2, x2, 3
56+
addi x2, x2, 31
5857

59-
/* Subtract FG0.Z from 0.
60-
x2 <= 0 - x2 = FG0.Z ? 2^32 - 1 : 0 */
61-
sub x2, x0, x2
62-
63-
/* The `bn.lid` instruction causes an `BAD_DATA_ADDR` error if the
64-
memory address is out of bounds. Therefore, if FG0.Z is 1, this
65-
instruction causes an error, but if FG0.Z is 0 it simply loads the word at
66-
address 0 into w31. */
67-
li x3, 31
68-
bn.lid x3, 0(x2)
58+
/* The `bn.lid` instruction causes an `ILLEGAL_INSN` error if the index of the
59+
bignum register (stored in x2 in this case) is invalid. Therefore, if FG0.Z
60+
is 1, this instruction causes an error, but if FG0.Z is 0 it simply loads
61+
the word at address 0 into w31. */
62+
bn.lid x2, 0(x0)
6963

7064
/* If we get here, the flag must have been 0. Restore w31 to zero and return.
7165
w31 <= 0 */
72-
bn.xor w31, w31, w31
66+
bn.xor w31, w31, w31
7367

7468
ret
7569

@@ -84,29 +78,28 @@ trigger_fault_if_fg0_z:
8478
* sensitive; since aborting the program will be quicker than completing it,
8579
* the flag's value is likely clearly visible to an attacker through timing.
8680
*
87-
* @param[in] w31: all-zero
88-
* @param[in] FG0.Z: boolean indicating fault condition
81+
* @param[in] FG0.Z: boolean indicating fault condition when 0
8982
*
90-
* clobbered registers: x2
83+
* clobbered registers: x2, w31
9184
* clobbered flag groups: none
9285
*/
93-
trigger_fault_if_fg0_not_z:
86+
trigger_fault_if_fg0_z:
9487
/* Read the FG0.Z flag (position 3).
9588
x2 <= FG0.Z */
9689
csrrw x2, FG0, x0
9790
andi x2, x2, 8
98-
slli x2, x2, 3
91+
xori x2, x2, 8
92+
addi x2, x2, 31
9993

100-
/* The `bn.lid` instruction causes an `BAD_DATA_ADDR` error if the
101-
memory address is out of bounds. Therefore, if FG0.Z is 1, this
102-
instruction causes an error, but if FG0.Z is 0 it simply loads the word at
103-
address 0 into w31. */
104-
li x3, 31
105-
bn.lid x3, 0(x2)
94+
/* The `bn.lid` instruction causes an `ILLEGAL_INSN` error if the index of the
95+
bignum register (stored in x2 in this case) is invalid. Therefore, if FG0.Z
96+
is 0, this instruction causes an error, but if FG0.Z is 1 it simply loads
97+
the word at address 0 into w31. */
98+
bn.lid x2, 0(x0)
10699

107100
/* If we get here, the flag must have been 1. Restore w31 to zero and return.
108101
w31 <= 0 */
109-
bn.xor w31, w31, w31
102+
bn.xor w31, w31, w31
110103

111104
ret
112105

@@ -1358,7 +1351,7 @@ scalar_mult_int:
13581351
bn.rshi w2, w2, w20 >> 65
13591352

13601353
/* double-and-add loop with decreasing index */
1361-
loopi 321, 64
1354+
loopi 321, 63
13621355

13631356
/* double point Q
13641357
Q = (w8, w9, w10) <= 2*(w8, w9, w10) = 2*Q */
@@ -1517,7 +1510,7 @@ scalar_mult_int:
15171510

15181511
FG0.Z <= if (w10 == 0) then 1 else 0 */
15191512
bn.cmp w10, w31
1520-
jal x0, trigger_fault_if_fg0_z
1513+
jal x0, trigger_fault_if_fg0_not_z
15211514

15221515

15231516
/**
@@ -1608,7 +1601,7 @@ p256_base_mult:
16081601
The check fails if both sides are not equal.
16091602
FG0.Z <= (y^2) mod p == (x^2 + ax + b) mod p */
16101603
bn.cmp w18, w19
1611-
jal x1, trigger_fault_if_fg0_not_z
1604+
jal x1, trigger_fault_if_fg0_z
16121605

16131606
ret
16141607

sw/otbn/crypto/p256_shared_key.s

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ p256_shared_key:
8989
The check fails if both sides are not equal.
9090
FG0.Z <= (y^2) mod p == (x^2 + ax + b) mod p */
9191
bn.cmp w18, w19
92-
jal x1, trigger_fault_if_fg0_not_z
92+
jal x1, trigger_fault_if_fg0_z
9393

9494
/* Arithmetic masking:
9595
1. Generate a random mask

sw/otbn/crypto/p256_sign.s

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ p256_sign:
126126
The check fails if both sides are not equal.
127127
FG0.Z <= (y^2) mod p == (x^2 + ax + b) mod p */
128128
bn.cmp w18, w19
129-
jal x1, trigger_fault_if_fg0_not_z
129+
jal x1, trigger_fault_if_fg0_z
130130

131131
/* setup modulus n (curve order) and Barrett constant
132132
MOD <= w29 <= n = dmem[p256_n]; w28 <= u_n = dmem[p256_u_n] */
@@ -288,7 +288,7 @@ p256_sign:
288288
which violates ECDSA private key requirements. This could technically be
289289
triggered by an unlucky key manager seed, but the probability is so low (~1/n)
290290
that it more likely indicates a fault attack. */
291-
jal x1, trigger_fault_if_fg0_z
291+
jal x1, trigger_fault_if_fg0_not_z
292292

293293
/* w24 = r <= w11 mod n */
294294
bn.addm w24, w11, w31

sw/otbn/crypto/p384_isoncurve.s

Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -27,30 +27,29 @@
2727
* sensitive; since aborting the program will be quicker than completing it,
2828
* the flag's value is likely clearly visible to an attacker through timing.
2929
*
30-
* @param[in] w31: all-zero
31-
* @param[in] FG0.Z: boolean indicating fault condition
30+
* @param[in] FG0.Z: boolean indicating fault condition when 0
3231
*
33-
* clobbered registers: x2, x3
32+
* clobbered registers: x2, w31
3433
* clobbered flag groups: none
3534
*/
36-
.globl trigger_fault_if_fg0_not_z
37-
trigger_fault_if_fg0_not_z:
35+
.globl trigger_fault_if_fg0_z
36+
trigger_fault_if_fg0_z:
3837
/* Read the FG0.Z flag (position 3).
3938
x2 <= FG0.Z */
4039
csrrw x2, FG0, x0
4140
andi x2, x2, 8
42-
slli x2, x2, 3
41+
xori x2, x2, 8
42+
addi x2, x2, 31
4343

44-
/* The `bn.lid` instruction causes an `BAD_DATA_ADDR` error if the
45-
memory address is out of bounds. Therefore, if FG0.Z is 1, this
46-
instruction causes an error, but if FG0.Z is 0 it simply loads the word at
47-
address 0 into w31. */
48-
li x3, 31
49-
bn.lid x3, 0(x2)
44+
/* The `bn.lid` instruction causes an `ILLEGAL_INSN` error if the index of the
45+
bignum register (stored in x2 in this case) is invalid. Therefore, if FG0.Z
46+
is 1, this instruction causes an error, but if FG0.Z is 0 it simply loads
47+
the word at address 0 into w31. */
48+
bn.lid x2, 0(x0)
5049

5150
/* If we get here, the flag must have been 1. Restore w31 to zero and return.
5251
w31 <= 0 */
53-
bn.xor w31, w31, w31
52+
bn.xor w31, w31, w31
5453

5554
ret
5655

@@ -214,11 +213,11 @@ p384_isoncurve_check:
214213
FG0.Z <= (y^2) mod p == (x^2 + ax + b) mod p */
215214
bn.cmp w4, w6
216215
/* Fail if FG0.Z is false. */
217-
jal x1, trigger_fault_if_fg0_not_z
216+
jal x1, trigger_fault_if_fg0_z
218217

219218
bn.cmp w5, w7
220219
/* Fail if FG0.Z is false. */
221-
jal x1, trigger_fault_if_fg0_not_z
220+
jal x1, trigger_fault_if_fg0_z
222221

223222
ret
224223

sw/otbn/crypto/p384_isoncurve_proj.s

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,11 +60,11 @@ p384_isoncurve_proj_check:
6060
FG0.Z <= (y^2) mod p == (x^2 + ax + b) mod p */
6161
bn.cmp w4, w2
6262
/* Fail if FG0.Z is false. */
63-
jal x1, trigger_fault_if_fg0_not_z
63+
jal x1, trigger_fault_if_fg0_z
6464

6565
bn.cmp w5, w3
6666
/* Fail if FG0.Z is false. */
67-
jal x1, trigger_fault_if_fg0_not_z
67+
jal x1, trigger_fault_if_fg0_z
6868

6969
ret
7070

sw/otbn/crypto/tests/BUILD

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,10 @@ otbn_sim_test(
207207

208208
otbn_consttime_test(
209209
name = "p256_base_mult_consttime",
210+
ignore = [
211+
"trigger_fault_if_fg0_z",
212+
"trigger_fault_if_fg0_not_z",
213+
],
210214
subroutine = "p256_base_mult",
211215
deps = [
212216
"//sw/otbn/crypto:run_p256",
@@ -275,6 +279,10 @@ otbn_sim_test(
275279

276280
otbn_consttime_test(
277281
name = "p256_shared_key_consttime",
282+
ignore = [
283+
"trigger_fault_if_fg0_z",
284+
"trigger_fault_if_fg0_not_z",
285+
],
278286
subroutine = "p256_shared_key",
279287
deps = [
280288
"//sw/otbn/crypto:run_p256",
@@ -674,6 +682,7 @@ otbn_consttime_test(
674682
otbn_consttime_test(
675683
name = "p384_scalar_mult_consttime",
676684
ignore = [
685+
"trigger_fault_if_fg0_z",
677686
"trigger_fault_if_fg0_not_z",
678687
],
679688
subroutine = "p384_scalar_mult",

0 commit comments

Comments
 (0)