Skip to content

Commit

Permalink
Wrap pointers to s2n-bignum functions - delocator fix (aws#2165)
Browse files Browse the repository at this point in the history
The original issue was caused by assigning s2n-bignum functions directly to the members of a `methods` struct. This assignment uses `adrp` instructions at the assembly level. The delocator (in FIPS static build) replaces `adrp` with `adr` which has only +/- 1MB range of addressing. In some versions of gcc, the compiled code ends up exceeding that range between the instruction and its target address when it's in another assembly file such as s2n-bignum functions.

Wrapping those pointers to s2n-bignum functions does the following
- those wrapper functions are closer to where they're assigned to the members `methods` structs because they're in the same compilation unit.
- the body of these wrapper functions is simply a `b` branch instruction to the target label. The branch instruction has an address range of +/- 32MB. (The caller of the method member function will be responsible for the link register, i.e. where the control flow will continue when the function returns.)
  • Loading branch information
nebeid authored Feb 6, 2025
1 parent 54d5051 commit 3a76070
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 6 deletions.
26 changes: 23 additions & 3 deletions crypto/fipsmodule/ec/p384.c
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,26 @@ static p384_limb_t p384_felem_nz(const p384_limb_t in1[P384_NLIMBS]) {

#endif // EC_NISTP_USE_S2N_BIGNUM

// The wrapper functions are needed for FIPS static build.
// Otherwise, initializing ec_nistp_meth with pointers to s2n-bignum
// functions directly generates :got: references that are also thought
// to be local_target by the delocator.
static inline void p384_felem_add_wrapper(ec_nistp_felem_limb *c,
const ec_nistp_felem_limb *a,
const ec_nistp_felem_limb *b) {
p384_felem_add(c, a, b);
}

static inline void p384_felem_sub_wrapper(ec_nistp_felem_limb *c,
const ec_nistp_felem_limb *a,
const ec_nistp_felem_limb *b) {
p384_felem_sub(c, a, b);
}

static inline void p384_felem_neg_wrapper(ec_nistp_felem_limb *c,
const ec_nistp_felem_limb *a) {
p384_felem_opp(c, a);
}

static void p384_from_generic(p384_felem out, const EC_FELEM *in) {
#ifdef OPENSSL_BIG_ENDIAN
Expand Down Expand Up @@ -273,11 +293,11 @@ static void p384_point_add(p384_felem x3, p384_felem y3, p384_felem z3,
DEFINE_METHOD_FUNCTION(ec_nistp_meth, p384_methods) {
out->felem_num_limbs = P384_NLIMBS;
out->felem_num_bits = 384;
out->felem_add = bignum_add_p384;
out->felem_sub = bignum_sub_p384;
out->felem_add = p384_felem_add_wrapper;
out->felem_sub = p384_felem_sub_wrapper;
out->felem_mul = bignum_montmul_p384_selector;
out->felem_sqr = bignum_montsqr_p384_selector;
out->felem_neg = bignum_neg_p384;
out->felem_neg = p384_felem_neg_wrapper;
out->felem_nz = p384_felem_nz;
out->felem_one = p384_felem_one;
out->point_dbl = p384_point_double;
Expand Down
27 changes: 24 additions & 3 deletions crypto/fipsmodule/ec/p521.c
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,27 @@ static const p521_limb_t p521_felem_p[P521_NLIMBS] = {

#endif // EC_NISTP_USE_S2N_BIGNUM

// The wrapper functions are needed for FIPS static build.
// Otherwise, initializing ec_nistp_meth with pointers to s2n-bignum
// functions directly generates :got: references that are also thought
// to be local_target by the delocator.
static inline void p521_felem_add_wrapper(ec_nistp_felem_limb *c,
const ec_nistp_felem_limb *a,
const ec_nistp_felem_limb *b) {
p521_felem_add(c, a, b);
}

static inline void p521_felem_sub_wrapper(ec_nistp_felem_limb *c,
const ec_nistp_felem_limb *a,
const ec_nistp_felem_limb *b) {
p521_felem_sub(c, a, b);
}

static inline void p521_felem_neg_wrapper(ec_nistp_felem_limb *c,
const ec_nistp_felem_limb *a) {
p521_felem_opp(c, a);
}

static p521_limb_t p521_felem_nz(const p521_limb_t in1[P521_NLIMBS]) {
p521_limb_t is_not_zero = 0;
for (int i = 0; i < P521_NLIMBS; i++) {
Expand Down Expand Up @@ -289,11 +310,11 @@ static void p521_point_add(p521_felem x3, p521_felem y3, p521_felem z3,
DEFINE_METHOD_FUNCTION(ec_nistp_meth, p521_methods) {
out->felem_num_limbs = P521_NLIMBS;
out->felem_num_bits = 521;
out->felem_add = bignum_add_p521;
out->felem_sub = bignum_sub_p521;
out->felem_add = p521_felem_add_wrapper;
out->felem_sub = p521_felem_sub_wrapper;
out->felem_mul = bignum_mul_p521_selector;
out->felem_sqr = bignum_sqr_p521_selector;
out->felem_neg = bignum_neg_p521;
out->felem_neg = p521_felem_neg_wrapper;
out->felem_nz = p521_felem_nz;
out->felem_one = p521_felem_one;
out->point_dbl = p521_point_double;
Expand Down

0 comments on commit 3a76070

Please sign in to comment.