int dslink_handshake_read_key_pair(mbedtls_ecdh_context *ctx, char *buf) { mbedtls_ecdh_init(ctx); dslink_handshake_get_group(&ctx->grp); char *q = strchr(buf, ' '); if (!q || *(q + 1) == '\0') { errno = 0; return DSLINK_CRYPT_KEY_DECODE_ERR; } size_t len = (q - buf); unsigned char dec[90]; size_t decLen = 0; if (dslink_base64_url_decode(dec, sizeof(dec), &decLen, (unsigned char *) buf, len) != 0) { return DSLINK_CRYPT_BASE64_URL_DECODE_ERR; } if ((errno = mbedtls_mpi_read_binary(&ctx->d, dec, decLen)) != 0) { return DSLINK_CRYPT_KEY_DECODE_ERR; } len = strlen(buf) - len - 1; if (dslink_base64_url_decode(dec, sizeof(dec), &decLen, (unsigned char *) (q + 1), len) != 0) { return DSLINK_CRYPT_BASE64_URL_DECODE_ERR; } if ((errno = mbedtls_ecp_point_read_binary(&ctx->grp, &ctx->Q, dec, decLen)) != 0) { return DSLINK_CRYPT_KEY_DECODE_ERR; } return 0; }
TEE_Result crypto_acipher_ecc_shared_secret(struct ecc_keypair *private_key, struct ecc_public_key *public_key, void *secret, unsigned long *secret_len) { TEE_Result res = TEE_SUCCESS; int lmd_res = 0; uint8_t one[1] = { 1 }; mbedtls_ecdh_context ecdh; size_t out_len = 0; memset(&ecdh, 0, sizeof(ecdh)); mbedtls_ecdh_init(&ecdh); lmd_res = mbedtls_ecp_group_load(&ecdh.grp, private_key->curve); if (lmd_res != 0) { res = TEE_ERROR_NOT_SUPPORTED; goto out; } ecdh.d = *(mbedtls_mpi *)private_key->d; ecdh.Qp.X = *(mbedtls_mpi *)public_key->x; ecdh.Qp.Y = *(mbedtls_mpi *)public_key->y; mbedtls_mpi_read_binary(&ecdh.Qp.Z, one, sizeof(one)); lmd_res = mbedtls_ecdh_calc_secret(&ecdh, &out_len, secret, *secret_len, mbd_rand, NULL); if (lmd_res != 0) { res = get_tee_result(lmd_res); goto out; } *secret_len = out_len; out: /* Reset mpi to skip freeing here, those mpis will be freed with key */ mbedtls_mpi_init(&ecdh.d); mbedtls_mpi_init(&ecdh.Qp.X); mbedtls_mpi_init(&ecdh.Qp.Y); mbedtls_ecdh_free(&ecdh); return res; }
int dslink_handshake_generate_key_pair(mbedtls_ecdh_context *ctx) { mbedtls_entropy_context ent; mbedtls_entropy_init(&ent); mbedtls_ecdh_init(ctx); int ret = 0; if ((ret = dslink_handshake_get_group(&ctx->grp)) != 0) { goto exit; } if ((errno = mbedtls_ecp_gen_keypair(&ctx->grp, &ctx->d, &ctx->Q, mbedtls_entropy_func, &ent)) != 0) { ret = DSLINK_CRYPT_KEY_PAIR_GEN_ERR; goto exit; } exit: mbedtls_entropy_free(&ent); return ret; }
int main( int argc, char *argv[] ) { int ret; mbedtls_ecdh_context ctx_cli, ctx_srv; mbedtls_entropy_context entropy; mbedtls_ctr_drbg_context ctr_drbg; unsigned char cli_to_srv[32], srv_to_cli[32]; const char pers[] = "ecdh"; ((void) argc); ((void) argv); mbedtls_ecdh_init( &ctx_cli ); mbedtls_ecdh_init( &ctx_srv ); mbedtls_ctr_drbg_init( &ctr_drbg ); /* * Initialize random number generation */ mbedtls_printf( " . Seeding the random number generator..." ); fflush( stdout ); mbedtls_entropy_init( &entropy ); if( ( ret = mbedtls_ctr_drbg_seed( &ctr_drbg, mbedtls_entropy_func, &entropy, (const unsigned char *) pers, sizeof pers ) ) != 0 ) { mbedtls_printf( " failed\n ! mbedtls_ctr_drbg_seed returned %d\n", ret ); goto exit; } mbedtls_printf( " ok\n" ); /* * Client: inialize context and generate keypair */ mbedtls_printf( " . Setting up client context..." ); fflush( stdout ); ret = mbedtls_ecp_group_load( &ctx_cli.grp, MBEDTLS_ECP_DP_CURVE25519 ); if( ret != 0 ) { mbedtls_printf( " failed\n ! mbedtls_ecp_group_load returned %d\n", ret ); goto exit; } ret = mbedtls_ecdh_gen_public( &ctx_cli.grp, &ctx_cli.d, &ctx_cli.Q, mbedtls_ctr_drbg_random, &ctr_drbg ); if( ret != 0 ) { mbedtls_printf( " failed\n ! mbedtls_ecdh_gen_public returned %d\n", ret ); goto exit; } ret = mbedtls_mpi_write_binary( &ctx_cli.Q.X, cli_to_srv, 32 ); if( ret != 0 ) { mbedtls_printf( " failed\n ! mbedtls_mpi_write_binary returned %d\n", ret ); goto exit; } mbedtls_printf( " ok\n" ); /* * Server: initialize context and generate keypair */ mbedtls_printf( " . Setting up server context..." ); fflush( stdout ); ret = mbedtls_ecp_group_load( &ctx_srv.grp, MBEDTLS_ECP_DP_CURVE25519 ); if( ret != 0 ) { mbedtls_printf( " failed\n ! mbedtls_ecp_group_load returned %d\n", ret ); goto exit; } ret = mbedtls_ecdh_gen_public( &ctx_srv.grp, &ctx_srv.d, &ctx_srv.Q, mbedtls_ctr_drbg_random, &ctr_drbg ); if( ret != 0 ) { mbedtls_printf( " failed\n ! mbedtls_ecdh_gen_public returned %d\n", ret ); goto exit; } ret = mbedtls_mpi_write_binary( &ctx_srv.Q.X, srv_to_cli, 32 ); if( ret != 0 ) { mbedtls_printf( " failed\n ! mbedtls_mpi_write_binary returned %d\n", ret ); goto exit; } mbedtls_printf( " ok\n" ); /* * Server: read peer's key and generate shared secret */ mbedtls_printf( " . Server reading client key and computing secret..." ); fflush( stdout ); ret = mbedtls_mpi_lset( &ctx_srv.Qp.Z, 1 ); if( ret != 0 ) { mbedtls_printf( " failed\n ! mbedtls_mpi_lset returned %d\n", ret ); goto exit; } ret = mbedtls_mpi_read_binary( &ctx_srv.Qp.X, cli_to_srv, 32 ); if( ret != 0 ) { mbedtls_printf( " failed\n ! mbedtls_mpi_read_binary returned %d\n", ret ); goto exit; } ret = mbedtls_ecdh_compute_shared( &ctx_srv.grp, &ctx_srv.z, &ctx_srv.Qp, &ctx_srv.d, mbedtls_ctr_drbg_random, &ctr_drbg ); if( ret != 0 ) { mbedtls_printf( " failed\n ! mbedtls_ecdh_compute_shared returned %d\n", ret ); goto exit; } mbedtls_printf( " ok\n" ); /* * Client: read peer's key and generate shared secret */ mbedtls_printf( " . Client reading server key and computing secret..." ); fflush( stdout ); ret = mbedtls_mpi_lset( &ctx_cli.Qp.Z, 1 ); if( ret != 0 ) { mbedtls_printf( " failed\n ! mbedtls_mpi_lset returned %d\n", ret ); goto exit; } ret = mbedtls_mpi_read_binary( &ctx_cli.Qp.X, srv_to_cli, 32 ); if( ret != 0 ) { mbedtls_printf( " failed\n ! mbedtls_mpi_read_binary returned %d\n", ret ); goto exit; } ret = mbedtls_ecdh_compute_shared( &ctx_cli.grp, &ctx_cli.z, &ctx_cli.Qp, &ctx_cli.d, mbedtls_ctr_drbg_random, &ctr_drbg ); if( ret != 0 ) { mbedtls_printf( " failed\n ! mbedtls_ecdh_compute_shared returned %d\n", ret ); goto exit; } mbedtls_printf( " ok\n" ); /* * Verification: are the computed secret equal? */ mbedtls_printf( " . Checking if both computed secrets are equal..." ); fflush( stdout ); ret = mbedtls_mpi_cmp_mpi( &ctx_cli.z, &ctx_srv.z ); if( ret != 0 ) { mbedtls_printf( " failed\n ! mbedtls_ecdh_compute_shared returned %d\n", ret ); goto exit; } mbedtls_printf( " ok\n" ); exit: #if defined(_WIN32) mbedtls_printf( " + Press Enter to exit this program.\n" ); fflush( stdout ); getchar(); #endif mbedtls_ecdh_free( &ctx_srv ); mbedtls_ecdh_free( &ctx_cli ); mbedtls_ctr_drbg_free( &ctr_drbg ); mbedtls_entropy_free( &entropy ); return( ret != 0 ); }