-
Notifications
You must be signed in to change notification settings - Fork 2.7k
mbedtls_ecp_point_read_binary from compressed fmt #6282
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
2ff7711
369bfb9
cbfd5e9
fcabc28
4524161
8b6d14b
efde9d5
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
Features | ||
* Add support for reading points in compressed format | ||
(MBEDTLS_ECP_PF_COMPRESSED) with mbedtls_ecp_point_read_binary() | ||
(and callers) for Short Weierstrass curves with prime p where p = 3 mod 4 | ||
(all mbedtls MBEDTLS_ECP_DP_SECP* and MBEDTLS_ECP_DP_BP* curves | ||
except MBEDTLS_ECP_DP_SECP224R1 and MBEDTLS_ECP_DP_SECP224K1) |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -767,6 +767,13 @@ int mbedtls_ecp_point_write_binary( const mbedtls_ecp_group *grp, | |
return( ret ); | ||
} | ||
|
||
#if defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED) | ||
static int mbedtls_ecp_sw_derive_y( const mbedtls_ecp_group *grp, | ||
const mbedtls_mpi *X, | ||
mbedtls_mpi *Y, | ||
int parity_bit ); | ||
#endif /* MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED */ | ||
|
||
/* | ||
* Import a point from unsigned binary data (SEC1 2.3.4 and RFC7748) | ||
*/ | ||
|
@@ -808,16 +815,29 @@ int mbedtls_ecp_point_read_binary( const mbedtls_ecp_group *grp, | |
return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); | ||
} | ||
|
||
if( buf[0] != 0x04 ) | ||
return( MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE ); | ||
|
||
if( ilen != 2 * plen + 1 ) | ||
if( ilen < 1 + plen ) | ||
return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); | ||
|
||
MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &pt->X, buf + 1, plen ) ); | ||
MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &pt->Y, | ||
buf + 1 + plen, plen ) ); | ||
MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &pt->Z, 1 ) ); | ||
|
||
if( buf[0] == 0x04 ) | ||
{ | ||
/* format == MBEDTLS_ECP_PF_UNCOMPRESSED */ | ||
if( ilen != 1 + plen * 2 ) | ||
return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); | ||
return( mbedtls_mpi_read_binary( &pt->Y, buf + 1 + plen, plen ) ); | ||
} | ||
else if( buf[0] == 0x02 || buf[0] == 0x03 ) | ||
{ | ||
/* format == MBEDTLS_ECP_PF_COMPRESSED */ | ||
if( ilen != 1 + plen ) | ||
return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); | ||
return( mbedtls_ecp_sw_derive_y( grp, &pt->X, &pt->Y, | ||
( buf[0] & 1 ) ) ); | ||
} | ||
else | ||
return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Note: we could have avoided the need to change test data by returning However, if we consider this for backporting in 2.28, then we might consider making There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Use of |
||
} | ||
#endif | ||
|
||
|
@@ -1204,6 +1224,86 @@ static inline int mbedtls_mpi_shift_l_mod( const mbedtls_ecp_group *grp, | |
MBEDTLS_MPI_CHK( mbedtls_mpi_safe_cond_swap( (X), (Y), (cond) ) ) | ||
|
||
#if defined(MBEDTLS_ECP_SHORT_WEIERSTRASS_ENABLED) | ||
|
||
/* | ||
* Computes the right-hand side of the Short Weierstrass equation | ||
* RHS = X^3 + A X + B | ||
*/ | ||
static int ecp_sw_rhs( const mbedtls_ecp_group *grp, | ||
mbedtls_mpi *rhs, | ||
const mbedtls_mpi *X ) | ||
{ | ||
int ret; | ||
|
||
/* Compute X^3 + A X + B as X (X^2 + A) + B */ | ||
MPI_ECP_SQR( rhs, X ); | ||
|
||
/* Special case for A = -3 */ | ||
if( grp->A.p == NULL ) | ||
{ | ||
MPI_ECP_SUB_INT( rhs, rhs, 3 ); | ||
} | ||
else | ||
{ | ||
MPI_ECP_ADD( rhs, rhs, &grp->A ); | ||
} | ||
|
||
MPI_ECP_MUL( rhs, rhs, X ); | ||
MPI_ECP_ADD( rhs, rhs, &grp->B ); | ||
|
||
cleanup: | ||
return( ret ); | ||
} | ||
|
||
/* | ||
* Derive Y from X and a parity bit | ||
*/ | ||
static int mbedtls_ecp_sw_derive_y( const mbedtls_ecp_group *grp, | ||
const mbedtls_mpi *X, | ||
mbedtls_mpi *Y, | ||
int parity_bit ) | ||
{ | ||
/* w = y^2 = x^3 + ax + b | ||
* y = sqrt(w) = w^((p+1)/4) mod p (for prime p where p = 3 mod 4) | ||
* | ||
* Note: this method for extracting square root does not validate that w | ||
* was indeed a square so this function will return garbage in Y if X | ||
* does not correspond to a point on the curve. | ||
*/ | ||
|
||
/* Check prerequisite p = 3 mod 4 */ | ||
if( mbedtls_mpi_get_bit( &grp->P, 0 ) != 1 || | ||
mbedtls_mpi_get_bit( &grp->P, 1 ) != 1 ) | ||
return( MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE ); | ||
|
||
int ret; | ||
mbedtls_mpi exp; | ||
mbedtls_mpi_init( &exp ); | ||
|
||
/* use Y to store intermediate result, actually w above */ | ||
MBEDTLS_MPI_CHK( ecp_sw_rhs( grp, Y, X ) ); | ||
|
||
/* w = y^2 */ /* Y contains y^2 intermediate result */ | ||
/* exp = ((p+1)/4) */ | ||
MBEDTLS_MPI_CHK( mbedtls_mpi_add_int( &exp, &grp->P, 1 ) ); | ||
MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &exp, 2 ) ); | ||
/* sqrt(w) = w^((p+1)/4) mod p (for prime p where p = 3 mod 4) */ | ||
MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( Y, Y /*y^2*/, &exp, &grp->P, NULL ) ); | ||
|
||
/* check parity bit match or else invert Y */ | ||
/* This quick inversion implementation is valid because Y != 0 for all | ||
* Short Weierstrass curves supported by mbedtls, as each supported curve | ||
* has an order that is a large prime, so each supported curve does not | ||
* have any point of order 2, and a point with Y == 0 would be of order 2 */ | ||
if( mbedtls_mpi_get_bit( Y, 0 ) != parity_bit ) | ||
MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( Y, &grp->P, Y ) ); | ||
|
||
cleanup: | ||
|
||
mbedtls_mpi_free( &exp ); | ||
return( ret ); | ||
} | ||
|
||
/* | ||
* For curves in short Weierstrass form, we do all the internal operations in | ||
* Jacobian coordinates. | ||
|
@@ -2620,23 +2720,10 @@ static int ecp_check_pubkey_sw( const mbedtls_ecp_group *grp, const mbedtls_ecp_ | |
|
||
/* | ||
* YY = Y^2 | ||
* RHS = X (X^2 + A) + B = X^3 + A X + B | ||
* RHS = X^3 + A X + B | ||
*/ | ||
MPI_ECP_SQR( &YY, &pt->Y ); | ||
MPI_ECP_SQR( &RHS, &pt->X ); | ||
|
||
/* Special case for A = -3 */ | ||
if( grp->A.p == NULL ) | ||
{ | ||
MPI_ECP_SUB_INT( &RHS, &RHS, 3 ); | ||
} | ||
else | ||
{ | ||
MPI_ECP_ADD( &RHS, &RHS, &grp->A ); | ||
} | ||
|
||
MPI_ECP_MUL( &RHS, &RHS, &pt->X ); | ||
MPI_ECP_ADD( &RHS, &RHS, &grp->B ); | ||
MBEDTLS_MPI_CHK( ecp_sw_rhs( grp, &RHS, &pt->X ) ); | ||
|
||
if( MPI_ECP_CMP( &YY, &RHS ) != 0 ) | ||
ret = MBEDTLS_ERR_ECP_INVALID_KEY; | ||
|
Uh oh!
There was an error while loading. Please reload this page.