diff --git a/crypto/ec/ecp_montp256.c b/crypto/ec/ecp_montp256.c index 5462d92..4082054 100644 --- a/crypto/ec/ecp_montp256.c +++ b/crypto/ec/ecp_montp256.c @@ -531,6 +531,18 @@ static void ec_p256_mod_inverse( memcpy(r, res, 32); } +/* ec_p256_bignum_to_field_elem copies the contents of |in| to |out| and + * returns one if it fits. Otherwise it returns zero. */ +static int ec_p256_bignum_to_field_elem(uint64_t out[4], const BIGNUM *in) + { + if (in->top > 4) + return 0; + + memset(out, 0, 32); + memcpy(out, in->d, sizeof(BN_ULONG) * in->top); + return 1; + } + /* r = sum(scalar[i]*point[i]) */ void ec_p256_windowed_mul( const EC_GROUP *group, @@ -593,13 +605,16 @@ void ec_p256_windowed_mul( /* table[0] is implicitly (0,0,0) (the point at infinity), * therefore it is not stored. All other values are actually * stored with an offset of -1 in table. */ - memcpy(r->X, point[i]->X.d, 32); - memcpy(r->Y, point[i]->Y.d, 32); - memcpy(r->Z, point[i]->Z.d, 32); - memcpy(p.X, point[i]->X.d, 32); - memcpy(p.Y, point[i]->Y.d, 32); - memcpy(p.Z, point[i]->Z.d, 32); + if (!ec_p256_bignum_to_field_elem(r->X, &point[i]->X) || + !ec_p256_bignum_to_field_elem(r->Y, &point[i]->Y) || + !ec_p256_bignum_to_field_elem(r->Z, &point[i]->Z)) + { + ECerr(EC_F_P256_MONT_POINTS_MUL_W, + EC_R_COORDINATES_OUT_OF_RANGE); + goto err; + } + memcpy(&p, r, sizeof(P256_POINT)); memcpy(&table[i][1-1], r, sizeof(P256_POINT)); ec_p256_point_double(r, r, p256_mul_mont, p256_sqr_mont); @@ -802,8 +817,8 @@ int ec_p256_mult_precompute(EC_GROUP *group, BN_CTX *ctx) * ec_GFp_simple_points_make_affine and make multiple * points affine at the same time. */ ec_GFp_simple_make_affine(group, P, ctx); - memcpy(preComputedTable[j][k].X, P->X.d, 32); - memcpy(preComputedTable[j][k].Y, P->Y.d, 32); + ec_p256_bignum_to_field_elem(preComputedTable[j][k].X, &P->X); + ec_p256_bignum_to_field_elem(preComputedTable[j][k].Y, &P->Y); for (i=0; i<7; i++) ec_GFp_simple_dbl(group, P, P, ctx); } @@ -1279,6 +1294,7 @@ int ec_p256_get_affine( uint64_t z_inv3[4]; uint64_t x_aff[4]; uint64_t y_aff[4]; + uint64_t point_x[4], point_y[4], point_z[4]; void (*p256_mul_mont)(uint64_t*,const uint64_t*,const uint64_t*) = NULL; void (*p256_sqr_mont)(uint64_t*,const uint64_t*) = NULL; @@ -1303,9 +1319,18 @@ int ec_p256_get_affine( return 0; } - ec_p256_mod_inverse(z_inv3, point->Z.d, p256_mul_mont, p256_sqr_mont); + if (!ec_p256_bignum_to_field_elem(point_x, &point->X) || + !ec_p256_bignum_to_field_elem(point_y, &point->Y) || + !ec_p256_bignum_to_field_elem(point_z, &point->Z)) + { + ECerr(EC_F_P256_MONT_GET_AFFINE_COORDINATES, + EC_R_COORDINATES_OUT_OF_RANGE); + return 0; + } + + ec_p256_mod_inverse(z_inv3, point_z, p256_mul_mont, p256_sqr_mont); p256_sqr_mont(z_inv2, z_inv3); - p256_mul_mont(x_aff, z_inv2, point->X.d); + p256_mul_mont(x_aff, z_inv2, point_x); if (x != NULL) { @@ -1318,7 +1343,7 @@ int ec_p256_get_affine( if (y != NULL) { p256_mul_mont(z_inv3, z_inv3, z_inv2); - p256_mul_mont(y_aff, z_inv3, point->Y.d); + p256_mul_mont(y_aff, z_inv3, point_y); bn_wexpand(y, 4); y->top = 4; ecp_montp256_mont_back(y->d, y_aff);