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