Skip to content

Commit

Permalink
cc: fix ed25519 signatures malleability (#632)
Browse files Browse the repository at this point in the history
* cc: fix ed25519 signatures malleability

- #630
- https://soatok.blog/2024/08/14/security-issues-in-matrixs-olm-library/#vuln-ed25519

Actually, the current CC code doesn’t use Ed25519 signatures, so `CVE-2024-45193` has no impact on Komodo (KMD) or any existing assetchains. However, since CC could potentially use these types of signatures in the future (e.g., for newly developed CCs), we’ve added a `0 <= s < L` check to prevent signature malleability.

* add ed25519 signature malleability test

* use int instead of size_t in 0 <= s < L check loop

using a signed integer type (int) is preferable here,
to avoid potential issues with unsigned underflow.

* cc: test, update pytest ver. requirement

addressed in #631
  • Loading branch information
DeckerSU authored Oct 3, 2024
1 parent 9eeace7 commit 956650e
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 1 deletion.
23 changes: 23 additions & 0 deletions src/cryptoconditions/src/include/ed25519/src/verify.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,14 @@
#include "ge.h"
#include "sc.h"

/* L = 2^252+27742317777372353535851937790883648493 in little-endian form */
const unsigned char curve25519_order[32] = {
0xed, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58,
0xd6, 0x9c, 0xf7, 0xa2, 0xde, 0xf9, 0xde, 0x14,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10
};

static int consttime_equal(const unsigned char *x, const unsigned char *y) {
unsigned char r = 0;

Expand Down Expand Up @@ -59,6 +67,21 @@ int ed25519_verify(const unsigned char *signature, const unsigned char *message,
return 0;
}

/* make sure 0 <= s < L, as per RFC 8032, section 5.1.7 to prevent signature
* malleability. Due to the three-bit check above (forces s < 2^253) there
* is not that much room, but adding L once works with most signatures */
for (int i = 31; ; i--)
{
if (signature[i+32] < curve25519_order[i])
{
break;
}
else if (signature[i+32] > curve25519_order[i] || i == 0)
{
return 0;
}
}

sha512_init(&hash);
sha512_update(&hash, signature, 32);
sha512_update(&hash, public_key, 32);
Expand Down
47 changes: 47 additions & 0 deletions src/cryptoconditions/src/include/ed25519/test.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,17 @@
#include "src/ge.h"
#include "src/sc.h"

void print_signature(unsigned char signature[64], char *msg) {
printf("%s\n", msg);
for (int i = 0; i < 64; i++) {
printf("%02x", signature[i]);
if ((i + 1) % 8 != 0) {
printf(" ");
} else {
printf("\n");
}
}
}

int main() {
unsigned char public_key[32], private_key[64], seed[32], scalar[32];
Expand Down Expand Up @@ -146,5 +157,41 @@ int main() {

printf("%fus per shared secret\n", ((double) ((end - start) * 1000)) / CLOCKS_PER_SEC / i * 1000);

/* ed25519 signature malleability test */

printf("testing signature malleability\n");

const unsigned char curve25519_order[32] = {
0xed, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58,
0xd6, 0x9c, 0xf7, 0xa2, 0xde, 0xf9, 0xde, 0x14,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10
};

ed25519_create_seed(seed);
ed25519_create_keypair(public_key, private_key, seed);
ed25519_sign(signature, message, message_len, public_key, private_key);

print_signature(signature, "Signature:");
if (ed25519_verify(signature, message, message_len, public_key)) {
printf("valid signature\n");
} else {
printf("invalid signature\n");
}

// add L to S, which starts at sig[32]
unsigned int s = 0;
for (size_t i = 0; i < 32; i++) {
s = signature[32 + i] + curve25519_order[i] + (s >> 8);
signature[32 + i] = s & 0xff;
}

print_signature(signature,"Modified signature:");
if (ed25519_verify(signature, message, message_len, public_key)) {
printf("valid signature\n");
} else {
printf("invalid signature\n");
}

return 0;
}
2 changes: 1 addition & 1 deletion src/cryptoconditions/test-requirements.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
base58==0.2.5
secp256k1
pytest
pytest>=8.0.0

0 comments on commit 956650e

Please sign in to comment.