Skip to content

Commit

Permalink
Fix endianness issues in X25519 code
Browse files Browse the repository at this point in the history
  • Loading branch information
cpq committed May 15, 2024
1 parent 3ae1a0f commit 4ce4169
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 12 deletions.
22 changes: 16 additions & 6 deletions mongoose.c
Original file line number Diff line number Diff line change
Expand Up @@ -14465,7 +14465,6 @@ const uint8_t X25519_BASE_POINT[X25519_BYTES] = {9};
typedef uint32_t limb_t;
typedef uint64_t dlimb_t;
typedef int64_t sdlimb_t;
#define LIMB(x) (uint32_t)(x##ull), (uint32_t) ((x##ull) >> 32)

#define NLIMBS (256 / X25519_WBITS)
typedef limb_t fe[NLIMBS];
Expand Down Expand Up @@ -14634,11 +14633,15 @@ static void ladder_part2(fe xs[5], const fe x1) {
static void x25519_core(fe xs[5], const uint8_t scalar[X25519_BYTES],
const uint8_t *x1, int clamp) {
int i;
fe x1_limbs;
limb_t swap = 0;
limb_t *x2 = xs[0], *x3 = xs[2], *z3 = xs[3];
memset(xs, 0, 4 * sizeof(fe));
x2[0] = z3[0] = 1;
memcpy(x3, x1, sizeof(fe));
for (i = 0; i < NLIMBS; i++) {
x3[i] = x1_limbs[i] =
MG_U32(x1[i * 4 + 3], x1[i * 4 + 2], x1[i * 4 + 1], x1[i * 4]);
}

for (i = 255; i >= 0; i--) {
uint8_t bytei = scalar[i / 8];
Expand All @@ -14656,15 +14659,15 @@ static void x25519_core(fe xs[5], const uint8_t scalar[X25519_BYTES],
swap = doswap;

ladder_part1(xs);
ladder_part2(xs, (const limb_t *) x1);
ladder_part2(xs, (const limb_t *) x1_limbs);
}
condswap(x2, x3, swap);
}

int mg_tls_x25519(uint8_t out[X25519_BYTES], const uint8_t scalar[X25519_BYTES],
const uint8_t x1[X25519_BYTES], int clamp) {
int i, ret;
fe xs[5];
fe xs[5], out_limbs;
limb_t *x2, *z2, *z3, *prev;
static const struct {
uint8_t a, c, n;
Expand All @@ -14691,9 +14694,16 @@ int mg_tls_x25519(uint8_t out[X25519_BYTES], const uint8_t scalar[X25519_BYTES],

// Here prev = z3
// x2 /= z2
mul((limb_t *) out, x2, z3, NLIMBS);
ret = (int) canon((limb_t *) out);
mul(out_limbs, x2, z3, NLIMBS);
ret = (int) canon(out_limbs);
if (!clamp) ret = 0;
for (i = 0; i < NLIMBS; i++) {
uint32_t n = out_limbs[i];
out[i * 4] = n & 0xff;
out[i * 4 + 1] = (n >> 8) & 0xff;
out[i * 4 + 2] = (n >> 16) & 0xff;
out[i * 4 + 3] = (n >> 24) & 0xff;
}
return ret;
}

Expand Down
22 changes: 16 additions & 6 deletions src/tls_x25519.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ const uint8_t X25519_BASE_POINT[X25519_BYTES] = {9};
typedef uint32_t limb_t;
typedef uint64_t dlimb_t;
typedef int64_t sdlimb_t;
#define LIMB(x) (uint32_t)(x##ull), (uint32_t) ((x##ull) >> 32)

#define NLIMBS (256 / X25519_WBITS)
typedef limb_t fe[NLIMBS];
Expand Down Expand Up @@ -182,11 +181,15 @@ static void ladder_part2(fe xs[5], const fe x1) {
static void x25519_core(fe xs[5], const uint8_t scalar[X25519_BYTES],
const uint8_t *x1, int clamp) {
int i;
fe x1_limbs;
limb_t swap = 0;
limb_t *x2 = xs[0], *x3 = xs[2], *z3 = xs[3];
memset(xs, 0, 4 * sizeof(fe));
x2[0] = z3[0] = 1;
memcpy(x3, x1, sizeof(fe));
for (i = 0; i < NLIMBS; i++) {
x3[i] = x1_limbs[i] =
MG_U32(x1[i * 4 + 3], x1[i * 4 + 2], x1[i * 4 + 1], x1[i * 4]);
}

for (i = 255; i >= 0; i--) {
uint8_t bytei = scalar[i / 8];
Expand All @@ -204,15 +207,15 @@ static void x25519_core(fe xs[5], const uint8_t scalar[X25519_BYTES],
swap = doswap;

ladder_part1(xs);
ladder_part2(xs, (const limb_t *) x1);
ladder_part2(xs, (const limb_t *) x1_limbs);
}
condswap(x2, x3, swap);
}

int mg_tls_x25519(uint8_t out[X25519_BYTES], const uint8_t scalar[X25519_BYTES],
const uint8_t x1[X25519_BYTES], int clamp) {
int i, ret;
fe xs[5];
fe xs[5], out_limbs;
limb_t *x2, *z2, *z3, *prev;
static const struct {
uint8_t a, c, n;
Expand All @@ -239,8 +242,15 @@ int mg_tls_x25519(uint8_t out[X25519_BYTES], const uint8_t scalar[X25519_BYTES],

// Here prev = z3
// x2 /= z2
mul((limb_t *) out, x2, z3, NLIMBS);
ret = (int) canon((limb_t *) out);
mul(out_limbs, x2, z3, NLIMBS);
ret = (int) canon(out_limbs);
if (!clamp) ret = 0;
for (i = 0; i < NLIMBS; i++) {
uint32_t n = out_limbs[i];
out[i * 4] = n & 0xff;
out[i * 4 + 1] = (n >> 8) & 0xff;
out[i * 4 + 2] = (n >> 16) & 0xff;
out[i * 4 + 3] = (n >> 24) & 0xff;
}
return ret;
}
14 changes: 14 additions & 0 deletions test/unit_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -3349,11 +3349,25 @@ static void test_split(void) {
ASSERT(mg_strcmp(b, mg_str("")) == 0);
}

static void test_crypto(void) {
uint8_t key[X25519_BYTES];
uint8_t buf[X25519_BYTES];
char tmp[100];
size_t i;
for (i = 0; i < sizeof(key); i++) key[i] = (uint8_t) i;
for (i = 0; i < sizeof(buf); i++) buf[i] = 0;
mg_tls_x25519(buf, key, X25519_BASE_POINT, 1);
mg_snprintf(tmp, sizeof(tmp), "%M", mg_print_hex, sizeof(buf), buf);
MG_INFO(("%s", tmp));
ASSERT(mg_strcmp(mg_str("8f40c5adb6"), mg_str_n(tmp, 10)) == 0);
}

int main(void) {
const char *debug_level = getenv("V");
if (debug_level == NULL) debug_level = "3";
mg_log_set(atoi(debug_level));

test_crypto();
test_split();
test_json();
test_queue();
Expand Down

0 comments on commit 4ce4169

Please sign in to comment.