mirror of
https://github.com/ipxe/ipxe
synced 2026-07-01 00:04:54 +03:00
[crypto] Provide X25519 as a generic key exchange algorithm
Provide X25519 as a generic key exchange algorithm (independent of the elliptic curve abstraction). The existing RFC7748 test vectors are not structured in a way amenable to treatment as a generic key exchange algorithm. Retain these test vectors unaltered for completeness, add the single "Alice/Bob" key exchange example presented in RFC7748, and add a selection of test vectors from Project Wycheproof (including some known edge cases). Signed-off-by: Michael Brown <mcb30@ipxe.org>
This commit is contained in:
@@ -33,7 +33,7 @@ FILE_SECBOOT ( PERMITTED );
|
|||||||
static uint8_t oid_x25519[] = { ASN1_OID_X25519 };
|
static uint8_t oid_x25519[] = { ASN1_OID_X25519 };
|
||||||
|
|
||||||
/** "x25519" OID-identified algorithm */
|
/** "x25519" OID-identified algorithm */
|
||||||
struct asn1_algorithm x25519_algorithm __asn1_algorithm = {
|
struct asn1_algorithm oid_x25519_algorithm __asn1_algorithm = {
|
||||||
.name = "x25519",
|
.name = "x25519",
|
||||||
.curve = &x25519_curve,
|
.curve = &x25519_curve,
|
||||||
.oid = ASN1_CURSOR ( oid_x25519 ),
|
.oid = ASN1_CURSOR ( oid_x25519 ),
|
||||||
|
|||||||
@@ -882,3 +882,46 @@ struct elliptic_curve x25519_curve = {
|
|||||||
.multiply = x25519_curve_multiply,
|
.multiply = x25519_curve_multiply,
|
||||||
.add = x25519_curve_add,
|
.add = x25519_curve_add,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculate public key
|
||||||
|
*
|
||||||
|
* @v private Private key
|
||||||
|
* @v public Public key to fill in
|
||||||
|
*/
|
||||||
|
static void x25519_public ( const void *private, void *public ) {
|
||||||
|
|
||||||
|
/* Calculate public key */
|
||||||
|
x25519_key ( &x25519_generator, private, public );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculate shared secret
|
||||||
|
*
|
||||||
|
* @v private Private key
|
||||||
|
* @v partner Partner public key
|
||||||
|
* @v shared Shared secret to fill in
|
||||||
|
* @ret rc Return status code
|
||||||
|
*/
|
||||||
|
static int x25519_shared ( const void *private, const void *partner,
|
||||||
|
void *shared ) {
|
||||||
|
|
||||||
|
/* Calculate shared secret */
|
||||||
|
x25519_key ( partner, private, shared );
|
||||||
|
|
||||||
|
/* Check for point at infinity (all zeros as per RFC8422) */
|
||||||
|
if ( x25519_is_zero ( shared ) )
|
||||||
|
return -EPERM;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** X25519 key exchange algorithm */
|
||||||
|
struct exchange_algorithm x25519_algorithm = {
|
||||||
|
.name = "x25519",
|
||||||
|
.privsize = sizeof ( struct x25519_value ),
|
||||||
|
.pubsize = sizeof ( struct x25519_value ),
|
||||||
|
.sharedsize = sizeof ( struct x25519_value ),
|
||||||
|
.public = x25519_public,
|
||||||
|
.shared = x25519_shared,
|
||||||
|
};
|
||||||
|
|||||||
@@ -92,5 +92,6 @@ extern void x25519_key ( const struct x25519_value *base,
|
|||||||
extern int x25519_is_zero ( const struct x25519_value *value );
|
extern int x25519_is_zero ( const struct x25519_value *value );
|
||||||
|
|
||||||
extern struct elliptic_curve x25519_curve;
|
extern struct elliptic_curve x25519_curve;
|
||||||
|
extern struct exchange_algorithm x25519_algorithm;
|
||||||
|
|
||||||
#endif /* _IPXE_X25519_H */
|
#endif /* _IPXE_X25519_H */
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <ipxe/x25519.h>
|
#include <ipxe/x25519.h>
|
||||||
#include <ipxe/test.h>
|
#include <ipxe/test.h>
|
||||||
|
#include "exchange_test.h"
|
||||||
|
|
||||||
/** Define inline multiplicand */
|
/** Define inline multiplicand */
|
||||||
#define MULTIPLICAND(...) { __VA_ARGS__ }
|
#define MULTIPLICAND(...) { __VA_ARGS__ }
|
||||||
@@ -562,6 +563,118 @@ X25519_KEY_TEST ( malicious, 1, 1,
|
|||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00 ) );
|
0x00, 0x00 ) );
|
||||||
|
|
||||||
|
/* Private: 0x77076d0a7318a57d3c16c17251b26645df4c2f87ebc0992ab177fba51db92c2a
|
||||||
|
* Partner: 0xde9edb7d7b7dc1b4d35b61c2ece435373f8343c85b78674dadfc7e146f882b4f
|
||||||
|
* Public: 0x8520f0098930a754748b7ddcb43ef75a0dbf3a0d26381af4eba4a98eaa9b4e6a
|
||||||
|
* Shared: 0x4a5d9d5ba4ce2de1728e3bf480350f25e07e21c947d19e3376f09b3c1e161742
|
||||||
|
*/
|
||||||
|
EXCHANGE_TEST ( rfc7748_alice, &x25519_algorithm,
|
||||||
|
PRIVATE ( 0x77, 0x07, 0x6d, 0x0a, 0x73, 0x18, 0xa5, 0x7d, 0x3c, 0x16,
|
||||||
|
0xc1, 0x72, 0x51, 0xb2, 0x66, 0x45, 0xdf, 0x4c, 0x2f, 0x87,
|
||||||
|
0xeb, 0xc0, 0x99, 0x2a, 0xb1, 0x77, 0xfb, 0xa5, 0x1d, 0xb9,
|
||||||
|
0x2c, 0x2a ),
|
||||||
|
PARTNER ( 0xde, 0x9e, 0xdb, 0x7d, 0x7b, 0x7d, 0xc1, 0xb4, 0xd3, 0x5b,
|
||||||
|
0x61, 0xc2, 0xec, 0xe4, 0x35, 0x37, 0x3f, 0x83, 0x43, 0xc8,
|
||||||
|
0x5b, 0x78, 0x67, 0x4d, 0xad, 0xfc, 0x7e, 0x14, 0x6f, 0x88,
|
||||||
|
0x2b, 0x4f ),
|
||||||
|
PUBLIC ( 0x85, 0x20, 0xf0, 0x09, 0x89, 0x30, 0xa7, 0x54, 0x74, 0x8b,
|
||||||
|
0x7d, 0xdc, 0xb4, 0x3e, 0xf7, 0x5a, 0x0d, 0xbf, 0x3a, 0x0d,
|
||||||
|
0x26, 0x38, 0x1a, 0xf4, 0xeb, 0xa4, 0xa9, 0x8e, 0xaa, 0x9b,
|
||||||
|
0x4e, 0x6a ),
|
||||||
|
SHARED ( 0x4a, 0x5d, 0x9d, 0x5b, 0xa4, 0xce, 0x2d, 0xe1, 0x72, 0x8e,
|
||||||
|
0x3b, 0xf4, 0x80, 0x35, 0x0f, 0x25, 0xe0, 0x7e, 0x21, 0xc9,
|
||||||
|
0x47, 0xd1, 0x9e, 0x33, 0x76, 0xf0, 0x9b, 0x3c, 0x1e, 0x16,
|
||||||
|
0x17, 0x42 ) );
|
||||||
|
|
||||||
|
/* Private: 0x5dab087e624a8a4b79e17f8b83800ee66f3bb1292618b6fd1c2f8b27ff88e0eb
|
||||||
|
* Partner: 0x8520f0098930a754748b7ddcb43ef75a0dbf3a0d26381af4eba4a98eaa9b4e6a
|
||||||
|
* Public: 0xde9edb7d7b7dc1b4d35b61c2ece435373f8343c85b78674dadfc7e146f882b4f
|
||||||
|
* Shared: 0x4a5d9d5ba4ce2de1728e3bf480350f25e07e21c947d19e3376f09b3c1e161742
|
||||||
|
*/
|
||||||
|
EXCHANGE_TEST ( rfc7748_bob, &x25519_algorithm,
|
||||||
|
PRIVATE ( 0x5d, 0xab, 0x08, 0x7e, 0x62, 0x4a, 0x8a, 0x4b, 0x79, 0xe1,
|
||||||
|
0x7f, 0x8b, 0x83, 0x80, 0x0e, 0xe6, 0x6f, 0x3b, 0xb1, 0x29,
|
||||||
|
0x26, 0x18, 0xb6, 0xfd, 0x1c, 0x2f, 0x8b, 0x27, 0xff, 0x88,
|
||||||
|
0xe0, 0xeb ),
|
||||||
|
PARTNER ( 0x85, 0x20, 0xf0, 0x09, 0x89, 0x30, 0xa7, 0x54, 0x74, 0x8b,
|
||||||
|
0x7d, 0xdc, 0xb4, 0x3e, 0xf7, 0x5a, 0x0d, 0xbf, 0x3a, 0x0d,
|
||||||
|
0x26, 0x38, 0x1a, 0xf4, 0xeb, 0xa4, 0xa9, 0x8e, 0xaa, 0x9b,
|
||||||
|
0x4e, 0x6a ),
|
||||||
|
PUBLIC ( 0xde, 0x9e, 0xdb, 0x7d, 0x7b, 0x7d, 0xc1, 0xb4, 0xd3, 0x5b,
|
||||||
|
0x61, 0xc2, 0xec, 0xe4, 0x35, 0x37, 0x3f, 0x83, 0x43, 0xc8,
|
||||||
|
0x5b, 0x78, 0x67, 0x4d, 0xad, 0xfc, 0x7e, 0x14, 0x6f, 0x88,
|
||||||
|
0x2b, 0x4f ),
|
||||||
|
SHARED ( 0x4a, 0x5d, 0x9d, 0x5b, 0xa4, 0xce, 0x2d, 0xe1, 0x72, 0x8e,
|
||||||
|
0x3b, 0xf4, 0x80, 0x35, 0x0f, 0x25, 0xe0, 0x7e, 0x21, 0xc9,
|
||||||
|
0x47, 0xd1, 0x9e, 0x33, 0x76, 0xf0, 0x9b, 0x3c, 0x1e, 0x16,
|
||||||
|
0x17, 0x42 ) );
|
||||||
|
|
||||||
|
/* Private: 0x106221fe5694a710d6e147696c5d5b93d6887d584f24f228182ebe1b1d2db85d
|
||||||
|
* Partner: 0xffffff0f000000ffffff0f000000ffffff0f000000ffffff0f000000ffffff0f
|
||||||
|
* Public: 0xecba343f4a89013fea83e869ea3f7a670715d833ab0ec43adb3acd4b48229607
|
||||||
|
* Shared: 0x5e64924b91873b499a5402fa64337c65d4b2ed54beeb3fa5d7347809e43aef1c
|
||||||
|
*/
|
||||||
|
EXCHANGE_TEST ( wycheproof_49, &x25519_algorithm,
|
||||||
|
PRIVATE ( 0x10, 0x62, 0x21, 0xfe, 0x56, 0x94, 0xa7, 0x10, 0xd6, 0xe1,
|
||||||
|
0x47, 0x69, 0x6c, 0x5d, 0x5b, 0x93, 0xd6, 0x88, 0x7d, 0x58,
|
||||||
|
0x4f, 0x24, 0xf2, 0x28, 0x18, 0x2e, 0xbe, 0x1b, 0x1d, 0x2d,
|
||||||
|
0xb8, 0x5d ),
|
||||||
|
PARTNER ( 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff,
|
||||||
|
0x0f, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00,
|
||||||
|
0x00, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00, 0xff, 0xff,
|
||||||
|
0xff, 0x0f ),
|
||||||
|
PUBLIC ( 0xec, 0xba, 0x34, 0x3f, 0x4a, 0x89, 0x01, 0x3f, 0xea, 0x83,
|
||||||
|
0xe8, 0x69, 0xea, 0x3f, 0x7a, 0x67, 0x07, 0x15, 0xd8, 0x33,
|
||||||
|
0xab, 0x0e, 0xc4, 0x3a, 0xdb, 0x3a, 0xcd, 0x4b, 0x48, 0x22,
|
||||||
|
0x96, 0x07 ),
|
||||||
|
SHARED ( 0x5e, 0x64, 0x92, 0x4b, 0x91, 0x87, 0x3b, 0x49, 0x9a, 0x54,
|
||||||
|
0x02, 0xfa, 0x64, 0x33, 0x7c, 0x65, 0xd4, 0xb2, 0xed, 0x54,
|
||||||
|
0xbe, 0xeb, 0x3f, 0xa5, 0xd7, 0x34, 0x78, 0x09, 0xe4, 0x3a,
|
||||||
|
0xef, 0x1c ) );
|
||||||
|
|
||||||
|
/* Private: 0xe0f978dfcd3a8f1a5093418de54136a584c20b7b349afdf6c0520886f95b1272
|
||||||
|
* Partner: 0xe0eb7a7c3b41b8ae1656e3faf19fc46ada098deb9c32b1fd866205165f49b800
|
||||||
|
* Public: 0x124e0f1487c9b38f1c7fd4a6518a47699d158d44cc18665c7bcca03bdc726e5d
|
||||||
|
* Shared: Failure (all zeros)
|
||||||
|
*/
|
||||||
|
EXCHANGE_TEST ( wycheproof_63, &x25519_algorithm,
|
||||||
|
PRIVATE ( 0xe0, 0xf9, 0x78, 0xdf, 0xcd, 0x3a, 0x8f, 0x1a, 0x50, 0x93,
|
||||||
|
0x41, 0x8d, 0xe5, 0x41, 0x36, 0xa5, 0x84, 0xc2, 0x0b, 0x7b,
|
||||||
|
0x34, 0x9a, 0xfd, 0xf6, 0xc0, 0x52, 0x08, 0x86, 0xf9, 0x5b,
|
||||||
|
0x12, 0x72 ),
|
||||||
|
PARTNER ( 0xe0, 0xeb, 0x7a, 0x7c, 0x3b, 0x41, 0xb8, 0xae, 0x16, 0x56,
|
||||||
|
0xe3, 0xfa, 0xf1, 0x9f, 0xc4, 0x6a, 0xda, 0x09, 0x8d, 0xeb,
|
||||||
|
0x9c, 0x32, 0xb1, 0xfd, 0x86, 0x62, 0x05, 0x16, 0x5f, 0x49,
|
||||||
|
0xb8, 0x00 ),
|
||||||
|
PUBLIC ( 0x12, 0x4e, 0x0f, 0x14, 0x87, 0xc9, 0xb3, 0x8f, 0x1c, 0x7f,
|
||||||
|
0xd4, 0xa6, 0x51, 0x8a, 0x47, 0x69, 0x9d, 0x15, 0x8d, 0x44,
|
||||||
|
0xcc, 0x18, 0x66, 0x5c, 0x7b, 0xcc, 0xa0, 0x3b, 0xdc, 0x72,
|
||||||
|
0x6e, 0x5d ),
|
||||||
|
SHARED_FAIL );
|
||||||
|
|
||||||
|
/* Private: 0x60a3a4f130b98a5be4b1cedb7cb85584a3520e142d474dc9ccb909a073a9767f
|
||||||
|
* Partner: 0x8d612c5831aa64b057300e7e310f3aa332af34066fefcab2b089c9592878f832
|
||||||
|
* Public: 0x7c6ccba92ff00a6e83382cd06b9ec9e6581eafe3c243f0c52cf68e067843e37a
|
||||||
|
* Shared: 0xe3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7f
|
||||||
|
*/
|
||||||
|
EXCHANGE_TEST ( wycheproof_112, &x25519_algorithm,
|
||||||
|
PRIVATE ( 0x60, 0xa3, 0xa4, 0xf1, 0x30, 0xb9, 0x8a, 0x5b, 0xe4, 0xb1,
|
||||||
|
0xce, 0xdb, 0x7c, 0xb8, 0x55, 0x84, 0xa3, 0x52, 0x0e, 0x14,
|
||||||
|
0x2d, 0x47, 0x4d, 0xc9, 0xcc, 0xb9, 0x09, 0xa0, 0x73, 0xa9,
|
||||||
|
0x76, 0x7f ),
|
||||||
|
PARTNER ( 0x8d, 0x61, 0x2c, 0x58, 0x31, 0xaa, 0x64, 0xb0, 0x57, 0x30,
|
||||||
|
0x0e, 0x7e, 0x31, 0x0f, 0x3a, 0xa3, 0x32, 0xaf, 0x34, 0x06,
|
||||||
|
0x6f, 0xef, 0xca, 0xb2, 0xb0, 0x89, 0xc9, 0x59, 0x28, 0x78,
|
||||||
|
0xf8, 0x32 ),
|
||||||
|
PUBLIC ( 0x7c, 0x6c, 0xcb, 0xa9, 0x2f, 0xf0, 0x0a, 0x6e, 0x83, 0x38,
|
||||||
|
0x2c, 0xd0, 0x6b, 0x9e, 0xc9, 0xe6, 0x58, 0x1e, 0xaf, 0xe3,
|
||||||
|
0xc2, 0x43, 0xf0, 0xc5, 0x2c, 0xf6, 0x8e, 0x06, 0x78, 0x43,
|
||||||
|
0xe3, 0x7a ),
|
||||||
|
SHARED ( 0xe3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0x7f ) );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Perform X25519 self-tests
|
* Perform X25519 self-tests
|
||||||
*
|
*
|
||||||
@@ -590,6 +703,13 @@ static void x25519_test_exec ( void ) {
|
|||||||
x25519_key_ok ( &rfc7748_3 );
|
x25519_key_ok ( &rfc7748_3 );
|
||||||
x25519_key_ok ( &rfc7748_4_100 );
|
x25519_key_ok ( &rfc7748_4_100 );
|
||||||
x25519_key_ok ( &malicious );
|
x25519_key_ok ( &malicious );
|
||||||
|
|
||||||
|
/* Perform key exchange tests via generic key exchange algorithm */
|
||||||
|
exchange_ok ( &rfc7748_alice );
|
||||||
|
exchange_ok ( &rfc7748_bob );
|
||||||
|
exchange_ok ( &wycheproof_49 );
|
||||||
|
exchange_ok ( &wycheproof_63 );
|
||||||
|
exchange_ok ( &wycheproof_112 );
|
||||||
}
|
}
|
||||||
|
|
||||||
/** X25519 self-test */
|
/** X25519 self-test */
|
||||||
|
|||||||
Reference in New Issue
Block a user