blob: 398f4d9071ec7f08f248f6262920feca9c1d1801 [file] [log] [blame]
Manuel Pégourié-Gonnard4d8685b2015-08-05 15:44:42 +02001/*
2 * Elliptic curve J-PAKE
3 *
4 * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
5 * 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.
18 *
19 * This file is part of mbed TLS (https://tls.mbed.org)
20 */
21
22/*
23 * EC-JPAKE is defined in Chapter 7.4 of the Thread specification.
Manuel Pégourié-Gonnard3dbf2fb2015-08-06 17:24:39 +020024 * References below are base on the draft-1.0.0 spec.
Manuel Pégourié-Gonnard4d8685b2015-08-05 15:44:42 +020025 */
26
27#if !defined(MBEDTLS_CONFIG_FILE)
28#include "mbedtls/config.h"
29#else
30#include MBEDTLS_CONFIG_FILE
31#endif
32
33#if defined(MBEDTLS_ECJPAKE_C)
34
35#include "mbedtls/ecjpake.h"
36
Manuel Pégourié-Gonnard3dbf2fb2015-08-06 17:24:39 +020037#include <string.h>
38
39/*
40 * Write a point plus its length to a buffer
41 */
42static int ecjpake_write_len_point( unsigned char **p,
43 const unsigned char *end,
44 const mbedtls_ecp_group *grp,
45 const mbedtls_ecp_point *P )
46{
47 int ret;
48 size_t len;
49
50 /* Need at least 4 for length plus 1 for point */
51 if( end < *p || end - *p < 5 )
52 return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL );
53
54 ret = mbedtls_ecp_point_write_binary( grp, P, MBEDTLS_ECP_PF_UNCOMPRESSED,
55 &len, *p + 4, end - ( *p + 4 ) );
56 if( ret != 0 )
57 return( ret );
58
59 (*p)[0] = (unsigned char)( ( len >> 24 ) & 0xFF );
60 (*p)[1] = (unsigned char)( ( len >> 16 ) & 0xFF );
61 (*p)[2] = (unsigned char)( ( len >> 8 ) & 0xFF );
62 (*p)[3] = (unsigned char)( ( len ) & 0xFF );
63
64 *p += 4 + len;
65
66 return( 0 );
67}
68
69/*
70 * Size of the temporary buffer for ecjpake_hash:
71 * 3 EC points plus their length, plus ID (6 bytes)
72 */
73#define ECJPAKE_HASH_BUF_LEN ( 3 * ( 4 + MBEDTLS_ECP_MAX_PT_LEN ) + 6 )
74
75/*
76 * Compute hash for ZKP (7.4.2.2.2.1)
77 */
78static int ecjpake_hash( const mbedtls_md_info_t *md_info,
79 const mbedtls_ecp_group *grp,
80 const mbedtls_ecp_point *G,
81 const mbedtls_ecp_point *V,
82 const mbedtls_ecp_point *X,
83 const char *id,
84 mbedtls_mpi *h )
85{
86 int ret;
87 unsigned char buf[ECJPAKE_HASH_BUF_LEN];
88 unsigned char *p = buf;
89 const unsigned char *end = buf + sizeof( buf );
90 size_t id_len = strlen( id );
91 unsigned char hash[MBEDTLS_MD_MAX_SIZE];
92
93 /* Write things to temporary buffer */
94 MBEDTLS_MPI_CHK( ecjpake_write_len_point( &p, end, grp, G ) );
95 MBEDTLS_MPI_CHK( ecjpake_write_len_point( &p, end, grp, V ) );
96 MBEDTLS_MPI_CHK( ecjpake_write_len_point( &p, end, grp, X ) );
97
98 if( end < p || (size_t)( end - p ) < id_len )
99 return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL );
100
101 *p++ = (unsigned char)( ( id_len >> 24 ) & 0xFF );
102 *p++ = (unsigned char)( ( id_len >> 16 ) & 0xFF );
103 *p++ = (unsigned char)( ( id_len >> 8 ) & 0xFF );
104 *p++ = (unsigned char)( ( id_len ) & 0xFF );
105
106 memcpy( p, id, id_len );
107 p += id_len;
108
109 /* Compute hash */
110 mbedtls_md( md_info, buf, p - buf, hash );
111
112 /* Turn it into an integer mod n */
113 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( h, hash,
114 mbedtls_md_get_size( md_info ) ) );
115 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( h, h, &grp->N ) );
116
117cleanup:
118 return( ret );
119}
120
Manuel Pégourié-Gonnard4d8685b2015-08-05 15:44:42 +0200121#if defined(MBEDTLS_SELF_TEST)
122
123#if defined(MBEDTLS_PLATFORM_C)
124#include "mbedtls/platform.h"
125#else
126#include <stdio.h>
127#define mbedtls_printf printf
128#endif
129
Manuel Pégourié-Gonnard3dbf2fb2015-08-06 17:24:39 +0200130#if !defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) || \
131 !defined(MBEDTLS_SHA256_C)
132int mbedtls_ecjpake_self_test( int verbose )
133{
134 (void) verbose;
135 return( 0 );
136}
137#else
138
139static const unsigned char ecjpake_test_G[] = {
140 0x04, 0x6b, 0x17, 0xd1, 0xf2, 0xe1, 0x2c, 0x42, 0x47, 0xf8, 0xbc, 0xe6,
141 0xe5, 0x63, 0xa4, 0x40, 0xf2, 0x77, 0x03, 0x7d, 0x81, 0x2d, 0xeb, 0x33,
142 0xa0, 0xf4, 0xa1, 0x39, 0x45, 0xd8, 0x98, 0xc2, 0x96, 0x4f, 0xe3, 0x42,
143 0xe2, 0xfe, 0x1a, 0x7f, 0x9b, 0x8e, 0xe7, 0xeb, 0x4a, 0x7c, 0x0f, 0x9e,
144 0x16, 0x2b, 0xce, 0x33, 0x57, 0x6b, 0x31, 0x5e, 0xce, 0xcb, 0xb6, 0x40,
145 0x68, 0x37, 0xbf, 0x51, 0xf5
146};
147
148static const unsigned char ecjpake_test_V[] = {
149 0x04, 0xfa, 0x9a, 0x24, 0x9d, 0x73, 0x6e, 0x30, 0x28, 0xd1, 0x2d, 0xf1,
150 0xdc, 0xfa, 0x22, 0xd1, 0xed, 0x62, 0x82, 0xbf, 0xab, 0x27, 0x7c, 0x7c,
151 0x52, 0x56, 0xf3, 0xfd, 0x38, 0x07, 0xa5, 0xae, 0xe0, 0x72, 0xfb, 0x4d,
152 0x9c, 0x2b, 0xd6, 0xa4, 0x70, 0xf7, 0xb4, 0xd0, 0xbd, 0xfb, 0x4a, 0x94,
153 0x96, 0xcf, 0xcd, 0xd3, 0x53, 0xf9, 0x90, 0x3c, 0x0a, 0x69, 0xa4, 0x4b,
154 0x18, 0xc6, 0xd2, 0x9b, 0xb8
155};
156
157static const unsigned char ecjpake_test_X[] = {
158 0x04, 0x52, 0xa4, 0xda, 0x90, 0xa5, 0x15, 0x7f, 0xc0, 0xe5, 0x1f, 0x79,
159 0x4b, 0xe3, 0xbb, 0x3f, 0x1d, 0xf8, 0xdf, 0xb1, 0xe3, 0x18, 0xa8, 0x10,
160 0xf2, 0x05, 0x2e, 0x64, 0xa8, 0xe8, 0x35, 0x64, 0xe8, 0xe2, 0x8c, 0x17,
161 0x15, 0xab, 0xf7, 0x8d, 0x1f, 0x8b, 0x18, 0x99, 0x6d, 0x6a, 0xb7, 0xbd,
162 0xcc, 0xbe, 0x52, 0x08, 0x1a, 0x3a, 0xe7, 0x65, 0x4b, 0xdf, 0x66, 0x62,
163 0xf5, 0x74, 0xe0, 0xfd, 0x80
164};
165
166static const unsigned char ecjpake_test_h[] = {
167 0xec, 0xf3, 0x24, 0x46, 0x16, 0xce, 0xa5, 0x34, 0x58, 0x46, 0xd2, 0x45,
168 0xba, 0x27, 0x63, 0x36, 0x50, 0xc4, 0x70, 0x3d, 0x56, 0x0c, 0x7a, 0x7c,
169 0x51, 0x69, 0xfe, 0xa7, 0xa3, 0xf7, 0x79, 0x10
170};
171
Manuel Pégourié-Gonnard4d8685b2015-08-05 15:44:42 +0200172/*
173 * Checkup routine
174 */
175int mbedtls_ecjpake_self_test( int verbose )
176{
177 int ret;
Manuel Pégourié-Gonnard3dbf2fb2015-08-06 17:24:39 +0200178 mbedtls_ecp_group grp;
179 mbedtls_ecp_point G, V, X;
180 mbedtls_mpi h, h_ref;
181 const mbedtls_md_info_t *md_info;
Manuel Pégourié-Gonnard4d8685b2015-08-05 15:44:42 +0200182
Manuel Pégourié-Gonnard3dbf2fb2015-08-06 17:24:39 +0200183 mbedtls_ecp_group_init( &grp );
184 mbedtls_ecp_point_init( &G );
185 mbedtls_ecp_point_init( &V );
186 mbedtls_ecp_point_init( &X );
187 mbedtls_mpi_init( &h_ref );
188 mbedtls_mpi_init( &h );
189
190 if( verbose != 0 )
191 mbedtls_printf( " ECJPAKE test #1 (hash): " );
192
193 md_info = mbedtls_md_info_from_type( MBEDTLS_MD_SHA256 );
194 MBEDTLS_MPI_CHK( mbedtls_ecp_group_load( &grp, MBEDTLS_ECP_DP_SECP256R1 ) );
195 MBEDTLS_MPI_CHK( mbedtls_ecp_point_read_binary( &grp, &G, ecjpake_test_G,
196 sizeof( ecjpake_test_G ) ) );
197 MBEDTLS_MPI_CHK( mbedtls_ecp_point_read_binary( &grp, &V, ecjpake_test_V,
198 sizeof( ecjpake_test_V ) ) );
199 MBEDTLS_MPI_CHK( mbedtls_ecp_point_read_binary( &grp, &X, ecjpake_test_X,
200 sizeof( ecjpake_test_X ) ) );
201 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &h_ref, ecjpake_test_h,
202 sizeof( ecjpake_test_h ) ) );
203
204 MBEDTLS_MPI_CHK( ecjpake_hash( md_info, &grp, &G, &V, &X, "client", &h ) );
205
206 if( mbedtls_mpi_cmp_mpi( &h, &h_ref ) != 0 )
207 {
208 ret = 1;
209 goto cleanup;
210 }
211
212 if( verbose != 0 )
213 mbedtls_printf( "passed\n" );
214
215cleanup:
216 mbedtls_ecp_group_free( &grp );
217 mbedtls_ecp_point_free( &G );
218 mbedtls_ecp_point_free( &V );
219 mbedtls_ecp_point_free( &X );
220 mbedtls_mpi_free( &h_ref );
221 mbedtls_mpi_free( &h );
222
223 if( ret != 0 )
224 {
225 if( verbose != 0 )
226 mbedtls_printf( "failed\n" );
227
228 ret = 1;
229 }
Manuel Pégourié-Gonnard4d8685b2015-08-05 15:44:42 +0200230
231 if( verbose != 0 )
232 mbedtls_printf( "\n" );
233
234 return( ret );
235}
236
Manuel Pégourié-Gonnard3dbf2fb2015-08-06 17:24:39 +0200237#endif /* MBEDTLS_ECP_DP_SECP256R1_ENABLED && MBEDTLS_SHA256_C */
238
Manuel Pégourié-Gonnard4d8685b2015-08-05 15:44:42 +0200239#endif /* MBEDTLS_SELF_TEST */
240
241#endif /* MBEDTLS_ECJPAKE_C */