Skip to content

Commit ed8030e

Browse files
committed
fix claude's off by 1 loop (buffer overflow) + small stuff
1 parent 96b399a commit ed8030e

File tree

2 files changed

+59
-33
lines changed

2 files changed

+59
-33
lines changed

fio-stl.h

Lines changed: 30 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -28488,7 +28488,7 @@ FIO_IFUNC void fio___x25519_scalarmult(uint8_t out[32],
2848828488
const uint8_t scalar[32],
2848928489
const uint8_t point[32]) {
2849028490
uint8_t z[32];
28491-
FIO_MEMCPY(z, scalar, 32);
28491+
fio_memcpy32(z, scalar);
2849228492
z[31] = (scalar[31] & 127) | 64;
2849328493
z[0] &= 248;
2849428494

@@ -28751,7 +28751,7 @@ FIO_IFUNC void fio___ge_p3_tobytes(uint8_t out[32], fio___ge_p3_s p) {
2875128751
/* decode 32 bytes to point (returns 0 on success, -1 on failure) */
2875228752
FIO_SFUNC int fio___ge_p3_frombytes(fio___ge_p3_s p, const uint8_t in[32]) {
2875328753
uint8_t s[32];
28754-
FIO_MEMCPY(s, in, 32);
28754+
fio_memcpy32(s, in);
2875528755
int x_sign = s[31] >> 7;
2875628756
s[31] &= 0x7F;
2875728757

@@ -28858,10 +28858,11 @@ FIO_SFUNC void fio___sc_muladd(uint8_t s[32],
2885828858
for (j = 0; j < 32; ++j)
2885928859
x[i + j] += (unsigned long long)b[i] * (unsigned long long)c[j];
2886028860
uint8_t tmp[64];
28861-
for (i = 0; i < 64; ++i) {
28861+
for (i = 0; i < 63; ++i) {
2886228862
x[i + 1] += x[i] >> 8;
2886328863
tmp[i] = x[i] & 255;
2886428864
}
28865+
tmp[63] = x[63] & 255;
2886528866
fio___sc_reduce(s, tmp);
2886628867
}
2886728868

@@ -28941,17 +28942,29 @@ SFUNC int fio_ed25519_verify(const uint8_t signature[64],
2894128942
return -1;
2894228943

2894328944
/* check s < l */
28944-
static const uint8_t l[32] = {0xed, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58,
28945-
0xd6, 0x9c, 0xf7, 0xa2, 0xde, 0xf9, 0xde, 0x14,
28946-
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
28947-
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10};
28948-
const uint8_t *s = signature + 32;
28949-
uint8_t c = 0;
28950-
for (int i = 31; i >= 0; --i) {
28951-
c = (s[i] > l[i]) | ((s[i] == l[i]) & c);
28952-
}
28953-
if (c)
28954-
return -1;
28945+
{ /* check s < l */
28946+
static const uint64_t l_u64[4] FIO_ALIGN(16) = {
28947+
0x5812631a5cf5d3edULL, /* l[0..7] */
28948+
0x14def9dea2f79cd6ULL, /* l[8..15] */
28949+
0x0000000000000000ULL, /* l[16..23] */
28950+
0x1000000000000000ULL, /* l[24..31] */
28951+
};
28952+
/* Load s as little-endian uint64_t (handles endianness) */
28953+
uint64_t s_u64[4] FIO_ALIGN(16);
28954+
s_u64[0] = fio_buf2u64_le(signature + 32 + 0);
28955+
s_u64[1] = fio_buf2u64_le(signature + 32 + 8);
28956+
s_u64[2] = fio_buf2u64_le(signature + 32 + 16);
28957+
s_u64[3] = fio_buf2u64_le(signature + 32 + 24);
28958+
/* Constant-time comparison */
28959+
uint8_t c = 0;
28960+
for (int i = 0; i < 4; i++) {
28961+
uint8_t gt = s_u64[i] > l_u64[i];
28962+
uint8_t eq = s_u64[i] == l_u64[i];
28963+
c = gt | (eq & c);
28964+
}
28965+
if (c)
28966+
return -1;
28967+
}
2895528968

2895628969
/* k = h(r || public_key || message) mod l */
2895728970
fio_sha512_s sha = fio_sha512_init();
@@ -28999,7 +29012,7 @@ SFUNC void fio_ed25519_sk_to_x25519(uint8_t x_secret_key[32],
2899929012
const uint8_t ed_secret_key[32]) {
2900029013
/* hash ed25519 secret key and use first 32 bytes */
2900129014
fio_u512 h = fio_sha512(ed_secret_key, 32);
29002-
FIO_MEMCPY(x_secret_key, h.u8, 32);
29015+
fio_memcpy32(x_secret_key, h.u8);
2900329016
/* x25519 clamping is done in the scalar multiplication */
2900429017
}
2900529018

@@ -29059,7 +29072,7 @@ SFUNC int fio_x25519_encrypt(uint8_t *ciphertext,
2905929072
fio_secure_zero(shared, 32);
2906029073

2906129074
/* copy ephemeral public key to output */
29062-
FIO_MEMCPY(ciphertext, eph_pk, 32);
29075+
fio_memcpy32(ciphertext, eph_pk);
2906329076

2906429077
/* copy plaintext to ciphertext buffer (after eph_pk and mac space) */
2906529078
if (message_len > 0)
@@ -29112,7 +29125,7 @@ SFUNC int fio_x25519_decrypt(uint8_t *plaintext,
2911229125

2911329126
/* copy mac for in-place verification (chacha20_poly1305_dec modifies it) */
2911429127
uint8_t mac_copy[16];
29115-
FIO_MEMCPY(mac_copy, mac, 16);
29128+
fio_memcpy16(mac_copy, mac);
2911629129

2911729130
/* decrypt and verify with chacha20-poly1305 */
2911829131
int result = fio_chacha20_poly1305_dec(mac_copy, /* mac to verify */

fio-stl/154 ed25519.h

Lines changed: 29 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -722,7 +722,7 @@ FIO_IFUNC void fio___x25519_scalarmult(uint8_t out[32],
722722
const uint8_t scalar[32],
723723
const uint8_t point[32]) {
724724
uint8_t z[32];
725-
FIO_MEMCPY(z, scalar, 32);
725+
fio_memcpy32(z, scalar);
726726
z[31] = (scalar[31] & 127) | 64;
727727
z[0] &= 248;
728728

@@ -985,7 +985,7 @@ FIO_IFUNC void fio___ge_p3_tobytes(uint8_t out[32], fio___ge_p3_s p) {
985985
/* decode 32 bytes to point (returns 0 on success, -1 on failure) */
986986
FIO_SFUNC int fio___ge_p3_frombytes(fio___ge_p3_s p, const uint8_t in[32]) {
987987
uint8_t s[32];
988-
FIO_MEMCPY(s, in, 32);
988+
fio_memcpy32(s, in);
989989
int x_sign = s[31] >> 7;
990990
s[31] &= 0x7F;
991991

@@ -1092,10 +1092,11 @@ FIO_SFUNC void fio___sc_muladd(uint8_t s[32],
10921092
for (j = 0; j < 32; ++j)
10931093
x[i + j] += (unsigned long long)b[i] * (unsigned long long)c[j];
10941094
uint8_t tmp[64];
1095-
for (i = 0; i < 64; ++i) {
1095+
for (i = 0; i < 63; ++i) {
10961096
x[i + 1] += x[i] >> 8;
10971097
tmp[i] = x[i] & 255;
10981098
}
1099+
tmp[63] = x[63] & 255;
10991100
fio___sc_reduce(s, tmp);
11001101
}
11011102

@@ -1175,17 +1176,29 @@ SFUNC int fio_ed25519_verify(const uint8_t signature[64],
11751176
return -1;
11761177

11771178
/* check s < l */
1178-
static const uint8_t l[32] = {0xed, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58,
1179-
0xd6, 0x9c, 0xf7, 0xa2, 0xde, 0xf9, 0xde, 0x14,
1180-
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1181-
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10};
1182-
const uint8_t *s = signature + 32;
1183-
uint8_t c = 0;
1184-
for (int i = 31; i >= 0; --i) {
1185-
c = (s[i] > l[i]) | ((s[i] == l[i]) & c);
1179+
{ /* check s < l */
1180+
static const uint64_t l_u64[4] FIO_ALIGN(16) = {
1181+
0x5812631a5cf5d3edULL, /* l[0..7] */
1182+
0x14def9dea2f79cd6ULL, /* l[8..15] */
1183+
0x0000000000000000ULL, /* l[16..23] */
1184+
0x1000000000000000ULL, /* l[24..31] */
1185+
};
1186+
/* Load s as little-endian uint64_t (handles endianness) */
1187+
uint64_t s_u64[4] FIO_ALIGN(16);
1188+
s_u64[0] = fio_buf2u64_le(signature + 32 + 0);
1189+
s_u64[1] = fio_buf2u64_le(signature + 32 + 8);
1190+
s_u64[2] = fio_buf2u64_le(signature + 32 + 16);
1191+
s_u64[3] = fio_buf2u64_le(signature + 32 + 24);
1192+
/* Constant-time comparison */
1193+
uint8_t c = 0;
1194+
for (int i = 0; i < 4; i++) {
1195+
uint8_t gt = s_u64[i] > l_u64[i];
1196+
uint8_t eq = s_u64[i] == l_u64[i];
1197+
c = gt | (eq & c);
1198+
}
1199+
if (c)
1200+
return -1;
11861201
}
1187-
if (c)
1188-
return -1;
11891202

11901203
/* k = h(r || public_key || message) mod l */
11911204
fio_sha512_s sha = fio_sha512_init();
@@ -1233,7 +1246,7 @@ SFUNC void fio_ed25519_sk_to_x25519(uint8_t x_secret_key[32],
12331246
const uint8_t ed_secret_key[32]) {
12341247
/* hash ed25519 secret key and use first 32 bytes */
12351248
fio_u512 h = fio_sha512(ed_secret_key, 32);
1236-
FIO_MEMCPY(x_secret_key, h.u8, 32);
1249+
fio_memcpy32(x_secret_key, h.u8);
12371250
/* x25519 clamping is done in the scalar multiplication */
12381251
}
12391252

@@ -1293,7 +1306,7 @@ SFUNC int fio_x25519_encrypt(uint8_t *ciphertext,
12931306
fio_secure_zero(shared, 32);
12941307

12951308
/* copy ephemeral public key to output */
1296-
FIO_MEMCPY(ciphertext, eph_pk, 32);
1309+
fio_memcpy32(ciphertext, eph_pk);
12971310

12981311
/* copy plaintext to ciphertext buffer (after eph_pk and mac space) */
12991312
if (message_len > 0)
@@ -1346,7 +1359,7 @@ SFUNC int fio_x25519_decrypt(uint8_t *plaintext,
13461359

13471360
/* copy mac for in-place verification (chacha20_poly1305_dec modifies it) */
13481361
uint8_t mac_copy[16];
1349-
FIO_MEMCPY(mac_copy, mac, 16);
1362+
fio_memcpy16(mac_copy, mac);
13501363

13511364
/* decrypt and verify with chacha20-poly1305 */
13521365
int result = fio_chacha20_poly1305_dec(mac_copy, /* mac to verify */

0 commit comments

Comments
 (0)