blob: 6719be1c37c0de74535c9b5cf86549b1876c6426 [file] [log] [blame]
kXuanb2b3ec42021-04-10 14:56:39 +08001#!/usr/bin/env python3
2"""
3Purpose
4
5This script dumps comb table of ec curve. When you add a new ec curve, you
6can use this script to generate codes to define `<curve>_T` in ecp_curves.c
7"""
8
9# Copyright The Mbed TLS Contributors
10# SPDX-License-Identifier: Apache-2.0
11#
12# Licensed under the Apache License, Version 2.0 (the "License"); you may
13# not use this file except in compliance with the License.
14# You may obtain a copy of the License at
15#
16# http://www.apache.org/licenses/LICENSE-2.0
17#
18# Unless required by applicable law or agreed to in writing, software
19# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
20# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
21# See the License for the specific language governing permissions and
22# limitations under the License.
23
24import os
25import subprocess
26import sys
27import tempfile
28
29HOW_TO_ADD_NEW_CURVE = """
30If you are trying to add new curve, you can follow these steps:
31
321. Define curve parameters (<curve>_p, <curve>_gx, etc...) in ecp_curves.c.
332. Add a macro to define <curve>_T to NULL following these parameters.
343. Build mbedcrypto
354. Run this script with an argument of new curve
365. Copy the output of this script into ecp_curves.c and replace the macro added
37 in Step 2
386. Rebuild and test if everything is ok
39
40Replace the <curve> in the above with the name of the curve you want to add."""
41
42CC = os.getenv('CC', 'cc')
43MBEDTLS_LIBRARY_PATH = os.getenv('MBEDTLS_LIBRARY_PATH', "library")
44
45SRC_DUMP_COMB_TABLE = r'''
46#include <stdio.h>
47#include <stdlib.h>
48#include "mbedtls/ecp.h"
49#include "mbedtls/error.h"
50
51static void dump_mpi_initialize( const char *name, const mbedtls_mpi *d )
52{
53 uint8_t buf[128] = {0};
54 size_t olen;
55 uint8_t *p;
56
57 olen = mbedtls_mpi_size( d );
58 mbedtls_mpi_write_binary_le( d, buf, olen );
59 printf("static const mbedtls_mpi_uint %s[] = {\n", name);
60 for (p = buf; p < buf + olen; p += 8) {
61 printf( " BYTES_TO_T_UINT_8( 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X ),\n",
62 p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7] );
63 }
64 printf("};\n");
65}
66
67static void dump_T( const mbedtls_ecp_group *grp )
68{
69 char name[128];
70
71 printf( "#if MBEDTLS_ECP_FIXED_POINT_OPTIM == 1\n" );
72
73 for (size_t i = 0; i < grp->T_size; ++i) {
74 snprintf( name, sizeof(name), "%s_T_%zu_X", CURVE_NAME, i );
75 dump_mpi_initialize( name, &grp->T[i].X );
76
77 snprintf( name, sizeof(name), "%s_T_%zu_Y", CURVE_NAME, i );
78 dump_mpi_initialize( name, &grp->T[i].Y );
79 }
80 printf( "static const mbedtls_ecp_point %s_T[%zu] = {\n", CURVE_NAME, grp->T_size );
81 size_t olen;
82 for (size_t i = 0; i < grp->T_size; ++i) {
83 int z;
84 if ( mbedtls_mpi_cmp_int(&grp->T[i].Z, 0) == 0 ) {
85 z = 0;
86 } else if ( mbedtls_mpi_cmp_int(&grp->T[i].Z, 1) == 0 ) {
87 z = 1;
88 } else {
89 fprintf( stderr, "Unexpected value of Z (i = %d)\n", (int)i );
90 exit( 1 );
91 }
92 printf( " ECP_POINT_INIT_XY_Z%d(%s_T_%zu_X, %s_T_%zu_Y),\n",
93 z,
94 CURVE_NAME, i,
95 CURVE_NAME, i
96 );
97 }
98 printf("};\n#endif\n\n");
99}
100
101int main()
102{
103 int rc;
104 mbedtls_mpi m;
105 mbedtls_ecp_point R;
106 mbedtls_ecp_group grp;
107
108 mbedtls_ecp_group_init( &grp );
109 rc = mbedtls_ecp_group_load( &grp, CURVE_ID );
110 if (rc != 0) {
111 char buf[100];
112 mbedtls_strerror( rc, buf, sizeof(buf) );
113 fprintf( stderr, "mbedtls_ecp_group_load: %s (-0x%x)\n", buf, -rc );
114 return 1;
115 }
116 grp.T = NULL;
117 mbedtls_ecp_point_init( &R );
118 mbedtls_mpi_init( &m);
119 mbedtls_mpi_lset( &m, 1 );
120 rc = mbedtls_ecp_mul( &grp, &R, &m, &grp.G, NULL, NULL );
121 if ( rc != 0 ) {
122 char buf[100];
123 mbedtls_strerror( rc, buf, sizeof(buf) );
124 fprintf( stderr, "mbedtls_ecp_mul: %s (-0x%x)\n", buf, -rc );
125 return 1;
126 }
127 if ( grp.T == NULL ) {
128 fprintf( stderr, "grp.T is not generated. Please make sure"
Bence Szépkútibb0cfeb2021-05-28 09:42:25 +0200129 "MBEDTLS_ECP_FIXED_POINT_OPTIM is enabled in mbedtls_config.h\n" );
kXuanb2b3ec42021-04-10 14:56:39 +0800130 return 1;
131 }
132 dump_T( &grp );
133 return 0;
134}
135'''
136
137SRC_DUMP_KNOWN_CURVE = r'''
138#include <stdio.h>
139#include <stdlib.h>
140#include "mbedtls/ecp.h"
141
142int main() {
143 const mbedtls_ecp_curve_info *info = mbedtls_ecp_curve_list();
144 mbedtls_ecp_group grp;
145
146 mbedtls_ecp_group_init( &grp );
147 while ( info->name != NULL ) {
148 mbedtls_ecp_group_load( &grp, info->grp_id );
149 if ( mbedtls_ecp_get_type(&grp) == MBEDTLS_ECP_TYPE_SHORT_WEIERSTRASS ) {
150 printf( " %s", info->name );
151 }
152 info++;
153 }
154 printf( "\n" );
155 return 0;
156}
157'''
158
159
160def join_src_path(*args):
161 return os.path.normpath(os.path.join(os.path.dirname(__file__), "..", *args))
162
163
164def run_c_source(src, cflags):
165 """
166 Compile and run C source code
167 :param src: the c language code to run
168 :param cflags: additional cflags passing to compiler
169 :return:
170 """
171 binname = tempfile.mktemp(prefix="mbedtls")
172 fd, srcname = tempfile.mkstemp(prefix="mbedtls", suffix=".c")
173 srcfile = os.fdopen(fd, mode="w")
174 srcfile.write(src)
175 srcfile.close()
176 args = [CC,
177 *cflags,
178 '-I' + join_src_path("include"),
179 "-o", binname,
180 '-L' + MBEDTLS_LIBRARY_PATH,
181 srcname,
182 '-lmbedcrypto']
183
184 p = subprocess.run(args=args, check=False)
185 if p.returncode != 0:
186 return False
187 p = subprocess.run(args=[binname], check=False, env={
188 'LD_LIBRARY_PATH': MBEDTLS_LIBRARY_PATH
189 })
190 if p.returncode != 0:
191 return False
192 os.unlink(srcname)
193 os.unlink(binname)
194 return True
195
196
197def compute_curve(curve):
198 """compute comb table for curve"""
199 r = run_c_source(
200 SRC_DUMP_COMB_TABLE,
201 [
202 '-g',
203 '-DCURVE_ID=MBEDTLS_ECP_DP_%s' % curve.upper(),
204 '-DCURVE_NAME="%s"' % curve.lower(),
205 ])
206 if not r:
207 print("""\
208Unable to compile and run utility.""", file=sys.stderr)
209 sys.exit(1)
210
211
212def usage():
213 print("""
214Usage: python %s <curve>...
215
216Arguments:
217 curve Specify one or more curve names (e.g secp256r1)
218
219All possible curves: """ % sys.argv[0])
220 run_c_source(SRC_DUMP_KNOWN_CURVE, [])
221 print("""
222Environment Variable:
223 CC Specify which c compile to use to compile utility.
224 MBEDTLS_LIBRARY_PATH
225 Specify the path to mbedcrypto library. (e.g. build/library/)
226
227How to add a new curve: %s""" % HOW_TO_ADD_NEW_CURVE)
228
229
230def run_main():
231 shared_lib_path = os.path.normpath(os.path.join(MBEDTLS_LIBRARY_PATH, "libmbedcrypto.so"))
232 static_lib_path = os.path.normpath(os.path.join(MBEDTLS_LIBRARY_PATH, "libmbedcrypto.a"))
233 if not os.path.exists(shared_lib_path) and not os.path.exists(static_lib_path):
234 print("Warning: both '%s' and '%s' are not exists. This script will use "
235 "the library from your system instead of the library compiled by "
236 "this source directory.\n"
237 "You can specify library path using environment variable "
238 "'MBEDTLS_LIBRARY_PATH'." % (shared_lib_path, static_lib_path),
239 file=sys.stderr)
240
241 if len(sys.argv) <= 1:
242 usage()
243 else:
244 for curve in sys.argv[1:]:
245 compute_curve(curve)
246
247
248if __name__ == '__main__':
249 run_main()