1a8e1175bSopenharmony_ci/* 2a8e1175bSopenharmony_ci * Elliptic curve J-PAKE 3a8e1175bSopenharmony_ci * 4a8e1175bSopenharmony_ci * Copyright The Mbed TLS Contributors 5a8e1175bSopenharmony_ci * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later 6a8e1175bSopenharmony_ci */ 7a8e1175bSopenharmony_ci 8a8e1175bSopenharmony_ci/* 9a8e1175bSopenharmony_ci * References in the code are to the Thread v1.0 Specification, 10a8e1175bSopenharmony_ci * available to members of the Thread Group http://threadgroup.org/ 11a8e1175bSopenharmony_ci */ 12a8e1175bSopenharmony_ci 13a8e1175bSopenharmony_ci#include "common.h" 14a8e1175bSopenharmony_ci 15a8e1175bSopenharmony_ci#if defined(MBEDTLS_ECJPAKE_C) 16a8e1175bSopenharmony_ci 17a8e1175bSopenharmony_ci#include "mbedtls/ecjpake.h" 18a8e1175bSopenharmony_ci#include "mbedtls/platform_util.h" 19a8e1175bSopenharmony_ci#include "mbedtls/error.h" 20a8e1175bSopenharmony_ci 21a8e1175bSopenharmony_ci#include <string.h> 22a8e1175bSopenharmony_ci 23a8e1175bSopenharmony_ci#if !defined(MBEDTLS_ECJPAKE_ALT) 24a8e1175bSopenharmony_ci 25a8e1175bSopenharmony_ci/* 26a8e1175bSopenharmony_ci * Convert a mbedtls_ecjpake_role to identifier string 27a8e1175bSopenharmony_ci */ 28a8e1175bSopenharmony_cistatic const char * const ecjpake_id[] = { 29a8e1175bSopenharmony_ci "client", 30a8e1175bSopenharmony_ci "server" 31a8e1175bSopenharmony_ci}; 32a8e1175bSopenharmony_ci 33a8e1175bSopenharmony_ci#define ID_MINE (ecjpake_id[ctx->role]) 34a8e1175bSopenharmony_ci#define ID_PEER (ecjpake_id[1 - ctx->role]) 35a8e1175bSopenharmony_ci 36a8e1175bSopenharmony_ci/** 37a8e1175bSopenharmony_ci * Helper to Compute a hash from md_type 38a8e1175bSopenharmony_ci */ 39a8e1175bSopenharmony_cistatic int mbedtls_ecjpake_compute_hash(mbedtls_md_type_t md_type, 40a8e1175bSopenharmony_ci const unsigned char *input, size_t ilen, 41a8e1175bSopenharmony_ci unsigned char *output) 42a8e1175bSopenharmony_ci{ 43a8e1175bSopenharmony_ci return mbedtls_md(mbedtls_md_info_from_type(md_type), 44a8e1175bSopenharmony_ci input, ilen, output); 45a8e1175bSopenharmony_ci} 46a8e1175bSopenharmony_ci 47a8e1175bSopenharmony_ci/* 48a8e1175bSopenharmony_ci * Initialize context 49a8e1175bSopenharmony_ci */ 50a8e1175bSopenharmony_civoid mbedtls_ecjpake_init(mbedtls_ecjpake_context *ctx) 51a8e1175bSopenharmony_ci{ 52a8e1175bSopenharmony_ci ctx->md_type = MBEDTLS_MD_NONE; 53a8e1175bSopenharmony_ci mbedtls_ecp_group_init(&ctx->grp); 54a8e1175bSopenharmony_ci ctx->point_format = MBEDTLS_ECP_PF_UNCOMPRESSED; 55a8e1175bSopenharmony_ci 56a8e1175bSopenharmony_ci mbedtls_ecp_point_init(&ctx->Xm1); 57a8e1175bSopenharmony_ci mbedtls_ecp_point_init(&ctx->Xm2); 58a8e1175bSopenharmony_ci mbedtls_ecp_point_init(&ctx->Xp1); 59a8e1175bSopenharmony_ci mbedtls_ecp_point_init(&ctx->Xp2); 60a8e1175bSopenharmony_ci mbedtls_ecp_point_init(&ctx->Xp); 61a8e1175bSopenharmony_ci 62a8e1175bSopenharmony_ci mbedtls_mpi_init(&ctx->xm1); 63a8e1175bSopenharmony_ci mbedtls_mpi_init(&ctx->xm2); 64a8e1175bSopenharmony_ci mbedtls_mpi_init(&ctx->s); 65a8e1175bSopenharmony_ci} 66a8e1175bSopenharmony_ci 67a8e1175bSopenharmony_ci/* 68a8e1175bSopenharmony_ci * Free context 69a8e1175bSopenharmony_ci */ 70a8e1175bSopenharmony_civoid mbedtls_ecjpake_free(mbedtls_ecjpake_context *ctx) 71a8e1175bSopenharmony_ci{ 72a8e1175bSopenharmony_ci if (ctx == NULL) { 73a8e1175bSopenharmony_ci return; 74a8e1175bSopenharmony_ci } 75a8e1175bSopenharmony_ci 76a8e1175bSopenharmony_ci ctx->md_type = MBEDTLS_MD_NONE; 77a8e1175bSopenharmony_ci mbedtls_ecp_group_free(&ctx->grp); 78a8e1175bSopenharmony_ci 79a8e1175bSopenharmony_ci mbedtls_ecp_point_free(&ctx->Xm1); 80a8e1175bSopenharmony_ci mbedtls_ecp_point_free(&ctx->Xm2); 81a8e1175bSopenharmony_ci mbedtls_ecp_point_free(&ctx->Xp1); 82a8e1175bSopenharmony_ci mbedtls_ecp_point_free(&ctx->Xp2); 83a8e1175bSopenharmony_ci mbedtls_ecp_point_free(&ctx->Xp); 84a8e1175bSopenharmony_ci 85a8e1175bSopenharmony_ci mbedtls_mpi_free(&ctx->xm1); 86a8e1175bSopenharmony_ci mbedtls_mpi_free(&ctx->xm2); 87a8e1175bSopenharmony_ci mbedtls_mpi_free(&ctx->s); 88a8e1175bSopenharmony_ci} 89a8e1175bSopenharmony_ci 90a8e1175bSopenharmony_ci/* 91a8e1175bSopenharmony_ci * Setup context 92a8e1175bSopenharmony_ci */ 93a8e1175bSopenharmony_ciint mbedtls_ecjpake_setup(mbedtls_ecjpake_context *ctx, 94a8e1175bSopenharmony_ci mbedtls_ecjpake_role role, 95a8e1175bSopenharmony_ci mbedtls_md_type_t hash, 96a8e1175bSopenharmony_ci mbedtls_ecp_group_id curve, 97a8e1175bSopenharmony_ci const unsigned char *secret, 98a8e1175bSopenharmony_ci size_t len) 99a8e1175bSopenharmony_ci{ 100a8e1175bSopenharmony_ci int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 101a8e1175bSopenharmony_ci 102a8e1175bSopenharmony_ci if (role != MBEDTLS_ECJPAKE_CLIENT && role != MBEDTLS_ECJPAKE_SERVER) { 103a8e1175bSopenharmony_ci return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; 104a8e1175bSopenharmony_ci } 105a8e1175bSopenharmony_ci 106a8e1175bSopenharmony_ci ctx->role = role; 107a8e1175bSopenharmony_ci 108a8e1175bSopenharmony_ci if ((mbedtls_md_info_from_type(hash)) == NULL) { 109a8e1175bSopenharmony_ci return MBEDTLS_ERR_MD_FEATURE_UNAVAILABLE; 110a8e1175bSopenharmony_ci } 111a8e1175bSopenharmony_ci 112a8e1175bSopenharmony_ci ctx->md_type = hash; 113a8e1175bSopenharmony_ci 114a8e1175bSopenharmony_ci MBEDTLS_MPI_CHK(mbedtls_ecp_group_load(&ctx->grp, curve)); 115a8e1175bSopenharmony_ci 116a8e1175bSopenharmony_ci MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&ctx->s, secret, len)); 117a8e1175bSopenharmony_ci 118a8e1175bSopenharmony_cicleanup: 119a8e1175bSopenharmony_ci if (ret != 0) { 120a8e1175bSopenharmony_ci mbedtls_ecjpake_free(ctx); 121a8e1175bSopenharmony_ci } 122a8e1175bSopenharmony_ci 123a8e1175bSopenharmony_ci return ret; 124a8e1175bSopenharmony_ci} 125a8e1175bSopenharmony_ci 126a8e1175bSopenharmony_ciint mbedtls_ecjpake_set_point_format(mbedtls_ecjpake_context *ctx, 127a8e1175bSopenharmony_ci int point_format) 128a8e1175bSopenharmony_ci{ 129a8e1175bSopenharmony_ci switch (point_format) { 130a8e1175bSopenharmony_ci case MBEDTLS_ECP_PF_UNCOMPRESSED: 131a8e1175bSopenharmony_ci case MBEDTLS_ECP_PF_COMPRESSED: 132a8e1175bSopenharmony_ci ctx->point_format = point_format; 133a8e1175bSopenharmony_ci return 0; 134a8e1175bSopenharmony_ci default: 135a8e1175bSopenharmony_ci return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; 136a8e1175bSopenharmony_ci } 137a8e1175bSopenharmony_ci} 138a8e1175bSopenharmony_ci 139a8e1175bSopenharmony_ci/* 140a8e1175bSopenharmony_ci * Check if context is ready for use 141a8e1175bSopenharmony_ci */ 142a8e1175bSopenharmony_ciint mbedtls_ecjpake_check(const mbedtls_ecjpake_context *ctx) 143a8e1175bSopenharmony_ci{ 144a8e1175bSopenharmony_ci if (ctx->md_type == MBEDTLS_MD_NONE || 145a8e1175bSopenharmony_ci ctx->grp.id == MBEDTLS_ECP_DP_NONE || 146a8e1175bSopenharmony_ci ctx->s.p == NULL) { 147a8e1175bSopenharmony_ci return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; 148a8e1175bSopenharmony_ci } 149a8e1175bSopenharmony_ci 150a8e1175bSopenharmony_ci return 0; 151a8e1175bSopenharmony_ci} 152a8e1175bSopenharmony_ci 153a8e1175bSopenharmony_ci/* 154a8e1175bSopenharmony_ci * Write a point plus its length to a buffer 155a8e1175bSopenharmony_ci */ 156a8e1175bSopenharmony_cistatic int ecjpake_write_len_point(unsigned char **p, 157a8e1175bSopenharmony_ci const unsigned char *end, 158a8e1175bSopenharmony_ci const mbedtls_ecp_group *grp, 159a8e1175bSopenharmony_ci const int pf, 160a8e1175bSopenharmony_ci const mbedtls_ecp_point *P) 161a8e1175bSopenharmony_ci{ 162a8e1175bSopenharmony_ci int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 163a8e1175bSopenharmony_ci size_t len; 164a8e1175bSopenharmony_ci 165a8e1175bSopenharmony_ci /* Need at least 4 for length plus 1 for point */ 166a8e1175bSopenharmony_ci if (end < *p || end - *p < 5) { 167a8e1175bSopenharmony_ci return MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL; 168a8e1175bSopenharmony_ci } 169a8e1175bSopenharmony_ci 170a8e1175bSopenharmony_ci ret = mbedtls_ecp_point_write_binary(grp, P, pf, 171a8e1175bSopenharmony_ci &len, *p + 4, (size_t) (end - (*p + 4))); 172a8e1175bSopenharmony_ci if (ret != 0) { 173a8e1175bSopenharmony_ci return ret; 174a8e1175bSopenharmony_ci } 175a8e1175bSopenharmony_ci 176a8e1175bSopenharmony_ci MBEDTLS_PUT_UINT32_BE(len, *p, 0); 177a8e1175bSopenharmony_ci 178a8e1175bSopenharmony_ci *p += 4 + len; 179a8e1175bSopenharmony_ci 180a8e1175bSopenharmony_ci return 0; 181a8e1175bSopenharmony_ci} 182a8e1175bSopenharmony_ci 183a8e1175bSopenharmony_ci/* 184a8e1175bSopenharmony_ci * Size of the temporary buffer for ecjpake_hash: 185a8e1175bSopenharmony_ci * 3 EC points plus their length, plus ID and its length (4 + 6 bytes) 186a8e1175bSopenharmony_ci */ 187a8e1175bSopenharmony_ci#define ECJPAKE_HASH_BUF_LEN (3 * (4 + MBEDTLS_ECP_MAX_PT_LEN) + 4 + 6) 188a8e1175bSopenharmony_ci 189a8e1175bSopenharmony_ci/* 190a8e1175bSopenharmony_ci * Compute hash for ZKP (7.4.2.2.2.1) 191a8e1175bSopenharmony_ci */ 192a8e1175bSopenharmony_cistatic int ecjpake_hash(const mbedtls_md_type_t md_type, 193a8e1175bSopenharmony_ci const mbedtls_ecp_group *grp, 194a8e1175bSopenharmony_ci const int pf, 195a8e1175bSopenharmony_ci const mbedtls_ecp_point *G, 196a8e1175bSopenharmony_ci const mbedtls_ecp_point *V, 197a8e1175bSopenharmony_ci const mbedtls_ecp_point *X, 198a8e1175bSopenharmony_ci const char *id, 199a8e1175bSopenharmony_ci mbedtls_mpi *h) 200a8e1175bSopenharmony_ci{ 201a8e1175bSopenharmony_ci int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 202a8e1175bSopenharmony_ci unsigned char buf[ECJPAKE_HASH_BUF_LEN]; 203a8e1175bSopenharmony_ci unsigned char *p = buf; 204a8e1175bSopenharmony_ci const unsigned char *end = buf + sizeof(buf); 205a8e1175bSopenharmony_ci const size_t id_len = strlen(id); 206a8e1175bSopenharmony_ci unsigned char hash[MBEDTLS_MD_MAX_SIZE]; 207a8e1175bSopenharmony_ci 208a8e1175bSopenharmony_ci /* Write things to temporary buffer */ 209a8e1175bSopenharmony_ci MBEDTLS_MPI_CHK(ecjpake_write_len_point(&p, end, grp, pf, G)); 210a8e1175bSopenharmony_ci MBEDTLS_MPI_CHK(ecjpake_write_len_point(&p, end, grp, pf, V)); 211a8e1175bSopenharmony_ci MBEDTLS_MPI_CHK(ecjpake_write_len_point(&p, end, grp, pf, X)); 212a8e1175bSopenharmony_ci 213a8e1175bSopenharmony_ci if (end - p < 4) { 214a8e1175bSopenharmony_ci return MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL; 215a8e1175bSopenharmony_ci } 216a8e1175bSopenharmony_ci 217a8e1175bSopenharmony_ci MBEDTLS_PUT_UINT32_BE(id_len, p, 0); 218a8e1175bSopenharmony_ci p += 4; 219a8e1175bSopenharmony_ci 220a8e1175bSopenharmony_ci if (end < p || (size_t) (end - p) < id_len) { 221a8e1175bSopenharmony_ci return MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL; 222a8e1175bSopenharmony_ci } 223a8e1175bSopenharmony_ci 224a8e1175bSopenharmony_ci memcpy(p, id, id_len); 225a8e1175bSopenharmony_ci p += id_len; 226a8e1175bSopenharmony_ci 227a8e1175bSopenharmony_ci /* Compute hash */ 228a8e1175bSopenharmony_ci MBEDTLS_MPI_CHK(mbedtls_ecjpake_compute_hash(md_type, 229a8e1175bSopenharmony_ci buf, (size_t) (p - buf), hash)); 230a8e1175bSopenharmony_ci 231a8e1175bSopenharmony_ci /* Turn it into an integer mod n */ 232a8e1175bSopenharmony_ci MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(h, hash, 233a8e1175bSopenharmony_ci mbedtls_md_get_size_from_type(md_type))); 234a8e1175bSopenharmony_ci MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(h, h, &grp->N)); 235a8e1175bSopenharmony_ci 236a8e1175bSopenharmony_cicleanup: 237a8e1175bSopenharmony_ci return ret; 238a8e1175bSopenharmony_ci} 239a8e1175bSopenharmony_ci 240a8e1175bSopenharmony_ci/* 241a8e1175bSopenharmony_ci * Parse a ECShnorrZKP (7.4.2.2.2) and verify it (7.4.2.3.3) 242a8e1175bSopenharmony_ci */ 243a8e1175bSopenharmony_cistatic int ecjpake_zkp_read(const mbedtls_md_type_t md_type, 244a8e1175bSopenharmony_ci const mbedtls_ecp_group *grp, 245a8e1175bSopenharmony_ci const int pf, 246a8e1175bSopenharmony_ci const mbedtls_ecp_point *G, 247a8e1175bSopenharmony_ci const mbedtls_ecp_point *X, 248a8e1175bSopenharmony_ci const char *id, 249a8e1175bSopenharmony_ci const unsigned char **p, 250a8e1175bSopenharmony_ci const unsigned char *end) 251a8e1175bSopenharmony_ci{ 252a8e1175bSopenharmony_ci int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 253a8e1175bSopenharmony_ci mbedtls_ecp_point V, VV; 254a8e1175bSopenharmony_ci mbedtls_mpi r, h; 255a8e1175bSopenharmony_ci size_t r_len; 256a8e1175bSopenharmony_ci 257a8e1175bSopenharmony_ci mbedtls_ecp_point_init(&V); 258a8e1175bSopenharmony_ci mbedtls_ecp_point_init(&VV); 259a8e1175bSopenharmony_ci mbedtls_mpi_init(&r); 260a8e1175bSopenharmony_ci mbedtls_mpi_init(&h); 261a8e1175bSopenharmony_ci 262a8e1175bSopenharmony_ci /* 263a8e1175bSopenharmony_ci * struct { 264a8e1175bSopenharmony_ci * ECPoint V; 265a8e1175bSopenharmony_ci * opaque r<1..2^8-1>; 266a8e1175bSopenharmony_ci * } ECSchnorrZKP; 267a8e1175bSopenharmony_ci */ 268a8e1175bSopenharmony_ci if (end < *p) { 269a8e1175bSopenharmony_ci return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; 270a8e1175bSopenharmony_ci } 271a8e1175bSopenharmony_ci 272a8e1175bSopenharmony_ci MBEDTLS_MPI_CHK(mbedtls_ecp_tls_read_point(grp, &V, p, (size_t) (end - *p))); 273a8e1175bSopenharmony_ci 274a8e1175bSopenharmony_ci if (end < *p || (size_t) (end - *p) < 1) { 275a8e1175bSopenharmony_ci ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA; 276a8e1175bSopenharmony_ci goto cleanup; 277a8e1175bSopenharmony_ci } 278a8e1175bSopenharmony_ci 279a8e1175bSopenharmony_ci r_len = *(*p)++; 280a8e1175bSopenharmony_ci 281a8e1175bSopenharmony_ci if (end < *p || (size_t) (end - *p) < r_len || r_len == 0) { 282a8e1175bSopenharmony_ci ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA; 283a8e1175bSopenharmony_ci goto cleanup; 284a8e1175bSopenharmony_ci } 285a8e1175bSopenharmony_ci 286a8e1175bSopenharmony_ci MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&r, *p, r_len)); 287a8e1175bSopenharmony_ci *p += r_len; 288a8e1175bSopenharmony_ci 289a8e1175bSopenharmony_ci /* 290a8e1175bSopenharmony_ci * Verification 291a8e1175bSopenharmony_ci */ 292a8e1175bSopenharmony_ci MBEDTLS_MPI_CHK(ecjpake_hash(md_type, grp, pf, G, &V, X, id, &h)); 293a8e1175bSopenharmony_ci MBEDTLS_MPI_CHK(mbedtls_ecp_muladd((mbedtls_ecp_group *) grp, 294a8e1175bSopenharmony_ci &VV, &h, X, &r, G)); 295a8e1175bSopenharmony_ci 296a8e1175bSopenharmony_ci if (mbedtls_ecp_point_cmp(&VV, &V) != 0) { 297a8e1175bSopenharmony_ci ret = MBEDTLS_ERR_ECP_VERIFY_FAILED; 298a8e1175bSopenharmony_ci goto cleanup; 299a8e1175bSopenharmony_ci } 300a8e1175bSopenharmony_ci 301a8e1175bSopenharmony_cicleanup: 302a8e1175bSopenharmony_ci mbedtls_ecp_point_free(&V); 303a8e1175bSopenharmony_ci mbedtls_ecp_point_free(&VV); 304a8e1175bSopenharmony_ci mbedtls_mpi_free(&r); 305a8e1175bSopenharmony_ci mbedtls_mpi_free(&h); 306a8e1175bSopenharmony_ci 307a8e1175bSopenharmony_ci return ret; 308a8e1175bSopenharmony_ci} 309a8e1175bSopenharmony_ci 310a8e1175bSopenharmony_ci/* 311a8e1175bSopenharmony_ci * Generate ZKP (7.4.2.3.2) and write it as ECSchnorrZKP (7.4.2.2.2) 312a8e1175bSopenharmony_ci */ 313a8e1175bSopenharmony_cistatic int ecjpake_zkp_write(const mbedtls_md_type_t md_type, 314a8e1175bSopenharmony_ci const mbedtls_ecp_group *grp, 315a8e1175bSopenharmony_ci const int pf, 316a8e1175bSopenharmony_ci const mbedtls_ecp_point *G, 317a8e1175bSopenharmony_ci const mbedtls_mpi *x, 318a8e1175bSopenharmony_ci const mbedtls_ecp_point *X, 319a8e1175bSopenharmony_ci const char *id, 320a8e1175bSopenharmony_ci unsigned char **p, 321a8e1175bSopenharmony_ci const unsigned char *end, 322a8e1175bSopenharmony_ci int (*f_rng)(void *, unsigned char *, size_t), 323a8e1175bSopenharmony_ci void *p_rng) 324a8e1175bSopenharmony_ci{ 325a8e1175bSopenharmony_ci int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 326a8e1175bSopenharmony_ci mbedtls_ecp_point V; 327a8e1175bSopenharmony_ci mbedtls_mpi v; 328a8e1175bSopenharmony_ci mbedtls_mpi h; /* later recycled to hold r */ 329a8e1175bSopenharmony_ci size_t len; 330a8e1175bSopenharmony_ci 331a8e1175bSopenharmony_ci if (end < *p) { 332a8e1175bSopenharmony_ci return MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL; 333a8e1175bSopenharmony_ci } 334a8e1175bSopenharmony_ci 335a8e1175bSopenharmony_ci mbedtls_ecp_point_init(&V); 336a8e1175bSopenharmony_ci mbedtls_mpi_init(&v); 337a8e1175bSopenharmony_ci mbedtls_mpi_init(&h); 338a8e1175bSopenharmony_ci 339a8e1175bSopenharmony_ci /* Compute signature */ 340a8e1175bSopenharmony_ci MBEDTLS_MPI_CHK(mbedtls_ecp_gen_keypair_base((mbedtls_ecp_group *) grp, 341a8e1175bSopenharmony_ci G, &v, &V, f_rng, p_rng)); 342a8e1175bSopenharmony_ci MBEDTLS_MPI_CHK(ecjpake_hash(md_type, grp, pf, G, &V, X, id, &h)); 343a8e1175bSopenharmony_ci MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&h, &h, x)); /* x*h */ 344a8e1175bSopenharmony_ci MBEDTLS_MPI_CHK(mbedtls_mpi_sub_mpi(&h, &v, &h)); /* v - x*h */ 345a8e1175bSopenharmony_ci MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&h, &h, &grp->N)); /* r */ 346a8e1175bSopenharmony_ci 347a8e1175bSopenharmony_ci /* Write it out */ 348a8e1175bSopenharmony_ci MBEDTLS_MPI_CHK(mbedtls_ecp_tls_write_point(grp, &V, 349a8e1175bSopenharmony_ci pf, &len, *p, (size_t) (end - *p))); 350a8e1175bSopenharmony_ci *p += len; 351a8e1175bSopenharmony_ci 352a8e1175bSopenharmony_ci len = mbedtls_mpi_size(&h); /* actually r */ 353a8e1175bSopenharmony_ci if (end < *p || (size_t) (end - *p) < 1 + len || len > 255) { 354a8e1175bSopenharmony_ci ret = MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL; 355a8e1175bSopenharmony_ci goto cleanup; 356a8e1175bSopenharmony_ci } 357a8e1175bSopenharmony_ci 358a8e1175bSopenharmony_ci *(*p)++ = MBEDTLS_BYTE_0(len); 359a8e1175bSopenharmony_ci MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(&h, *p, len)); /* r */ 360a8e1175bSopenharmony_ci *p += len; 361a8e1175bSopenharmony_ci 362a8e1175bSopenharmony_cicleanup: 363a8e1175bSopenharmony_ci mbedtls_ecp_point_free(&V); 364a8e1175bSopenharmony_ci mbedtls_mpi_free(&v); 365a8e1175bSopenharmony_ci mbedtls_mpi_free(&h); 366a8e1175bSopenharmony_ci 367a8e1175bSopenharmony_ci return ret; 368a8e1175bSopenharmony_ci} 369a8e1175bSopenharmony_ci 370a8e1175bSopenharmony_ci/* 371a8e1175bSopenharmony_ci * Parse a ECJPAKEKeyKP (7.4.2.2.1) and check proof 372a8e1175bSopenharmony_ci * Output: verified public key X 373a8e1175bSopenharmony_ci */ 374a8e1175bSopenharmony_cistatic int ecjpake_kkp_read(const mbedtls_md_type_t md_type, 375a8e1175bSopenharmony_ci const mbedtls_ecp_group *grp, 376a8e1175bSopenharmony_ci const int pf, 377a8e1175bSopenharmony_ci const mbedtls_ecp_point *G, 378a8e1175bSopenharmony_ci mbedtls_ecp_point *X, 379a8e1175bSopenharmony_ci const char *id, 380a8e1175bSopenharmony_ci const unsigned char **p, 381a8e1175bSopenharmony_ci const unsigned char *end) 382a8e1175bSopenharmony_ci{ 383a8e1175bSopenharmony_ci int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 384a8e1175bSopenharmony_ci 385a8e1175bSopenharmony_ci if (end < *p) { 386a8e1175bSopenharmony_ci return MBEDTLS_ERR_ECP_BAD_INPUT_DATA; 387a8e1175bSopenharmony_ci } 388a8e1175bSopenharmony_ci 389a8e1175bSopenharmony_ci /* 390a8e1175bSopenharmony_ci * struct { 391a8e1175bSopenharmony_ci * ECPoint X; 392a8e1175bSopenharmony_ci * ECSchnorrZKP zkp; 393a8e1175bSopenharmony_ci * } ECJPAKEKeyKP; 394a8e1175bSopenharmony_ci */ 395a8e1175bSopenharmony_ci MBEDTLS_MPI_CHK(mbedtls_ecp_tls_read_point(grp, X, p, (size_t) (end - *p))); 396a8e1175bSopenharmony_ci if (mbedtls_ecp_is_zero(X)) { 397a8e1175bSopenharmony_ci ret = MBEDTLS_ERR_ECP_INVALID_KEY; 398a8e1175bSopenharmony_ci goto cleanup; 399a8e1175bSopenharmony_ci } 400a8e1175bSopenharmony_ci 401a8e1175bSopenharmony_ci MBEDTLS_MPI_CHK(ecjpake_zkp_read(md_type, grp, pf, G, X, id, p, end)); 402a8e1175bSopenharmony_ci 403a8e1175bSopenharmony_cicleanup: 404a8e1175bSopenharmony_ci return ret; 405a8e1175bSopenharmony_ci} 406a8e1175bSopenharmony_ci 407a8e1175bSopenharmony_ci/* 408a8e1175bSopenharmony_ci * Generate an ECJPAKEKeyKP 409a8e1175bSopenharmony_ci * Output: the serialized structure, plus private/public key pair 410a8e1175bSopenharmony_ci */ 411a8e1175bSopenharmony_cistatic int ecjpake_kkp_write(const mbedtls_md_type_t md_type, 412a8e1175bSopenharmony_ci const mbedtls_ecp_group *grp, 413a8e1175bSopenharmony_ci const int pf, 414a8e1175bSopenharmony_ci const mbedtls_ecp_point *G, 415a8e1175bSopenharmony_ci mbedtls_mpi *x, 416a8e1175bSopenharmony_ci mbedtls_ecp_point *X, 417a8e1175bSopenharmony_ci const char *id, 418a8e1175bSopenharmony_ci unsigned char **p, 419a8e1175bSopenharmony_ci const unsigned char *end, 420a8e1175bSopenharmony_ci int (*f_rng)(void *, unsigned char *, size_t), 421a8e1175bSopenharmony_ci void *p_rng) 422a8e1175bSopenharmony_ci{ 423a8e1175bSopenharmony_ci int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 424a8e1175bSopenharmony_ci size_t len; 425a8e1175bSopenharmony_ci 426a8e1175bSopenharmony_ci if (end < *p) { 427a8e1175bSopenharmony_ci return MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL; 428a8e1175bSopenharmony_ci } 429a8e1175bSopenharmony_ci 430a8e1175bSopenharmony_ci /* Generate key (7.4.2.3.1) and write it out */ 431a8e1175bSopenharmony_ci MBEDTLS_MPI_CHK(mbedtls_ecp_gen_keypair_base((mbedtls_ecp_group *) grp, G, x, X, 432a8e1175bSopenharmony_ci f_rng, p_rng)); 433a8e1175bSopenharmony_ci MBEDTLS_MPI_CHK(mbedtls_ecp_tls_write_point(grp, X, 434a8e1175bSopenharmony_ci pf, &len, *p, (size_t) (end - *p))); 435a8e1175bSopenharmony_ci *p += len; 436a8e1175bSopenharmony_ci 437a8e1175bSopenharmony_ci /* Generate and write proof */ 438a8e1175bSopenharmony_ci MBEDTLS_MPI_CHK(ecjpake_zkp_write(md_type, grp, pf, G, x, X, id, 439a8e1175bSopenharmony_ci p, end, f_rng, p_rng)); 440a8e1175bSopenharmony_ci 441a8e1175bSopenharmony_cicleanup: 442a8e1175bSopenharmony_ci return ret; 443a8e1175bSopenharmony_ci} 444a8e1175bSopenharmony_ci 445a8e1175bSopenharmony_ci/* 446a8e1175bSopenharmony_ci * Read a ECJPAKEKeyKPPairList (7.4.2.3) and check proofs 447a8e1175bSopenharmony_ci * Outputs: verified peer public keys Xa, Xb 448a8e1175bSopenharmony_ci */ 449a8e1175bSopenharmony_cistatic int ecjpake_kkpp_read(const mbedtls_md_type_t md_type, 450a8e1175bSopenharmony_ci const mbedtls_ecp_group *grp, 451a8e1175bSopenharmony_ci const int pf, 452a8e1175bSopenharmony_ci const mbedtls_ecp_point *G, 453a8e1175bSopenharmony_ci mbedtls_ecp_point *Xa, 454a8e1175bSopenharmony_ci mbedtls_ecp_point *Xb, 455a8e1175bSopenharmony_ci const char *id, 456a8e1175bSopenharmony_ci const unsigned char *buf, 457a8e1175bSopenharmony_ci size_t len) 458a8e1175bSopenharmony_ci{ 459a8e1175bSopenharmony_ci int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 460a8e1175bSopenharmony_ci const unsigned char *p = buf; 461a8e1175bSopenharmony_ci const unsigned char *end = buf + len; 462a8e1175bSopenharmony_ci 463a8e1175bSopenharmony_ci /* 464a8e1175bSopenharmony_ci * struct { 465a8e1175bSopenharmony_ci * ECJPAKEKeyKP ecjpake_key_kp_pair_list[2]; 466a8e1175bSopenharmony_ci * } ECJPAKEKeyKPPairList; 467a8e1175bSopenharmony_ci */ 468a8e1175bSopenharmony_ci MBEDTLS_MPI_CHK(ecjpake_kkp_read(md_type, grp, pf, G, Xa, id, &p, end)); 469a8e1175bSopenharmony_ci MBEDTLS_MPI_CHK(ecjpake_kkp_read(md_type, grp, pf, G, Xb, id, &p, end)); 470a8e1175bSopenharmony_ci 471a8e1175bSopenharmony_ci if (p != end) { 472a8e1175bSopenharmony_ci ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA; 473a8e1175bSopenharmony_ci } 474a8e1175bSopenharmony_ci 475a8e1175bSopenharmony_cicleanup: 476a8e1175bSopenharmony_ci return ret; 477a8e1175bSopenharmony_ci} 478a8e1175bSopenharmony_ci 479a8e1175bSopenharmony_ci/* 480a8e1175bSopenharmony_ci * Generate a ECJPAKEKeyKPPairList 481a8e1175bSopenharmony_ci * Outputs: the serialized structure, plus two private/public key pairs 482a8e1175bSopenharmony_ci */ 483a8e1175bSopenharmony_cistatic int ecjpake_kkpp_write(const mbedtls_md_type_t md_type, 484a8e1175bSopenharmony_ci const mbedtls_ecp_group *grp, 485a8e1175bSopenharmony_ci const int pf, 486a8e1175bSopenharmony_ci const mbedtls_ecp_point *G, 487a8e1175bSopenharmony_ci mbedtls_mpi *xm1, 488a8e1175bSopenharmony_ci mbedtls_ecp_point *Xa, 489a8e1175bSopenharmony_ci mbedtls_mpi *xm2, 490a8e1175bSopenharmony_ci mbedtls_ecp_point *Xb, 491a8e1175bSopenharmony_ci const char *id, 492a8e1175bSopenharmony_ci unsigned char *buf, 493a8e1175bSopenharmony_ci size_t len, 494a8e1175bSopenharmony_ci size_t *olen, 495a8e1175bSopenharmony_ci int (*f_rng)(void *, unsigned char *, size_t), 496a8e1175bSopenharmony_ci void *p_rng) 497a8e1175bSopenharmony_ci{ 498a8e1175bSopenharmony_ci int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 499a8e1175bSopenharmony_ci unsigned char *p = buf; 500a8e1175bSopenharmony_ci const unsigned char *end = buf + len; 501a8e1175bSopenharmony_ci 502a8e1175bSopenharmony_ci MBEDTLS_MPI_CHK(ecjpake_kkp_write(md_type, grp, pf, G, xm1, Xa, id, 503a8e1175bSopenharmony_ci &p, end, f_rng, p_rng)); 504a8e1175bSopenharmony_ci MBEDTLS_MPI_CHK(ecjpake_kkp_write(md_type, grp, pf, G, xm2, Xb, id, 505a8e1175bSopenharmony_ci &p, end, f_rng, p_rng)); 506a8e1175bSopenharmony_ci 507a8e1175bSopenharmony_ci *olen = (size_t) (p - buf); 508a8e1175bSopenharmony_ci 509a8e1175bSopenharmony_cicleanup: 510a8e1175bSopenharmony_ci return ret; 511a8e1175bSopenharmony_ci} 512a8e1175bSopenharmony_ci 513a8e1175bSopenharmony_ci/* 514a8e1175bSopenharmony_ci * Read and process the first round message 515a8e1175bSopenharmony_ci */ 516a8e1175bSopenharmony_ciint mbedtls_ecjpake_read_round_one(mbedtls_ecjpake_context *ctx, 517a8e1175bSopenharmony_ci const unsigned char *buf, 518a8e1175bSopenharmony_ci size_t len) 519a8e1175bSopenharmony_ci{ 520a8e1175bSopenharmony_ci return ecjpake_kkpp_read(ctx->md_type, &ctx->grp, ctx->point_format, 521a8e1175bSopenharmony_ci &ctx->grp.G, 522a8e1175bSopenharmony_ci &ctx->Xp1, &ctx->Xp2, ID_PEER, 523a8e1175bSopenharmony_ci buf, len); 524a8e1175bSopenharmony_ci} 525a8e1175bSopenharmony_ci 526a8e1175bSopenharmony_ci/* 527a8e1175bSopenharmony_ci * Generate and write the first round message 528a8e1175bSopenharmony_ci */ 529a8e1175bSopenharmony_ciint mbedtls_ecjpake_write_round_one(mbedtls_ecjpake_context *ctx, 530a8e1175bSopenharmony_ci unsigned char *buf, size_t len, size_t *olen, 531a8e1175bSopenharmony_ci int (*f_rng)(void *, unsigned char *, size_t), 532a8e1175bSopenharmony_ci void *p_rng) 533a8e1175bSopenharmony_ci{ 534a8e1175bSopenharmony_ci return ecjpake_kkpp_write(ctx->md_type, &ctx->grp, ctx->point_format, 535a8e1175bSopenharmony_ci &ctx->grp.G, 536a8e1175bSopenharmony_ci &ctx->xm1, &ctx->Xm1, &ctx->xm2, &ctx->Xm2, 537a8e1175bSopenharmony_ci ID_MINE, buf, len, olen, f_rng, p_rng); 538a8e1175bSopenharmony_ci} 539a8e1175bSopenharmony_ci 540a8e1175bSopenharmony_ci/* 541a8e1175bSopenharmony_ci * Compute the sum of three points R = A + B + C 542a8e1175bSopenharmony_ci */ 543a8e1175bSopenharmony_cistatic int ecjpake_ecp_add3(mbedtls_ecp_group *grp, mbedtls_ecp_point *R, 544a8e1175bSopenharmony_ci const mbedtls_ecp_point *A, 545a8e1175bSopenharmony_ci const mbedtls_ecp_point *B, 546a8e1175bSopenharmony_ci const mbedtls_ecp_point *C) 547a8e1175bSopenharmony_ci{ 548a8e1175bSopenharmony_ci int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 549a8e1175bSopenharmony_ci mbedtls_mpi one; 550a8e1175bSopenharmony_ci 551a8e1175bSopenharmony_ci mbedtls_mpi_init(&one); 552a8e1175bSopenharmony_ci 553a8e1175bSopenharmony_ci MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&one, 1)); 554a8e1175bSopenharmony_ci MBEDTLS_MPI_CHK(mbedtls_ecp_muladd(grp, R, &one, A, &one, B)); 555a8e1175bSopenharmony_ci MBEDTLS_MPI_CHK(mbedtls_ecp_muladd(grp, R, &one, R, &one, C)); 556a8e1175bSopenharmony_ci 557a8e1175bSopenharmony_cicleanup: 558a8e1175bSopenharmony_ci mbedtls_mpi_free(&one); 559a8e1175bSopenharmony_ci 560a8e1175bSopenharmony_ci return ret; 561a8e1175bSopenharmony_ci} 562a8e1175bSopenharmony_ci 563a8e1175bSopenharmony_ci/* 564a8e1175bSopenharmony_ci * Read and process second round message (C: 7.4.2.5, S: 7.4.2.6) 565a8e1175bSopenharmony_ci */ 566a8e1175bSopenharmony_ciint mbedtls_ecjpake_read_round_two(mbedtls_ecjpake_context *ctx, 567a8e1175bSopenharmony_ci const unsigned char *buf, 568a8e1175bSopenharmony_ci size_t len) 569a8e1175bSopenharmony_ci{ 570a8e1175bSopenharmony_ci int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 571a8e1175bSopenharmony_ci const unsigned char *p = buf; 572a8e1175bSopenharmony_ci const unsigned char *end = buf + len; 573a8e1175bSopenharmony_ci mbedtls_ecp_group grp; 574a8e1175bSopenharmony_ci mbedtls_ecp_point G; /* C: GB, S: GA */ 575a8e1175bSopenharmony_ci 576a8e1175bSopenharmony_ci mbedtls_ecp_group_init(&grp); 577a8e1175bSopenharmony_ci mbedtls_ecp_point_init(&G); 578a8e1175bSopenharmony_ci 579a8e1175bSopenharmony_ci /* 580a8e1175bSopenharmony_ci * Server: GA = X3 + X4 + X1 (7.4.2.6.1) 581a8e1175bSopenharmony_ci * Client: GB = X1 + X2 + X3 (7.4.2.5.1) 582a8e1175bSopenharmony_ci * Unified: G = Xm1 + Xm2 + Xp1 583a8e1175bSopenharmony_ci * We need that before parsing in order to check Xp as we read it 584a8e1175bSopenharmony_ci */ 585a8e1175bSopenharmony_ci MBEDTLS_MPI_CHK(ecjpake_ecp_add3(&ctx->grp, &G, 586a8e1175bSopenharmony_ci &ctx->Xm1, &ctx->Xm2, &ctx->Xp1)); 587a8e1175bSopenharmony_ci 588a8e1175bSopenharmony_ci /* 589a8e1175bSopenharmony_ci * struct { 590a8e1175bSopenharmony_ci * ECParameters curve_params; // only client reading server msg 591a8e1175bSopenharmony_ci * ECJPAKEKeyKP ecjpake_key_kp; 592a8e1175bSopenharmony_ci * } Client/ServerECJPAKEParams; 593a8e1175bSopenharmony_ci */ 594a8e1175bSopenharmony_ci if (ctx->role == MBEDTLS_ECJPAKE_CLIENT) { 595a8e1175bSopenharmony_ci MBEDTLS_MPI_CHK(mbedtls_ecp_tls_read_group(&grp, &p, len)); 596a8e1175bSopenharmony_ci if (grp.id != ctx->grp.id) { 597a8e1175bSopenharmony_ci ret = MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE; 598a8e1175bSopenharmony_ci goto cleanup; 599a8e1175bSopenharmony_ci } 600a8e1175bSopenharmony_ci } 601a8e1175bSopenharmony_ci 602a8e1175bSopenharmony_ci MBEDTLS_MPI_CHK(ecjpake_kkp_read(ctx->md_type, &ctx->grp, 603a8e1175bSopenharmony_ci ctx->point_format, 604a8e1175bSopenharmony_ci &G, &ctx->Xp, ID_PEER, &p, end)); 605a8e1175bSopenharmony_ci 606a8e1175bSopenharmony_ci if (p != end) { 607a8e1175bSopenharmony_ci ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA; 608a8e1175bSopenharmony_ci goto cleanup; 609a8e1175bSopenharmony_ci } 610a8e1175bSopenharmony_ci 611a8e1175bSopenharmony_cicleanup: 612a8e1175bSopenharmony_ci mbedtls_ecp_group_free(&grp); 613a8e1175bSopenharmony_ci mbedtls_ecp_point_free(&G); 614a8e1175bSopenharmony_ci 615a8e1175bSopenharmony_ci return ret; 616a8e1175bSopenharmony_ci} 617a8e1175bSopenharmony_ci 618a8e1175bSopenharmony_ci/* 619a8e1175bSopenharmony_ci * Compute R = +/- X * S mod N, taking care not to leak S 620a8e1175bSopenharmony_ci */ 621a8e1175bSopenharmony_cistatic int ecjpake_mul_secret(mbedtls_mpi *R, int sign, 622a8e1175bSopenharmony_ci const mbedtls_mpi *X, 623a8e1175bSopenharmony_ci const mbedtls_mpi *S, 624a8e1175bSopenharmony_ci const mbedtls_mpi *N, 625a8e1175bSopenharmony_ci int (*f_rng)(void *, unsigned char *, size_t), 626a8e1175bSopenharmony_ci void *p_rng) 627a8e1175bSopenharmony_ci{ 628a8e1175bSopenharmony_ci int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 629a8e1175bSopenharmony_ci mbedtls_mpi b; /* Blinding value, then s + N * blinding */ 630a8e1175bSopenharmony_ci 631a8e1175bSopenharmony_ci mbedtls_mpi_init(&b); 632a8e1175bSopenharmony_ci 633a8e1175bSopenharmony_ci /* b = s + rnd-128-bit * N */ 634a8e1175bSopenharmony_ci MBEDTLS_MPI_CHK(mbedtls_mpi_fill_random(&b, 16, f_rng, p_rng)); 635a8e1175bSopenharmony_ci MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&b, &b, N)); 636a8e1175bSopenharmony_ci MBEDTLS_MPI_CHK(mbedtls_mpi_add_mpi(&b, &b, S)); 637a8e1175bSopenharmony_ci 638a8e1175bSopenharmony_ci /* R = sign * X * b mod N */ 639a8e1175bSopenharmony_ci MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(R, X, &b)); 640a8e1175bSopenharmony_ci R->s *= sign; 641a8e1175bSopenharmony_ci MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(R, R, N)); 642a8e1175bSopenharmony_ci 643a8e1175bSopenharmony_cicleanup: 644a8e1175bSopenharmony_ci mbedtls_mpi_free(&b); 645a8e1175bSopenharmony_ci 646a8e1175bSopenharmony_ci return ret; 647a8e1175bSopenharmony_ci} 648a8e1175bSopenharmony_ci 649a8e1175bSopenharmony_ci/* 650a8e1175bSopenharmony_ci * Generate and write the second round message (S: 7.4.2.5, C: 7.4.2.6) 651a8e1175bSopenharmony_ci */ 652a8e1175bSopenharmony_ciint mbedtls_ecjpake_write_round_two(mbedtls_ecjpake_context *ctx, 653a8e1175bSopenharmony_ci unsigned char *buf, size_t len, size_t *olen, 654a8e1175bSopenharmony_ci int (*f_rng)(void *, unsigned char *, size_t), 655a8e1175bSopenharmony_ci void *p_rng) 656a8e1175bSopenharmony_ci{ 657a8e1175bSopenharmony_ci int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 658a8e1175bSopenharmony_ci mbedtls_ecp_point G; /* C: GA, S: GB */ 659a8e1175bSopenharmony_ci mbedtls_ecp_point Xm; /* C: Xc, S: Xs */ 660a8e1175bSopenharmony_ci mbedtls_mpi xm; /* C: xc, S: xs */ 661a8e1175bSopenharmony_ci unsigned char *p = buf; 662a8e1175bSopenharmony_ci const unsigned char *end = buf + len; 663a8e1175bSopenharmony_ci size_t ec_len; 664a8e1175bSopenharmony_ci 665a8e1175bSopenharmony_ci mbedtls_ecp_point_init(&G); 666a8e1175bSopenharmony_ci mbedtls_ecp_point_init(&Xm); 667a8e1175bSopenharmony_ci mbedtls_mpi_init(&xm); 668a8e1175bSopenharmony_ci 669a8e1175bSopenharmony_ci /* 670a8e1175bSopenharmony_ci * First generate private/public key pair (S: 7.4.2.5.1, C: 7.4.2.6.1) 671a8e1175bSopenharmony_ci * 672a8e1175bSopenharmony_ci * Client: GA = X1 + X3 + X4 | xs = x2 * s | Xc = xc * GA 673a8e1175bSopenharmony_ci * Server: GB = X3 + X1 + X2 | xs = x4 * s | Xs = xs * GB 674a8e1175bSopenharmony_ci * Unified: G = Xm1 + Xp1 + Xp2 | xm = xm2 * s | Xm = xm * G 675a8e1175bSopenharmony_ci */ 676a8e1175bSopenharmony_ci MBEDTLS_MPI_CHK(ecjpake_ecp_add3(&ctx->grp, &G, 677a8e1175bSopenharmony_ci &ctx->Xp1, &ctx->Xp2, &ctx->Xm1)); 678a8e1175bSopenharmony_ci MBEDTLS_MPI_CHK(ecjpake_mul_secret(&xm, 1, &ctx->xm2, &ctx->s, 679a8e1175bSopenharmony_ci &ctx->grp.N, f_rng, p_rng)); 680a8e1175bSopenharmony_ci MBEDTLS_MPI_CHK(mbedtls_ecp_mul(&ctx->grp, &Xm, &xm, &G, f_rng, p_rng)); 681a8e1175bSopenharmony_ci 682a8e1175bSopenharmony_ci /* 683a8e1175bSopenharmony_ci * Now write things out 684a8e1175bSopenharmony_ci * 685a8e1175bSopenharmony_ci * struct { 686a8e1175bSopenharmony_ci * ECParameters curve_params; // only server writing its message 687a8e1175bSopenharmony_ci * ECJPAKEKeyKP ecjpake_key_kp; 688a8e1175bSopenharmony_ci * } Client/ServerECJPAKEParams; 689a8e1175bSopenharmony_ci */ 690a8e1175bSopenharmony_ci if (ctx->role == MBEDTLS_ECJPAKE_SERVER) { 691a8e1175bSopenharmony_ci if (end < p) { 692a8e1175bSopenharmony_ci ret = MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL; 693a8e1175bSopenharmony_ci goto cleanup; 694a8e1175bSopenharmony_ci } 695a8e1175bSopenharmony_ci MBEDTLS_MPI_CHK(mbedtls_ecp_tls_write_group(&ctx->grp, &ec_len, 696a8e1175bSopenharmony_ci p, (size_t) (end - p))); 697a8e1175bSopenharmony_ci p += ec_len; 698a8e1175bSopenharmony_ci } 699a8e1175bSopenharmony_ci 700a8e1175bSopenharmony_ci if (end < p) { 701a8e1175bSopenharmony_ci ret = MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL; 702a8e1175bSopenharmony_ci goto cleanup; 703a8e1175bSopenharmony_ci } 704a8e1175bSopenharmony_ci MBEDTLS_MPI_CHK(mbedtls_ecp_tls_write_point(&ctx->grp, &Xm, 705a8e1175bSopenharmony_ci ctx->point_format, &ec_len, p, (size_t) (end - p))); 706a8e1175bSopenharmony_ci p += ec_len; 707a8e1175bSopenharmony_ci 708a8e1175bSopenharmony_ci MBEDTLS_MPI_CHK(ecjpake_zkp_write(ctx->md_type, &ctx->grp, 709a8e1175bSopenharmony_ci ctx->point_format, 710a8e1175bSopenharmony_ci &G, &xm, &Xm, ID_MINE, 711a8e1175bSopenharmony_ci &p, end, f_rng, p_rng)); 712a8e1175bSopenharmony_ci 713a8e1175bSopenharmony_ci *olen = (size_t) (p - buf); 714a8e1175bSopenharmony_ci 715a8e1175bSopenharmony_cicleanup: 716a8e1175bSopenharmony_ci mbedtls_ecp_point_free(&G); 717a8e1175bSopenharmony_ci mbedtls_ecp_point_free(&Xm); 718a8e1175bSopenharmony_ci mbedtls_mpi_free(&xm); 719a8e1175bSopenharmony_ci 720a8e1175bSopenharmony_ci return ret; 721a8e1175bSopenharmony_ci} 722a8e1175bSopenharmony_ci 723a8e1175bSopenharmony_ci/* 724a8e1175bSopenharmony_ci * Derive PMS (7.4.2.7 / 7.4.2.8) 725a8e1175bSopenharmony_ci */ 726a8e1175bSopenharmony_cistatic int mbedtls_ecjpake_derive_k(mbedtls_ecjpake_context *ctx, 727a8e1175bSopenharmony_ci mbedtls_ecp_point *K, 728a8e1175bSopenharmony_ci int (*f_rng)(void *, unsigned char *, size_t), 729a8e1175bSopenharmony_ci void *p_rng) 730a8e1175bSopenharmony_ci{ 731a8e1175bSopenharmony_ci int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 732a8e1175bSopenharmony_ci mbedtls_mpi m_xm2_s, one; 733a8e1175bSopenharmony_ci 734a8e1175bSopenharmony_ci mbedtls_mpi_init(&m_xm2_s); 735a8e1175bSopenharmony_ci mbedtls_mpi_init(&one); 736a8e1175bSopenharmony_ci 737a8e1175bSopenharmony_ci MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&one, 1)); 738a8e1175bSopenharmony_ci 739a8e1175bSopenharmony_ci /* 740a8e1175bSopenharmony_ci * Client: K = ( Xs - X4 * x2 * s ) * x2 741a8e1175bSopenharmony_ci * Server: K = ( Xc - X2 * x4 * s ) * x4 742a8e1175bSopenharmony_ci * Unified: K = ( Xp - Xp2 * xm2 * s ) * xm2 743a8e1175bSopenharmony_ci */ 744a8e1175bSopenharmony_ci MBEDTLS_MPI_CHK(ecjpake_mul_secret(&m_xm2_s, -1, &ctx->xm2, &ctx->s, 745a8e1175bSopenharmony_ci &ctx->grp.N, f_rng, p_rng)); 746a8e1175bSopenharmony_ci MBEDTLS_MPI_CHK(mbedtls_ecp_muladd(&ctx->grp, K, 747a8e1175bSopenharmony_ci &one, &ctx->Xp, 748a8e1175bSopenharmony_ci &m_xm2_s, &ctx->Xp2)); 749a8e1175bSopenharmony_ci MBEDTLS_MPI_CHK(mbedtls_ecp_mul(&ctx->grp, K, &ctx->xm2, K, 750a8e1175bSopenharmony_ci f_rng, p_rng)); 751a8e1175bSopenharmony_ci 752a8e1175bSopenharmony_cicleanup: 753a8e1175bSopenharmony_ci mbedtls_mpi_free(&m_xm2_s); 754a8e1175bSopenharmony_ci mbedtls_mpi_free(&one); 755a8e1175bSopenharmony_ci 756a8e1175bSopenharmony_ci return ret; 757a8e1175bSopenharmony_ci} 758a8e1175bSopenharmony_ci 759a8e1175bSopenharmony_ciint mbedtls_ecjpake_derive_secret(mbedtls_ecjpake_context *ctx, 760a8e1175bSopenharmony_ci unsigned char *buf, size_t len, size_t *olen, 761a8e1175bSopenharmony_ci int (*f_rng)(void *, unsigned char *, size_t), 762a8e1175bSopenharmony_ci void *p_rng) 763a8e1175bSopenharmony_ci{ 764a8e1175bSopenharmony_ci int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 765a8e1175bSopenharmony_ci mbedtls_ecp_point K; 766a8e1175bSopenharmony_ci unsigned char kx[MBEDTLS_ECP_MAX_BYTES]; 767a8e1175bSopenharmony_ci size_t x_bytes; 768a8e1175bSopenharmony_ci 769a8e1175bSopenharmony_ci *olen = mbedtls_md_get_size_from_type(ctx->md_type); 770a8e1175bSopenharmony_ci if (len < *olen) { 771a8e1175bSopenharmony_ci return MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL; 772a8e1175bSopenharmony_ci } 773a8e1175bSopenharmony_ci 774a8e1175bSopenharmony_ci mbedtls_ecp_point_init(&K); 775a8e1175bSopenharmony_ci 776a8e1175bSopenharmony_ci ret = mbedtls_ecjpake_derive_k(ctx, &K, f_rng, p_rng); 777a8e1175bSopenharmony_ci if (ret) { 778a8e1175bSopenharmony_ci goto cleanup; 779a8e1175bSopenharmony_ci } 780a8e1175bSopenharmony_ci 781a8e1175bSopenharmony_ci /* PMS = SHA-256( K.X ) */ 782a8e1175bSopenharmony_ci x_bytes = (ctx->grp.pbits + 7) / 8; 783a8e1175bSopenharmony_ci MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(&K.X, kx, x_bytes)); 784a8e1175bSopenharmony_ci MBEDTLS_MPI_CHK(mbedtls_ecjpake_compute_hash(ctx->md_type, 785a8e1175bSopenharmony_ci kx, x_bytes, buf)); 786a8e1175bSopenharmony_ci 787a8e1175bSopenharmony_cicleanup: 788a8e1175bSopenharmony_ci mbedtls_ecp_point_free(&K); 789a8e1175bSopenharmony_ci 790a8e1175bSopenharmony_ci return ret; 791a8e1175bSopenharmony_ci} 792a8e1175bSopenharmony_ci 793a8e1175bSopenharmony_ciint mbedtls_ecjpake_write_shared_key(mbedtls_ecjpake_context *ctx, 794a8e1175bSopenharmony_ci unsigned char *buf, size_t len, size_t *olen, 795a8e1175bSopenharmony_ci int (*f_rng)(void *, unsigned char *, size_t), 796a8e1175bSopenharmony_ci void *p_rng) 797a8e1175bSopenharmony_ci{ 798a8e1175bSopenharmony_ci int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 799a8e1175bSopenharmony_ci mbedtls_ecp_point K; 800a8e1175bSopenharmony_ci 801a8e1175bSopenharmony_ci mbedtls_ecp_point_init(&K); 802a8e1175bSopenharmony_ci 803a8e1175bSopenharmony_ci ret = mbedtls_ecjpake_derive_k(ctx, &K, f_rng, p_rng); 804a8e1175bSopenharmony_ci if (ret) { 805a8e1175bSopenharmony_ci goto cleanup; 806a8e1175bSopenharmony_ci } 807a8e1175bSopenharmony_ci 808a8e1175bSopenharmony_ci ret = mbedtls_ecp_point_write_binary(&ctx->grp, &K, ctx->point_format, 809a8e1175bSopenharmony_ci olen, buf, len); 810a8e1175bSopenharmony_ci if (ret != 0) { 811a8e1175bSopenharmony_ci goto cleanup; 812a8e1175bSopenharmony_ci } 813a8e1175bSopenharmony_ci 814a8e1175bSopenharmony_cicleanup: 815a8e1175bSopenharmony_ci mbedtls_ecp_point_free(&K); 816a8e1175bSopenharmony_ci 817a8e1175bSopenharmony_ci return ret; 818a8e1175bSopenharmony_ci} 819a8e1175bSopenharmony_ci 820a8e1175bSopenharmony_ci#undef ID_MINE 821a8e1175bSopenharmony_ci#undef ID_PEER 822a8e1175bSopenharmony_ci 823a8e1175bSopenharmony_ci#endif /* ! MBEDTLS_ECJPAKE_ALT */ 824a8e1175bSopenharmony_ci 825a8e1175bSopenharmony_ci#if defined(MBEDTLS_SELF_TEST) 826a8e1175bSopenharmony_ci 827a8e1175bSopenharmony_ci#include "mbedtls/platform.h" 828a8e1175bSopenharmony_ci 829a8e1175bSopenharmony_ci#if !defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) || \ 830a8e1175bSopenharmony_ci !defined(MBEDTLS_MD_CAN_SHA256) 831a8e1175bSopenharmony_ciint mbedtls_ecjpake_self_test(int verbose) 832a8e1175bSopenharmony_ci{ 833a8e1175bSopenharmony_ci (void) verbose; 834a8e1175bSopenharmony_ci return 0; 835a8e1175bSopenharmony_ci} 836a8e1175bSopenharmony_ci#else 837a8e1175bSopenharmony_ci 838a8e1175bSopenharmony_cistatic const unsigned char ecjpake_test_password[] = { 839a8e1175bSopenharmony_ci 0x74, 0x68, 0x72, 0x65, 0x61, 0x64, 0x6a, 0x70, 0x61, 0x6b, 0x65, 0x74, 840a8e1175bSopenharmony_ci 0x65, 0x73, 0x74 841a8e1175bSopenharmony_ci}; 842a8e1175bSopenharmony_ci 843a8e1175bSopenharmony_ci#if !defined(MBEDTLS_ECJPAKE_ALT) 844a8e1175bSopenharmony_ci 845a8e1175bSopenharmony_cistatic const unsigned char ecjpake_test_x1[] = { 846a8e1175bSopenharmony_ci 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 847a8e1175bSopenharmony_ci 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 848a8e1175bSopenharmony_ci 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x21 849a8e1175bSopenharmony_ci}; 850a8e1175bSopenharmony_ci 851a8e1175bSopenharmony_cistatic const unsigned char ecjpake_test_x2[] = { 852a8e1175bSopenharmony_ci 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 853a8e1175bSopenharmony_ci 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 854a8e1175bSopenharmony_ci 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x81 855a8e1175bSopenharmony_ci}; 856a8e1175bSopenharmony_ci 857a8e1175bSopenharmony_cistatic const unsigned char ecjpake_test_x3[] = { 858a8e1175bSopenharmony_ci 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 859a8e1175bSopenharmony_ci 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 860a8e1175bSopenharmony_ci 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x81 861a8e1175bSopenharmony_ci}; 862a8e1175bSopenharmony_ci 863a8e1175bSopenharmony_cistatic const unsigned char ecjpake_test_x4[] = { 864a8e1175bSopenharmony_ci 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 865a8e1175bSopenharmony_ci 0xcd, 0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 866a8e1175bSopenharmony_ci 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, 0xe1 867a8e1175bSopenharmony_ci}; 868a8e1175bSopenharmony_ci 869a8e1175bSopenharmony_cistatic const unsigned char ecjpake_test_cli_one[] = { 870a8e1175bSopenharmony_ci 0x41, 0x04, 0xac, 0xcf, 0x01, 0x06, 0xef, 0x85, 0x8f, 0xa2, 0xd9, 0x19, 871a8e1175bSopenharmony_ci 0x33, 0x13, 0x46, 0x80, 0x5a, 0x78, 0xb5, 0x8b, 0xba, 0xd0, 0xb8, 0x44, 872a8e1175bSopenharmony_ci 0xe5, 0xc7, 0x89, 0x28, 0x79, 0x14, 0x61, 0x87, 0xdd, 0x26, 0x66, 0xad, 873a8e1175bSopenharmony_ci 0xa7, 0x81, 0xbb, 0x7f, 0x11, 0x13, 0x72, 0x25, 0x1a, 0x89, 0x10, 0x62, 874a8e1175bSopenharmony_ci 0x1f, 0x63, 0x4d, 0xf1, 0x28, 0xac, 0x48, 0xe3, 0x81, 0xfd, 0x6e, 0xf9, 875a8e1175bSopenharmony_ci 0x06, 0x07, 0x31, 0xf6, 0x94, 0xa4, 0x41, 0x04, 0x1d, 0xd0, 0xbd, 0x5d, 876a8e1175bSopenharmony_ci 0x45, 0x66, 0xc9, 0xbe, 0xd9, 0xce, 0x7d, 0xe7, 0x01, 0xb5, 0xe8, 0x2e, 877a8e1175bSopenharmony_ci 0x08, 0xe8, 0x4b, 0x73, 0x04, 0x66, 0x01, 0x8a, 0xb9, 0x03, 0xc7, 0x9e, 878a8e1175bSopenharmony_ci 0xb9, 0x82, 0x17, 0x22, 0x36, 0xc0, 0xc1, 0x72, 0x8a, 0xe4, 0xbf, 0x73, 879a8e1175bSopenharmony_ci 0x61, 0x0d, 0x34, 0xde, 0x44, 0x24, 0x6e, 0xf3, 0xd9, 0xc0, 0x5a, 0x22, 880a8e1175bSopenharmony_ci 0x36, 0xfb, 0x66, 0xa6, 0x58, 0x3d, 0x74, 0x49, 0x30, 0x8b, 0xab, 0xce, 881a8e1175bSopenharmony_ci 0x20, 0x72, 0xfe, 0x16, 0x66, 0x29, 0x92, 0xe9, 0x23, 0x5c, 0x25, 0x00, 882a8e1175bSopenharmony_ci 0x2f, 0x11, 0xb1, 0x50, 0x87, 0xb8, 0x27, 0x38, 0xe0, 0x3c, 0x94, 0x5b, 883a8e1175bSopenharmony_ci 0xf7, 0xa2, 0x99, 0x5d, 0xda, 0x1e, 0x98, 0x34, 0x58, 0x41, 0x04, 0x7e, 884a8e1175bSopenharmony_ci 0xa6, 0xe3, 0xa4, 0x48, 0x70, 0x37, 0xa9, 0xe0, 0xdb, 0xd7, 0x92, 0x62, 885a8e1175bSopenharmony_ci 0xb2, 0xcc, 0x27, 0x3e, 0x77, 0x99, 0x30, 0xfc, 0x18, 0x40, 0x9a, 0xc5, 886a8e1175bSopenharmony_ci 0x36, 0x1c, 0x5f, 0xe6, 0x69, 0xd7, 0x02, 0xe1, 0x47, 0x79, 0x0a, 0xeb, 887a8e1175bSopenharmony_ci 0x4c, 0xe7, 0xfd, 0x65, 0x75, 0xab, 0x0f, 0x6c, 0x7f, 0xd1, 0xc3, 0x35, 888a8e1175bSopenharmony_ci 0x93, 0x9a, 0xa8, 0x63, 0xba, 0x37, 0xec, 0x91, 0xb7, 0xe3, 0x2b, 0xb0, 889a8e1175bSopenharmony_ci 0x13, 0xbb, 0x2b, 0x41, 0x04, 0xa4, 0x95, 0x58, 0xd3, 0x2e, 0xd1, 0xeb, 890a8e1175bSopenharmony_ci 0xfc, 0x18, 0x16, 0xaf, 0x4f, 0xf0, 0x9b, 0x55, 0xfc, 0xb4, 0xca, 0x47, 891a8e1175bSopenharmony_ci 0xb2, 0xa0, 0x2d, 0x1e, 0x7c, 0xaf, 0x11, 0x79, 0xea, 0x3f, 0xe1, 0x39, 892a8e1175bSopenharmony_ci 0x5b, 0x22, 0xb8, 0x61, 0x96, 0x40, 0x16, 0xfa, 0xba, 0xf7, 0x2c, 0x97, 893a8e1175bSopenharmony_ci 0x56, 0x95, 0xd9, 0x3d, 0x4d, 0xf0, 0xe5, 0x19, 0x7f, 0xe9, 0xf0, 0x40, 894a8e1175bSopenharmony_ci 0x63, 0x4e, 0xd5, 0x97, 0x64, 0x93, 0x77, 0x87, 0xbe, 0x20, 0xbc, 0x4d, 895a8e1175bSopenharmony_ci 0xee, 0xbb, 0xf9, 0xb8, 0xd6, 0x0a, 0x33, 0x5f, 0x04, 0x6c, 0xa3, 0xaa, 896a8e1175bSopenharmony_ci 0x94, 0x1e, 0x45, 0x86, 0x4c, 0x7c, 0xad, 0xef, 0x9c, 0xf7, 0x5b, 0x3d, 897a8e1175bSopenharmony_ci 0x8b, 0x01, 0x0e, 0x44, 0x3e, 0xf0 898a8e1175bSopenharmony_ci}; 899a8e1175bSopenharmony_ci 900a8e1175bSopenharmony_cistatic const unsigned char ecjpake_test_srv_one[] = { 901a8e1175bSopenharmony_ci 0x41, 0x04, 0x7e, 0xa6, 0xe3, 0xa4, 0x48, 0x70, 0x37, 0xa9, 0xe0, 0xdb, 902a8e1175bSopenharmony_ci 0xd7, 0x92, 0x62, 0xb2, 0xcc, 0x27, 0x3e, 0x77, 0x99, 0x30, 0xfc, 0x18, 903a8e1175bSopenharmony_ci 0x40, 0x9a, 0xc5, 0x36, 0x1c, 0x5f, 0xe6, 0x69, 0xd7, 0x02, 0xe1, 0x47, 904a8e1175bSopenharmony_ci 0x79, 0x0a, 0xeb, 0x4c, 0xe7, 0xfd, 0x65, 0x75, 0xab, 0x0f, 0x6c, 0x7f, 905a8e1175bSopenharmony_ci 0xd1, 0xc3, 0x35, 0x93, 0x9a, 0xa8, 0x63, 0xba, 0x37, 0xec, 0x91, 0xb7, 906a8e1175bSopenharmony_ci 0xe3, 0x2b, 0xb0, 0x13, 0xbb, 0x2b, 0x41, 0x04, 0x09, 0xf8, 0x5b, 0x3d, 907a8e1175bSopenharmony_ci 0x20, 0xeb, 0xd7, 0x88, 0x5c, 0xe4, 0x64, 0xc0, 0x8d, 0x05, 0x6d, 0x64, 908a8e1175bSopenharmony_ci 0x28, 0xfe, 0x4d, 0xd9, 0x28, 0x7a, 0xa3, 0x65, 0xf1, 0x31, 0xf4, 0x36, 909a8e1175bSopenharmony_ci 0x0f, 0xf3, 0x86, 0xd8, 0x46, 0x89, 0x8b, 0xc4, 0xb4, 0x15, 0x83, 0xc2, 910a8e1175bSopenharmony_ci 0xa5, 0x19, 0x7f, 0x65, 0xd7, 0x87, 0x42, 0x74, 0x6c, 0x12, 0xa5, 0xec, 911a8e1175bSopenharmony_ci 0x0a, 0x4f, 0xfe, 0x2f, 0x27, 0x0a, 0x75, 0x0a, 0x1d, 0x8f, 0xb5, 0x16, 912a8e1175bSopenharmony_ci 0x20, 0x93, 0x4d, 0x74, 0xeb, 0x43, 0xe5, 0x4d, 0xf4, 0x24, 0xfd, 0x96, 913a8e1175bSopenharmony_ci 0x30, 0x6c, 0x01, 0x17, 0xbf, 0x13, 0x1a, 0xfa, 0xbf, 0x90, 0xa9, 0xd3, 914a8e1175bSopenharmony_ci 0x3d, 0x11, 0x98, 0xd9, 0x05, 0x19, 0x37, 0x35, 0x14, 0x41, 0x04, 0x19, 915a8e1175bSopenharmony_ci 0x0a, 0x07, 0x70, 0x0f, 0xfa, 0x4b, 0xe6, 0xae, 0x1d, 0x79, 0xee, 0x0f, 916a8e1175bSopenharmony_ci 0x06, 0xae, 0xb5, 0x44, 0xcd, 0x5a, 0xdd, 0xaa, 0xbe, 0xdf, 0x70, 0xf8, 917a8e1175bSopenharmony_ci 0x62, 0x33, 0x21, 0x33, 0x2c, 0x54, 0xf3, 0x55, 0xf0, 0xfb, 0xfe, 0xc7, 918a8e1175bSopenharmony_ci 0x83, 0xed, 0x35, 0x9e, 0x5d, 0x0b, 0xf7, 0x37, 0x7a, 0x0f, 0xc4, 0xea, 919a8e1175bSopenharmony_ci 0x7a, 0xce, 0x47, 0x3c, 0x9c, 0x11, 0x2b, 0x41, 0xcc, 0xd4, 0x1a, 0xc5, 920a8e1175bSopenharmony_ci 0x6a, 0x56, 0x12, 0x41, 0x04, 0x36, 0x0a, 0x1c, 0xea, 0x33, 0xfc, 0xe6, 921a8e1175bSopenharmony_ci 0x41, 0x15, 0x64, 0x58, 0xe0, 0xa4, 0xea, 0xc2, 0x19, 0xe9, 0x68, 0x31, 922a8e1175bSopenharmony_ci 0xe6, 0xae, 0xbc, 0x88, 0xb3, 0xf3, 0x75, 0x2f, 0x93, 0xa0, 0x28, 0x1d, 923a8e1175bSopenharmony_ci 0x1b, 0xf1, 0xfb, 0x10, 0x60, 0x51, 0xdb, 0x96, 0x94, 0xa8, 0xd6, 0xe8, 924a8e1175bSopenharmony_ci 0x62, 0xa5, 0xef, 0x13, 0x24, 0xa3, 0xd9, 0xe2, 0x78, 0x94, 0xf1, 0xee, 925a8e1175bSopenharmony_ci 0x4f, 0x7c, 0x59, 0x19, 0x99, 0x65, 0xa8, 0xdd, 0x4a, 0x20, 0x91, 0x84, 926a8e1175bSopenharmony_ci 0x7d, 0x2d, 0x22, 0xdf, 0x3e, 0xe5, 0x5f, 0xaa, 0x2a, 0x3f, 0xb3, 0x3f, 927a8e1175bSopenharmony_ci 0xd2, 0xd1, 0xe0, 0x55, 0xa0, 0x7a, 0x7c, 0x61, 0xec, 0xfb, 0x8d, 0x80, 928a8e1175bSopenharmony_ci 0xec, 0x00, 0xc2, 0xc9, 0xeb, 0x12 929a8e1175bSopenharmony_ci}; 930a8e1175bSopenharmony_ci 931a8e1175bSopenharmony_cistatic const unsigned char ecjpake_test_srv_two[] = { 932a8e1175bSopenharmony_ci 0x03, 0x00, 0x17, 0x41, 0x04, 0x0f, 0xb2, 0x2b, 0x1d, 0x5d, 0x11, 0x23, 933a8e1175bSopenharmony_ci 0xe0, 0xef, 0x9f, 0xeb, 0x9d, 0x8a, 0x2e, 0x59, 0x0a, 0x1f, 0x4d, 0x7c, 934a8e1175bSopenharmony_ci 0xed, 0x2c, 0x2b, 0x06, 0x58, 0x6e, 0x8f, 0x2a, 0x16, 0xd4, 0xeb, 0x2f, 935a8e1175bSopenharmony_ci 0xda, 0x43, 0x28, 0xa2, 0x0b, 0x07, 0xd8, 0xfd, 0x66, 0x76, 0x54, 0xca, 936a8e1175bSopenharmony_ci 0x18, 0xc5, 0x4e, 0x32, 0xa3, 0x33, 0xa0, 0x84, 0x54, 0x51, 0xe9, 0x26, 937a8e1175bSopenharmony_ci 0xee, 0x88, 0x04, 0xfd, 0x7a, 0xf0, 0xaa, 0xa7, 0xa6, 0x41, 0x04, 0x55, 938a8e1175bSopenharmony_ci 0x16, 0xea, 0x3e, 0x54, 0xa0, 0xd5, 0xd8, 0xb2, 0xce, 0x78, 0x6b, 0x38, 939a8e1175bSopenharmony_ci 0xd3, 0x83, 0x37, 0x00, 0x29, 0xa5, 0xdb, 0xe4, 0x45, 0x9c, 0x9d, 0xd6, 940a8e1175bSopenharmony_ci 0x01, 0xb4, 0x08, 0xa2, 0x4a, 0xe6, 0x46, 0x5c, 0x8a, 0xc9, 0x05, 0xb9, 941a8e1175bSopenharmony_ci 0xeb, 0x03, 0xb5, 0xd3, 0x69, 0x1c, 0x13, 0x9e, 0xf8, 0x3f, 0x1c, 0xd4, 942a8e1175bSopenharmony_ci 0x20, 0x0f, 0x6c, 0x9c, 0xd4, 0xec, 0x39, 0x22, 0x18, 0xa5, 0x9e, 0xd2, 943a8e1175bSopenharmony_ci 0x43, 0xd3, 0xc8, 0x20, 0xff, 0x72, 0x4a, 0x9a, 0x70, 0xb8, 0x8c, 0xb8, 944a8e1175bSopenharmony_ci 0x6f, 0x20, 0xb4, 0x34, 0xc6, 0x86, 0x5a, 0xa1, 0xcd, 0x79, 0x06, 0xdd, 945a8e1175bSopenharmony_ci 0x7c, 0x9b, 0xce, 0x35, 0x25, 0xf5, 0x08, 0x27, 0x6f, 0x26, 0x83, 0x6c 946a8e1175bSopenharmony_ci}; 947a8e1175bSopenharmony_ci 948a8e1175bSopenharmony_cistatic const unsigned char ecjpake_test_cli_two[] = { 949a8e1175bSopenharmony_ci 0x41, 0x04, 0x69, 0xd5, 0x4e, 0xe8, 0x5e, 0x90, 0xce, 0x3f, 0x12, 0x46, 950a8e1175bSopenharmony_ci 0x74, 0x2d, 0xe5, 0x07, 0xe9, 0x39, 0xe8, 0x1d, 0x1d, 0xc1, 0xc5, 0xcb, 951a8e1175bSopenharmony_ci 0x98, 0x8b, 0x58, 0xc3, 0x10, 0xc9, 0xfd, 0xd9, 0x52, 0x4d, 0x93, 0x72, 952a8e1175bSopenharmony_ci 0x0b, 0x45, 0x54, 0x1c, 0x83, 0xee, 0x88, 0x41, 0x19, 0x1d, 0xa7, 0xce, 953a8e1175bSopenharmony_ci 0xd8, 0x6e, 0x33, 0x12, 0xd4, 0x36, 0x23, 0xc1, 0xd6, 0x3e, 0x74, 0x98, 954a8e1175bSopenharmony_ci 0x9a, 0xba, 0x4a, 0xff, 0xd1, 0xee, 0x41, 0x04, 0x07, 0x7e, 0x8c, 0x31, 955a8e1175bSopenharmony_ci 0xe2, 0x0e, 0x6b, 0xed, 0xb7, 0x60, 0xc1, 0x35, 0x93, 0xe6, 0x9f, 0x15, 956a8e1175bSopenharmony_ci 0xbe, 0x85, 0xc2, 0x7d, 0x68, 0xcd, 0x09, 0xcc, 0xb8, 0xc4, 0x18, 0x36, 957a8e1175bSopenharmony_ci 0x08, 0x91, 0x7c, 0x5c, 0x3d, 0x40, 0x9f, 0xac, 0x39, 0xfe, 0xfe, 0xe8, 958a8e1175bSopenharmony_ci 0x2f, 0x72, 0x92, 0xd3, 0x6f, 0x0d, 0x23, 0xe0, 0x55, 0x91, 0x3f, 0x45, 959a8e1175bSopenharmony_ci 0xa5, 0x2b, 0x85, 0xdd, 0x8a, 0x20, 0x52, 0xe9, 0xe1, 0x29, 0xbb, 0x4d, 960a8e1175bSopenharmony_ci 0x20, 0x0f, 0x01, 0x1f, 0x19, 0x48, 0x35, 0x35, 0xa6, 0xe8, 0x9a, 0x58, 961a8e1175bSopenharmony_ci 0x0c, 0x9b, 0x00, 0x03, 0xba, 0xf2, 0x14, 0x62, 0xec, 0xe9, 0x1a, 0x82, 962a8e1175bSopenharmony_ci 0xcc, 0x38, 0xdb, 0xdc, 0xae, 0x60, 0xd9, 0xc5, 0x4c 963a8e1175bSopenharmony_ci}; 964a8e1175bSopenharmony_ci 965a8e1175bSopenharmony_cistatic const unsigned char ecjpake_test_shared_key[] = { 966a8e1175bSopenharmony_ci 0x04, 0x01, 0xab, 0xe9, 0xf2, 0xc7, 0x3a, 0x99, 0x14, 0xcb, 0x1f, 0x80, 967a8e1175bSopenharmony_ci 0xfb, 0x9d, 0xdb, 0x7e, 0x00, 0x12, 0xa8, 0x9c, 0x2f, 0x39, 0x27, 0x79, 968a8e1175bSopenharmony_ci 0xf9, 0x64, 0x40, 0x14, 0x75, 0xea, 0xc1, 0x31, 0x28, 0x43, 0x8f, 0xe1, 969a8e1175bSopenharmony_ci 0x12, 0x41, 0xd6, 0xc1, 0xe5, 0x5f, 0x7b, 0x80, 0x88, 0x94, 0xc9, 0xc0, 970a8e1175bSopenharmony_ci 0x27, 0xa3, 0x34, 0x41, 0xf5, 0xcb, 0xa1, 0xfe, 0x6c, 0xc7, 0xe6, 0x12, 971a8e1175bSopenharmony_ci 0x17, 0xc3, 0xde, 0x27, 0xb4, 972a8e1175bSopenharmony_ci}; 973a8e1175bSopenharmony_ci 974a8e1175bSopenharmony_cistatic const unsigned char ecjpake_test_pms[] = { 975a8e1175bSopenharmony_ci 0xf3, 0xd4, 0x7f, 0x59, 0x98, 0x44, 0xdb, 0x92, 0xa5, 0x69, 0xbb, 0xe7, 976a8e1175bSopenharmony_ci 0x98, 0x1e, 0x39, 0xd9, 0x31, 0xfd, 0x74, 0x3b, 0xf2, 0x2e, 0x98, 0xf9, 977a8e1175bSopenharmony_ci 0xb4, 0x38, 0xf7, 0x19, 0xd3, 0xc4, 0xf3, 0x51 978a8e1175bSopenharmony_ci}; 979a8e1175bSopenharmony_ci 980a8e1175bSopenharmony_ci/* 981a8e1175bSopenharmony_ci * PRNG for test - !!!INSECURE NEVER USE IN PRODUCTION!!! 982a8e1175bSopenharmony_ci * 983a8e1175bSopenharmony_ci * This is the linear congruential generator from numerical recipes, 984a8e1175bSopenharmony_ci * except we only use the low byte as the output. See 985a8e1175bSopenharmony_ci * https://en.wikipedia.org/wiki/Linear_congruential_generator#Parameters_in_common_use 986a8e1175bSopenharmony_ci */ 987a8e1175bSopenharmony_cistatic int self_test_rng(void *ctx, unsigned char *out, size_t len) 988a8e1175bSopenharmony_ci{ 989a8e1175bSopenharmony_ci static uint32_t state = 42; 990a8e1175bSopenharmony_ci 991a8e1175bSopenharmony_ci (void) ctx; 992a8e1175bSopenharmony_ci 993a8e1175bSopenharmony_ci for (size_t i = 0; i < len; i++) { 994a8e1175bSopenharmony_ci state = state * 1664525u + 1013904223u; 995a8e1175bSopenharmony_ci out[i] = (unsigned char) state; 996a8e1175bSopenharmony_ci } 997a8e1175bSopenharmony_ci 998a8e1175bSopenharmony_ci return 0; 999a8e1175bSopenharmony_ci} 1000a8e1175bSopenharmony_ci 1001a8e1175bSopenharmony_ci/* Load my private keys and generate the corresponding public keys */ 1002a8e1175bSopenharmony_cistatic int ecjpake_test_load(mbedtls_ecjpake_context *ctx, 1003a8e1175bSopenharmony_ci const unsigned char *xm1, size_t len1, 1004a8e1175bSopenharmony_ci const unsigned char *xm2, size_t len2) 1005a8e1175bSopenharmony_ci{ 1006a8e1175bSopenharmony_ci int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 1007a8e1175bSopenharmony_ci 1008a8e1175bSopenharmony_ci MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&ctx->xm1, xm1, len1)); 1009a8e1175bSopenharmony_ci MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&ctx->xm2, xm2, len2)); 1010a8e1175bSopenharmony_ci MBEDTLS_MPI_CHK(mbedtls_ecp_mul(&ctx->grp, &ctx->Xm1, &ctx->xm1, 1011a8e1175bSopenharmony_ci &ctx->grp.G, self_test_rng, NULL)); 1012a8e1175bSopenharmony_ci MBEDTLS_MPI_CHK(mbedtls_ecp_mul(&ctx->grp, &ctx->Xm2, &ctx->xm2, 1013a8e1175bSopenharmony_ci &ctx->grp.G, self_test_rng, NULL)); 1014a8e1175bSopenharmony_ci 1015a8e1175bSopenharmony_cicleanup: 1016a8e1175bSopenharmony_ci return ret; 1017a8e1175bSopenharmony_ci} 1018a8e1175bSopenharmony_ci 1019a8e1175bSopenharmony_ci#endif /* ! MBEDTLS_ECJPAKE_ALT */ 1020a8e1175bSopenharmony_ci 1021a8e1175bSopenharmony_ci/* For tests we don't need a secure RNG; 1022a8e1175bSopenharmony_ci * use the LGC from Numerical Recipes for simplicity */ 1023a8e1175bSopenharmony_cistatic int ecjpake_lgc(void *p, unsigned char *out, size_t len) 1024a8e1175bSopenharmony_ci{ 1025a8e1175bSopenharmony_ci static uint32_t x = 42; 1026a8e1175bSopenharmony_ci (void) p; 1027a8e1175bSopenharmony_ci 1028a8e1175bSopenharmony_ci while (len > 0) { 1029a8e1175bSopenharmony_ci size_t use_len = len > 4 ? 4 : len; 1030a8e1175bSopenharmony_ci x = 1664525 * x + 1013904223; 1031a8e1175bSopenharmony_ci memcpy(out, &x, use_len); 1032a8e1175bSopenharmony_ci out += use_len; 1033a8e1175bSopenharmony_ci len -= use_len; 1034a8e1175bSopenharmony_ci } 1035a8e1175bSopenharmony_ci 1036a8e1175bSopenharmony_ci return 0; 1037a8e1175bSopenharmony_ci} 1038a8e1175bSopenharmony_ci 1039a8e1175bSopenharmony_ci#define TEST_ASSERT(x) \ 1040a8e1175bSopenharmony_ci do { \ 1041a8e1175bSopenharmony_ci if (x) \ 1042a8e1175bSopenharmony_ci ret = 0; \ 1043a8e1175bSopenharmony_ci else \ 1044a8e1175bSopenharmony_ci { \ 1045a8e1175bSopenharmony_ci ret = 1; \ 1046a8e1175bSopenharmony_ci goto cleanup; \ 1047a8e1175bSopenharmony_ci } \ 1048a8e1175bSopenharmony_ci } while (0) 1049a8e1175bSopenharmony_ci 1050a8e1175bSopenharmony_ci/* 1051a8e1175bSopenharmony_ci * Checkup routine 1052a8e1175bSopenharmony_ci */ 1053a8e1175bSopenharmony_ciint mbedtls_ecjpake_self_test(int verbose) 1054a8e1175bSopenharmony_ci{ 1055a8e1175bSopenharmony_ci int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 1056a8e1175bSopenharmony_ci mbedtls_ecjpake_context cli; 1057a8e1175bSopenharmony_ci mbedtls_ecjpake_context srv; 1058a8e1175bSopenharmony_ci unsigned char buf[512], pms[32]; 1059a8e1175bSopenharmony_ci size_t len, pmslen; 1060a8e1175bSopenharmony_ci 1061a8e1175bSopenharmony_ci mbedtls_ecjpake_init(&cli); 1062a8e1175bSopenharmony_ci mbedtls_ecjpake_init(&srv); 1063a8e1175bSopenharmony_ci 1064a8e1175bSopenharmony_ci if (verbose != 0) { 1065a8e1175bSopenharmony_ci mbedtls_printf(" ECJPAKE test #0 (setup): "); 1066a8e1175bSopenharmony_ci } 1067a8e1175bSopenharmony_ci 1068a8e1175bSopenharmony_ci TEST_ASSERT(mbedtls_ecjpake_setup(&cli, MBEDTLS_ECJPAKE_CLIENT, 1069a8e1175bSopenharmony_ci MBEDTLS_MD_SHA256, MBEDTLS_ECP_DP_SECP256R1, 1070a8e1175bSopenharmony_ci ecjpake_test_password, 1071a8e1175bSopenharmony_ci sizeof(ecjpake_test_password)) == 0); 1072a8e1175bSopenharmony_ci 1073a8e1175bSopenharmony_ci TEST_ASSERT(mbedtls_ecjpake_setup(&srv, MBEDTLS_ECJPAKE_SERVER, 1074a8e1175bSopenharmony_ci MBEDTLS_MD_SHA256, MBEDTLS_ECP_DP_SECP256R1, 1075a8e1175bSopenharmony_ci ecjpake_test_password, 1076a8e1175bSopenharmony_ci sizeof(ecjpake_test_password)) == 0); 1077a8e1175bSopenharmony_ci 1078a8e1175bSopenharmony_ci if (verbose != 0) { 1079a8e1175bSopenharmony_ci mbedtls_printf("passed\n"); 1080a8e1175bSopenharmony_ci } 1081a8e1175bSopenharmony_ci 1082a8e1175bSopenharmony_ci if (verbose != 0) { 1083a8e1175bSopenharmony_ci mbedtls_printf(" ECJPAKE test #1 (random handshake): "); 1084a8e1175bSopenharmony_ci } 1085a8e1175bSopenharmony_ci 1086a8e1175bSopenharmony_ci TEST_ASSERT(mbedtls_ecjpake_write_round_one(&cli, 1087a8e1175bSopenharmony_ci buf, sizeof(buf), &len, ecjpake_lgc, NULL) == 0); 1088a8e1175bSopenharmony_ci 1089a8e1175bSopenharmony_ci TEST_ASSERT(mbedtls_ecjpake_read_round_one(&srv, buf, len) == 0); 1090a8e1175bSopenharmony_ci 1091a8e1175bSopenharmony_ci TEST_ASSERT(mbedtls_ecjpake_write_round_one(&srv, 1092a8e1175bSopenharmony_ci buf, sizeof(buf), &len, ecjpake_lgc, NULL) == 0); 1093a8e1175bSopenharmony_ci 1094a8e1175bSopenharmony_ci TEST_ASSERT(mbedtls_ecjpake_read_round_one(&cli, buf, len) == 0); 1095a8e1175bSopenharmony_ci 1096a8e1175bSopenharmony_ci TEST_ASSERT(mbedtls_ecjpake_write_round_two(&srv, 1097a8e1175bSopenharmony_ci buf, sizeof(buf), &len, ecjpake_lgc, NULL) == 0); 1098a8e1175bSopenharmony_ci 1099a8e1175bSopenharmony_ci TEST_ASSERT(mbedtls_ecjpake_read_round_two(&cli, buf, len) == 0); 1100a8e1175bSopenharmony_ci 1101a8e1175bSopenharmony_ci TEST_ASSERT(mbedtls_ecjpake_derive_secret(&cli, 1102a8e1175bSopenharmony_ci pms, sizeof(pms), &pmslen, ecjpake_lgc, NULL) == 0); 1103a8e1175bSopenharmony_ci 1104a8e1175bSopenharmony_ci TEST_ASSERT(mbedtls_ecjpake_write_round_two(&cli, 1105a8e1175bSopenharmony_ci buf, sizeof(buf), &len, ecjpake_lgc, NULL) == 0); 1106a8e1175bSopenharmony_ci 1107a8e1175bSopenharmony_ci TEST_ASSERT(mbedtls_ecjpake_read_round_two(&srv, buf, len) == 0); 1108a8e1175bSopenharmony_ci 1109a8e1175bSopenharmony_ci TEST_ASSERT(mbedtls_ecjpake_derive_secret(&srv, 1110a8e1175bSopenharmony_ci buf, sizeof(buf), &len, ecjpake_lgc, NULL) == 0); 1111a8e1175bSopenharmony_ci 1112a8e1175bSopenharmony_ci TEST_ASSERT(len == pmslen); 1113a8e1175bSopenharmony_ci TEST_ASSERT(memcmp(buf, pms, len) == 0); 1114a8e1175bSopenharmony_ci 1115a8e1175bSopenharmony_ci if (verbose != 0) { 1116a8e1175bSopenharmony_ci mbedtls_printf("passed\n"); 1117a8e1175bSopenharmony_ci } 1118a8e1175bSopenharmony_ci 1119a8e1175bSopenharmony_ci#if !defined(MBEDTLS_ECJPAKE_ALT) 1120a8e1175bSopenharmony_ci /* 'reference handshake' tests can only be run against implementations 1121a8e1175bSopenharmony_ci * for which we have 100% control over how the random ephemeral keys 1122a8e1175bSopenharmony_ci * are generated. This is only the case for the internal Mbed TLS 1123a8e1175bSopenharmony_ci * implementation, so these tests are skipped in case the internal 1124a8e1175bSopenharmony_ci * implementation is swapped out for an alternative one. */ 1125a8e1175bSopenharmony_ci if (verbose != 0) { 1126a8e1175bSopenharmony_ci mbedtls_printf(" ECJPAKE test #2 (reference handshake): "); 1127a8e1175bSopenharmony_ci } 1128a8e1175bSopenharmony_ci 1129a8e1175bSopenharmony_ci /* Simulate generation of round one */ 1130a8e1175bSopenharmony_ci MBEDTLS_MPI_CHK(ecjpake_test_load(&cli, 1131a8e1175bSopenharmony_ci ecjpake_test_x1, sizeof(ecjpake_test_x1), 1132a8e1175bSopenharmony_ci ecjpake_test_x2, sizeof(ecjpake_test_x2))); 1133a8e1175bSopenharmony_ci 1134a8e1175bSopenharmony_ci MBEDTLS_MPI_CHK(ecjpake_test_load(&srv, 1135a8e1175bSopenharmony_ci ecjpake_test_x3, sizeof(ecjpake_test_x3), 1136a8e1175bSopenharmony_ci ecjpake_test_x4, sizeof(ecjpake_test_x4))); 1137a8e1175bSopenharmony_ci 1138a8e1175bSopenharmony_ci /* Read round one */ 1139a8e1175bSopenharmony_ci TEST_ASSERT(mbedtls_ecjpake_read_round_one(&srv, 1140a8e1175bSopenharmony_ci ecjpake_test_cli_one, 1141a8e1175bSopenharmony_ci sizeof(ecjpake_test_cli_one)) == 0); 1142a8e1175bSopenharmony_ci 1143a8e1175bSopenharmony_ci TEST_ASSERT(mbedtls_ecjpake_read_round_one(&cli, 1144a8e1175bSopenharmony_ci ecjpake_test_srv_one, 1145a8e1175bSopenharmony_ci sizeof(ecjpake_test_srv_one)) == 0); 1146a8e1175bSopenharmony_ci 1147a8e1175bSopenharmony_ci /* Skip generation of round two, read round two */ 1148a8e1175bSopenharmony_ci TEST_ASSERT(mbedtls_ecjpake_read_round_two(&cli, 1149a8e1175bSopenharmony_ci ecjpake_test_srv_two, 1150a8e1175bSopenharmony_ci sizeof(ecjpake_test_srv_two)) == 0); 1151a8e1175bSopenharmony_ci 1152a8e1175bSopenharmony_ci TEST_ASSERT(mbedtls_ecjpake_read_round_two(&srv, 1153a8e1175bSopenharmony_ci ecjpake_test_cli_two, 1154a8e1175bSopenharmony_ci sizeof(ecjpake_test_cli_two)) == 0); 1155a8e1175bSopenharmony_ci 1156a8e1175bSopenharmony_ci /* Server derives PMS */ 1157a8e1175bSopenharmony_ci TEST_ASSERT(mbedtls_ecjpake_derive_secret(&srv, 1158a8e1175bSopenharmony_ci buf, sizeof(buf), &len, ecjpake_lgc, NULL) == 0); 1159a8e1175bSopenharmony_ci 1160a8e1175bSopenharmony_ci TEST_ASSERT(len == sizeof(ecjpake_test_pms)); 1161a8e1175bSopenharmony_ci TEST_ASSERT(memcmp(buf, ecjpake_test_pms, len) == 0); 1162a8e1175bSopenharmony_ci 1163a8e1175bSopenharmony_ci /* Server derives K as unsigned binary data */ 1164a8e1175bSopenharmony_ci TEST_ASSERT(mbedtls_ecjpake_write_shared_key(&srv, 1165a8e1175bSopenharmony_ci buf, sizeof(buf), &len, ecjpake_lgc, NULL) == 0); 1166a8e1175bSopenharmony_ci 1167a8e1175bSopenharmony_ci TEST_ASSERT(len == sizeof(ecjpake_test_shared_key)); 1168a8e1175bSopenharmony_ci TEST_ASSERT(memcmp(buf, ecjpake_test_shared_key, len) == 0); 1169a8e1175bSopenharmony_ci 1170a8e1175bSopenharmony_ci memset(buf, 0, len); /* Avoid interferences with next step */ 1171a8e1175bSopenharmony_ci 1172a8e1175bSopenharmony_ci /* Client derives PMS */ 1173a8e1175bSopenharmony_ci TEST_ASSERT(mbedtls_ecjpake_derive_secret(&cli, 1174a8e1175bSopenharmony_ci buf, sizeof(buf), &len, ecjpake_lgc, NULL) == 0); 1175a8e1175bSopenharmony_ci 1176a8e1175bSopenharmony_ci TEST_ASSERT(len == sizeof(ecjpake_test_pms)); 1177a8e1175bSopenharmony_ci TEST_ASSERT(memcmp(buf, ecjpake_test_pms, len) == 0); 1178a8e1175bSopenharmony_ci 1179a8e1175bSopenharmony_ci /* Client derives K as unsigned binary data */ 1180a8e1175bSopenharmony_ci TEST_ASSERT(mbedtls_ecjpake_write_shared_key(&cli, 1181a8e1175bSopenharmony_ci buf, sizeof(buf), &len, ecjpake_lgc, NULL) == 0); 1182a8e1175bSopenharmony_ci 1183a8e1175bSopenharmony_ci TEST_ASSERT(len == sizeof(ecjpake_test_shared_key)); 1184a8e1175bSopenharmony_ci TEST_ASSERT(memcmp(buf, ecjpake_test_shared_key, len) == 0); 1185a8e1175bSopenharmony_ci 1186a8e1175bSopenharmony_ci if (verbose != 0) { 1187a8e1175bSopenharmony_ci mbedtls_printf("passed\n"); 1188a8e1175bSopenharmony_ci } 1189a8e1175bSopenharmony_ci#endif /* ! MBEDTLS_ECJPAKE_ALT */ 1190a8e1175bSopenharmony_ci 1191a8e1175bSopenharmony_cicleanup: 1192a8e1175bSopenharmony_ci mbedtls_ecjpake_free(&cli); 1193a8e1175bSopenharmony_ci mbedtls_ecjpake_free(&srv); 1194a8e1175bSopenharmony_ci 1195a8e1175bSopenharmony_ci if (ret != 0) { 1196a8e1175bSopenharmony_ci if (verbose != 0) { 1197a8e1175bSopenharmony_ci mbedtls_printf("failed\n"); 1198a8e1175bSopenharmony_ci } 1199a8e1175bSopenharmony_ci 1200a8e1175bSopenharmony_ci ret = 1; 1201a8e1175bSopenharmony_ci } 1202a8e1175bSopenharmony_ci 1203a8e1175bSopenharmony_ci if (verbose != 0) { 1204a8e1175bSopenharmony_ci mbedtls_printf("\n"); 1205a8e1175bSopenharmony_ci } 1206a8e1175bSopenharmony_ci 1207a8e1175bSopenharmony_ci return ret; 1208a8e1175bSopenharmony_ci} 1209a8e1175bSopenharmony_ci 1210a8e1175bSopenharmony_ci#undef TEST_ASSERT 1211a8e1175bSopenharmony_ci 1212a8e1175bSopenharmony_ci#endif /* MBEDTLS_ECP_DP_SECP256R1_ENABLED && MBEDTLS_MD_CAN_SHA256 */ 1213a8e1175bSopenharmony_ci 1214a8e1175bSopenharmony_ci#endif /* MBEDTLS_SELF_TEST */ 1215a8e1175bSopenharmony_ci 1216a8e1175bSopenharmony_ci#endif /* MBEDTLS_ECJPAKE_C */ 1217