blob: aadd05726b3bf6d4eba625ada4617647506344b1 [file] [log] [blame]
Manuel Pégourié-Gonnard4d8685b2015-08-05 15:44:42 +02001/*
2 * Elliptic curve J-PAKE
3 *
Bence Szépkúti1e148272020-08-07 13:07:28 +02004 * Copyright The Mbed TLS Contributors
Manuel Pégourié-Gonnard4d8685b2015-08-05 15:44:42 +02005 * SPDX-License-Identifier: Apache-2.0
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License"); you may
8 * not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
Manuel Pégourié-Gonnard4d8685b2015-08-05 15:44:42 +020018 */
19
20/*
Manuel Pégourié-Gonnard6b798b92015-08-14 11:18:30 +020021 * References in the code are to the Thread v1.0 Specification,
Manuel Pégourié-Gonnardc9070812015-08-14 14:48:50 +020022 * available to members of the Thread Group http://threadgroup.org/
Manuel Pégourié-Gonnard4d8685b2015-08-05 15:44:42 +020023 */
24
Gilles Peskinedb09ef62020-06-03 01:43:33 +020025#include "common.h"
Manuel Pégourié-Gonnard4d8685b2015-08-05 15:44:42 +020026
27#if defined(MBEDTLS_ECJPAKE_C)
28
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020029# include "mbedtls/ecjpake.h"
30# include "mbedtls/platform_util.h"
31# include "mbedtls/error.h"
Manuel Pégourié-Gonnard4d8685b2015-08-05 15:44:42 +020032
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020033# include <string.h>
Manuel Pégourié-Gonnard3dbf2fb2015-08-06 17:24:39 +020034
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020035# if !defined(MBEDTLS_ECJPAKE_ALT)
Hanno Becker616d1ca2018-01-24 10:25:05 +000036
Hanno Becker71c8e1b2018-12-14 17:09:39 +000037/* Parameter validation macros based on platform_util.h */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020038# define ECJPAKE_VALIDATE_RET(cond) \
39 MBEDTLS_INTERNAL_VALIDATE_RET(cond, MBEDTLS_ERR_ECP_BAD_INPUT_DATA)
40# define ECJPAKE_VALIDATE(cond) MBEDTLS_INTERNAL_VALIDATE(cond)
Hanno Becker71c8e1b2018-12-14 17:09:39 +000041
Manuel Pégourié-Gonnard3dbf2fb2015-08-06 17:24:39 +020042/*
Manuel Pégourié-Gonnarde0ad57b2015-08-14 11:10:39 +020043 * Convert a mbedtls_ecjpake_role to identifier string
44 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020045static const char *const ecjpake_id[] = { "client", "server" };
Manuel Pégourié-Gonnarde0ad57b2015-08-14 11:10:39 +020046
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020047# define ID_MINE (ecjpake_id[ctx->role])
48# define ID_PEER (ecjpake_id[1 - ctx->role])
Manuel Pégourié-Gonnarde0ad57b2015-08-14 11:10:39 +020049
50/*
Manuel Pégourié-Gonnard7af8bc12015-08-12 16:58:50 +020051 * Initialize context
52 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020053void mbedtls_ecjpake_init(mbedtls_ecjpake_context *ctx)
Manuel Pégourié-Gonnard7af8bc12015-08-12 16:58:50 +020054{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020055 ECJPAKE_VALIDATE(ctx != NULL);
Manuel Pégourié-Gonnard7af8bc12015-08-12 16:58:50 +020056
57 ctx->md_info = NULL;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020058 mbedtls_ecp_group_init(&ctx->grp);
Manuel Pégourié-Gonnardb7da1942015-10-19 13:35:22 +020059 ctx->point_format = MBEDTLS_ECP_PF_UNCOMPRESSED;
Manuel Pégourié-Gonnard7af8bc12015-08-12 16:58:50 +020060
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020061 mbedtls_ecp_point_init(&ctx->Xm1);
62 mbedtls_ecp_point_init(&ctx->Xm2);
63 mbedtls_ecp_point_init(&ctx->Xp1);
64 mbedtls_ecp_point_init(&ctx->Xp2);
65 mbedtls_ecp_point_init(&ctx->Xp);
Manuel Pégourié-Gonnard7af8bc12015-08-12 16:58:50 +020066
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020067 mbedtls_mpi_init(&ctx->xm1);
68 mbedtls_mpi_init(&ctx->xm2);
69 mbedtls_mpi_init(&ctx->s);
Manuel Pégourié-Gonnard7af8bc12015-08-12 16:58:50 +020070}
71
72/*
73 * Free context
74 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020075void mbedtls_ecjpake_free(mbedtls_ecjpake_context *ctx)
Manuel Pégourié-Gonnard7af8bc12015-08-12 16:58:50 +020076{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020077 if (ctx == NULL)
Manuel Pégourié-Gonnard7af8bc12015-08-12 16:58:50 +020078 return;
79
80 ctx->md_info = NULL;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020081 mbedtls_ecp_group_free(&ctx->grp);
Manuel Pégourié-Gonnard7af8bc12015-08-12 16:58:50 +020082
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020083 mbedtls_ecp_point_free(&ctx->Xm1);
84 mbedtls_ecp_point_free(&ctx->Xm2);
85 mbedtls_ecp_point_free(&ctx->Xp1);
86 mbedtls_ecp_point_free(&ctx->Xp2);
87 mbedtls_ecp_point_free(&ctx->Xp);
Manuel Pégourié-Gonnard7af8bc12015-08-12 16:58:50 +020088
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020089 mbedtls_mpi_free(&ctx->xm1);
90 mbedtls_mpi_free(&ctx->xm2);
91 mbedtls_mpi_free(&ctx->s);
Manuel Pégourié-Gonnard7af8bc12015-08-12 16:58:50 +020092}
93
94/*
95 * Setup context
96 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +020097int mbedtls_ecjpake_setup(mbedtls_ecjpake_context *ctx,
98 mbedtls_ecjpake_role role,
99 mbedtls_md_type_t hash,
100 mbedtls_ecp_group_id curve,
101 const unsigned char *secret,
102 size_t len)
Manuel Pégourié-Gonnard7af8bc12015-08-12 16:58:50 +0200103{
Janos Follath24eed8d2019-11-22 13:21:35 +0000104 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Hanno Becker185e5162018-12-19 09:48:50 +0000105
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200106 ECJPAKE_VALIDATE_RET(ctx != NULL);
107 ECJPAKE_VALIDATE_RET(role == MBEDTLS_ECJPAKE_CLIENT ||
108 role == MBEDTLS_ECJPAKE_SERVER);
109 ECJPAKE_VALIDATE_RET(secret != NULL || len == 0);
Manuel Pégourié-Gonnard7af8bc12015-08-12 16:58:50 +0200110
Manuel Pégourié-Gonnard64493912015-08-13 20:19:51 +0200111 ctx->role = role;
112
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200113 if ((ctx->md_info = mbedtls_md_info_from_type(hash)) == NULL)
114 return MBEDTLS_ERR_MD_FEATURE_UNAVAILABLE;
Manuel Pégourié-Gonnard7af8bc12015-08-12 16:58:50 +0200115
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200116 MBEDTLS_MPI_CHK(mbedtls_ecp_group_load(&ctx->grp, curve));
Manuel Pégourié-Gonnard7af8bc12015-08-12 16:58:50 +0200117
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200118 MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&ctx->s, secret, len));
Manuel Pégourié-Gonnard23dcbe32015-08-13 09:37:00 +0200119
120cleanup:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200121 if (ret != 0)
122 mbedtls_ecjpake_free(ctx);
Manuel Pégourié-Gonnard23dcbe32015-08-13 09:37:00 +0200123
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200124 return ret;
Manuel Pégourié-Gonnard7af8bc12015-08-12 16:58:50 +0200125}
126
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200127int mbedtls_ecjpake_set_point_format(mbedtls_ecjpake_context *ctx,
128 int point_format)
Gilles Peskinecd07e222021-05-27 23:17:34 +0200129{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200130 switch (point_format) {
Gilles Peskinecd07e222021-05-27 23:17:34 +0200131 case MBEDTLS_ECP_PF_UNCOMPRESSED:
132 case MBEDTLS_ECP_PF_COMPRESSED:
133 ctx->point_format = point_format;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200134 return 0;
Gilles Peskinecd07e222021-05-27 23:17:34 +0200135 default:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200136 return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
Gilles Peskinecd07e222021-05-27 23:17:34 +0200137 }
138}
139
Manuel Pégourié-Gonnard7af8bc12015-08-12 16:58:50 +0200140/*
Manuel Pégourié-Gonnardb813acc2015-09-15 15:34:09 +0200141 * Check if context is ready for use
142 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200143int mbedtls_ecjpake_check(const mbedtls_ecjpake_context *ctx)
Manuel Pégourié-Gonnardb813acc2015-09-15 15:34:09 +0200144{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200145 ECJPAKE_VALIDATE_RET(ctx != NULL);
Hanno Becker71c8e1b2018-12-14 17:09:39 +0000146
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200147 if (ctx->md_info == NULL || ctx->grp.id == MBEDTLS_ECP_DP_NONE ||
148 ctx->s.p == NULL) {
149 return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
Manuel Pégourié-Gonnardb813acc2015-09-15 15:34:09 +0200150 }
151
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200152 return 0;
Manuel Pégourié-Gonnardb813acc2015-09-15 15:34:09 +0200153}
154
155/*
Manuel Pégourié-Gonnard3dbf2fb2015-08-06 17:24:39 +0200156 * Write a point plus its length to a buffer
157 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200158static int ecjpake_write_len_point(unsigned char **p,
159 const unsigned char *end,
160 const mbedtls_ecp_group *grp,
161 const int pf,
162 const mbedtls_ecp_point *P)
Manuel Pégourié-Gonnard3dbf2fb2015-08-06 17:24:39 +0200163{
Janos Follath24eed8d2019-11-22 13:21:35 +0000164 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard3dbf2fb2015-08-06 17:24:39 +0200165 size_t len;
166
167 /* Need at least 4 for length plus 1 for point */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200168 if (end < *p || end - *p < 5)
169 return MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL;
Manuel Pégourié-Gonnard3dbf2fb2015-08-06 17:24:39 +0200170
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200171 ret = mbedtls_ecp_point_write_binary(grp, P, pf, &len, *p + 4,
172 end - (*p + 4));
173 if (ret != 0)
174 return ret;
Manuel Pégourié-Gonnard3dbf2fb2015-08-06 17:24:39 +0200175
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200176 (*p)[0] = (unsigned char)((len >> 24) & 0xFF);
177 (*p)[1] = (unsigned char)((len >> 16) & 0xFF);
178 (*p)[2] = (unsigned char)((len >> 8) & 0xFF);
179 (*p)[3] = (unsigned char)((len)&0xFF);
Manuel Pégourié-Gonnard3dbf2fb2015-08-06 17:24:39 +0200180
181 *p += 4 + len;
182
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200183 return 0;
Manuel Pégourié-Gonnard3dbf2fb2015-08-06 17:24:39 +0200184}
185
186/*
187 * Size of the temporary buffer for ecjpake_hash:
Manuel Pégourié-Gonnard4b20c0e2015-10-20 16:16:38 +0200188 * 3 EC points plus their length, plus ID and its length (4 + 6 bytes)
Manuel Pégourié-Gonnard3dbf2fb2015-08-06 17:24:39 +0200189 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200190# define ECJPAKE_HASH_BUF_LEN (3 * (4 + MBEDTLS_ECP_MAX_PT_LEN) + 4 + 6)
Manuel Pégourié-Gonnard3dbf2fb2015-08-06 17:24:39 +0200191
192/*
193 * Compute hash for ZKP (7.4.2.2.2.1)
194 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200195static int ecjpake_hash(const mbedtls_md_info_t *md_info,
196 const mbedtls_ecp_group *grp,
197 const int pf,
198 const mbedtls_ecp_point *G,
199 const mbedtls_ecp_point *V,
200 const mbedtls_ecp_point *X,
201 const char *id,
202 mbedtls_mpi *h)
Manuel Pégourié-Gonnard3dbf2fb2015-08-06 17:24:39 +0200203{
Janos Follath24eed8d2019-11-22 13:21:35 +0000204 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard3dbf2fb2015-08-06 17:24:39 +0200205 unsigned char buf[ECJPAKE_HASH_BUF_LEN];
206 unsigned char *p = buf;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200207 const unsigned char *end = buf + sizeof(buf);
208 const size_t id_len = strlen(id);
Manuel Pégourié-Gonnard3dbf2fb2015-08-06 17:24:39 +0200209 unsigned char hash[MBEDTLS_MD_MAX_SIZE];
210
211 /* Write things to temporary buffer */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200212 MBEDTLS_MPI_CHK(ecjpake_write_len_point(&p, end, grp, pf, G));
213 MBEDTLS_MPI_CHK(ecjpake_write_len_point(&p, end, grp, pf, V));
214 MBEDTLS_MPI_CHK(ecjpake_write_len_point(&p, end, grp, pf, X));
Manuel Pégourié-Gonnard3dbf2fb2015-08-06 17:24:39 +0200215
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200216 if (end - p < 4)
217 return MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL;
Manuel Pégourié-Gonnard3dbf2fb2015-08-06 17:24:39 +0200218
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200219 *p++ = (unsigned char)((id_len >> 24) & 0xFF);
220 *p++ = (unsigned char)((id_len >> 16) & 0xFF);
221 *p++ = (unsigned char)((id_len >> 8) & 0xFF);
222 *p++ = (unsigned char)((id_len)&0xFF);
Manuel Pégourié-Gonnard3dbf2fb2015-08-06 17:24:39 +0200223
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200224 if (end < p || (size_t)(end - p) < id_len)
225 return MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL;
Manuel Pégourié-Gonnard4b20c0e2015-10-20 16:16:38 +0200226
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200227 memcpy(p, id, id_len);
Manuel Pégourié-Gonnard3dbf2fb2015-08-06 17:24:39 +0200228 p += id_len;
229
230 /* Compute hash */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200231 MBEDTLS_MPI_CHK(mbedtls_md(md_info, buf, p - buf, hash));
Manuel Pégourié-Gonnard3dbf2fb2015-08-06 17:24:39 +0200232
233 /* Turn it into an integer mod n */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200234 MBEDTLS_MPI_CHK(
235 mbedtls_mpi_read_binary(h, hash, mbedtls_md_get_size(md_info)));
236 MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(h, h, &grp->N));
Manuel Pégourié-Gonnard3dbf2fb2015-08-06 17:24:39 +0200237
238cleanup:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200239 return ret;
Manuel Pégourié-Gonnard3dbf2fb2015-08-06 17:24:39 +0200240}
241
Manuel Pégourié-Gonnard8489f172015-08-07 17:47:39 +0200242/*
Manuel Pégourié-Gonnard6029a852015-08-11 15:44:41 +0200243 * Parse a ECShnorrZKP (7.4.2.2.2) and verify it (7.4.2.3.3)
244 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200245static int ecjpake_zkp_read(const mbedtls_md_info_t *md_info,
246 const mbedtls_ecp_group *grp,
247 const int pf,
248 const mbedtls_ecp_point *G,
249 const mbedtls_ecp_point *X,
250 const char *id,
251 const unsigned char **p,
252 const unsigned char *end)
Manuel Pégourié-Gonnard6029a852015-08-11 15:44:41 +0200253{
Janos Follath24eed8d2019-11-22 13:21:35 +0000254 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard6029a852015-08-11 15:44:41 +0200255 mbedtls_ecp_point V, VV;
256 mbedtls_mpi r, h;
257 size_t r_len;
258
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200259 mbedtls_ecp_point_init(&V);
260 mbedtls_ecp_point_init(&VV);
261 mbedtls_mpi_init(&r);
262 mbedtls_mpi_init(&h);
Manuel Pégourié-Gonnard6029a852015-08-11 15:44:41 +0200263
264 /*
265 * struct {
266 * ECPoint V;
267 * opaque r<1..2^8-1>;
268 * } ECSchnorrZKP;
269 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200270 if (end < *p)
271 return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
Manuel Pégourié-Gonnard6029a852015-08-11 15:44:41 +0200272
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200273 MBEDTLS_MPI_CHK(mbedtls_ecp_tls_read_point(grp, &V, p, end - *p));
Manuel Pégourié-Gonnard6029a852015-08-11 15:44:41 +0200274
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200275 if (end < *p || (size_t)(end - *p) < 1) {
Manuel Pégourié-Gonnard4f2cd952015-08-12 11:17:55 +0200276 ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
277 goto cleanup;
278 }
Manuel Pégourié-Gonnard6029a852015-08-11 15:44:41 +0200279
280 r_len = *(*p)++;
Manuel Pégourié-Gonnard9028c5a2015-08-12 14:51:36 +0200281
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200282 if (end < *p || (size_t)(end - *p) < r_len || r_len == 0) {
Manuel Pégourié-Gonnard4f2cd952015-08-12 11:17:55 +0200283 ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
284 goto cleanup;
285 }
Manuel Pégourié-Gonnard6029a852015-08-11 15:44:41 +0200286
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200287 MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&r, *p, r_len));
Manuel Pégourié-Gonnard6029a852015-08-11 15:44:41 +0200288 *p += r_len;
289
290 /*
291 * Verification
292 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200293 MBEDTLS_MPI_CHK(ecjpake_hash(md_info, grp, pf, G, &V, X, id, &h));
294 MBEDTLS_MPI_CHK(
295 mbedtls_ecp_muladd((mbedtls_ecp_group *)grp, &VV, &h, X, &r, G));
Manuel Pégourié-Gonnard6029a852015-08-11 15:44:41 +0200296
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200297 if (mbedtls_ecp_point_cmp(&VV, &V) != 0) {
Manuel Pégourié-Gonnard4f2cd952015-08-12 11:17:55 +0200298 ret = MBEDTLS_ERR_ECP_VERIFY_FAILED;
299 goto cleanup;
300 }
Manuel Pégourié-Gonnard6029a852015-08-11 15:44:41 +0200301
302cleanup:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200303 mbedtls_ecp_point_free(&V);
304 mbedtls_ecp_point_free(&VV);
305 mbedtls_mpi_free(&r);
306 mbedtls_mpi_free(&h);
Manuel Pégourié-Gonnard6029a852015-08-11 15:44:41 +0200307
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200308 return ret;
Manuel Pégourié-Gonnard6029a852015-08-11 15:44:41 +0200309}
310
Manuel Pégourié-Gonnardb1b250b2015-08-12 11:01:58 +0200311/*
Manuel Pégourié-Gonnard3aed1852015-08-12 14:53:56 +0200312 * Generate ZKP (7.4.2.3.2) and write it as ECSchnorrZKP (7.4.2.2.2)
313 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200314static int ecjpake_zkp_write(const mbedtls_md_info_t *md_info,
315 const mbedtls_ecp_group *grp,
316 const int pf,
317 const mbedtls_ecp_point *G,
318 const mbedtls_mpi *x,
319 const mbedtls_ecp_point *X,
320 const char *id,
321 unsigned char **p,
322 const unsigned char *end,
323 int (*f_rng)(void *, unsigned char *, size_t),
324 void *p_rng)
Manuel Pégourié-Gonnard3aed1852015-08-12 14:53:56 +0200325{
Janos Follath24eed8d2019-11-22 13:21:35 +0000326 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard3aed1852015-08-12 14:53:56 +0200327 mbedtls_ecp_point V;
328 mbedtls_mpi v;
329 mbedtls_mpi h; /* later recycled to hold r */
330 size_t len;
331
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200332 if (end < *p)
333 return MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL;
Manuel Pégourié-Gonnard3aed1852015-08-12 14:53:56 +0200334
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200335 mbedtls_ecp_point_init(&V);
336 mbedtls_mpi_init(&v);
337 mbedtls_mpi_init(&h);
Manuel Pégourié-Gonnard3aed1852015-08-12 14:53:56 +0200338
339 /* Compute signature */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200340 MBEDTLS_MPI_CHK(mbedtls_ecp_gen_keypair_base((mbedtls_ecp_group *)grp, G,
341 &v, &V, f_rng, p_rng));
342 MBEDTLS_MPI_CHK(ecjpake_hash(md_info, grp, pf, G, &V, X, id, &h));
343 MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&h, &h, x)); /* x*h */
344 MBEDTLS_MPI_CHK(mbedtls_mpi_sub_mpi(&h, &v, &h)); /* v - x*h */
345 MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&h, &h, &grp->N)); /* r */
Manuel Pégourié-Gonnard3aed1852015-08-12 14:53:56 +0200346
347 /* Write it out */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200348 MBEDTLS_MPI_CHK(
349 mbedtls_ecp_tls_write_point(grp, &V, pf, &len, *p, end - *p));
Manuel Pégourié-Gonnard3aed1852015-08-12 14:53:56 +0200350 *p += len;
351
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200352 len = mbedtls_mpi_size(&h); /* actually r */
353 if (end < *p || (size_t)(end - *p) < 1 + len || len > 255) {
Manuel Pégourié-Gonnard3aed1852015-08-12 14:53:56 +0200354 ret = MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL;
355 goto cleanup;
356 }
357
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200358 *(*p)++ = (unsigned char)(len & 0xFF);
359 MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(&h, *p, len)); /* r */
Manuel Pégourié-Gonnard3aed1852015-08-12 14:53:56 +0200360 *p += len;
361
362cleanup:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200363 mbedtls_ecp_point_free(&V);
364 mbedtls_mpi_free(&v);
365 mbedtls_mpi_free(&h);
Manuel Pégourié-Gonnard3aed1852015-08-12 14:53:56 +0200366
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200367 return ret;
Manuel Pégourié-Gonnard3aed1852015-08-12 14:53:56 +0200368}
369
370/*
Manuel Pégourié-Gonnard082767f2015-08-12 14:43:57 +0200371 * Parse a ECJPAKEKeyKP (7.4.2.2.1) and check proof
372 * Output: verified public key X
Manuel Pégourié-Gonnardb1b250b2015-08-12 11:01:58 +0200373 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200374static int ecjpake_kkp_read(const mbedtls_md_info_t *md_info,
375 const mbedtls_ecp_group *grp,
376 const int pf,
377 const mbedtls_ecp_point *G,
378 mbedtls_ecp_point *X,
379 const char *id,
380 const unsigned char **p,
381 const unsigned char *end)
Manuel Pégourié-Gonnardb1b250b2015-08-12 11:01:58 +0200382{
Janos Follath24eed8d2019-11-22 13:21:35 +0000383 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnardb1b250b2015-08-12 11:01:58 +0200384
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200385 if (end < *p)
386 return MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
Manuel Pégourié-Gonnardb1b250b2015-08-12 11:01:58 +0200387
388 /*
389 * struct {
390 * ECPoint X;
391 * ECSchnorrZKP zkp;
392 * } ECJPAKEKeyKP;
393 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200394 MBEDTLS_MPI_CHK(mbedtls_ecp_tls_read_point(grp, X, p, end - *p));
395 if (mbedtls_ecp_is_zero(X)) {
Manuel Pégourié-Gonnard30590952015-08-17 10:37:40 +0200396 ret = MBEDTLS_ERR_ECP_INVALID_KEY;
397 goto cleanup;
398 }
399
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200400 MBEDTLS_MPI_CHK(ecjpake_zkp_read(md_info, grp, pf, G, X, id, p, end));
Manuel Pégourié-Gonnardb1b250b2015-08-12 11:01:58 +0200401
402cleanup:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200403 return ret;
Manuel Pégourié-Gonnardb1b250b2015-08-12 11:01:58 +0200404}
405
406/*
407 * Generate an ECJPAKEKeyKP
408 * Output: the serialized structure, plus private/public key pair
409 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200410static int ecjpake_kkp_write(const mbedtls_md_info_t *md_info,
411 const mbedtls_ecp_group *grp,
412 const int pf,
413 const mbedtls_ecp_point *G,
414 mbedtls_mpi *x,
415 mbedtls_ecp_point *X,
416 const char *id,
417 unsigned char **p,
418 const unsigned char *end,
419 int (*f_rng)(void *, unsigned char *, size_t),
420 void *p_rng)
Manuel Pégourié-Gonnardb1b250b2015-08-12 11:01:58 +0200421{
Janos Follath24eed8d2019-11-22 13:21:35 +0000422 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnardb1b250b2015-08-12 11:01:58 +0200423 size_t len;
424
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200425 if (end < *p)
426 return MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL;
Manuel Pégourié-Gonnardb1b250b2015-08-12 11:01:58 +0200427
428 /* Generate key (7.4.2.3.1) and write it out */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200429 MBEDTLS_MPI_CHK(mbedtls_ecp_gen_keypair_base((mbedtls_ecp_group *)grp, G, x,
430 X, f_rng, p_rng));
431 MBEDTLS_MPI_CHK(
432 mbedtls_ecp_tls_write_point(grp, X, pf, &len, *p, end - *p));
Manuel Pégourié-Gonnardb1b250b2015-08-12 11:01:58 +0200433 *p += len;
434
435 /* Generate and write proof */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200436 MBEDTLS_MPI_CHK(
437 ecjpake_zkp_write(md_info, grp, pf, G, x, X, id, p, end, f_rng, p_rng));
Manuel Pégourié-Gonnardb1b250b2015-08-12 11:01:58 +0200438
439cleanup:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200440 return ret;
Manuel Pégourié-Gonnardb1b250b2015-08-12 11:01:58 +0200441}
Manuel Pégourié-Gonnard6029a852015-08-11 15:44:41 +0200442
Manuel Pégourié-Gonnard082767f2015-08-12 14:43:57 +0200443/*
444 * Read a ECJPAKEKeyKPPairList (7.4.2.3) and check proofs
445 * Ouputs: verified peer public keys Xa, Xb
446 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200447static int ecjpake_kkpp_read(const mbedtls_md_info_t *md_info,
448 const mbedtls_ecp_group *grp,
449 const int pf,
450 const mbedtls_ecp_point *G,
451 mbedtls_ecp_point *Xa,
452 mbedtls_ecp_point *Xb,
453 const char *id,
454 const unsigned char *buf,
455 size_t len)
Manuel Pégourié-Gonnard082767f2015-08-12 14:43:57 +0200456{
Janos Follath24eed8d2019-11-22 13:21:35 +0000457 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard9028c5a2015-08-12 14:51:36 +0200458 const unsigned char *p = buf;
Manuel Pégourié-Gonnard082767f2015-08-12 14:43:57 +0200459 const unsigned char *end = buf + len;
460
461 /*
462 * struct {
463 * ECJPAKEKeyKP ecjpake_key_kp_pair_list[2];
464 * } ECJPAKEKeyKPPairList;
465 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200466 MBEDTLS_MPI_CHK(ecjpake_kkp_read(md_info, grp, pf, G, Xa, id, &p, end));
467 MBEDTLS_MPI_CHK(ecjpake_kkp_read(md_info, grp, pf, G, Xb, id, &p, end));
Manuel Pégourié-Gonnard082767f2015-08-12 14:43:57 +0200468
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200469 if (p != end)
Manuel Pégourié-Gonnard082767f2015-08-12 14:43:57 +0200470 ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
471
472cleanup:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200473 return ret;
Manuel Pégourié-Gonnard082767f2015-08-12 14:43:57 +0200474}
475
476/*
477 * Generate a ECJPAKEKeyKPPairList
478 * Outputs: the serialized structure, plus two private/public key pairs
479 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200480static int ecjpake_kkpp_write(const mbedtls_md_info_t *md_info,
481 const mbedtls_ecp_group *grp,
482 const int pf,
483 const mbedtls_ecp_point *G,
484 mbedtls_mpi *xm1,
485 mbedtls_ecp_point *Xa,
486 mbedtls_mpi *xm2,
487 mbedtls_ecp_point *Xb,
488 const char *id,
489 unsigned char *buf,
490 size_t len,
491 size_t *olen,
492 int (*f_rng)(void *, unsigned char *, size_t),
493 void *p_rng)
Manuel Pégourié-Gonnard082767f2015-08-12 14:43:57 +0200494{
Janos Follath24eed8d2019-11-22 13:21:35 +0000495 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard082767f2015-08-12 14:43:57 +0200496 unsigned char *p = buf;
497 const unsigned char *end = buf + len;
498
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200499 MBEDTLS_MPI_CHK(ecjpake_kkp_write(md_info, grp, pf, G, xm1, Xa, id, &p, end,
500 f_rng, p_rng));
501 MBEDTLS_MPI_CHK(ecjpake_kkp_write(md_info, grp, pf, G, xm2, Xb, id, &p, end,
502 f_rng, p_rng));
Manuel Pégourié-Gonnard082767f2015-08-12 14:43:57 +0200503
504 *olen = p - buf;
505
506cleanup:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200507 return ret;
Manuel Pégourié-Gonnard082767f2015-08-12 14:43:57 +0200508}
509
Manuel Pégourié-Gonnard4e8bc782015-08-12 20:50:31 +0200510/*
Manuel Pégourié-Gonnardd8204a72015-08-14 13:36:55 +0200511 * Read and process the first round message
Manuel Pégourié-Gonnard4e8bc782015-08-12 20:50:31 +0200512 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200513int mbedtls_ecjpake_read_round_one(mbedtls_ecjpake_context *ctx,
514 const unsigned char *buf,
515 size_t len)
Manuel Pégourié-Gonnard4e8bc782015-08-12 20:50:31 +0200516{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200517 ECJPAKE_VALIDATE_RET(ctx != NULL);
518 ECJPAKE_VALIDATE_RET(buf != NULL);
Hanno Becker71c8e1b2018-12-14 17:09:39 +0000519
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200520 return (ecjpake_kkpp_read(ctx->md_info, &ctx->grp, ctx->point_format,
521 &ctx->grp.G, &ctx->Xp1, &ctx->Xp2, ID_PEER, buf,
522 len));
Manuel Pégourié-Gonnard4e8bc782015-08-12 20:50:31 +0200523}
524
525/*
Manuel Pégourié-Gonnardd8204a72015-08-14 13:36:55 +0200526 * Generate and write the first round message
Manuel Pégourié-Gonnard4e8bc782015-08-12 20:50:31 +0200527 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200528int mbedtls_ecjpake_write_round_one(mbedtls_ecjpake_context *ctx,
529 unsigned char *buf,
530 size_t len,
531 size_t *olen,
532 int (*f_rng)(void *,
533 unsigned char *,
534 size_t),
535 void *p_rng)
Manuel Pégourié-Gonnard4e8bc782015-08-12 20:50:31 +0200536{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200537 ECJPAKE_VALIDATE_RET(ctx != NULL);
538 ECJPAKE_VALIDATE_RET(buf != NULL);
539 ECJPAKE_VALIDATE_RET(olen != NULL);
540 ECJPAKE_VALIDATE_RET(f_rng != NULL);
Hanno Becker71c8e1b2018-12-14 17:09:39 +0000541
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200542 return (ecjpake_kkpp_write(ctx->md_info, &ctx->grp, ctx->point_format,
543 &ctx->grp.G, &ctx->xm1, &ctx->Xm1, &ctx->xm2,
544 &ctx->Xm2, ID_MINE, buf, len, olen, f_rng,
545 p_rng));
Manuel Pégourié-Gonnard4e8bc782015-08-12 20:50:31 +0200546}
547
Manuel Pégourié-Gonnardcb7cd032015-08-13 10:09:10 +0200548/*
Manuel Pégourié-Gonnardbed9e412015-08-13 18:53:59 +0200549 * Compute the sum of three points R = A + B + C
550 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200551static int ecjpake_ecp_add3(mbedtls_ecp_group *grp,
552 mbedtls_ecp_point *R,
553 const mbedtls_ecp_point *A,
554 const mbedtls_ecp_point *B,
555 const mbedtls_ecp_point *C)
Manuel Pégourié-Gonnardbed9e412015-08-13 18:53:59 +0200556{
Janos Follath24eed8d2019-11-22 13:21:35 +0000557 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnardbed9e412015-08-13 18:53:59 +0200558 mbedtls_mpi one;
559
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200560 mbedtls_mpi_init(&one);
Manuel Pégourié-Gonnardbed9e412015-08-13 18:53:59 +0200561
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200562 MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&one, 1));
563 MBEDTLS_MPI_CHK(mbedtls_ecp_muladd(grp, R, &one, A, &one, B));
564 MBEDTLS_MPI_CHK(mbedtls_ecp_muladd(grp, R, &one, R, &one, C));
Manuel Pégourié-Gonnardbed9e412015-08-13 18:53:59 +0200565
566cleanup:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200567 mbedtls_mpi_free(&one);
Manuel Pégourié-Gonnardbed9e412015-08-13 18:53:59 +0200568
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200569 return ret;
Manuel Pégourié-Gonnardbed9e412015-08-13 18:53:59 +0200570}
571
572/*
Manuel Pégourié-Gonnarde1927102015-08-14 14:20:48 +0200573 * Read and process second round message (C: 7.4.2.5, S: 7.4.2.6)
Manuel Pégourié-Gonnardcb7cd032015-08-13 10:09:10 +0200574 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200575int mbedtls_ecjpake_read_round_two(mbedtls_ecjpake_context *ctx,
576 const unsigned char *buf,
577 size_t len)
Manuel Pégourié-Gonnardcb7cd032015-08-13 10:09:10 +0200578{
Janos Follath24eed8d2019-11-22 13:21:35 +0000579 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnardcb7cd032015-08-13 10:09:10 +0200580 const unsigned char *p = buf;
581 const unsigned char *end = buf + len;
582 mbedtls_ecp_group grp;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200583 mbedtls_ecp_point G; /* C: GB, S: GA */
Hanno Becker185e5162018-12-19 09:48:50 +0000584
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200585 ECJPAKE_VALIDATE_RET(ctx != NULL);
586 ECJPAKE_VALIDATE_RET(buf != NULL);
Manuel Pégourié-Gonnardcb7cd032015-08-13 10:09:10 +0200587
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200588 mbedtls_ecp_group_init(&grp);
589 mbedtls_ecp_point_init(&G);
Manuel Pégourié-Gonnardcb7cd032015-08-13 10:09:10 +0200590
591 /*
Manuel Pégourié-Gonnarde1927102015-08-14 14:20:48 +0200592 * Server: GA = X3 + X4 + X1 (7.4.2.6.1)
593 * Client: GB = X1 + X2 + X3 (7.4.2.5.1)
594 * Unified: G = Xm1 + Xm2 + Xp1
Manuel Pégourié-Gonnardce456762015-08-14 11:54:35 +0200595 * We need that before parsing in order to check Xp as we read it
Manuel Pégourié-Gonnardcb7cd032015-08-13 10:09:10 +0200596 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200597 MBEDTLS_MPI_CHK(
598 ecjpake_ecp_add3(&ctx->grp, &G, &ctx->Xm1, &ctx->Xm2, &ctx->Xp1));
Manuel Pégourié-Gonnardcb7cd032015-08-13 10:09:10 +0200599
600 /*
601 * struct {
Manuel Pégourié-Gonnarde1927102015-08-14 14:20:48 +0200602 * ECParameters curve_params; // only client reading server msg
Manuel Pégourié-Gonnardcb7cd032015-08-13 10:09:10 +0200603 * ECJPAKEKeyKP ecjpake_key_kp;
Manuel Pégourié-Gonnarde1927102015-08-14 14:20:48 +0200604 * } Client/ServerECJPAKEParams;
Manuel Pégourié-Gonnardcb7cd032015-08-13 10:09:10 +0200605 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200606 if (ctx->role == MBEDTLS_ECJPAKE_CLIENT) {
607 MBEDTLS_MPI_CHK(mbedtls_ecp_tls_read_group(&grp, &p, len));
608 if (grp.id != ctx->grp.id) {
Manuel Pégourié-Gonnardd9802af2015-08-17 12:47:38 +0200609 ret = MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE;
610 goto cleanup;
611 }
612 }
613
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200614 MBEDTLS_MPI_CHK(ecjpake_kkp_read(ctx->md_info, &ctx->grp, ctx->point_format,
615 &G, &ctx->Xp, ID_PEER, &p, end));
Manuel Pégourié-Gonnardcb7cd032015-08-13 10:09:10 +0200616
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200617 if (p != end) {
Manuel Pégourié-Gonnardcb7cd032015-08-13 10:09:10 +0200618 ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA;
619 goto cleanup;
620 }
621
Manuel Pégourié-Gonnardcb7cd032015-08-13 10:09:10 +0200622cleanup:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200623 mbedtls_ecp_group_free(&grp);
624 mbedtls_ecp_point_free(&G);
Manuel Pégourié-Gonnardbed9e412015-08-13 18:53:59 +0200625
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200626 return ret;
Manuel Pégourié-Gonnardbed9e412015-08-13 18:53:59 +0200627}
628
629/*
Manuel Pégourié-Gonnardd0d8a932015-08-14 15:14:50 +0200630 * Compute R = +/- X * S mod N, taking care not to leak S
631 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200632static int ecjpake_mul_secret(mbedtls_mpi *R,
633 int sign,
634 const mbedtls_mpi *X,
635 const mbedtls_mpi *S,
636 const mbedtls_mpi *N,
637 int (*f_rng)(void *, unsigned char *, size_t),
638 void *p_rng)
Manuel Pégourié-Gonnardd0d8a932015-08-14 15:14:50 +0200639{
Janos Follath24eed8d2019-11-22 13:21:35 +0000640 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnardd0d8a932015-08-14 15:14:50 +0200641 mbedtls_mpi b; /* Blinding value, then s + N * blinding */
642
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200643 mbedtls_mpi_init(&b);
Manuel Pégourié-Gonnardd0d8a932015-08-14 15:14:50 +0200644
645 /* b = s + rnd-128-bit * N */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200646 MBEDTLS_MPI_CHK(mbedtls_mpi_fill_random(&b, 16, f_rng, p_rng));
647 MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&b, &b, N));
648 MBEDTLS_MPI_CHK(mbedtls_mpi_add_mpi(&b, &b, S));
Manuel Pégourié-Gonnardd0d8a932015-08-14 15:14:50 +0200649
650 /* R = sign * X * b mod N */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200651 MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(R, X, &b));
Manuel Pégourié-Gonnardd0d8a932015-08-14 15:14:50 +0200652 R->s *= sign;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200653 MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(R, R, N));
Manuel Pégourié-Gonnardd0d8a932015-08-14 15:14:50 +0200654
655cleanup:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200656 mbedtls_mpi_free(&b);
Manuel Pégourié-Gonnardd0d8a932015-08-14 15:14:50 +0200657
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200658 return ret;
Manuel Pégourié-Gonnardd0d8a932015-08-14 15:14:50 +0200659}
660
661/*
Manuel Pégourié-Gonnarde1927102015-08-14 14:20:48 +0200662 * Generate and write the second round message (S: 7.4.2.5, C: 7.4.2.6)
Manuel Pégourié-Gonnardbed9e412015-08-13 18:53:59 +0200663 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200664int mbedtls_ecjpake_write_round_two(mbedtls_ecjpake_context *ctx,
665 unsigned char *buf,
666 size_t len,
667 size_t *olen,
668 int (*f_rng)(void *,
669 unsigned char *,
670 size_t),
671 void *p_rng)
Manuel Pégourié-Gonnardbed9e412015-08-13 18:53:59 +0200672{
Janos Follath24eed8d2019-11-22 13:21:35 +0000673 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200674 mbedtls_ecp_point G; /* C: GA, S: GB */
675 mbedtls_ecp_point Xm; /* C: Xc, S: Xs */
676 mbedtls_mpi xm; /* C: xc, S: xs */
Manuel Pégourié-Gonnardbed9e412015-08-13 18:53:59 +0200677 unsigned char *p = buf;
678 const unsigned char *end = buf + len;
679 size_t ec_len;
Hanno Becker185e5162018-12-19 09:48:50 +0000680
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200681 ECJPAKE_VALIDATE_RET(ctx != NULL);
682 ECJPAKE_VALIDATE_RET(buf != NULL);
683 ECJPAKE_VALIDATE_RET(olen != NULL);
684 ECJPAKE_VALIDATE_RET(f_rng != NULL);
Manuel Pégourié-Gonnardbed9e412015-08-13 18:53:59 +0200685
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200686 mbedtls_ecp_point_init(&G);
687 mbedtls_ecp_point_init(&Xm);
688 mbedtls_mpi_init(&xm);
Manuel Pégourié-Gonnardbed9e412015-08-13 18:53:59 +0200689
690 /*
Manuel Pégourié-Gonnarde1927102015-08-14 14:20:48 +0200691 * First generate private/public key pair (S: 7.4.2.5.1, C: 7.4.2.6.1)
Manuel Pégourié-Gonnardbed9e412015-08-13 18:53:59 +0200692 *
Manuel Pégourié-Gonnarde1927102015-08-14 14:20:48 +0200693 * Client: GA = X1 + X3 + X4 | xs = x2 * s | Xc = xc * GA
694 * Server: GB = X3 + X1 + X2 | xs = x4 * s | Xs = xs * GB
695 * Unified: G = Xm1 + Xp1 + Xp2 | xm = xm2 * s | Xm = xm * G
Manuel Pégourié-Gonnardbed9e412015-08-13 18:53:59 +0200696 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200697 MBEDTLS_MPI_CHK(
698 ecjpake_ecp_add3(&ctx->grp, &G, &ctx->Xp1, &ctx->Xp2, &ctx->Xm1));
699 MBEDTLS_MPI_CHK(ecjpake_mul_secret(&xm, 1, &ctx->xm2, &ctx->s, &ctx->grp.N,
700 f_rng, p_rng));
701 MBEDTLS_MPI_CHK(mbedtls_ecp_mul(&ctx->grp, &Xm, &xm, &G, f_rng, p_rng));
Manuel Pégourié-Gonnardbed9e412015-08-13 18:53:59 +0200702
703 /*
704 * Now write things out
Manuel Pégourié-Gonnarde1927102015-08-14 14:20:48 +0200705 *
706 * struct {
707 * ECParameters curve_params; // only server writing its message
708 * ECJPAKEKeyKP ecjpake_key_kp;
709 * } Client/ServerECJPAKEParams;
Manuel Pégourié-Gonnardbed9e412015-08-13 18:53:59 +0200710 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200711 if (ctx->role == MBEDTLS_ECJPAKE_SERVER) {
712 if (end < p) {
Manuel Pégourié-Gonnarde1927102015-08-14 14:20:48 +0200713 ret = MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL;
714 goto cleanup;
715 }
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200716 MBEDTLS_MPI_CHK(
717 mbedtls_ecp_tls_write_group(&ctx->grp, &ec_len, p, end - p));
Manuel Pégourié-Gonnarde1927102015-08-14 14:20:48 +0200718 p += ec_len;
719 }
Manuel Pégourié-Gonnardbed9e412015-08-13 18:53:59 +0200720
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200721 if (end < p) {
Manuel Pégourié-Gonnardbed9e412015-08-13 18:53:59 +0200722 ret = MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL;
723 goto cleanup;
724 }
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200725 MBEDTLS_MPI_CHK(mbedtls_ecp_tls_write_point(
726 &ctx->grp, &Xm, ctx->point_format, &ec_len, p, end - p));
Manuel Pégourié-Gonnardbed9e412015-08-13 18:53:59 +0200727 p += ec_len;
728
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200729 MBEDTLS_MPI_CHK(ecjpake_zkp_write(ctx->md_info, &ctx->grp,
730 ctx->point_format, &G, &xm, &Xm, ID_MINE,
731 &p, end, f_rng, p_rng));
Manuel Pégourié-Gonnardbed9e412015-08-13 18:53:59 +0200732
733 *olen = p - buf;
734
735cleanup:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200736 mbedtls_ecp_point_free(&G);
737 mbedtls_ecp_point_free(&Xm);
738 mbedtls_mpi_free(&xm);
Manuel Pégourié-Gonnard614bd5e2015-08-13 20:19:16 +0200739
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200740 return ret;
Manuel Pégourié-Gonnard614bd5e2015-08-13 20:19:16 +0200741}
742
Manuel Pégourié-Gonnard5f188292015-08-14 10:52:39 +0200743/*
744 * Derive PMS (7.4.2.7 / 7.4.2.8)
745 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200746int mbedtls_ecjpake_derive_secret(mbedtls_ecjpake_context *ctx,
747 unsigned char *buf,
748 size_t len,
749 size_t *olen,
750 int (*f_rng)(void *, unsigned char *, size_t),
751 void *p_rng)
Manuel Pégourié-Gonnard5f188292015-08-14 10:52:39 +0200752{
Janos Follath24eed8d2019-11-22 13:21:35 +0000753 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnardc9070812015-08-14 14:48:50 +0200754 mbedtls_ecp_point K;
755 mbedtls_mpi m_xm2_s, one;
Manuel Pégourié-Gonnard5f188292015-08-14 10:52:39 +0200756 unsigned char kx[MBEDTLS_ECP_MAX_BYTES];
757 size_t x_bytes;
Hanno Becker185e5162018-12-19 09:48:50 +0000758
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200759 ECJPAKE_VALIDATE_RET(ctx != NULL);
760 ECJPAKE_VALIDATE_RET(buf != NULL);
761 ECJPAKE_VALIDATE_RET(olen != NULL);
762 ECJPAKE_VALIDATE_RET(f_rng != NULL);
Manuel Pégourié-Gonnard5f188292015-08-14 10:52:39 +0200763
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200764 *olen = mbedtls_md_get_size(ctx->md_info);
765 if (len < *olen)
766 return MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL;
Manuel Pégourié-Gonnard5f188292015-08-14 10:52:39 +0200767
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200768 mbedtls_ecp_point_init(&K);
769 mbedtls_mpi_init(&m_xm2_s);
770 mbedtls_mpi_init(&one);
Manuel Pégourié-Gonnard5f188292015-08-14 10:52:39 +0200771
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200772 MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&one, 1));
Manuel Pégourié-Gonnard5f188292015-08-14 10:52:39 +0200773
774 /*
Manuel Pégourié-Gonnardc9070812015-08-14 14:48:50 +0200775 * Client: K = ( Xs - X4 * x2 * s ) * x2
776 * Server: K = ( Xc - X2 * x4 * s ) * x4
Manuel Pégourié-Gonnardd0d8a932015-08-14 15:14:50 +0200777 * Unified: K = ( Xp - Xp2 * xm2 * s ) * xm2
Manuel Pégourié-Gonnard5f188292015-08-14 10:52:39 +0200778 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200779 MBEDTLS_MPI_CHK(ecjpake_mul_secret(&m_xm2_s, -1, &ctx->xm2, &ctx->s,
780 &ctx->grp.N, f_rng, p_rng));
781 MBEDTLS_MPI_CHK(
782 mbedtls_ecp_muladd(&ctx->grp, &K, &one, &ctx->Xp, &m_xm2_s, &ctx->Xp2));
783 MBEDTLS_MPI_CHK(
784 mbedtls_ecp_mul(&ctx->grp, &K, &ctx->xm2, &K, f_rng, p_rng));
Manuel Pégourié-Gonnard5f188292015-08-14 10:52:39 +0200785
786 /* PMS = SHA-256( K.X ) */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200787 x_bytes = (ctx->grp.pbits + 7) / 8;
788 MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(&K.X, kx, x_bytes));
789 MBEDTLS_MPI_CHK(mbedtls_md(ctx->md_info, kx, x_bytes, buf));
Manuel Pégourié-Gonnard5f188292015-08-14 10:52:39 +0200790
791cleanup:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200792 mbedtls_ecp_point_free(&K);
793 mbedtls_mpi_free(&m_xm2_s);
794 mbedtls_mpi_free(&one);
Manuel Pégourié-Gonnard5f188292015-08-14 10:52:39 +0200795
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200796 return ret;
Manuel Pégourié-Gonnard5f188292015-08-14 10:52:39 +0200797}
798
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200799# undef ID_MINE
800# undef ID_PEER
Manuel Pégourié-Gonnarde0ad57b2015-08-14 11:10:39 +0200801
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200802# endif /* ! MBEDTLS_ECJPAKE_ALT */
Manuel Pégourié-Gonnarde0ad57b2015-08-14 11:10:39 +0200803
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200804# if defined(MBEDTLS_SELF_TEST)
Manuel Pégourié-Gonnard4d8685b2015-08-05 15:44:42 +0200805
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200806# if defined(MBEDTLS_PLATFORM_C)
807# include "mbedtls/platform.h"
808# else
809# include <stdio.h>
810# define mbedtls_printf printf
811# endif
Manuel Pégourié-Gonnard4d8685b2015-08-05 15:44:42 +0200812
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200813# if !defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) || \
814 !defined(MBEDTLS_SHA256_C)
815int mbedtls_ecjpake_self_test(int verbose)
Manuel Pégourié-Gonnard3dbf2fb2015-08-06 17:24:39 +0200816{
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200817 (void)verbose;
818 return 0;
Manuel Pégourié-Gonnard3dbf2fb2015-08-06 17:24:39 +0200819}
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200820# else
Manuel Pégourié-Gonnard3dbf2fb2015-08-06 17:24:39 +0200821
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200822static const unsigned char ecjpake_test_password[] = { 0x74, 0x68, 0x72, 0x65,
823 0x61, 0x64, 0x6a, 0x70,
824 0x61, 0x6b, 0x65, 0x74,
825 0x65, 0x73, 0x74 };
Manuel Pégourié-Gonnard8d31e802015-08-13 14:44:57 +0200826
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200827# if !defined(MBEDTLS_ECJPAKE_ALT)
Steven Cooreman64f27732021-01-11 17:20:10 +0100828
Manuel Pégourié-Gonnard8d31e802015-08-13 14:44:57 +0200829static const unsigned char ecjpake_test_x1[] = {
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200830 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
831 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16,
832 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x21
Manuel Pégourié-Gonnard8d31e802015-08-13 14:44:57 +0200833};
834
835static const unsigned char ecjpake_test_x2[] = {
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200836 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b,
837 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76,
838 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x81
Manuel Pégourié-Gonnard8d31e802015-08-13 14:44:57 +0200839};
840
841static const unsigned char ecjpake_test_x3[] = {
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200842 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b,
843 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76,
844 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x81
Manuel Pégourié-Gonnard8d31e802015-08-13 14:44:57 +0200845};
846
847static const unsigned char ecjpake_test_x4[] = {
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200848 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb,
849 0xcc, 0xcd, 0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6,
850 0xd7, 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, 0xe1
Manuel Pégourié-Gonnard8d31e802015-08-13 14:44:57 +0200851};
852
Manuel Pégourié-Gonnardc9070812015-08-14 14:48:50 +0200853static const unsigned char ecjpake_test_cli_one[] = {
Manuel Pégourié-Gonnardb1b250b2015-08-12 11:01:58 +0200854 0x41, 0x04, 0xac, 0xcf, 0x01, 0x06, 0xef, 0x85, 0x8f, 0xa2, 0xd9, 0x19,
855 0x33, 0x13, 0x46, 0x80, 0x5a, 0x78, 0xb5, 0x8b, 0xba, 0xd0, 0xb8, 0x44,
856 0xe5, 0xc7, 0x89, 0x28, 0x79, 0x14, 0x61, 0x87, 0xdd, 0x26, 0x66, 0xad,
857 0xa7, 0x81, 0xbb, 0x7f, 0x11, 0x13, 0x72, 0x25, 0x1a, 0x89, 0x10, 0x62,
858 0x1f, 0x63, 0x4d, 0xf1, 0x28, 0xac, 0x48, 0xe3, 0x81, 0xfd, 0x6e, 0xf9,
859 0x06, 0x07, 0x31, 0xf6, 0x94, 0xa4, 0x41, 0x04, 0x1d, 0xd0, 0xbd, 0x5d,
860 0x45, 0x66, 0xc9, 0xbe, 0xd9, 0xce, 0x7d, 0xe7, 0x01, 0xb5, 0xe8, 0x2e,
861 0x08, 0xe8, 0x4b, 0x73, 0x04, 0x66, 0x01, 0x8a, 0xb9, 0x03, 0xc7, 0x9e,
862 0xb9, 0x82, 0x17, 0x22, 0x36, 0xc0, 0xc1, 0x72, 0x8a, 0xe4, 0xbf, 0x73,
863 0x61, 0x0d, 0x34, 0xde, 0x44, 0x24, 0x6e, 0xf3, 0xd9, 0xc0, 0x5a, 0x22,
864 0x36, 0xfb, 0x66, 0xa6, 0x58, 0x3d, 0x74, 0x49, 0x30, 0x8b, 0xab, 0xce,
865 0x20, 0x72, 0xfe, 0x16, 0x66, 0x29, 0x92, 0xe9, 0x23, 0x5c, 0x25, 0x00,
866 0x2f, 0x11, 0xb1, 0x50, 0x87, 0xb8, 0x27, 0x38, 0xe0, 0x3c, 0x94, 0x5b,
Manuel Pégourié-Gonnard082767f2015-08-12 14:43:57 +0200867 0xf7, 0xa2, 0x99, 0x5d, 0xda, 0x1e, 0x98, 0x34, 0x58, 0x41, 0x04, 0x7e,
868 0xa6, 0xe3, 0xa4, 0x48, 0x70, 0x37, 0xa9, 0xe0, 0xdb, 0xd7, 0x92, 0x62,
869 0xb2, 0xcc, 0x27, 0x3e, 0x77, 0x99, 0x30, 0xfc, 0x18, 0x40, 0x9a, 0xc5,
870 0x36, 0x1c, 0x5f, 0xe6, 0x69, 0xd7, 0x02, 0xe1, 0x47, 0x79, 0x0a, 0xeb,
871 0x4c, 0xe7, 0xfd, 0x65, 0x75, 0xab, 0x0f, 0x6c, 0x7f, 0xd1, 0xc3, 0x35,
872 0x93, 0x9a, 0xa8, 0x63, 0xba, 0x37, 0xec, 0x91, 0xb7, 0xe3, 0x2b, 0xb0,
873 0x13, 0xbb, 0x2b, 0x41, 0x04, 0xa4, 0x95, 0x58, 0xd3, 0x2e, 0xd1, 0xeb,
874 0xfc, 0x18, 0x16, 0xaf, 0x4f, 0xf0, 0x9b, 0x55, 0xfc, 0xb4, 0xca, 0x47,
875 0xb2, 0xa0, 0x2d, 0x1e, 0x7c, 0xaf, 0x11, 0x79, 0xea, 0x3f, 0xe1, 0x39,
876 0x5b, 0x22, 0xb8, 0x61, 0x96, 0x40, 0x16, 0xfa, 0xba, 0xf7, 0x2c, 0x97,
877 0x56, 0x95, 0xd9, 0x3d, 0x4d, 0xf0, 0xe5, 0x19, 0x7f, 0xe9, 0xf0, 0x40,
878 0x63, 0x4e, 0xd5, 0x97, 0x64, 0x93, 0x77, 0x87, 0xbe, 0x20, 0xbc, 0x4d,
879 0xee, 0xbb, 0xf9, 0xb8, 0xd6, 0x0a, 0x33, 0x5f, 0x04, 0x6c, 0xa3, 0xaa,
880 0x94, 0x1e, 0x45, 0x86, 0x4c, 0x7c, 0xad, 0xef, 0x9c, 0xf7, 0x5b, 0x3d,
881 0x8b, 0x01, 0x0e, 0x44, 0x3e, 0xf0
Manuel Pégourié-Gonnard3dbf2fb2015-08-06 17:24:39 +0200882};
883
Manuel Pégourié-Gonnardc9070812015-08-14 14:48:50 +0200884static const unsigned char ecjpake_test_srv_one[] = {
Manuel Pégourié-Gonnardcb7cd032015-08-13 10:09:10 +0200885 0x41, 0x04, 0x7e, 0xa6, 0xe3, 0xa4, 0x48, 0x70, 0x37, 0xa9, 0xe0, 0xdb,
886 0xd7, 0x92, 0x62, 0xb2, 0xcc, 0x27, 0x3e, 0x77, 0x99, 0x30, 0xfc, 0x18,
887 0x40, 0x9a, 0xc5, 0x36, 0x1c, 0x5f, 0xe6, 0x69, 0xd7, 0x02, 0xe1, 0x47,
888 0x79, 0x0a, 0xeb, 0x4c, 0xe7, 0xfd, 0x65, 0x75, 0xab, 0x0f, 0x6c, 0x7f,
889 0xd1, 0xc3, 0x35, 0x93, 0x9a, 0xa8, 0x63, 0xba, 0x37, 0xec, 0x91, 0xb7,
890 0xe3, 0x2b, 0xb0, 0x13, 0xbb, 0x2b, 0x41, 0x04, 0x09, 0xf8, 0x5b, 0x3d,
891 0x20, 0xeb, 0xd7, 0x88, 0x5c, 0xe4, 0x64, 0xc0, 0x8d, 0x05, 0x6d, 0x64,
892 0x28, 0xfe, 0x4d, 0xd9, 0x28, 0x7a, 0xa3, 0x65, 0xf1, 0x31, 0xf4, 0x36,
893 0x0f, 0xf3, 0x86, 0xd8, 0x46, 0x89, 0x8b, 0xc4, 0xb4, 0x15, 0x83, 0xc2,
894 0xa5, 0x19, 0x7f, 0x65, 0xd7, 0x87, 0x42, 0x74, 0x6c, 0x12, 0xa5, 0xec,
895 0x0a, 0x4f, 0xfe, 0x2f, 0x27, 0x0a, 0x75, 0x0a, 0x1d, 0x8f, 0xb5, 0x16,
896 0x20, 0x93, 0x4d, 0x74, 0xeb, 0x43, 0xe5, 0x4d, 0xf4, 0x24, 0xfd, 0x96,
897 0x30, 0x6c, 0x01, 0x17, 0xbf, 0x13, 0x1a, 0xfa, 0xbf, 0x90, 0xa9, 0xd3,
898 0x3d, 0x11, 0x98, 0xd9, 0x05, 0x19, 0x37, 0x35, 0x14, 0x41, 0x04, 0x19,
899 0x0a, 0x07, 0x70, 0x0f, 0xfa, 0x4b, 0xe6, 0xae, 0x1d, 0x79, 0xee, 0x0f,
900 0x06, 0xae, 0xb5, 0x44, 0xcd, 0x5a, 0xdd, 0xaa, 0xbe, 0xdf, 0x70, 0xf8,
901 0x62, 0x33, 0x21, 0x33, 0x2c, 0x54, 0xf3, 0x55, 0xf0, 0xfb, 0xfe, 0xc7,
902 0x83, 0xed, 0x35, 0x9e, 0x5d, 0x0b, 0xf7, 0x37, 0x7a, 0x0f, 0xc4, 0xea,
903 0x7a, 0xce, 0x47, 0x3c, 0x9c, 0x11, 0x2b, 0x41, 0xcc, 0xd4, 0x1a, 0xc5,
904 0x6a, 0x56, 0x12, 0x41, 0x04, 0x36, 0x0a, 0x1c, 0xea, 0x33, 0xfc, 0xe6,
905 0x41, 0x15, 0x64, 0x58, 0xe0, 0xa4, 0xea, 0xc2, 0x19, 0xe9, 0x68, 0x31,
906 0xe6, 0xae, 0xbc, 0x88, 0xb3, 0xf3, 0x75, 0x2f, 0x93, 0xa0, 0x28, 0x1d,
907 0x1b, 0xf1, 0xfb, 0x10, 0x60, 0x51, 0xdb, 0x96, 0x94, 0xa8, 0xd6, 0xe8,
908 0x62, 0xa5, 0xef, 0x13, 0x24, 0xa3, 0xd9, 0xe2, 0x78, 0x94, 0xf1, 0xee,
909 0x4f, 0x7c, 0x59, 0x19, 0x99, 0x65, 0xa8, 0xdd, 0x4a, 0x20, 0x91, 0x84,
910 0x7d, 0x2d, 0x22, 0xdf, 0x3e, 0xe5, 0x5f, 0xaa, 0x2a, 0x3f, 0xb3, 0x3f,
911 0xd2, 0xd1, 0xe0, 0x55, 0xa0, 0x7a, 0x7c, 0x61, 0xec, 0xfb, 0x8d, 0x80,
912 0xec, 0x00, 0xc2, 0xc9, 0xeb, 0x12
913};
914
Manuel Pégourié-Gonnardc9070812015-08-14 14:48:50 +0200915static const unsigned char ecjpake_test_srv_two[] = {
Manuel Pégourié-Gonnardcb7cd032015-08-13 10:09:10 +0200916 0x03, 0x00, 0x17, 0x41, 0x04, 0x0f, 0xb2, 0x2b, 0x1d, 0x5d, 0x11, 0x23,
917 0xe0, 0xef, 0x9f, 0xeb, 0x9d, 0x8a, 0x2e, 0x59, 0x0a, 0x1f, 0x4d, 0x7c,
918 0xed, 0x2c, 0x2b, 0x06, 0x58, 0x6e, 0x8f, 0x2a, 0x16, 0xd4, 0xeb, 0x2f,
919 0xda, 0x43, 0x28, 0xa2, 0x0b, 0x07, 0xd8, 0xfd, 0x66, 0x76, 0x54, 0xca,
920 0x18, 0xc5, 0x4e, 0x32, 0xa3, 0x33, 0xa0, 0x84, 0x54, 0x51, 0xe9, 0x26,
921 0xee, 0x88, 0x04, 0xfd, 0x7a, 0xf0, 0xaa, 0xa7, 0xa6, 0x41, 0x04, 0x55,
922 0x16, 0xea, 0x3e, 0x54, 0xa0, 0xd5, 0xd8, 0xb2, 0xce, 0x78, 0x6b, 0x38,
923 0xd3, 0x83, 0x37, 0x00, 0x29, 0xa5, 0xdb, 0xe4, 0x45, 0x9c, 0x9d, 0xd6,
924 0x01, 0xb4, 0x08, 0xa2, 0x4a, 0xe6, 0x46, 0x5c, 0x8a, 0xc9, 0x05, 0xb9,
925 0xeb, 0x03, 0xb5, 0xd3, 0x69, 0x1c, 0x13, 0x9e, 0xf8, 0x3f, 0x1c, 0xd4,
926 0x20, 0x0f, 0x6c, 0x9c, 0xd4, 0xec, 0x39, 0x22, 0x18, 0xa5, 0x9e, 0xd2,
927 0x43, 0xd3, 0xc8, 0x20, 0xff, 0x72, 0x4a, 0x9a, 0x70, 0xb8, 0x8c, 0xb8,
928 0x6f, 0x20, 0xb4, 0x34, 0xc6, 0x86, 0x5a, 0xa1, 0xcd, 0x79, 0x06, 0xdd,
929 0x7c, 0x9b, 0xce, 0x35, 0x25, 0xf5, 0x08, 0x27, 0x6f, 0x26, 0x83, 0x6c
930};
931
Manuel Pégourié-Gonnardc9070812015-08-14 14:48:50 +0200932static const unsigned char ecjpake_test_cli_two[] = {
Manuel Pégourié-Gonnardec0eece2015-08-13 19:13:20 +0200933 0x41, 0x04, 0x69, 0xd5, 0x4e, 0xe8, 0x5e, 0x90, 0xce, 0x3f, 0x12, 0x46,
934 0x74, 0x2d, 0xe5, 0x07, 0xe9, 0x39, 0xe8, 0x1d, 0x1d, 0xc1, 0xc5, 0xcb,
935 0x98, 0x8b, 0x58, 0xc3, 0x10, 0xc9, 0xfd, 0xd9, 0x52, 0x4d, 0x93, 0x72,
936 0x0b, 0x45, 0x54, 0x1c, 0x83, 0xee, 0x88, 0x41, 0x19, 0x1d, 0xa7, 0xce,
937 0xd8, 0x6e, 0x33, 0x12, 0xd4, 0x36, 0x23, 0xc1, 0xd6, 0x3e, 0x74, 0x98,
938 0x9a, 0xba, 0x4a, 0xff, 0xd1, 0xee, 0x41, 0x04, 0x07, 0x7e, 0x8c, 0x31,
939 0xe2, 0x0e, 0x6b, 0xed, 0xb7, 0x60, 0xc1, 0x35, 0x93, 0xe6, 0x9f, 0x15,
940 0xbe, 0x85, 0xc2, 0x7d, 0x68, 0xcd, 0x09, 0xcc, 0xb8, 0xc4, 0x18, 0x36,
941 0x08, 0x91, 0x7c, 0x5c, 0x3d, 0x40, 0x9f, 0xac, 0x39, 0xfe, 0xfe, 0xe8,
942 0x2f, 0x72, 0x92, 0xd3, 0x6f, 0x0d, 0x23, 0xe0, 0x55, 0x91, 0x3f, 0x45,
943 0xa5, 0x2b, 0x85, 0xdd, 0x8a, 0x20, 0x52, 0xe9, 0xe1, 0x29, 0xbb, 0x4d,
944 0x20, 0x0f, 0x01, 0x1f, 0x19, 0x48, 0x35, 0x35, 0xa6, 0xe8, 0x9a, 0x58,
945 0x0c, 0x9b, 0x00, 0x03, 0xba, 0xf2, 0x14, 0x62, 0xec, 0xe9, 0x1a, 0x82,
946 0xcc, 0x38, 0xdb, 0xdc, 0xae, 0x60, 0xd9, 0xc5, 0x4c
947};
948
Manuel Pégourié-Gonnard5f188292015-08-14 10:52:39 +0200949static const unsigned char ecjpake_test_pms[] = {
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200950 0xf3, 0xd4, 0x7f, 0x59, 0x98, 0x44, 0xdb, 0x92, 0xa5, 0x69, 0xbb,
951 0xe7, 0x98, 0x1e, 0x39, 0xd9, 0x31, 0xfd, 0x74, 0x3b, 0xf2, 0x2e,
952 0x98, 0xf9, 0xb4, 0x38, 0xf7, 0x19, 0xd3, 0xc4, 0xf3, 0x51
Manuel Pégourié-Gonnard5f188292015-08-14 10:52:39 +0200953};
954
Manuel Pégourié-Gonnardaa3ed6f2021-06-15 11:29:26 +0200955/*
956 * PRNG for test - !!!INSECURE NEVER USE IN PRODUCTION!!!
957 *
958 * This is the linear congruential generator from numerical recipes,
959 * except we only use the low byte as the output. See
960 * https://en.wikipedia.org/wiki/Linear_congruential_generator#Parameters_in_common_use
961 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200962static int self_test_rng(void *ctx, unsigned char *out, size_t len)
Manuel Pégourié-Gonnardaa3ed6f2021-06-15 11:29:26 +0200963{
964 static uint32_t state = 42;
965
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200966 (void)ctx;
Manuel Pégourié-Gonnardaa3ed6f2021-06-15 11:29:26 +0200967
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200968 for (size_t i = 0; i < len; i++) {
Manuel Pégourié-Gonnardaa3ed6f2021-06-15 11:29:26 +0200969 state = state * 1664525u + 1013904223u;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200970 out[i] = (unsigned char)state;
Manuel Pégourié-Gonnardaa3ed6f2021-06-15 11:29:26 +0200971 }
972
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200973 return 0;
Manuel Pégourié-Gonnardaa3ed6f2021-06-15 11:29:26 +0200974}
975
Antonin Décimo36e89b52019-01-23 15:24:37 +0100976/* Load my private keys and generate the corresponding public keys */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200977static int ecjpake_test_load(mbedtls_ecjpake_context *ctx,
978 const unsigned char *xm1,
979 size_t len1,
980 const unsigned char *xm2,
981 size_t len2)
Manuel Pégourié-Gonnarde2d3a4e2015-08-14 12:03:04 +0200982{
Janos Follath24eed8d2019-11-22 13:21:35 +0000983 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnarde2d3a4e2015-08-14 12:03:04 +0200984
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200985 MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&ctx->xm1, xm1, len1));
986 MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&ctx->xm2, xm2, len2));
987 MBEDTLS_MPI_CHK(mbedtls_ecp_mul(&ctx->grp, &ctx->Xm1, &ctx->xm1,
988 &ctx->grp.G, self_test_rng, NULL));
989 MBEDTLS_MPI_CHK(mbedtls_ecp_mul(&ctx->grp, &ctx->Xm2, &ctx->xm2,
990 &ctx->grp.G, self_test_rng, NULL));
Manuel Pégourié-Gonnarde2d3a4e2015-08-14 12:03:04 +0200991
992cleanup:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200993 return ret;
Manuel Pégourié-Gonnarde2d3a4e2015-08-14 12:03:04 +0200994}
995
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +0200996# endif /* ! MBEDTLS_ECJPAKE_ALT */
Steven Cooreman64f27732021-01-11 17:20:10 +0100997
Manuel Pégourié-Gonnard8489f172015-08-07 17:47:39 +0200998/* For tests we don't need a secure RNG;
999 * use the LGC from Numerical Recipes for simplicity */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001000static int ecjpake_lgc(void *p, unsigned char *out, size_t len)
Manuel Pégourié-Gonnard8489f172015-08-07 17:47:39 +02001001{
1002 static uint32_t x = 42;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001003 (void)p;
Manuel Pégourié-Gonnard8489f172015-08-07 17:47:39 +02001004
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001005 while (len > 0) {
Manuel Pégourié-Gonnard8489f172015-08-07 17:47:39 +02001006 size_t use_len = len > 4 ? 4 : len;
1007 x = 1664525 * x + 1013904223;
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001008 memcpy(out, &x, use_len);
Manuel Pégourié-Gonnard8489f172015-08-07 17:47:39 +02001009 out += use_len;
1010 len -= use_len;
1011 }
1012
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001013 return 0;
Manuel Pégourié-Gonnard8489f172015-08-07 17:47:39 +02001014}
1015
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001016# define TEST_ASSERT(x) \
1017 do { \
1018 if (x) \
1019 ret = 0; \
1020 else { \
1021 ret = 1; \
1022 goto cleanup; \
1023 } \
1024 } while (0)
Manuel Pégourié-Gonnardb1b250b2015-08-12 11:01:58 +02001025
Manuel Pégourié-Gonnard4d8685b2015-08-05 15:44:42 +02001026/*
1027 * Checkup routine
1028 */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001029int mbedtls_ecjpake_self_test(int verbose)
Manuel Pégourié-Gonnard4d8685b2015-08-05 15:44:42 +02001030{
Janos Follath24eed8d2019-11-22 13:21:35 +00001031 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard8d31e802015-08-13 14:44:57 +02001032 mbedtls_ecjpake_context cli;
1033 mbedtls_ecjpake_context srv;
Manuel Pégourié-Gonnard5f188292015-08-14 10:52:39 +02001034 unsigned char buf[512], pms[32];
1035 size_t len, pmslen;
Manuel Pégourié-Gonnard4d8685b2015-08-05 15:44:42 +02001036
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001037 mbedtls_ecjpake_init(&cli);
1038 mbedtls_ecjpake_init(&srv);
Manuel Pégourié-Gonnard3dbf2fb2015-08-06 17:24:39 +02001039
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001040 if (verbose != 0)
1041 mbedtls_printf(" ECJPAKE test #0 (setup): ");
Manuel Pégourié-Gonnardcb7cd032015-08-13 10:09:10 +02001042
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001043 TEST_ASSERT(
1044 mbedtls_ecjpake_setup(&cli, MBEDTLS_ECJPAKE_CLIENT, MBEDTLS_MD_SHA256,
1045 MBEDTLS_ECP_DP_SECP256R1, ecjpake_test_password,
1046 sizeof(ecjpake_test_password)) == 0);
Manuel Pégourié-Gonnard3dbf2fb2015-08-06 17:24:39 +02001047
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001048 TEST_ASSERT(
1049 mbedtls_ecjpake_setup(&srv, MBEDTLS_ECJPAKE_SERVER, MBEDTLS_MD_SHA256,
1050 MBEDTLS_ECP_DP_SECP256R1, ecjpake_test_password,
1051 sizeof(ecjpake_test_password)) == 0);
Manuel Pégourié-Gonnard8d31e802015-08-13 14:44:57 +02001052
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001053 if (verbose != 0)
1054 mbedtls_printf("passed\n");
Manuel Pégourié-Gonnard8d31e802015-08-13 14:44:57 +02001055
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001056 if (verbose != 0)
1057 mbedtls_printf(" ECJPAKE test #1 (random handshake): ");
Manuel Pégourié-Gonnard8d31e802015-08-13 14:44:57 +02001058
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001059 TEST_ASSERT(mbedtls_ecjpake_write_round_one(&cli, buf, sizeof(buf), &len,
1060 ecjpake_lgc, NULL) == 0);
Manuel Pégourié-Gonnard8d31e802015-08-13 14:44:57 +02001061
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001062 TEST_ASSERT(mbedtls_ecjpake_read_round_one(&srv, buf, len) == 0);
Manuel Pégourié-Gonnard8d31e802015-08-13 14:44:57 +02001063
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001064 TEST_ASSERT(mbedtls_ecjpake_write_round_one(&srv, buf, sizeof(buf), &len,
1065 ecjpake_lgc, NULL) == 0);
Manuel Pégourié-Gonnard8d31e802015-08-13 14:44:57 +02001066
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001067 TEST_ASSERT(mbedtls_ecjpake_read_round_one(&cli, buf, len) == 0);
Manuel Pégourié-Gonnard8d31e802015-08-13 14:44:57 +02001068
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001069 TEST_ASSERT(mbedtls_ecjpake_write_round_two(&srv, buf, sizeof(buf), &len,
1070 ecjpake_lgc, NULL) == 0);
Manuel Pégourié-Gonnardbed9e412015-08-13 18:53:59 +02001071
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001072 TEST_ASSERT(mbedtls_ecjpake_read_round_two(&cli, buf, len) == 0);
Manuel Pégourié-Gonnardbed9e412015-08-13 18:53:59 +02001073
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001074 TEST_ASSERT(mbedtls_ecjpake_derive_secret(&cli, pms, sizeof(pms), &pmslen,
1075 ecjpake_lgc, NULL) == 0);
Manuel Pégourié-Gonnard5f188292015-08-14 10:52:39 +02001076
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001077 TEST_ASSERT(mbedtls_ecjpake_write_round_two(&cli, buf, sizeof(buf), &len,
1078 ecjpake_lgc, NULL) == 0);
Manuel Pégourié-Gonnard614bd5e2015-08-13 20:19:16 +02001079
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001080 TEST_ASSERT(mbedtls_ecjpake_read_round_two(&srv, buf, len) == 0);
Manuel Pégourié-Gonnard614bd5e2015-08-13 20:19:16 +02001081
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001082 TEST_ASSERT(mbedtls_ecjpake_derive_secret(&srv, buf, sizeof(buf), &len,
1083 ecjpake_lgc, NULL) == 0);
Manuel Pégourié-Gonnard5f188292015-08-14 10:52:39 +02001084
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001085 TEST_ASSERT(len == pmslen);
1086 TEST_ASSERT(memcmp(buf, pms, len) == 0);
Manuel Pégourié-Gonnard5f188292015-08-14 10:52:39 +02001087
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001088 if (verbose != 0)
1089 mbedtls_printf("passed\n");
Manuel Pégourié-Gonnard8d31e802015-08-13 14:44:57 +02001090
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001091# if !defined(MBEDTLS_ECJPAKE_ALT)
Steven Cooreman64f27732021-01-11 17:20:10 +01001092 /* 'reference handshake' tests can only be run against implementations
1093 * for which we have 100% control over how the random ephemeral keys
1094 * are generated. This is only the case for the internal mbed TLS
1095 * implementation, so these tests are skipped in case the internal
1096 * implementation is swapped out for an alternative one. */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001097 if (verbose != 0)
1098 mbedtls_printf(" ECJPAKE test #2 (reference handshake): ");
Manuel Pégourié-Gonnard8d31e802015-08-13 14:44:57 +02001099
Manuel Pégourié-Gonnardc9070812015-08-14 14:48:50 +02001100 /* Simulate generation of round one */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001101 MBEDTLS_MPI_CHK(ecjpake_test_load(&cli, ecjpake_test_x1,
1102 sizeof(ecjpake_test_x1), ecjpake_test_x2,
1103 sizeof(ecjpake_test_x2)));
Manuel Pégourié-Gonnard8d31e802015-08-13 14:44:57 +02001104
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001105 MBEDTLS_MPI_CHK(ecjpake_test_load(&srv, ecjpake_test_x3,
1106 sizeof(ecjpake_test_x3), ecjpake_test_x4,
1107 sizeof(ecjpake_test_x4)));
Manuel Pégourié-Gonnard8d31e802015-08-13 14:44:57 +02001108
Manuel Pégourié-Gonnardc9070812015-08-14 14:48:50 +02001109 /* Read round one */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001110 TEST_ASSERT(mbedtls_ecjpake_read_round_one(&srv, ecjpake_test_cli_one,
1111 sizeof(ecjpake_test_cli_one)) ==
1112 0);
Manuel Pégourié-Gonnardc9070812015-08-14 14:48:50 +02001113
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001114 TEST_ASSERT(mbedtls_ecjpake_read_round_one(&cli, ecjpake_test_srv_one,
1115 sizeof(ecjpake_test_srv_one)) ==
1116 0);
Manuel Pégourié-Gonnard3dbf2fb2015-08-06 17:24:39 +02001117
Manuel Pégourié-Gonnardc9070812015-08-14 14:48:50 +02001118 /* Skip generation of round two, read round two */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001119 TEST_ASSERT(mbedtls_ecjpake_read_round_two(&cli, ecjpake_test_srv_two,
1120 sizeof(ecjpake_test_srv_two)) ==
1121 0);
Manuel Pégourié-Gonnard6029a852015-08-11 15:44:41 +02001122
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001123 TEST_ASSERT(mbedtls_ecjpake_read_round_two(&srv, ecjpake_test_cli_two,
1124 sizeof(ecjpake_test_cli_two)) ==
1125 0);
Manuel Pégourié-Gonnardec0eece2015-08-13 19:13:20 +02001126
Manuel Pégourié-Gonnard5f188292015-08-14 10:52:39 +02001127 /* Server derives PMS */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001128 TEST_ASSERT(mbedtls_ecjpake_derive_secret(&srv, buf, sizeof(buf), &len,
1129 ecjpake_lgc, NULL) == 0);
Manuel Pégourié-Gonnard5f188292015-08-14 10:52:39 +02001130
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001131 TEST_ASSERT(len == sizeof(ecjpake_test_pms));
1132 TEST_ASSERT(memcmp(buf, ecjpake_test_pms, len) == 0);
Manuel Pégourié-Gonnard5f188292015-08-14 10:52:39 +02001133
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001134 memset(buf, 0, len); /* Avoid interferences with next step */
Manuel Pégourié-Gonnard5f188292015-08-14 10:52:39 +02001135
1136 /* Client derives PMS */
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001137 TEST_ASSERT(mbedtls_ecjpake_derive_secret(&cli, buf, sizeof(buf), &len,
1138 ecjpake_lgc, NULL) == 0);
Manuel Pégourié-Gonnard5f188292015-08-14 10:52:39 +02001139
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001140 TEST_ASSERT(len == sizeof(ecjpake_test_pms));
1141 TEST_ASSERT(memcmp(buf, ecjpake_test_pms, len) == 0);
Manuel Pégourié-Gonnard5f188292015-08-14 10:52:39 +02001142
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001143 if (verbose != 0)
1144 mbedtls_printf("passed\n");
1145# endif /* ! MBEDTLS_ECJPAKE_ALT */
Manuel Pégourié-Gonnard8489f172015-08-07 17:47:39 +02001146
Manuel Pégourié-Gonnard3dbf2fb2015-08-06 17:24:39 +02001147cleanup:
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001148 mbedtls_ecjpake_free(&cli);
1149 mbedtls_ecjpake_free(&srv);
Manuel Pégourié-Gonnard3dbf2fb2015-08-06 17:24:39 +02001150
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001151 if (ret != 0) {
1152 if (verbose != 0)
1153 mbedtls_printf("failed\n");
Manuel Pégourié-Gonnard3dbf2fb2015-08-06 17:24:39 +02001154
1155 ret = 1;
1156 }
Manuel Pégourié-Gonnard4d8685b2015-08-05 15:44:42 +02001157
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001158 if (verbose != 0)
1159 mbedtls_printf("\n");
Manuel Pégourié-Gonnard4d8685b2015-08-05 15:44:42 +02001160
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001161 return ret;
Manuel Pégourié-Gonnard4d8685b2015-08-05 15:44:42 +02001162}
1163
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001164# undef TEST_ASSERT
Manuel Pégourié-Gonnardb1b250b2015-08-12 11:01:58 +02001165
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001166# endif /* MBEDTLS_ECP_DP_SECP256R1_ENABLED && MBEDTLS_SHA256_C */
Manuel Pégourié-Gonnard3dbf2fb2015-08-06 17:24:39 +02001167
Mateusz Starzykc0eabdc2021-08-03 14:09:02 +02001168# endif /* MBEDTLS_SELF_TEST */
Manuel Pégourié-Gonnard4d8685b2015-08-05 15:44:42 +02001169
1170#endif /* MBEDTLS_ECJPAKE_C */