da07b2b4a7
Under WPA3-Personal, SAE authentication is used to derive PMK which is more secure and immune to offline dictionary attacks. 1. Add modules to generate SAE commit/confirm for the handshake 2. Add modules that build and parse SAE data in Auth frames 3. Add WPA3 association and key mgmt definitions 4. Invert y-bit while solving for ECC co-ordinate - Once an X co-ordinate is obtained, solving for Y co-ordinate using an elliptical curve equation results in 2 possible values, Y and (P - Y), where p is the prime number. The co-ordinates are used for deriving keys in SAE handshake. As par the 802.11 spec if LSB of X is same as LSB of Y then Y is chosen, (P - Y) otherwise. This is not what is implemented, so fix this behavior to obtain the correct Y co-ordinate.
604 lines
16 KiB
C
604 lines
16 KiB
C
// Copyright 2015-2018 Espressif Systems (Shanghai) PTE LTD
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
#ifdef ESP_PLATFORM
|
|
#include "esp_system.h"
|
|
#include "mbedtls/bignum.h"
|
|
#endif
|
|
|
|
#include "utils/includes.h"
|
|
#include "utils/common.h"
|
|
#include "crypto.h"
|
|
|
|
#include "mbedtls/ecp.h"
|
|
#include "mbedtls/entropy.h"
|
|
#include "mbedtls/ctr_drbg.h"
|
|
|
|
#ifdef ESP_PLATFORM
|
|
int crypto_get_random(void *buf, size_t len)
|
|
{
|
|
if (!buf) {
|
|
return -1;
|
|
}
|
|
esp_fill_random(buf, len);
|
|
return 0;
|
|
}
|
|
#endif
|
|
|
|
struct crypto_bignum *crypto_bignum_init(void)
|
|
{
|
|
mbedtls_mpi *bn = os_zalloc(sizeof(mbedtls_mpi));
|
|
if (bn == NULL) {
|
|
return NULL;
|
|
}
|
|
|
|
mbedtls_mpi_init(bn);
|
|
|
|
return (struct crypto_bignum *)bn;
|
|
}
|
|
|
|
|
|
struct crypto_bignum *crypto_bignum_init_set(const u8 *buf, size_t len)
|
|
{
|
|
int ret = 0;
|
|
mbedtls_mpi *bn = os_zalloc(sizeof(mbedtls_mpi));
|
|
if (bn == NULL) {
|
|
return NULL;
|
|
}
|
|
|
|
MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(bn, buf, len));
|
|
return (struct crypto_bignum *) bn;
|
|
|
|
cleanup:
|
|
os_free(bn);
|
|
return NULL;
|
|
}
|
|
|
|
|
|
void crypto_bignum_deinit(struct crypto_bignum *n, int clear)
|
|
{
|
|
mbedtls_mpi_free((mbedtls_mpi *)n);
|
|
os_free((mbedtls_mpi *)n);
|
|
}
|
|
|
|
|
|
int crypto_bignum_to_bin(const struct crypto_bignum *a,
|
|
u8 *buf, size_t buflen, size_t padlen)
|
|
{
|
|
int num_bytes, offset;
|
|
|
|
if (padlen > buflen) {
|
|
return -1;
|
|
}
|
|
|
|
num_bytes = mbedtls_mpi_size((mbedtls_mpi *) a);
|
|
|
|
if ((size_t) num_bytes > buflen) {
|
|
return -1;
|
|
}
|
|
if (padlen > (size_t) num_bytes) {
|
|
offset = padlen - num_bytes;
|
|
} else {
|
|
offset = 0;
|
|
}
|
|
|
|
os_memset(buf, 0, offset);
|
|
mbedtls_mpi_write_binary((mbedtls_mpi *) a, buf + offset, mbedtls_mpi_size((mbedtls_mpi *)a) );
|
|
|
|
return num_bytes + offset;
|
|
}
|
|
|
|
|
|
int crypto_bignum_add(const struct crypto_bignum *a,
|
|
const struct crypto_bignum *b,
|
|
struct crypto_bignum *c)
|
|
{
|
|
return mbedtls_mpi_add_mpi((mbedtls_mpi *) c, (const mbedtls_mpi *) a, (const mbedtls_mpi *) b) ?
|
|
-1 : 0;
|
|
}
|
|
|
|
|
|
int crypto_bignum_mod(const struct crypto_bignum *a,
|
|
const struct crypto_bignum *b,
|
|
struct crypto_bignum *c)
|
|
{
|
|
return mbedtls_mpi_mod_mpi((mbedtls_mpi *) c, (const mbedtls_mpi *) a, (const mbedtls_mpi *) b) ? -1 : 0;
|
|
}
|
|
|
|
|
|
int crypto_bignum_exptmod(const struct crypto_bignum *a,
|
|
const struct crypto_bignum *b,
|
|
const struct crypto_bignum *c,
|
|
struct crypto_bignum *d)
|
|
{
|
|
return mbedtls_mpi_exp_mod((mbedtls_mpi *) d, (const mbedtls_mpi *) a, (const mbedtls_mpi *) b, (const mbedtls_mpi *) c, NULL) ? -1 : 0;
|
|
|
|
}
|
|
|
|
|
|
int crypto_bignum_inverse(const struct crypto_bignum *a,
|
|
const struct crypto_bignum *b,
|
|
struct crypto_bignum *c)
|
|
{
|
|
return mbedtls_mpi_inv_mod((mbedtls_mpi *) c, (const mbedtls_mpi *) a,
|
|
(const mbedtls_mpi *) b) ? -1 : 0;
|
|
}
|
|
|
|
|
|
int crypto_bignum_sub(const struct crypto_bignum *a,
|
|
const struct crypto_bignum *b,
|
|
struct crypto_bignum *c)
|
|
{
|
|
return mbedtls_mpi_sub_mpi((mbedtls_mpi *) c, (const mbedtls_mpi *) a, (const mbedtls_mpi *) b) ?
|
|
-1 : 0;
|
|
}
|
|
|
|
|
|
int crypto_bignum_div(const struct crypto_bignum *a,
|
|
const struct crypto_bignum *b,
|
|
struct crypto_bignum *c)
|
|
{
|
|
return mbedtls_mpi_div_mpi((mbedtls_mpi *) c, NULL, (const mbedtls_mpi *) a, (const mbedtls_mpi *) b) ?
|
|
-1 : 0;
|
|
}
|
|
|
|
|
|
int crypto_bignum_mulmod(const struct crypto_bignum *a,
|
|
const struct crypto_bignum *b,
|
|
const struct crypto_bignum *c,
|
|
struct crypto_bignum *d)
|
|
{
|
|
int res;
|
|
#if ALLOW_EVEN_MOD // Must enable this macro if c is even.
|
|
mbedtls_mpi temp;
|
|
mbedtls_mpi_init(&temp);
|
|
|
|
res = mbedtls_mpi_mul_mpi(&temp, (const mbedtls_mpi *) a, (const mbedtls_mpi *) b);
|
|
if (res) {
|
|
return -1;
|
|
}
|
|
|
|
res = mbedtls_mpi_mod_mpi((mbedtls_mpi *) d, &temp, (mbedtls_mpi *) c);
|
|
|
|
mbedtls_mpi_free(&temp);
|
|
#else
|
|
// Works with odd modulus only, but it is faster with HW acceleration
|
|
res = esp_mpi_mul_mpi_mod((mbedtls_mpi *) d, (mbedtls_mpi *) a, (mbedtls_mpi *) b, (mbedtls_mpi *) c);
|
|
#endif
|
|
return res ? -1 : 0;
|
|
}
|
|
|
|
|
|
int crypto_bignum_cmp(const struct crypto_bignum *a,
|
|
const struct crypto_bignum *b)
|
|
{
|
|
return mbedtls_mpi_cmp_mpi((const mbedtls_mpi *) a, (const mbedtls_mpi *) b);
|
|
}
|
|
|
|
|
|
int crypto_bignum_bits(const struct crypto_bignum *a)
|
|
{
|
|
return mbedtls_mpi_bitlen((const mbedtls_mpi *) a);
|
|
}
|
|
|
|
|
|
int crypto_bignum_is_zero(const struct crypto_bignum *a)
|
|
{
|
|
return (mbedtls_mpi_cmp_int((const mbedtls_mpi *) a, 0) == 0);
|
|
}
|
|
|
|
|
|
int crypto_bignum_is_one(const struct crypto_bignum *a)
|
|
{
|
|
return (mbedtls_mpi_cmp_int((const mbedtls_mpi *) a, 1) == 0);
|
|
}
|
|
|
|
|
|
int crypto_bignum_legendre(const struct crypto_bignum *a,
|
|
const struct crypto_bignum *p)
|
|
{
|
|
mbedtls_mpi exp, tmp;
|
|
int res = -2, ret;
|
|
|
|
mbedtls_mpi_init(&exp);
|
|
mbedtls_mpi_init(&tmp);
|
|
|
|
/* exp = (p-1) / 2 */
|
|
MBEDTLS_MPI_CHK(mbedtls_mpi_sub_int(&exp, (const mbedtls_mpi *) p, 1));
|
|
MBEDTLS_MPI_CHK(mbedtls_mpi_shift_r(&exp, 1));
|
|
MBEDTLS_MPI_CHK(mbedtls_mpi_exp_mod(&tmp, (const mbedtls_mpi *) a, &exp, (const mbedtls_mpi *) p, NULL));
|
|
|
|
if (mbedtls_mpi_cmp_int(&tmp, 1) == 0) {
|
|
res = 1;
|
|
} else if (mbedtls_mpi_cmp_int(&tmp, 0) == 0
|
|
/* The below check is workaround for the case where HW
|
|
* does not behave properly for X ^ A mod M when X is
|
|
* power of M. Instead of returning value 0, value M is
|
|
* returned.*/
|
|
|| mbedtls_mpi_cmp_mpi(&tmp, (const mbedtls_mpi *)p) == 0) {
|
|
res = 0;
|
|
} else {
|
|
res = -1;
|
|
}
|
|
|
|
cleanup:
|
|
mbedtls_mpi_free(&tmp);
|
|
mbedtls_mpi_free(&exp);
|
|
return res;
|
|
}
|
|
|
|
#ifdef CONFIG_ECC
|
|
struct crypto_ec {
|
|
mbedtls_ecp_group group;
|
|
};
|
|
|
|
struct crypto_ec *crypto_ec_init(int group)
|
|
{
|
|
struct crypto_ec *e;
|
|
|
|
mbedtls_ecp_group_id grp_id;
|
|
|
|
/* IANA registry to mbedtls internal mapping*/
|
|
switch (group) {
|
|
case IANA_SECP256R1:
|
|
/* For now just support NIST-P256.
|
|
* This is of type "short Weierstrass".
|
|
*/
|
|
grp_id = MBEDTLS_ECP_DP_SECP256R1;
|
|
break;
|
|
default:
|
|
return NULL;
|
|
|
|
}
|
|
e = os_zalloc(sizeof(*e));
|
|
if (e == NULL) {
|
|
return NULL;
|
|
}
|
|
|
|
mbedtls_ecp_group_init( &e->group );
|
|
|
|
if (mbedtls_ecp_group_load(&e->group, grp_id)) {
|
|
crypto_ec_deinit(e);
|
|
e = NULL;
|
|
}
|
|
|
|
return e;
|
|
}
|
|
|
|
|
|
void crypto_ec_deinit(struct crypto_ec *e)
|
|
{
|
|
if (e == NULL) {
|
|
return;
|
|
}
|
|
|
|
mbedtls_ecp_group_free( &e->group );
|
|
os_free(e);
|
|
}
|
|
|
|
|
|
struct crypto_ec_point *crypto_ec_point_init(struct crypto_ec *e)
|
|
{
|
|
mbedtls_ecp_point *pt;
|
|
if (e == NULL) {
|
|
return NULL;
|
|
}
|
|
|
|
pt = os_zalloc(sizeof(mbedtls_ecp_point));
|
|
|
|
if( pt == NULL) {
|
|
return NULL;
|
|
}
|
|
|
|
mbedtls_ecp_point_init(pt);
|
|
|
|
return (struct crypto_ec_point *) pt;
|
|
}
|
|
|
|
|
|
size_t crypto_ec_prime_len(struct crypto_ec *e)
|
|
{
|
|
return mbedtls_mpi_size(&e->group.P);
|
|
}
|
|
|
|
|
|
size_t crypto_ec_prime_len_bits(struct crypto_ec *e)
|
|
{
|
|
return mbedtls_mpi_bitlen(&e->group.P);
|
|
}
|
|
|
|
|
|
const struct crypto_bignum *crypto_ec_get_prime(struct crypto_ec *e)
|
|
{
|
|
return (const struct crypto_bignum *) &e->group.P;
|
|
}
|
|
|
|
|
|
const struct crypto_bignum *crypto_ec_get_order(struct crypto_ec *e)
|
|
{
|
|
return (const struct crypto_bignum *) &e->group.N;
|
|
}
|
|
|
|
|
|
void crypto_ec_point_deinit(struct crypto_ec_point *p, int clear)
|
|
{
|
|
mbedtls_ecp_point_free((mbedtls_ecp_point *) p);
|
|
os_free(p);
|
|
}
|
|
|
|
|
|
int crypto_ec_point_to_bin(struct crypto_ec *e,
|
|
const struct crypto_ec_point *point, u8 *x, u8 *y)
|
|
{
|
|
int len = mbedtls_mpi_size(&e->group.P);
|
|
|
|
if (x) {
|
|
if(crypto_bignum_to_bin((struct crypto_bignum *) & ((mbedtls_ecp_point *) point)->X,
|
|
x, len, len) < 0) {
|
|
return -1;
|
|
}
|
|
|
|
}
|
|
|
|
if (y) {
|
|
if(crypto_bignum_to_bin((struct crypto_bignum *) & ((mbedtls_ecp_point *) point)->Y,
|
|
y, len, len) < 0) {
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
struct crypto_ec_point *crypto_ec_point_from_bin(struct crypto_ec *e,
|
|
const u8 *val)
|
|
{
|
|
mbedtls_ecp_point *pt;
|
|
int len, ret;
|
|
|
|
if (e == NULL) {
|
|
return NULL;
|
|
}
|
|
|
|
len = mbedtls_mpi_size(&e->group.P);
|
|
|
|
pt = os_zalloc(sizeof(mbedtls_ecp_point));
|
|
mbedtls_ecp_point_init(pt);
|
|
|
|
MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&pt->X, val, len));
|
|
MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&pt->Y, val + len, len));
|
|
MBEDTLS_MPI_CHK(mbedtls_mpi_lset((&pt->Z), 1));
|
|
|
|
return (struct crypto_ec_point *) pt;
|
|
|
|
cleanup:
|
|
mbedtls_ecp_point_free(pt);
|
|
os_free(pt);
|
|
return NULL;
|
|
}
|
|
|
|
|
|
int crypto_ec_point_add(struct crypto_ec *e, const struct crypto_ec_point *a,
|
|
const struct crypto_ec_point *b,
|
|
struct crypto_ec_point *c)
|
|
{
|
|
int ret;
|
|
mbedtls_mpi one;
|
|
|
|
mbedtls_mpi_init(&one);
|
|
|
|
MBEDTLS_MPI_CHK(mbedtls_mpi_lset( &one, 1 ));
|
|
MBEDTLS_MPI_CHK(mbedtls_ecp_muladd(&e->group, (mbedtls_ecp_point *) c, &one, (const mbedtls_ecp_point *)a , &one, (const mbedtls_ecp_point *)b));
|
|
|
|
cleanup:
|
|
mbedtls_mpi_free(&one);
|
|
return ret ? -1 : 0;
|
|
}
|
|
|
|
|
|
int crypto_ec_point_mul(struct crypto_ec *e, const struct crypto_ec_point *p,
|
|
const struct crypto_bignum *b,
|
|
struct crypto_ec_point *res)
|
|
{
|
|
int ret;
|
|
mbedtls_entropy_context entropy;
|
|
mbedtls_ctr_drbg_context ctr_drbg;
|
|
|
|
mbedtls_entropy_init(&entropy);
|
|
|
|
MBEDTLS_MPI_CHK(mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy,
|
|
NULL, 0));
|
|
|
|
MBEDTLS_MPI_CHK(mbedtls_ecp_mul(&e->group,
|
|
(mbedtls_ecp_point *) res,
|
|
(const mbedtls_mpi *)b,
|
|
(const mbedtls_ecp_point *)p,
|
|
mbedtls_ctr_drbg_random,
|
|
&ctr_drbg));
|
|
cleanup:
|
|
mbedtls_ctr_drbg_free( &ctr_drbg );
|
|
mbedtls_entropy_free( &entropy );
|
|
return ret ? -1 : 0;
|
|
}
|
|
|
|
|
|
/* Currently mbedtls does not have any function for inverse
|
|
* This function calculates inverse of a point.
|
|
* Set R = -P
|
|
*/
|
|
static int ecp_opp( const mbedtls_ecp_group *grp, mbedtls_ecp_point *R, const mbedtls_ecp_point *P)
|
|
{
|
|
int ret = 0;
|
|
|
|
/* Copy */
|
|
if (R != P) {
|
|
MBEDTLS_MPI_CHK(mbedtls_ecp_copy(R, P));
|
|
}
|
|
|
|
/* In-place opposite */
|
|
if (mbedtls_mpi_cmp_int( &R->Y, 0) != 0) {
|
|
MBEDTLS_MPI_CHK(mbedtls_mpi_sub_mpi(&R->Y, &grp->P, &R->Y));
|
|
}
|
|
|
|
cleanup:
|
|
return ( ret );
|
|
}
|
|
|
|
int crypto_ec_point_invert(struct crypto_ec *e, struct crypto_ec_point *p)
|
|
{
|
|
return ecp_opp(&e->group, (mbedtls_ecp_point *) p, (mbedtls_ecp_point *) p) ? -1 : 0;
|
|
}
|
|
|
|
int crypto_ec_point_solve_y_coord(struct crypto_ec *e,
|
|
struct crypto_ec_point *p,
|
|
const struct crypto_bignum *x, int y_bit)
|
|
{
|
|
mbedtls_mpi temp;
|
|
mbedtls_mpi *y_sqr, *y;
|
|
mbedtls_mpi_init(&temp);
|
|
int ret = 0;
|
|
|
|
y = &((mbedtls_ecp_point *)p)->Y;
|
|
|
|
/* Faster way to find sqrt
|
|
* Works only with curves having prime p
|
|
* such that p ≡ 3 (mod 4)
|
|
* y_ = (y2 ^ ((p+1)/4)) mod p
|
|
*
|
|
* if LSB of both x and y are same: y = y_
|
|
* else y = p - y_
|
|
* y_bit is LSB of x
|
|
*/
|
|
y_bit = (y_bit != 0);
|
|
|
|
y_sqr = (mbedtls_mpi *) crypto_ec_point_compute_y_sqr(e, x);
|
|
|
|
if (y_sqr) {
|
|
|
|
MBEDTLS_MPI_CHK(mbedtls_mpi_add_int(&temp, &e->group.P, 1));
|
|
MBEDTLS_MPI_CHK(mbedtls_mpi_div_int(&temp, NULL, &temp, 4));
|
|
MBEDTLS_MPI_CHK(mbedtls_mpi_exp_mod(y, y_sqr, &temp, &e->group.P, NULL));
|
|
|
|
if (y_bit != mbedtls_mpi_get_bit(y, 0))
|
|
MBEDTLS_MPI_CHK(mbedtls_mpi_sub_mpi(y, &e->group.P, y));
|
|
|
|
MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&((mbedtls_ecp_point* )p)->X, (const mbedtls_mpi*) x));
|
|
MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&((mbedtls_ecp_point *)p)->Z, 1));
|
|
} else {
|
|
ret = 1;
|
|
}
|
|
cleanup:
|
|
mbedtls_mpi_free(&temp);
|
|
mbedtls_mpi_free(y_sqr);
|
|
os_free(y_sqr);
|
|
return ret ? -1 : 0;
|
|
}
|
|
|
|
struct crypto_bignum *
|
|
crypto_ec_point_compute_y_sqr(struct crypto_ec *e,
|
|
const struct crypto_bignum *x)
|
|
{
|
|
mbedtls_mpi temp, temp2, num;
|
|
int ret = 0;
|
|
|
|
mbedtls_mpi *y_sqr = os_zalloc(sizeof(mbedtls_mpi));
|
|
if (y_sqr == NULL) {
|
|
return NULL;
|
|
}
|
|
|
|
mbedtls_mpi_init(&temp);
|
|
mbedtls_mpi_init(&temp2);
|
|
mbedtls_mpi_init(&num);
|
|
mbedtls_mpi_init(y_sqr);
|
|
|
|
/* y^2 = x^3 + ax + b mod P*/
|
|
/* mbedtls does not have mod-add or mod-mul apis.
|
|
*
|
|
*/
|
|
|
|
/* Calculate x^3 mod P*/
|
|
MBEDTLS_MPI_CHK(mbedtls_mpi_lset( &num, 3));
|
|
MBEDTLS_MPI_CHK(mbedtls_mpi_exp_mod(&temp, (const mbedtls_mpi *) x, &num, &e->group.P, NULL));
|
|
|
|
/* Calculate ax mod P*/
|
|
MBEDTLS_MPI_CHK(mbedtls_mpi_lset( &num, -3));
|
|
MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&temp2, (const mbedtls_mpi *) x, &num));
|
|
MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&temp2, &temp2, &e->group.P));
|
|
|
|
/* Calculate ax + b mod P. Note that b is already < P*/
|
|
MBEDTLS_MPI_CHK(mbedtls_mpi_add_mpi(&temp2, &temp2, &e->group.B));
|
|
MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&temp2, &temp2, &e->group.P));
|
|
|
|
/* Calculate x^3 + ax + b mod P*/
|
|
MBEDTLS_MPI_CHK(mbedtls_mpi_add_mpi(&temp2, &temp2, &temp));
|
|
MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(y_sqr, &temp2, &e->group.P));
|
|
|
|
|
|
cleanup:
|
|
mbedtls_mpi_free(&temp);
|
|
mbedtls_mpi_free(&temp2);
|
|
mbedtls_mpi_free(&num);
|
|
if (ret) {
|
|
mbedtls_mpi_free(y_sqr);
|
|
os_free(y_sqr);
|
|
return NULL;
|
|
} else {
|
|
return (struct crypto_bignum *) y_sqr;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
int crypto_ec_point_is_at_infinity(struct crypto_ec *e,
|
|
const struct crypto_ec_point *p)
|
|
{
|
|
return mbedtls_ecp_is_zero((mbedtls_ecp_point *) p);
|
|
}
|
|
|
|
int crypto_ec_point_is_on_curve(struct crypto_ec *e,
|
|
const struct crypto_ec_point *p)
|
|
{
|
|
mbedtls_mpi y_sqr_lhs, *y_sqr_rhs = NULL, two;
|
|
int ret = 0, on_curve = 0;
|
|
|
|
mbedtls_mpi_init(&y_sqr_lhs);
|
|
mbedtls_mpi_init(&two);
|
|
|
|
/* Calculate y^2 mod P*/
|
|
MBEDTLS_MPI_CHK(mbedtls_mpi_lset( &two, 2));
|
|
MBEDTLS_MPI_CHK(mbedtls_mpi_exp_mod(&y_sqr_lhs, &((const mbedtls_ecp_point *)p)->Y , &two, &e->group.P, NULL));
|
|
|
|
y_sqr_rhs = (mbedtls_mpi *) crypto_ec_point_compute_y_sqr(e, (const struct crypto_bignum *) & ((const mbedtls_ecp_point *)p)->X);
|
|
|
|
if (y_sqr_rhs && (mbedtls_mpi_cmp_mpi(y_sqr_rhs, &y_sqr_lhs) == 0)) {
|
|
on_curve = 1;
|
|
}
|
|
|
|
cleanup:
|
|
mbedtls_mpi_free(&y_sqr_lhs);
|
|
mbedtls_mpi_free(y_sqr_rhs);
|
|
os_free(y_sqr_rhs);
|
|
return (ret == 0) && (on_curve == 1);
|
|
}
|
|
|
|
int crypto_ec_point_cmp(const struct crypto_ec *e,
|
|
const struct crypto_ec_point *a,
|
|
const struct crypto_ec_point *b)
|
|
{
|
|
return mbedtls_ecp_point_cmp((const mbedtls_ecp_point *) a,
|
|
(const mbedtls_ecp_point *) b);
|
|
}
|
|
|
|
#endif /* CONFIG_ECC */
|