mirror of
				https://gitlab.com/qemu-project/ipxe.git
				synced 2025-10-30 07:56:50 +08:00 
			
		
		
		
	Compare commits
	
		
			4 Commits
		
	
	
		
			d88eb0a193
			...
			c2f21a2185
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| c2f21a2185 | |||
| c9291bc5c7 | |||
| df7ec31766 | |||
| cc38d7dd3e | 
| @ -26,6 +26,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); | ||||
| #include <stdint.h> | ||||
| #include <string.h> | ||||
| #include <assert.h> | ||||
| #include <stdio.h> | ||||
| #include <ipxe/profile.h> | ||||
| #include <ipxe/bigint.h> | ||||
|  | ||||
| @ -38,6 +39,52 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); | ||||
| static struct profiler bigint_mod_profiler __profiler = | ||||
| 	{ .name = "bigint_mod" }; | ||||
|  | ||||
| /** Minimum number of least significant bytes included in transcription */ | ||||
| #define BIGINT_NTOA_LSB_MIN 16 | ||||
|  | ||||
| /** | ||||
|  * Transcribe big integer (for debugging) | ||||
|  * | ||||
|  * @v value0		Element 0 of big integer to be transcribed | ||||
|  * @v size		Number of elements | ||||
|  * @ret string		Big integer in string form (may be abbreviated) | ||||
|  */ | ||||
| const char * bigint_ntoa_raw ( const bigint_element_t *value0, | ||||
| 			       unsigned int size ) { | ||||
| 	const bigint_t ( size ) __attribute__ (( may_alias )) | ||||
| 		*value = ( ( const void * ) value0 ); | ||||
| 	bigint_element_t element; | ||||
| 	static char buf[256]; | ||||
| 	unsigned int count; | ||||
| 	int threshold; | ||||
| 	uint8_t byte; | ||||
| 	char *tmp; | ||||
| 	int i; | ||||
|  | ||||
| 	/* Calculate abbreviation threshold, if any */ | ||||
| 	count = ( size * sizeof ( element ) ); | ||||
| 	threshold = count; | ||||
| 	if ( count >= ( ( sizeof ( buf ) - 1 /* NUL */ ) / 2 /* "xx" */ ) ) { | ||||
| 		threshold -= ( ( sizeof ( buf ) - 3 /* "..." */ | ||||
| 				 - ( BIGINT_NTOA_LSB_MIN * 2 /* "xx" */ ) | ||||
| 				 - 1 /* NUL */ ) / 2 /* "xx" */ ); | ||||
| 	} | ||||
|  | ||||
| 	/* Transcribe bytes, abbreviating with "..." if necessary */ | ||||
| 	for ( tmp = buf, i = ( count - 1 ) ; i >= 0 ; i-- ) { | ||||
| 		element = value->element[ i / sizeof ( element ) ]; | ||||
| 		byte = ( element >> ( 8 * ( i % sizeof ( element ) ) ) ); | ||||
| 		tmp += sprintf ( tmp, "%02x", byte ); | ||||
| 		if ( i == threshold ) { | ||||
| 			tmp += sprintf ( tmp, "..." ); | ||||
| 			i = BIGINT_NTOA_LSB_MIN; | ||||
| 		} | ||||
| 	} | ||||
| 	assert ( tmp < ( buf + sizeof ( buf ) ) ); | ||||
|  | ||||
| 	return buf; | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Conditionally swap big integers (in constant time) | ||||
|  * | ||||
|  | ||||
							
								
								
									
										66
									
								
								src/crypto/ecdhe.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										66
									
								
								src/crypto/ecdhe.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,66 @@ | ||||
| /* | ||||
|  * Copyright (C) 2025 Michael Brown <mbrown@fensystems.co.uk>. | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or | ||||
|  * modify it under the terms of the GNU General Public License as | ||||
|  * published by the Free Software Foundation; either version 2 of the | ||||
|  * License, or any later version. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, but | ||||
|  * WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | ||||
|  * General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program; if not, write to the Free Software | ||||
|  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA | ||||
|  * 02110-1301, USA. | ||||
|  * | ||||
|  * You can also choose to distribute this program under the terms of | ||||
|  * the Unmodified Binary Distribution Licence (as given in the file | ||||
|  * COPYING.UBDL), provided that you have satisfied its requirements. | ||||
|  */ | ||||
|  | ||||
| FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); | ||||
|  | ||||
| /** @file | ||||
|  * | ||||
|  * Elliptic Curve Ephemeral Diffie-Hellman (ECDHE) key exchange | ||||
|  * | ||||
|  */ | ||||
|  | ||||
| #include <string.h> | ||||
| #include <ipxe/ecdhe.h> | ||||
|  | ||||
| /** | ||||
|  * Calculate ECDHE key | ||||
|  * | ||||
|  * @v curve		Elliptic curve | ||||
|  * @v partner		Partner public curve point | ||||
|  * @v private		Private key | ||||
|  * @v public		Public curve point to fill in (may overlap partner key) | ||||
|  * @v shared		Shared secret curve point to fill in | ||||
|  * @ret rc		Return status code | ||||
|  */ | ||||
| int ecdhe_key ( struct elliptic_curve *curve, const void *partner, | ||||
| 		const void *private, void *public, void *shared ) { | ||||
| 	int rc; | ||||
|  | ||||
| 	/* Construct shared key */ | ||||
| 	if ( ( rc = elliptic_multiply ( curve, partner, private, | ||||
| 					shared ) ) != 0 ) { | ||||
| 		DBGC ( curve, "CURVE %s could not generate shared key: %s\n", | ||||
| 		       curve->name, strerror ( rc ) ); | ||||
| 		return rc; | ||||
| 	} | ||||
|  | ||||
| 	/* Construct public key */ | ||||
| 	if ( ( rc = elliptic_multiply ( curve, NULL, private, | ||||
| 					public ) ) != 0 ) { | ||||
| 		DBGC ( curve, "CURVE %s could not generate public key: %s\n", | ||||
| 		       curve->name, strerror ( rc ) ); | ||||
| 		return rc; | ||||
| 	} | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
| @ -42,4 +42,5 @@ struct asn1_algorithm x25519_algorithm __asn1_algorithm = { | ||||
| struct tls_named_curve tls_x25519_named_curve __tls_named_curve ( 01 ) = { | ||||
| 	.curve = &x25519_curve, | ||||
| 	.code = htons ( TLS_NAMED_CURVE_X25519 ), | ||||
| 	.pre_master_secret_len = sizeof ( struct x25519_value ), | ||||
| }; | ||||
|  | ||||
| @ -839,6 +839,7 @@ static int x25519_curve_multiply ( const void *base, const void *scalar, | ||||
| /** X25519 elliptic curve */ | ||||
| struct elliptic_curve x25519_curve = { | ||||
| 	.name = "x25519", | ||||
| 	.pointsize = sizeof ( struct x25519_value ), | ||||
| 	.keysize = sizeof ( struct x25519_value ), | ||||
| 	.multiply = x25519_curve_multiply, | ||||
| }; | ||||
|  | ||||
| @ -40,6 +40,17 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); | ||||
| #define bigint_size( bigint )						\ | ||||
| 	( sizeof ( *(bigint) ) / sizeof ( (bigint)->element[0] ) ) | ||||
|  | ||||
| /** | ||||
|  * Transcribe big integer (for debugging) | ||||
|  * | ||||
|  * @v value		Big integer to be transcribed | ||||
|  * @ret string		Big integer in string form (may be abbreviated) | ||||
|  */ | ||||
| #define bigint_ntoa( value ) ( {					\ | ||||
| 	unsigned int size = bigint_size (value);			\ | ||||
| 	bigint_ntoa_raw ( (value)->element, size );			\ | ||||
| 	} ) | ||||
|  | ||||
| /** | ||||
|  * Initialise big integer | ||||
|  * | ||||
| @ -360,6 +371,8 @@ bigint_msb_is_set_raw ( const bigint_element_t *value0, unsigned int size ) { | ||||
| 	return ( !! ( value->element[index] & ( 1UL << subindex ) ) ); | ||||
| } | ||||
|  | ||||
| const char * bigint_ntoa_raw ( const bigint_element_t *value0, | ||||
| 			       unsigned int size ); | ||||
| void bigint_init_raw ( bigint_element_t *value0, unsigned int size, | ||||
| 		       const void *data, size_t len ); | ||||
| void bigint_done_raw ( const bigint_element_t *value0, unsigned int size, | ||||
|  | ||||
| @ -184,7 +184,9 @@ struct pubkey_algorithm { | ||||
| struct elliptic_curve { | ||||
| 	/** Curve name */ | ||||
| 	const char *name; | ||||
| 	/** Key size */ | ||||
| 	/** Point (and public key) size */ | ||||
| 	size_t pointsize; | ||||
| 	/** Scalar (and private key) size */ | ||||
| 	size_t keysize; | ||||
| 	/** Multiply scalar by curve point | ||||
| 	 * | ||||
|  | ||||
							
								
								
									
										17
									
								
								src/include/ipxe/ecdhe.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								src/include/ipxe/ecdhe.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,17 @@ | ||||
| #ifndef _IPXE_ECDHE_H | ||||
| #define _IPXE_ECDHE_H | ||||
|  | ||||
| /** @file | ||||
|  * | ||||
|  * Elliptic Curve Ephemeral Diffie-Hellman (ECDHE) key exchange | ||||
|  * | ||||
|  */ | ||||
|  | ||||
| FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); | ||||
|  | ||||
| #include <ipxe/crypto.h> | ||||
|  | ||||
| extern int ecdhe_key ( struct elliptic_curve *curve, const void *partner, | ||||
| 		       const void *private, void *public, void *shared ); | ||||
|  | ||||
| #endif /* _IPXE_ECDHE_H */ | ||||
| @ -218,12 +218,19 @@ struct tls_cipher_suite { | ||||
| /** TLS named curved type */ | ||||
| #define TLS_NAMED_CURVE_TYPE 3 | ||||
|  | ||||
| /** TLS uncompressed curve point format */ | ||||
| #define TLS_POINT_FORMAT_UNCOMPRESSED 4 | ||||
|  | ||||
| /** A TLS named curve */ | ||||
| struct tls_named_curve { | ||||
| 	/** Elliptic curve */ | ||||
| 	struct elliptic_curve *curve; | ||||
| 	/** Numeric code (in network-endian order) */ | ||||
| 	uint16_t code; | ||||
| 	/** Curve point format byte (if any) */ | ||||
| 	uint8_t format; | ||||
| 	/** Pre-master secret length */ | ||||
| 	uint8_t pre_master_secret_len; | ||||
| }; | ||||
|  | ||||
| /** TLS named curve table */ | ||||
|  | ||||
| @ -50,6 +50,7 @@ FILE_LICENCE ( GPL2_OR_LATER ); | ||||
| #include <ipxe/validator.h> | ||||
| #include <ipxe/job.h> | ||||
| #include <ipxe/dhe.h> | ||||
| #include <ipxe/ecdhe.h> | ||||
| #include <ipxe/tls.h> | ||||
| #include <config/crypto.h> | ||||
|  | ||||
| @ -1670,6 +1671,9 @@ static int tls_send_client_key_exchange_ecdhe ( struct tls_connection *tls ) { | ||||
| 		uint8_t public[0]; | ||||
| 	} __attribute__ (( packed )) *ecdh; | ||||
| 	size_t param_len; | ||||
| 	size_t pointsize; | ||||
| 	size_t keysize; | ||||
| 	size_t offset; | ||||
| 	int rc; | ||||
|  | ||||
| 	/* Parse ServerKeyExchange record */ | ||||
| @ -1705,9 +1709,13 @@ static int tls_send_client_key_exchange_ecdhe ( struct tls_connection *tls ) { | ||||
| 			   tls->server.exchange_len ); | ||||
| 		return -ENOTSUP_CURVE; | ||||
| 	} | ||||
| 	DBGC ( tls, "TLS %p using named curve %s\n", tls, curve->curve->name ); | ||||
| 	pointsize = curve->curve->pointsize; | ||||
| 	keysize = curve->curve->keysize; | ||||
| 	offset = ( curve->format ? 1 : 0 ); | ||||
|  | ||||
| 	/* Check key length */ | ||||
| 	if ( ecdh->public_len != curve->curve->keysize ) { | ||||
| 	if ( ecdh->public_len != ( offset + pointsize ) ) { | ||||
| 		DBGC ( tls, "TLS %p invalid %s key\n", | ||||
| 		       tls, curve->curve->name ); | ||||
| 		DBGC_HDA ( tls, 0, tls->server.exchange, | ||||
| @ -1715,15 +1723,23 @@ static int tls_send_client_key_exchange_ecdhe ( struct tls_connection *tls ) { | ||||
| 		return -EINVAL_KEY_EXCHANGE; | ||||
| 	} | ||||
|  | ||||
| 	/* Check curve point format byte (if present) */ | ||||
| 	if ( curve->format && ( ecdh->public[0] != curve->format ) ) { | ||||
| 		DBGC ( tls, "TLS %p invalid %s curve point format\n", | ||||
| 		       tls, curve->curve->name ); | ||||
| 		DBGC_HDA ( tls, 0, tls->server.exchange, | ||||
| 			   tls->server.exchange_len ); | ||||
| 		return -EINVAL_KEY_EXCHANGE; | ||||
| 	} | ||||
|  | ||||
| 	/* Construct pre-master secret and ClientKeyExchange record */ | ||||
| 	{ | ||||
| 		size_t len = curve->curve->keysize; | ||||
| 		uint8_t private[len]; | ||||
| 		uint8_t pre_master_secret[len]; | ||||
| 		uint8_t private[keysize]; | ||||
| 		uint8_t pre_master_secret[pointsize]; | ||||
| 		struct { | ||||
| 			uint32_t type_length; | ||||
| 			uint8_t public_len; | ||||
| 			uint8_t public[len]; | ||||
| 			uint8_t public[ecdh->public_len]; | ||||
| 		} __attribute__ (( packed )) key_xchg; | ||||
|  | ||||
| 		/* Generate ephemeral private key */ | ||||
| @ -1732,30 +1748,27 @@ static int tls_send_client_key_exchange_ecdhe ( struct tls_connection *tls ) { | ||||
| 			return rc; | ||||
| 		} | ||||
|  | ||||
| 		/* Calculate pre-master secret */ | ||||
| 		if ( ( rc = elliptic_multiply ( curve->curve, | ||||
| 						ecdh->public, private, | ||||
| 						pre_master_secret ) ) != 0 ) { | ||||
| 		/* Exchange keys */ | ||||
| 		if ( ( rc = ecdhe_key ( curve->curve, ( ecdh->public + offset ), | ||||
| 					private, ( key_xchg.public + offset ), | ||||
| 					pre_master_secret ) ) != 0 ) { | ||||
| 			DBGC ( tls, "TLS %p could not exchange ECDHE key: %s\n", | ||||
| 			       tls, strerror ( rc ) ); | ||||
| 			return rc; | ||||
| 		} | ||||
|  | ||||
| 		/* Generate master secret */ | ||||
| 		tls_generate_master_secret ( tls, pre_master_secret, len ); | ||||
| 		tls_generate_master_secret ( tls, pre_master_secret, | ||||
| 					     curve->pre_master_secret_len ); | ||||
|  | ||||
| 		/* Generate Client Key Exchange record */ | ||||
| 		key_xchg.type_length = | ||||
| 			( cpu_to_le32 ( TLS_CLIENT_KEY_EXCHANGE ) | | ||||
| 			  htonl ( sizeof ( key_xchg ) - | ||||
| 				  sizeof ( key_xchg.type_length ) ) ); | ||||
| 		key_xchg.public_len = len; | ||||
| 		if ( ( rc = elliptic_multiply ( curve->curve, NULL, private, | ||||
| 						key_xchg.public ) ) != 0 ) { | ||||
| 			DBGC ( tls, "TLS %p could not generate ECDHE key: %s\n", | ||||
| 			       tls, strerror ( rc ) ); | ||||
| 			return rc; | ||||
| 		} | ||||
| 		key_xchg.public_len = sizeof ( key_xchg.public ); | ||||
| 		if ( curve->format ) | ||||
| 			key_xchg.public[0] = curve->format; | ||||
|  | ||||
| 		/* Transmit Client Key Exchange record */ | ||||
| 		if ( ( rc = tls_send_handshake ( tls, &key_xchg, | ||||
|  | ||||
							
								
								
									
										76
									
								
								src/tests/elliptic_test.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										76
									
								
								src/tests/elliptic_test.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,76 @@ | ||||
| /* | ||||
|  * Copyright (C) 2025 Michael Brown <mbrown@fensystems.co.uk>. | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or | ||||
|  * modify it under the terms of the GNU General Public License as | ||||
|  * published by the Free Software Foundation; either version 2 of the | ||||
|  * License, or any later version. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, but | ||||
|  * WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | ||||
|  * General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program; if not, write to the Free Software | ||||
|  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA | ||||
|  * 02110-1301, USA. | ||||
|  * | ||||
|  * You can also choose to distribute this program under the terms of | ||||
|  * the Unmodified Binary Distribution Licence (as given in the file | ||||
|  * COPYING.UBDL), provided that you have satisfied its requirements. | ||||
|  */ | ||||
|  | ||||
| FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); | ||||
|  | ||||
| /** @file | ||||
|  * | ||||
|  * Elliptic curve self-tests | ||||
|  * | ||||
|  */ | ||||
|  | ||||
| /* Forcibly enable assertions */ | ||||
| #undef NDEBUG | ||||
|  | ||||
| #include <stdint.h> | ||||
| #include <string.h> | ||||
| #include <assert.h> | ||||
| #include <ipxe/crypto.h> | ||||
| #include <ipxe/test.h> | ||||
| #include "elliptic_test.h" | ||||
|  | ||||
| /** | ||||
|  * Report elliptic curve point multiplication test result | ||||
|  * | ||||
|  * @v test		Elliptic curve point multiplication test | ||||
|  * @v file		Test code file | ||||
|  * @v line		Test code line | ||||
|  */ | ||||
| void elliptic_okx ( struct elliptic_test *test, const char *file, | ||||
| 		    unsigned int line ) { | ||||
| 	struct elliptic_curve *curve = test->curve; | ||||
| 	size_t pointsize = curve->pointsize; | ||||
| 	size_t keysize = curve->keysize; | ||||
| 	uint8_t actual[pointsize]; | ||||
| 	int rc; | ||||
|  | ||||
| 	/* Sanity checks */ | ||||
| 	okx ( ( test->base_len == pointsize ) || ( ! test->base_len ), | ||||
| 	      file, line ); | ||||
| 	okx ( test->scalar_len == keysize, file, line ); | ||||
| 	okx ( ( test->expected_len == pointsize ) || ( ! test->expected_len ), | ||||
| 	      file, line ); | ||||
|  | ||||
| 	/* Perform point multiplication */ | ||||
| 	rc = elliptic_multiply ( curve, ( test->base_len ? test->base : NULL ), | ||||
| 				 test->scalar, actual ); | ||||
| 	if ( test->expected_len ) { | ||||
| 		okx ( rc == 0, file, line ); | ||||
| 	} else { | ||||
| 		okx ( rc != 0, file, line ); | ||||
| 	} | ||||
|  | ||||
| 	/* Check expected result */ | ||||
| 	okx ( memcmp ( actual, test->expected, test->expected_len ) == 0, | ||||
| 	      file, line ); | ||||
| } | ||||
							
								
								
									
										77
									
								
								src/tests/elliptic_test.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										77
									
								
								src/tests/elliptic_test.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,77 @@ | ||||
| #ifndef _ELLIPTIC_TEST_H | ||||
| #define _ELLIPTIC_TEST_H | ||||
|  | ||||
| FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); | ||||
|  | ||||
| #include <stdint.h> | ||||
| #include <ipxe/crypto.h> | ||||
| #include <ipxe/test.h> | ||||
|  | ||||
| /** An elliptic curve point multiplication test */ | ||||
| struct elliptic_test { | ||||
| 	/** Elliptic curve */ | ||||
| 	struct elliptic_curve *curve; | ||||
| 	/** Base point */ | ||||
| 	const void *base; | ||||
| 	/** Length of base point (or 0 to use generator) */ | ||||
| 	size_t base_len; | ||||
| 	/** Scalar multiple */ | ||||
| 	const void *scalar; | ||||
| 	/** Length of scalar multiple */ | ||||
| 	size_t scalar_len; | ||||
| 	/** Expected result point */ | ||||
| 	const void *expected; | ||||
| 	/** Length of expected result point (or 0 to expect failure) */ | ||||
| 	size_t expected_len; | ||||
| }; | ||||
|  | ||||
| /** Define inline base point */ | ||||
| #define BASE(...) { __VA_ARGS__ } | ||||
|  | ||||
| /** Define base point to be curve's generator */ | ||||
| #define BASE_GENERATOR BASE() | ||||
|  | ||||
| /** Define inline scalar multiple */ | ||||
| #define SCALAR(...) { __VA_ARGS__ } | ||||
|  | ||||
| /** Define inline expected result point */ | ||||
| #define EXPECTED(...) { __VA_ARGS__ } | ||||
|  | ||||
| /** Define result as an expected failure */ | ||||
| #define EXPECTED_FAIL EXPECTED() | ||||
|  | ||||
| /** | ||||
|  * Define an elliptic curve point multiplication test | ||||
|  * | ||||
|  * @v name		Test name | ||||
|  * @v CURVE		Elliptic curve | ||||
|  * @v BASE		Base point | ||||
|  * @v SCALAR		Scalar multiple | ||||
|  * @v EXPECTED		Expected result point | ||||
|  * @ret test		Elliptic curve point multiplication test | ||||
|  */ | ||||
| #define ELLIPTIC_TEST( name, CURVE, BASE, SCALAR, EXPECTED )		\ | ||||
| 	static const uint8_t name ## _base[] = BASE;			\ | ||||
| 	static const uint8_t name ## _scalar[] = SCALAR;		\ | ||||
| 	static const uint8_t name ## _expected[] = EXPECTED;		\ | ||||
| 	static struct elliptic_test name = {				\ | ||||
| 		.curve = CURVE,						\ | ||||
| 		.base = name ## _base,					\ | ||||
| 		.base_len = sizeof ( name ## _base ),			\ | ||||
| 		.scalar = name ## _scalar,				\ | ||||
| 		.scalar_len = sizeof ( name ## _scalar ),		\ | ||||
| 		.expected = name ## _expected,				\ | ||||
| 		.expected_len = sizeof ( name ## _expected ),		\ | ||||
| 	}; | ||||
|  | ||||
| extern void elliptic_okx ( struct elliptic_test *test, const char *file, | ||||
| 			   unsigned int line ); | ||||
|  | ||||
| /** | ||||
|  * Report an elliptic curve point multiplication test result | ||||
|  * | ||||
|  * @v test		Elliptic curve point multiplication test | ||||
|  */ | ||||
| #define elliptic_ok( test ) elliptic_okx ( test, __FILE__, __LINE__ ) | ||||
|  | ||||
| #endif /* _ELLIPTIC_TEST_H */ | ||||
		Reference in New Issue
	
	Block a user
	