diff --git a/crypto_libraries/inc/nx_crypto_ec.h b/crypto_libraries/inc/nx_crypto_ec.h index 133b000ad..dc1a4694d 100644 --- a/crypto_libraries/inc/nx_crypto_ec.h +++ b/crypto_libraries/inc/nx_crypto_ec.h @@ -9,6 +9,8 @@ * SPDX-License-Identifier: MIT **************************************************************************/ +/* Portions of this file were generated with AI assistance. */ + /**************************************************************************/ /**************************************************************************/ @@ -460,12 +462,21 @@ extern NX_CRYPTO_CONST NX_CRYPTO_EC _nx_crypto_ec_secp224r1; extern NX_CRYPTO_CONST NX_CRYPTO_EC _nx_crypto_ec_secp256r1; extern NX_CRYPTO_CONST NX_CRYPTO_EC _nx_crypto_ec_secp384r1; extern NX_CRYPTO_CONST NX_CRYPTO_EC _nx_crypto_ec_secp521r1; +extern NX_CRYPTO_CONST NX_CRYPTO_EC _nx_crypto_ec_brainpoolp256r1; +extern NX_CRYPTO_CONST NX_CRYPTO_EC _nx_crypto_ec_brainpoolp384r1; +extern NX_CRYPTO_CONST NX_CRYPTO_EC _nx_crypto_ec_brainpoolp512r1; +extern NX_CRYPTO_METHOD crypto_method_ec_brainpoolp256; +extern NX_CRYPTO_METHOD crypto_method_ec_brainpoolp384; +extern NX_CRYPTO_METHOD crypto_method_ec_brainpoolp512; #define NX_CRYPTO_EC_GET_SECP192R1(curve) curve = (NX_CRYPTO_EC *)&_nx_crypto_ec_secp192r1 #define NX_CRYPTO_EC_GET_SECP224R1(curve) curve = (NX_CRYPTO_EC *)&_nx_crypto_ec_secp224r1 #define NX_CRYPTO_EC_GET_SECP256R1(curve) curve = (NX_CRYPTO_EC *)&_nx_crypto_ec_secp256r1 #define NX_CRYPTO_EC_GET_SECP384R1(curve) curve = (NX_CRYPTO_EC *)&_nx_crypto_ec_secp384r1 #define NX_CRYPTO_EC_GET_SECP521R1(curve) curve = (NX_CRYPTO_EC *)&_nx_crypto_ec_secp521r1 +#define NX_CRYPTO_EC_GET_BRAINPOOLP256R1(curve) curve = (NX_CRYPTO_EC *)&_nx_crypto_ec_brainpoolp256r1 +#define NX_CRYPTO_EC_GET_BRAINPOOLP384R1(curve) curve = (NX_CRYPTO_EC *)&_nx_crypto_ec_brainpoolp384r1 +#define NX_CRYPTO_EC_GET_BRAINPOOLP512R1(curve) curve = (NX_CRYPTO_EC *)&_nx_crypto_ec_brainpoolp512r1 UINT _nx_crypto_ec_point_is_infinite(NX_CRYPTO_EC_POINT *point); VOID _nx_crypto_ec_point_set_infinite(NX_CRYPTO_EC_POINT *point); @@ -614,6 +625,16 @@ UINT _nx_crypto_method_ec_secp521r1_operation(UINT op, VOID *crypto_metadata, ULONG crypto_metadata_size, VOID *packet_ptr, VOID (*nx_crypto_hw_process_callback)(VOID *, UINT)); +UINT _nx_crypto_method_ec_brainpool_operation(UINT op, + VOID *handle, + struct NX_CRYPTO_METHOD_STRUCT *method, + UCHAR *key, NX_CRYPTO_KEY_SIZE key_size_in_bits, + UCHAR *input, ULONG input_length_in_byte, + UCHAR *iv_ptr, + UCHAR *output, ULONG output_length_in_byte, + VOID *crypto_metadata, ULONG crypto_metadata_size, + VOID *packet_ptr, + VOID (*nx_crypto_hw_process_callback)(VOID *, UINT)); #ifdef NX_CRYPTO_ENABLE_CURVE25519_448 extern NX_CRYPTO_CONST NX_CRYPTO_EC _nx_crypto_ec_x25519; @@ -659,4 +680,3 @@ UINT _nx_crypto_ec_extract_fixed_size_le(NX_CRYPTO_HUGE_NUMBER *number, #endif #endif /* NX_CRYPTO_EC_H */ - diff --git a/crypto_libraries/src/nx_crypto_ec.c b/crypto_libraries/src/nx_crypto_ec.c index 30488f9ca..8da364742 100644 --- a/crypto_libraries/src/nx_crypto_ec.c +++ b/crypto_libraries/src/nx_crypto_ec.c @@ -371,6 +371,120 @@ static NX_CRYPTO_CONST HN_UBASE _nx_crypto_ec_secp521r1_h[] = HN_ULONG_TO_UBASE(0x00000001) }; +/* RFC 5639 brainpoolP256r1 domain parameters. */ +static NX_CRYPTO_CONST HN_UBASE _nx_crypto_ec_brainpoolp256r1_p[] = +{ + HN_ULONG_TO_UBASE(0x1F6E5377), HN_ULONG_TO_UBASE(0x2013481D), HN_ULONG_TO_UBASE(0xD5262028), HN_ULONG_TO_UBASE(0x6E3BF623), + HN_ULONG_TO_UBASE(0x9D838D72), HN_ULONG_TO_UBASE(0x3E660A90), HN_ULONG_TO_UBASE(0xA1EEA9BC), HN_ULONG_TO_UBASE(0xA9FB57DB) +}; +static NX_CRYPTO_CONST HN_UBASE _nx_crypto_ec_brainpoolp256r1_a[] = +{ + HN_ULONG_TO_UBASE(0xF330B5D9), HN_ULONG_TO_UBASE(0xE94A4B44), HN_ULONG_TO_UBASE(0x26DC5C6C), HN_ULONG_TO_UBASE(0xFB8055C1), + HN_ULONG_TO_UBASE(0x417AFFE7), HN_ULONG_TO_UBASE(0xEEF67530), HN_ULONG_TO_UBASE(0xFC2C3057), HN_ULONG_TO_UBASE(0x7D5A0975) +}; +static NX_CRYPTO_CONST HN_UBASE _nx_crypto_ec_brainpoolp256r1_b[] = +{ + HN_ULONG_TO_UBASE(0xFF8C07B6), HN_ULONG_TO_UBASE(0x6BCCDC18), HN_ULONG_TO_UBASE(0x5CF7E1CE), HN_ULONG_TO_UBASE(0x95841629), + HN_ULONG_TO_UBASE(0xBBD77CBF), HN_ULONG_TO_UBASE(0xF330B5D9), HN_ULONG_TO_UBASE(0xE94A4B44), HN_ULONG_TO_UBASE(0x26DC5C6C) +}; +static NX_CRYPTO_CONST HN_UBASE _nx_crypto_ec_brainpoolp256r1_gx[] = +{ + HN_ULONG_TO_UBASE(0x9ACE3262), HN_ULONG_TO_UBASE(0x3A4453BD), HN_ULONG_TO_UBASE(0xE3BD23C2), HN_ULONG_TO_UBASE(0xB9DE27E1), + HN_ULONG_TO_UBASE(0xFC81B7AF), HN_ULONG_TO_UBASE(0x2C4B482F), HN_ULONG_TO_UBASE(0xCB7E57CB), HN_ULONG_TO_UBASE(0x8BD2AEB9) +}; +static NX_CRYPTO_CONST HN_UBASE _nx_crypto_ec_brainpoolp256r1_gy[] = +{ + HN_ULONG_TO_UBASE(0x2F046997), HN_ULONG_TO_UBASE(0x5C1D54C7), HN_ULONG_TO_UBASE(0x2DED8E54), HN_ULONG_TO_UBASE(0xC2774513), + HN_ULONG_TO_UBASE(0x14611DC9), HN_ULONG_TO_UBASE(0x97F8461A), HN_ULONG_TO_UBASE(0xC3DAC4FD), HN_ULONG_TO_UBASE(0x547EF835) +}; +static NX_CRYPTO_CONST HN_UBASE _nx_crypto_ec_brainpoolp256r1_n[] = +{ + HN_ULONG_TO_UBASE(0x974856A7), HN_ULONG_TO_UBASE(0x901E0E82), HN_ULONG_TO_UBASE(0xB561A6F7), HN_ULONG_TO_UBASE(0x8C397AA3), + HN_ULONG_TO_UBASE(0x9D838D71), HN_ULONG_TO_UBASE(0x3E660A90), HN_ULONG_TO_UBASE(0xA1EEA9BC), HN_ULONG_TO_UBASE(0xA9FB57DB) +}; + +/* RFC 5639 brainpoolP384r1 domain parameters. */ +static NX_CRYPTO_CONST HN_UBASE _nx_crypto_ec_brainpoolp384r1_p[] = +{ + HN_ULONG_TO_UBASE(0x3107EC53), HN_ULONG_TO_UBASE(0x87470013), HN_ULONG_TO_UBASE(0x901D1A71), HN_ULONG_TO_UBASE(0xACD3A729), + HN_ULONG_TO_UBASE(0x7FB71123), HN_ULONG_TO_UBASE(0x12B1DA19), HN_ULONG_TO_UBASE(0xED5456B4), HN_ULONG_TO_UBASE(0x152F7109), + HN_ULONG_TO_UBASE(0x50E641DF), HN_ULONG_TO_UBASE(0x0F5D6F7E), HN_ULONG_TO_UBASE(0xA3386D28), HN_ULONG_TO_UBASE(0x8CB91E82) +}; +static NX_CRYPTO_CONST HN_UBASE _nx_crypto_ec_brainpoolp384r1_a[] = +{ + HN_ULONG_TO_UBASE(0x22CE2826), HN_ULONG_TO_UBASE(0x04A8C7DD), HN_ULONG_TO_UBASE(0x503AD4EB), HN_ULONG_TO_UBASE(0x8AA5814A), + HN_ULONG_TO_UBASE(0xBA91F90F), HN_ULONG_TO_UBASE(0x139165EF), HN_ULONG_TO_UBASE(0x4FB22787), HN_ULONG_TO_UBASE(0xC2BEA28E), + HN_ULONG_TO_UBASE(0xCE05AFA0), HN_ULONG_TO_UBASE(0x3C72080A), HN_ULONG_TO_UBASE(0x3D8C150C), HN_ULONG_TO_UBASE(0x7BC382C6) +}; +static NX_CRYPTO_CONST HN_UBASE _nx_crypto_ec_brainpoolp384r1_b[] = +{ + HN_ULONG_TO_UBASE(0xFA504C11), HN_ULONG_TO_UBASE(0x3AB78696), HN_ULONG_TO_UBASE(0x95DBC994), HN_ULONG_TO_UBASE(0x7CB43902), + HN_ULONG_TO_UBASE(0x3EEB62D5), HN_ULONG_TO_UBASE(0x2E880EA5), HN_ULONG_TO_UBASE(0x07DCD2A6), HN_ULONG_TO_UBASE(0x2FB77DE1), + HN_ULONG_TO_UBASE(0x16F0447C), HN_ULONG_TO_UBASE(0x8B39B554), HN_ULONG_TO_UBASE(0x22CE2826), HN_ULONG_TO_UBASE(0x04A8C7DD) +}; +static NX_CRYPTO_CONST HN_UBASE _nx_crypto_ec_brainpoolp384r1_gx[] = +{ + HN_ULONG_TO_UBASE(0x47D4AF1E), HN_ULONG_TO_UBASE(0xEF87B2E2), HN_ULONG_TO_UBASE(0x36D646AA), HN_ULONG_TO_UBASE(0xE826E034), + HN_ULONG_TO_UBASE(0x0CBD10E8), HN_ULONG_TO_UBASE(0xDB7FCAFE), HN_ULONG_TO_UBASE(0x7EF14FE3), HN_ULONG_TO_UBASE(0x8847A3E7), + HN_ULONG_TO_UBASE(0xB7C13F6B), HN_ULONG_TO_UBASE(0xA2A63A81), HN_ULONG_TO_UBASE(0x68CF45FF), HN_ULONG_TO_UBASE(0x1D1C64F0) +}; +static NX_CRYPTO_CONST HN_UBASE _nx_crypto_ec_brainpoolp384r1_gy[] = +{ + HN_ULONG_TO_UBASE(0x263C5315), HN_ULONG_TO_UBASE(0x42820341), HN_ULONG_TO_UBASE(0x77918111), HN_ULONG_TO_UBASE(0x0E464621), + HN_ULONG_TO_UBASE(0xF9912928), HN_ULONG_TO_UBASE(0xE19C054F), HN_ULONG_TO_UBASE(0xFEEC5864), HN_ULONG_TO_UBASE(0x62B70B29), + HN_ULONG_TO_UBASE(0x95CFD552), HN_ULONG_TO_UBASE(0x5CB1EB8E), HN_ULONG_TO_UBASE(0x20F9C2A4), HN_ULONG_TO_UBASE(0x8ABE1D75) +}; +static NX_CRYPTO_CONST HN_UBASE _nx_crypto_ec_brainpoolp384r1_n[] = +{ + HN_ULONG_TO_UBASE(0xE9046565), HN_ULONG_TO_UBASE(0x3B883202), HN_ULONG_TO_UBASE(0x6B7FC310), HN_ULONG_TO_UBASE(0xCF3AB6AF), + HN_ULONG_TO_UBASE(0xAC0425A7), HN_ULONG_TO_UBASE(0x1F166E6C), HN_ULONG_TO_UBASE(0xED5456B3), HN_ULONG_TO_UBASE(0x152F7109), + HN_ULONG_TO_UBASE(0x50E641DF), HN_ULONG_TO_UBASE(0x0F5D6F7E), HN_ULONG_TO_UBASE(0xA3386D28), HN_ULONG_TO_UBASE(0x8CB91E82) +}; + +/* RFC 5639 brainpoolP512r1 domain parameters. */ +static NX_CRYPTO_CONST HN_UBASE _nx_crypto_ec_brainpoolp512r1_p[] = +{ + HN_ULONG_TO_UBASE(0x583A48F3), HN_ULONG_TO_UBASE(0x28AA6056), HN_ULONG_TO_UBASE(0x2D82C685), HN_ULONG_TO_UBASE(0x2881FF2F), + HN_ULONG_TO_UBASE(0xE6A380E6), HN_ULONG_TO_UBASE(0xAECDA12A), HN_ULONG_TO_UBASE(0x9BC66842), HN_ULONG_TO_UBASE(0x7D4D9B00), + HN_ULONG_TO_UBASE(0x70330871), HN_ULONG_TO_UBASE(0xD6639CCA), HN_ULONG_TO_UBASE(0xB3C9D20E), HN_ULONG_TO_UBASE(0xCB308DB3), + HN_ULONG_TO_UBASE(0x33C9FC07), HN_ULONG_TO_UBASE(0x3FD4E6AE), HN_ULONG_TO_UBASE(0xDBE9C48B), HN_ULONG_TO_UBASE(0xAADD9DB8) +}; +static NX_CRYPTO_CONST HN_UBASE _nx_crypto_ec_brainpoolp512r1_a[] = +{ + HN_ULONG_TO_UBASE(0x77FC94CA), HN_ULONG_TO_UBASE(0xE7C1AC4D), HN_ULONG_TO_UBASE(0x2BF2C7B9), HN_ULONG_TO_UBASE(0x7F1117A7), + HN_ULONG_TO_UBASE(0x8B9AC8B5), HN_ULONG_TO_UBASE(0x0A2EF1C9), HN_ULONG_TO_UBASE(0xA8253AA1), HN_ULONG_TO_UBASE(0x2DED5D5A), + HN_ULONG_TO_UBASE(0xEA9863BC), HN_ULONG_TO_UBASE(0xA83441CA), HN_ULONG_TO_UBASE(0x3DF91610), HN_ULONG_TO_UBASE(0x94CBDD8D), + HN_ULONG_TO_UBASE(0xAC234CC5), HN_ULONG_TO_UBASE(0xE2327145), HN_ULONG_TO_UBASE(0x8B603B89), HN_ULONG_TO_UBASE(0x7830A331) +}; +static NX_CRYPTO_CONST HN_UBASE _nx_crypto_ec_brainpoolp512r1_b[] = +{ + HN_ULONG_TO_UBASE(0x8016F723), HN_ULONG_TO_UBASE(0x2809BD63), HN_ULONG_TO_UBASE(0x5EBAE5DD), HN_ULONG_TO_UBASE(0x984050B7), + HN_ULONG_TO_UBASE(0xDC083E67), HN_ULONG_TO_UBASE(0x77FC94CA), HN_ULONG_TO_UBASE(0xE7C1AC4D), HN_ULONG_TO_UBASE(0x2BF2C7B9), + HN_ULONG_TO_UBASE(0x7F1117A7), HN_ULONG_TO_UBASE(0x8B9AC8B5), HN_ULONG_TO_UBASE(0x0A2EF1C9), HN_ULONG_TO_UBASE(0xA8253AA1), + HN_ULONG_TO_UBASE(0x2DED5D5A), HN_ULONG_TO_UBASE(0xEA9863BC), HN_ULONG_TO_UBASE(0xA83441CA), HN_ULONG_TO_UBASE(0x3DF91610) +}; +static NX_CRYPTO_CONST HN_UBASE _nx_crypto_ec_brainpoolp512r1_gx[] = +{ + HN_ULONG_TO_UBASE(0xBCB9F822), HN_ULONG_TO_UBASE(0x8B352209), HN_ULONG_TO_UBASE(0x406A5E68), HN_ULONG_TO_UBASE(0x7C6D5047), + HN_ULONG_TO_UBASE(0x93B97D5F), HN_ULONG_TO_UBASE(0x50D1687B), HN_ULONG_TO_UBASE(0xE2D0D48D), HN_ULONG_TO_UBASE(0xFF3B1F78), + HN_ULONG_TO_UBASE(0xF4D0098E), HN_ULONG_TO_UBASE(0xB43B62EE), HN_ULONG_TO_UBASE(0xB5D916C1), HN_ULONG_TO_UBASE(0x85ED9F70), + HN_ULONG_TO_UBASE(0x9C4C6A93), HN_ULONG_TO_UBASE(0x5A21322E), HN_ULONG_TO_UBASE(0xD82ED964), HN_ULONG_TO_UBASE(0x81AEE4BD) +}; +static NX_CRYPTO_CONST HN_UBASE _nx_crypto_ec_brainpoolp512r1_gy[] = +{ + HN_ULONG_TO_UBASE(0x3AD80892), HN_ULONG_TO_UBASE(0x78CD1E0F), HN_ULONG_TO_UBASE(0xA8F05406), HN_ULONG_TO_UBASE(0xD1CA2B2F), + HN_ULONG_TO_UBASE(0x8A2763AE), HN_ULONG_TO_UBASE(0x5BCA4BD8), HN_ULONG_TO_UBASE(0x4A5F485E), HN_ULONG_TO_UBASE(0xB2DCDE49), + HN_ULONG_TO_UBASE(0x881F8111), HN_ULONG_TO_UBASE(0xA000C55B), HN_ULONG_TO_UBASE(0x24A57B1A), HN_ULONG_TO_UBASE(0xF209F700), + HN_ULONG_TO_UBASE(0xCF7822FD), HN_ULONG_TO_UBASE(0xC0EABFA9), HN_ULONG_TO_UBASE(0x566332EC), HN_ULONG_TO_UBASE(0x7DDE385D) +}; +static NX_CRYPTO_CONST HN_UBASE _nx_crypto_ec_brainpoolp512r1_n[] = +{ + HN_ULONG_TO_UBASE(0x9CA90069), HN_ULONG_TO_UBASE(0xB5879682), HN_ULONG_TO_UBASE(0x085DDADD), HN_ULONG_TO_UBASE(0x1DB1D381), + HN_ULONG_TO_UBASE(0x7FAC1047), HN_ULONG_TO_UBASE(0x41866119), HN_ULONG_TO_UBASE(0x4CA92619), HN_ULONG_TO_UBASE(0x553E5C41), + HN_ULONG_TO_UBASE(0x70330870), HN_ULONG_TO_UBASE(0xD6639CCA), HN_ULONG_TO_UBASE(0xB3C9D20E), HN_ULONG_TO_UBASE(0xCB308DB3), + HN_ULONG_TO_UBASE(0x33C9FC07), HN_ULONG_TO_UBASE(0x3FD4E6AE), HN_ULONG_TO_UBASE(0xDBE9C48B), HN_ULONG_TO_UBASE(0xAADD9DB8) +}; + extern NX_CRYPTO_CONST NX_CRYPTO_EC_FIXED_POINTS _nx_crypto_ec_secp192r1_fixed_points; extern NX_CRYPTO_CONST NX_CRYPTO_EC_FIXED_POINTS _nx_crypto_ec_secp224r1_fixed_points; extern NX_CRYPTO_CONST NX_CRYPTO_EC_FIXED_POINTS _nx_crypto_ec_secp256r1_fixed_points; @@ -686,6 +800,189 @@ NX_CRYPTO_CONST NX_CRYPTO_EC _nx_crypto_ec_secp521r1 = _nx_crypto_ec_fp_projective_multiple, _nx_crypto_ec_secp521r1_reduce }; +/* Prime-field Brainpool curves use the generic reduction path. */ +static NX_CRYPTO_CONST HN_UBASE _nx_crypto_ec_brainpool_h[] = { HN_ULONG_TO_UBASE(1) }; + +/* RFC 5639 brainpoolp256r1 curve for ECDH and ECDSA. */ +NX_CRYPTO_CONST NX_CRYPTO_EC _nx_crypto_ec_brainpoolp256r1 = +{ + "brainpoolP256r1", + NX_CRYPTO_EC_BRAINPOOLP256r1, + 4, + 256, + { .fp = { + (HN_UBASE *)_nx_crypto_ec_brainpoolp256r1_p, + sizeof(_nx_crypto_ec_brainpoolp256r1_p) >> HN_SIZE_SHIFT, + sizeof(_nx_crypto_ec_brainpoolp256r1_p), + (UINT)NX_CRYPTO_FALSE + } }, + { + (HN_UBASE *)_nx_crypto_ec_brainpoolp256r1_a, + sizeof(_nx_crypto_ec_brainpoolp256r1_a) >> HN_SIZE_SHIFT, + sizeof(_nx_crypto_ec_brainpoolp256r1_a), + (UINT)NX_CRYPTO_FALSE + }, + { + (HN_UBASE *)_nx_crypto_ec_brainpoolp256r1_b, + sizeof(_nx_crypto_ec_brainpoolp256r1_b) >> HN_SIZE_SHIFT, + sizeof(_nx_crypto_ec_brainpoolp256r1_b), + (UINT)NX_CRYPTO_FALSE + }, + { + NX_CRYPTO_EC_POINT_AFFINE, + { + (HN_UBASE *)_nx_crypto_ec_brainpoolp256r1_gx, + sizeof(_nx_crypto_ec_brainpoolp256r1_gx) >> HN_SIZE_SHIFT, + sizeof(_nx_crypto_ec_brainpoolp256r1_gx), + (UINT)NX_CRYPTO_FALSE + }, + { + (HN_UBASE *)_nx_crypto_ec_brainpoolp256r1_gy, + sizeof(_nx_crypto_ec_brainpoolp256r1_gy) >> HN_SIZE_SHIFT, + sizeof(_nx_crypto_ec_brainpoolp256r1_gy), + (UINT)NX_CRYPTO_FALSE + }, + {(HN_UBASE *)NX_CRYPTO_NULL, 0u, 0u, 0u} + }, + { + (HN_UBASE *)_nx_crypto_ec_brainpoolp256r1_n, + sizeof(_nx_crypto_ec_brainpoolp256r1_n) >> HN_SIZE_SHIFT, + sizeof(_nx_crypto_ec_brainpoolp256r1_n), + (UINT)NX_CRYPTO_FALSE + }, + { + (HN_UBASE *)_nx_crypto_ec_brainpool_h, + sizeof(_nx_crypto_ec_brainpool_h) >> HN_SIZE_SHIFT, + sizeof(_nx_crypto_ec_brainpool_h), + (UINT)NX_CRYPTO_FALSE + }, + NX_CRYPTO_NULL, + _nx_crypto_ec_fp_affine_add, + _nx_crypto_ec_fp_affine_subtract, + _nx_crypto_ec_fp_projective_multiple, + _nx_crypto_ec_fp_reduce +}; + +/* RFC 5639 brainpoolp384r1 curve for ECDH and ECDSA. */ +NX_CRYPTO_CONST NX_CRYPTO_EC _nx_crypto_ec_brainpoolp384r1 = +{ + "brainpoolP384r1", + NX_CRYPTO_EC_BRAINPOOLP384r1, + 4, + 384, + { .fp = { + (HN_UBASE *)_nx_crypto_ec_brainpoolp384r1_p, + sizeof(_nx_crypto_ec_brainpoolp384r1_p) >> HN_SIZE_SHIFT, + sizeof(_nx_crypto_ec_brainpoolp384r1_p), + (UINT)NX_CRYPTO_FALSE + } }, + { + (HN_UBASE *)_nx_crypto_ec_brainpoolp384r1_a, + sizeof(_nx_crypto_ec_brainpoolp384r1_a) >> HN_SIZE_SHIFT, + sizeof(_nx_crypto_ec_brainpoolp384r1_a), + (UINT)NX_CRYPTO_FALSE + }, + { + (HN_UBASE *)_nx_crypto_ec_brainpoolp384r1_b, + sizeof(_nx_crypto_ec_brainpoolp384r1_b) >> HN_SIZE_SHIFT, + sizeof(_nx_crypto_ec_brainpoolp384r1_b), + (UINT)NX_CRYPTO_FALSE + }, + { + NX_CRYPTO_EC_POINT_AFFINE, + { + (HN_UBASE *)_nx_crypto_ec_brainpoolp384r1_gx, + sizeof(_nx_crypto_ec_brainpoolp384r1_gx) >> HN_SIZE_SHIFT, + sizeof(_nx_crypto_ec_brainpoolp384r1_gx), + (UINT)NX_CRYPTO_FALSE + }, + { + (HN_UBASE *)_nx_crypto_ec_brainpoolp384r1_gy, + sizeof(_nx_crypto_ec_brainpoolp384r1_gy) >> HN_SIZE_SHIFT, + sizeof(_nx_crypto_ec_brainpoolp384r1_gy), + (UINT)NX_CRYPTO_FALSE + }, + {(HN_UBASE *)NX_CRYPTO_NULL, 0u, 0u, 0u} + }, + { + (HN_UBASE *)_nx_crypto_ec_brainpoolp384r1_n, + sizeof(_nx_crypto_ec_brainpoolp384r1_n) >> HN_SIZE_SHIFT, + sizeof(_nx_crypto_ec_brainpoolp384r1_n), + (UINT)NX_CRYPTO_FALSE + }, + { + (HN_UBASE *)_nx_crypto_ec_brainpool_h, + sizeof(_nx_crypto_ec_brainpool_h) >> HN_SIZE_SHIFT, + sizeof(_nx_crypto_ec_brainpool_h), + (UINT)NX_CRYPTO_FALSE + }, + NX_CRYPTO_NULL, + _nx_crypto_ec_fp_affine_add, + _nx_crypto_ec_fp_affine_subtract, + _nx_crypto_ec_fp_projective_multiple, + _nx_crypto_ec_fp_reduce +}; + +/* RFC 5639 brainpoolp512r1 curve for ECDH and ECDSA. */ +NX_CRYPTO_CONST NX_CRYPTO_EC _nx_crypto_ec_brainpoolp512r1 = +{ + "brainpoolP512r1", + NX_CRYPTO_EC_BRAINPOOLP512r1, + 4, + 512, + { .fp = { + (HN_UBASE *)_nx_crypto_ec_brainpoolp512r1_p, + sizeof(_nx_crypto_ec_brainpoolp512r1_p) >> HN_SIZE_SHIFT, + sizeof(_nx_crypto_ec_brainpoolp512r1_p), + (UINT)NX_CRYPTO_FALSE + } }, + { + (HN_UBASE *)_nx_crypto_ec_brainpoolp512r1_a, + sizeof(_nx_crypto_ec_brainpoolp512r1_a) >> HN_SIZE_SHIFT, + sizeof(_nx_crypto_ec_brainpoolp512r1_a), + (UINT)NX_CRYPTO_FALSE + }, + { + (HN_UBASE *)_nx_crypto_ec_brainpoolp512r1_b, + sizeof(_nx_crypto_ec_brainpoolp512r1_b) >> HN_SIZE_SHIFT, + sizeof(_nx_crypto_ec_brainpoolp512r1_b), + (UINT)NX_CRYPTO_FALSE + }, + { + NX_CRYPTO_EC_POINT_AFFINE, + { + (HN_UBASE *)_nx_crypto_ec_brainpoolp512r1_gx, + sizeof(_nx_crypto_ec_brainpoolp512r1_gx) >> HN_SIZE_SHIFT, + sizeof(_nx_crypto_ec_brainpoolp512r1_gx), + (UINT)NX_CRYPTO_FALSE + }, + { + (HN_UBASE *)_nx_crypto_ec_brainpoolp512r1_gy, + sizeof(_nx_crypto_ec_brainpoolp512r1_gy) >> HN_SIZE_SHIFT, + sizeof(_nx_crypto_ec_brainpoolp512r1_gy), + (UINT)NX_CRYPTO_FALSE + }, + {(HN_UBASE *)NX_CRYPTO_NULL, 0u, 0u, 0u} + }, + { + (HN_UBASE *)_nx_crypto_ec_brainpoolp512r1_n, + sizeof(_nx_crypto_ec_brainpoolp512r1_n) >> HN_SIZE_SHIFT, + sizeof(_nx_crypto_ec_brainpoolp512r1_n), + (UINT)NX_CRYPTO_FALSE + }, + { + (HN_UBASE *)_nx_crypto_ec_brainpool_h, + sizeof(_nx_crypto_ec_brainpool_h) >> HN_SIZE_SHIFT, + sizeof(_nx_crypto_ec_brainpool_h), + (UINT)NX_CRYPTO_FALSE + }, + NX_CRYPTO_NULL, + _nx_crypto_ec_fp_affine_add, + _nx_crypto_ec_fp_affine_subtract, + _nx_crypto_ec_fp_projective_multiple, + _nx_crypto_ec_fp_reduce +}; + #ifndef NX_CRYPTO_SELF_TEST static NX_CRYPTO_CONST NX_CRYPTO_EC *_nx_crypto_ec_named_curves[] = { @@ -693,7 +990,10 @@ static NX_CRYPTO_CONST NX_CRYPTO_EC *_nx_crypto_ec_named_curves[] = &_nx_crypto_ec_secp224r1, &_nx_crypto_ec_secp256r1, &_nx_crypto_ec_secp384r1, - &_nx_crypto_ec_secp521r1 + &_nx_crypto_ec_secp521r1, + &_nx_crypto_ec_brainpoolp256r1, + &_nx_crypto_ec_brainpoolp384r1, + &_nx_crypto_ec_brainpoolp512r1 }; #endif /**************************************************************************/ @@ -1904,7 +2204,6 @@ NX_CRYPTO_KEEP VOID _nx_crypto_ec_subtract_digit_reduce(NX_CRYPTO_EC *curve, /* Application Code */ /* */ /**************************************************************************/ -#ifndef NX_CRYPTO_SELF_TEST NX_CRYPTO_KEEP VOID _nx_crypto_ec_fp_reduce(NX_CRYPTO_EC *curve, NX_CRYPTO_HUGE_NUMBER *value, HN_UBASE *scratch) @@ -1913,7 +2212,6 @@ NX_CRYPTO_KEEP VOID _nx_crypto_ec_fp_reduce(NX_CRYPTO_EC *curve, _nx_crypto_huge_number_modulus(value, &curve -> nx_crypto_ec_field.fp); } -#endif /**************************************************************************/ /* */ /* FUNCTION RELEASE */ @@ -2274,15 +2572,31 @@ UINT buffer_size; NX_CRYPTO_EC_SQUARE_REDUCE(curve, &temp3, &temp2, scratch); NX_CRYPTO_EC_SHIFT_LEFT_REDUCE(curve, &temp2, 3, scratch); - /* C = 3 * (X1 - Z1 ^ 2) * (X1 + Z1 ^ 2) */ + /* C = 3 * X1^2 + a * Z1^4; use the shorter form for a = -3 curves. */ NX_CRYPTO_EC_SQUARE_REDUCE(curve, &projective_point -> nx_crypto_ec_point_z, &temp3, scratch); - NX_CRYPTO_HUGE_NUMBER_COPY(&temp4, &projective_point -> nx_crypto_ec_point_x); - NX_CRYPTO_HUGE_NUMBER_COPY(&temp5, &projective_point -> nx_crypto_ec_point_x); - _nx_crypto_ec_subtract_reduce(curve, &temp4, &temp3, scratch); - _nx_crypto_ec_add_reduce(curve, &temp5, &temp3, scratch); - NX_CRYPTO_EC_MULTIPLE_REDUCE(curve, &temp4, &temp5, &temp3, scratch); - NX_CRYPTO_EC_MULTIPLE_DIGIT_REDUCE(curve, &temp3, 3, &temp4, scratch); + if ((curve -> nx_crypto_ec_id == NX_CRYPTO_EC_BRAINPOOLP256r1) || + (curve -> nx_crypto_ec_id == NX_CRYPTO_EC_BRAINPOOLP384r1) || + (curve -> nx_crypto_ec_id == NX_CRYPTO_EC_BRAINPOOLP512r1)) + { + NX_CRYPTO_EC_SQUARE_REDUCE(curve, &temp3, &temp4, scratch); + NX_CRYPTO_EC_MULTIPLE_REDUCE(curve, &temp4, &curve -> nx_crypto_ec_a, + &temp3, scratch); + NX_CRYPTO_EC_SQUARE_REDUCE(curve, &projective_point -> nx_crypto_ec_point_x, + &temp4, scratch); + NX_CRYPTO_EC_MULTIPLE_DIGIT_REDUCE(curve, &temp4, 3, &temp5, scratch); + _nx_crypto_ec_add_reduce(curve, &temp5, &temp3, scratch); + NX_CRYPTO_HUGE_NUMBER_COPY(&temp4, &temp5); + } + else + { + NX_CRYPTO_HUGE_NUMBER_COPY(&temp4, &projective_point -> nx_crypto_ec_point_x); + NX_CRYPTO_HUGE_NUMBER_COPY(&temp5, &projective_point -> nx_crypto_ec_point_x); + _nx_crypto_ec_subtract_reduce(curve, &temp4, &temp3, scratch); + _nx_crypto_ec_add_reduce(curve, &temp5, &temp3, scratch); + NX_CRYPTO_EC_MULTIPLE_REDUCE(curve, &temp4, &temp5, &temp3, scratch); + NX_CRYPTO_EC_MULTIPLE_DIGIT_REDUCE(curve, &temp3, 3, &temp4, scratch); + } /* Z3 = 2 * Y1 * Z1 */ NX_CRYPTO_EC_MULTIPLE_REDUCE(curve, &projective_point -> nx_crypto_ec_point_y, @@ -3932,6 +4246,57 @@ NX_CRYPTO_KEEP UINT _nx_crypto_method_ec_secp521r1_operation(UINT op, return(NX_CRYPTO_SUCCESS); } +/* Return the RFC 5639 curve selected by the Brainpool crypto method. */ +NX_CRYPTO_KEEP UINT _nx_crypto_method_ec_brainpool_operation(UINT op, + VOID *handle, + struct NX_CRYPTO_METHOD_STRUCT *method, + UCHAR *key, NX_CRYPTO_KEY_SIZE key_size_in_bits, + UCHAR *input, ULONG input_length_in_byte, + UCHAR *iv_ptr, + UCHAR *output, ULONG output_length_in_byte, + VOID *crypto_metadata, ULONG crypto_metadata_size, + VOID *packet_ptr, + VOID (*nx_crypto_hw_process_callback)(VOID *, UINT)) +{ +NX_CRYPTO_EC *curve; + + NX_CRYPTO_PARAMETER_NOT_USED(handle); + NX_CRYPTO_PARAMETER_NOT_USED(key); + NX_CRYPTO_PARAMETER_NOT_USED(key_size_in_bits); + NX_CRYPTO_PARAMETER_NOT_USED(input); + NX_CRYPTO_PARAMETER_NOT_USED(input_length_in_byte); + NX_CRYPTO_PARAMETER_NOT_USED(iv_ptr); + NX_CRYPTO_PARAMETER_NOT_USED(output_length_in_byte); + NX_CRYPTO_PARAMETER_NOT_USED(crypto_metadata); + NX_CRYPTO_PARAMETER_NOT_USED(crypto_metadata_size); + NX_CRYPTO_PARAMETER_NOT_USED(packet_ptr); + NX_CRYPTO_PARAMETER_NOT_USED(nx_crypto_hw_process_callback); + + if ((op != NX_CRYPTO_EC_CURVE_GET) || (method == NX_CRYPTO_NULL) || + (output == NX_CRYPTO_NULL)) + { + return(NX_CRYPTO_NOT_SUCCESSFUL); + } + + switch (method -> nx_crypto_algorithm) + { + case NX_CRYPTO_EC_BRAINPOOLP256r1: + curve = (NX_CRYPTO_EC *)&_nx_crypto_ec_brainpoolp256r1; + break; + case NX_CRYPTO_EC_BRAINPOOLP384r1: + curve = (NX_CRYPTO_EC *)&_nx_crypto_ec_brainpoolp384r1; + break; + case NX_CRYPTO_EC_BRAINPOOLP512r1: + curve = (NX_CRYPTO_EC *)&_nx_crypto_ec_brainpoolp512r1; + break; + default: + return(NX_CRYPTO_NOT_SUCCESSFUL); + } + + *((NX_CRYPTO_EC **)output) = curve; + return(NX_CRYPTO_SUCCESS); +} + /**************************************************************************/ /* */ diff --git a/crypto_libraries/src/nx_crypto_generic_ciphersuites.c b/crypto_libraries/src/nx_crypto_generic_ciphersuites.c index fcad19eaa..0e47e7ccc 100644 --- a/crypto_libraries/src/nx_crypto_generic_ciphersuites.c +++ b/crypto_libraries/src/nx_crypto_generic_ciphersuites.c @@ -9,6 +9,8 @@ * SPDX-License-Identifier: MIT **************************************************************************/ +/* Portions of this file were generated with AI assistance. */ + /**************************************************************************/ /**************************************************************************/ @@ -80,6 +82,9 @@ extern NX_CRYPTO_METHOD crypto_method_auth_psk; extern NX_CRYPTO_METHOD crypto_method_ec_secp256; extern NX_CRYPTO_METHOD crypto_method_ec_secp384; extern NX_CRYPTO_METHOD crypto_method_ec_secp521; +extern NX_CRYPTO_METHOD crypto_method_ec_brainpoolp256; +extern NX_CRYPTO_METHOD crypto_method_ec_brainpoolp384; +extern NX_CRYPTO_METHOD crypto_method_ec_brainpoolp512; extern NX_CRYPTO_METHOD crypto_method_ec_x25519; extern NX_CRYPTO_METHOD crypto_method_ec_x448; extern NX_CRYPTO_METHOD crypto_method_md5; @@ -294,6 +299,9 @@ const USHORT nx_crypto_ecc_supported_groups[] = #endif /* NX_CRYPTO_ENABLE_CURVE25519_448 */ (USHORT)NX_CRYPTO_EC_SECP384R1, (USHORT)NX_CRYPTO_EC_SECP521R1, + (USHORT)NX_CRYPTO_EC_BRAINPOOLP256r1, + (USHORT)NX_CRYPTO_EC_BRAINPOOLP384r1, + (USHORT)NX_CRYPTO_EC_BRAINPOOLP512r1, }; const NX_CRYPTO_METHOD *nx_crypto_ecc_curves[] = @@ -305,6 +313,9 @@ const NX_CRYPTO_METHOD *nx_crypto_ecc_curves[] = #endif /* NX_CRYPTO_ENABLE_CURVE25519_448 */ &crypto_method_ec_secp384, &crypto_method_ec_secp521, + &crypto_method_ec_brainpoolp256, + &crypto_method_ec_brainpoolp384, + &crypto_method_ec_brainpoolp512, }; const UINT nx_crypto_ecc_supported_groups_size = sizeof(nx_crypto_ecc_supported_groups) / sizeof(USHORT); @@ -616,6 +627,9 @@ const NX_CRYPTO_METHOD *supported_crypto[] = #endif /* NX_CRYPTO_ENABLE_CURVE25519_448 */ &crypto_method_ec_secp384, &crypto_method_ec_secp521, + &crypto_method_ec_brainpoolp256, + &crypto_method_ec_brainpoolp384, + &crypto_method_ec_brainpoolp512, }; const UINT supported_crypto_size = sizeof(supported_crypto) / sizeof(NX_CRYPTO_METHOD*); @@ -649,4 +663,3 @@ const UINT ciphersuite_map_size = sizeof(ciphersuite_map) / sizeof(NX_CRYPTO_CIP - diff --git a/crypto_libraries/src/nx_crypto_methods.c b/crypto_libraries/src/nx_crypto_methods.c index c1304c441..8f9aaf905 100644 --- a/crypto_libraries/src/nx_crypto_methods.c +++ b/crypto_libraries/src/nx_crypto_methods.c @@ -9,6 +9,8 @@ * SPDX-License-Identifier: MIT **************************************************************************/ +/* Portions of this file were generated with AI assistance. */ + /**************************************************************************/ /**************************************************************************/ @@ -505,6 +507,27 @@ NX_CRYPTO_METHOD crypto_method_ec_secp521 = _nx_crypto_method_ec_secp521r1_operation, /* Operation */ }; +/* Declare the Brainpool P256r1 curve method. */ +NX_CRYPTO_METHOD crypto_method_ec_brainpoolp256 = +{ + NX_CRYPTO_EC_BRAINPOOLP256r1, 256, 0, 0, 0, 0, + NX_CRYPTO_NULL, NX_CRYPTO_NULL, _nx_crypto_method_ec_brainpool_operation +}; + +/* Declare the Brainpool P384r1 curve method. */ +NX_CRYPTO_METHOD crypto_method_ec_brainpoolp384 = +{ + NX_CRYPTO_EC_BRAINPOOLP384r1, 384, 0, 0, 0, 0, + NX_CRYPTO_NULL, NX_CRYPTO_NULL, _nx_crypto_method_ec_brainpool_operation +}; + +/* Declare the Brainpool P512r1 curve method. */ +NX_CRYPTO_METHOD crypto_method_ec_brainpoolp512 = +{ + NX_CRYPTO_EC_BRAINPOOLP512r1, 512, 0, 0, 0, 0, + NX_CRYPTO_NULL, NX_CRYPTO_NULL, _nx_crypto_method_ec_brainpool_operation +}; + #ifdef NX_CRYPTO_ENABLE_CURVE25519_448 /* Declare a placeholder for EC x25519. */ diff --git a/nx_secure/inc/nx_secure_tls.h b/nx_secure/inc/nx_secure_tls.h index 901a4f9aa..31fbc1eec 100644 --- a/nx_secure/inc/nx_secure_tls.h +++ b/nx_secure/inc/nx_secure_tls.h @@ -560,6 +560,9 @@ typedef struct NX_SECURE_VERSIONS_LIST_STRUCT #define NX_SECURE_TLS_SIGNATURE_ECDSA_SHA256 (((UINT)NX_SECURE_TLS_HASH_ALGORITHM_SHA256 << 8) + (UINT)NX_SECURE_TLS_SIGNATURE_ALGORITHM_ECDSA) #define NX_SECURE_TLS_SIGNATURE_ECDSA_SHA384 (((UINT)NX_SECURE_TLS_HASH_ALGORITHM_SHA384 << 8) + (UINT)NX_SECURE_TLS_SIGNATURE_ALGORITHM_ECDSA) #define NX_SECURE_TLS_SIGNATURE_ECDSA_SHA512 (((UINT)NX_SECURE_TLS_HASH_ALGORITHM_SHA512 << 8) + (UINT)NX_SECURE_TLS_SIGNATURE_ALGORITHM_ECDSA) +#define NX_SECURE_TLS_SIGNATURE_ECDSA_BRAINPOOLP256R1_SHA256 0x081Au +#define NX_SECURE_TLS_SIGNATURE_ECDSA_BRAINPOOLP384R1_SHA384 0x081Bu +#define NX_SECURE_TLS_SIGNATURE_ECDSA_BRAINPOOLP512R1_SHA512 0x081Cu /* Session key generation and assignment constants. */ @@ -1641,6 +1644,8 @@ UINT _nx_secure_tls_ecc_generate_keys(const NX_SECURE_TLS_CIPHERSUITE_INFO *ciph VOID *public_auth_metadata, ULONG public_auth_metadata_size); UINT _nx_secure_tls_find_curve_method(NX_SECURE_TLS_ECC *tls_ecc, USHORT named_curve, const NX_CRYPTO_METHOD **curve_method, UINT *curve_priority); +USHORT _nx_secure_tls_brainpool_group_to_wire(USHORT named_curve); +USHORT _nx_secure_tls_brainpool_group_from_wire(USHORT named_group); UINT _nx_secure_tls_proc_clienthello_sec_sa_extension(NX_SECURE_TLS_SESSION *tls_session, NX_SECURE_TLS_HELLO_EXTENSION *exts, UINT num_extensions, diff --git a/nx_secure/inc/nx_secure_x509.h b/nx_secure/inc/nx_secure_x509.h index 6029375ae..afb87062e 100644 --- a/nx_secure/inc/nx_secure_x509.h +++ b/nx_secure/inc/nx_secure_x509.h @@ -9,6 +9,8 @@ * SPDX-License-Identifier: MIT **************************************************************************/ +/* Portions of this file were generated with AI assistance. */ + /**************************************************************************/ /**************************************************************************/ @@ -367,6 +369,9 @@ extern "C" { #define NX_SECURE_TLS_X509_EC_SECP256R1 0x00060017 #define NX_SECURE_TLS_X509_EC_SECP384R1 0x00060018 #define NX_SECURE_TLS_X509_EC_SECP521R1 0x00060019 +#define NX_SECURE_TLS_X509_EC_BRAINPOOLP256R1 0x0006001A +#define NX_SECURE_TLS_X509_EC_BRAINPOOLP384R1 0x0006001B +#define NX_SECURE_TLS_X509_EC_BRAINPOOLP512R1 0x0006001C /* Bitfield mappings for Distinguished name comparison. When using nx_secure_x509_distinguished_name_compare, these values are used for the "compare_fields" parameter - bitwise OR these values together to compare @@ -1045,4 +1050,3 @@ UINT nx_secure_x509_key_usage_extension_parse(NX_SECURE_X509_CERT *certificate, #endif #endif /* SRC_NX_SECURE_X509_H_ */ - diff --git a/nx_secure/src/nx_secure_tls_find_curve_method.c b/nx_secure/src/nx_secure_tls_find_curve_method.c index eb1057fdd..b6b174b9e 100644 --- a/nx_secure/src/nx_secure_tls_find_curve_method.c +++ b/nx_secure/src/nx_secure_tls_find_curve_method.c @@ -9,6 +9,8 @@ * SPDX-License-Identifier: MIT **************************************************************************/ +/* Portions of this file were generated with AI assistance. */ + /**************************************************************************/ /**************************************************************************/ @@ -26,6 +28,27 @@ #ifdef NX_SECURE_ENABLE_ECC_CIPHERSUITE +/* Map RFC 7027 Brainpool curve IDs to their RFC 8734 TLS 1.3 group IDs. */ +USHORT _nx_secure_tls_brainpool_group_to_wire(USHORT named_curve) +{ + if ((named_curve >= (USHORT)NX_CRYPTO_EC_BRAINPOOLP256r1) && + (named_curve <= (USHORT)NX_CRYPTO_EC_BRAINPOOLP512r1)) + { + return((USHORT)(named_curve + 5u)); + } + return(named_curve); +} + +/* Map RFC 8734 TLS 1.3 group IDs to the corresponding crypto curve IDs. */ +USHORT _nx_secure_tls_brainpool_group_from_wire(USHORT named_group) +{ + if ((named_group >= 0x001Fu) && (named_group <= 0x0021u)) + { + return((USHORT)(named_group - 5u)); + } + return(named_group); +} + /**************************************************************************/ /* */ /* FUNCTION RELEASE */ diff --git a/nx_secure/src/nx_secure_tls_process_certificate_request.c b/nx_secure/src/nx_secure_tls_process_certificate_request.c index ac7f1c060..161fd3a3b 100644 --- a/nx_secure/src/nx_secure_tls_process_certificate_request.c +++ b/nx_secure/src/nx_secure_tls_process_certificate_request.c @@ -150,6 +150,15 @@ UINT extension_type; case NX_CRYPTO_EC_SECP521R1: expected_sign_alg = NX_SECURE_TLS_SIGNATURE_ECDSA_SHA512; break; + case NX_CRYPTO_EC_BRAINPOOLP256r1: + expected_sign_alg = NX_SECURE_TLS_SIGNATURE_ECDSA_BRAINPOOLP256R1_SHA256; + break; + case NX_CRYPTO_EC_BRAINPOOLP384r1: + expected_sign_alg = NX_SECURE_TLS_SIGNATURE_ECDSA_BRAINPOOLP384R1_SHA384; + break; + case NX_CRYPTO_EC_BRAINPOOLP512r1: + expected_sign_alg = NX_SECURE_TLS_SIGNATURE_ECDSA_BRAINPOOLP512R1_SHA512; + break; default: return(NX_SECURE_TLS_UNSUPPORTED_CERT_SIGN_ALG); } @@ -337,4 +346,3 @@ UINT extension_type; return(NX_NOT_SUPPORTED); #endif /* NX_SECURE_DISABLE_X509 */ } - diff --git a/nx_secure/src/nx_secure_tls_process_certificate_verify.c b/nx_secure/src/nx_secure_tls_process_certificate_verify.c index f06670849..4d9db981a 100644 --- a/nx_secure/src/nx_secure_tls_process_certificate_verify.c +++ b/nx_secure/src/nx_secure_tls_process_certificate_verify.c @@ -110,6 +110,9 @@ UCHAR *pss_scratch; #ifdef NX_SECURE_ENABLE_ECC_CIPHERSUITE const NX_CRYPTO_METHOD *curve_method_cert; NX_SECURE_EC_PUBLIC_KEY *ec_pubkey; +#if (NX_SECURE_TLS_TLS_1_3_ENABLED) +UINT brainpool_expected_curve = 0u; +#endif UCHAR *ecdsa_hash; #endif /* NX_SECURE_ENABLE_ECC_CIPHERSUITE */ @@ -185,6 +188,24 @@ UCHAR *ecdsa_hash; case NX_SECURE_TLS_SIGNATURE_ECDSA_SHA512: signature_algorithm = NX_SECURE_TLS_X509_TYPE_ECDSA_SHA_512; break; + case NX_SECURE_TLS_SIGNATURE_ECDSA_BRAINPOOLP256R1_SHA256: + signature_algorithm = NX_SECURE_TLS_X509_TYPE_ECDSA_SHA_256; +#ifdef NX_SECURE_ENABLE_ECC_CIPHERSUITE + brainpool_expected_curve = NX_CRYPTO_EC_BRAINPOOLP256r1; +#endif + break; + case NX_SECURE_TLS_SIGNATURE_ECDSA_BRAINPOOLP384R1_SHA384: + signature_algorithm = NX_SECURE_TLS_X509_TYPE_ECDSA_SHA_384; +#ifdef NX_SECURE_ENABLE_ECC_CIPHERSUITE + brainpool_expected_curve = NX_CRYPTO_EC_BRAINPOOLP384r1; +#endif + break; + case NX_SECURE_TLS_SIGNATURE_ECDSA_BRAINPOOLP512R1_SHA512: + signature_algorithm = NX_SECURE_TLS_X509_TYPE_ECDSA_SHA_512; +#ifdef NX_SECURE_ENABLE_ECC_CIPHERSUITE + brainpool_expected_curve = NX_CRYPTO_EC_BRAINPOOLP512r1; +#endif + break; case 0x0804u: /* rsa_pss_rsae_sha256 */ signature_algorithm = NX_SECURE_TLS_X509_TYPE_RSA_SHA_256; break; @@ -827,6 +848,17 @@ UCHAR *ecdsa_hash; ec_pubkey = &client_certificate -> nx_secure_x509_public_key.ec_public_key; +#if (NX_SECURE_TLS_TLS_1_3_ENABLED) + if (tls_session -> nx_secure_tls_1_3 && + ((brainpool_expected_curve != 0u) || + ((ec_pubkey -> nx_secure_ec_named_curve >= NX_CRYPTO_EC_BRAINPOOLP256r1) && + (ec_pubkey -> nx_secure_ec_named_curve <= NX_CRYPTO_EC_BRAINPOOLP512r1))) && + (brainpool_expected_curve != ec_pubkey -> nx_secure_ec_named_curve)) + { + return(NX_SECURE_TLS_UNSUPPORTED_CERT_SIGN_ALG); + } +#endif + /* Find out which named curve the remote certificate is using. */ status = _nx_secure_tls_find_curve_method(&tls_session -> nx_secure_tls_ecc, (USHORT)(ec_pubkey -> nx_secure_ec_named_curve), &curve_method_cert, NX_NULL); @@ -953,4 +985,3 @@ UCHAR *ecdsa_hash; return(NX_NOT_SUPPORTED); #endif } - diff --git a/nx_secure/src/nx_secure_tls_process_clienthello_extensions.c b/nx_secure/src/nx_secure_tls_process_clienthello_extensions.c index ef5e70fa3..5be3ec854 100644 --- a/nx_secure/src/nx_secure_tls_process_clienthello_extensions.c +++ b/nx_secure/src/nx_secure_tls_process_clienthello_extensions.c @@ -9,6 +9,8 @@ * SPDX-License-Identifier: MIT **************************************************************************/ +/* Portions of this file were generated with AI assistance. */ + /**************************************************************************/ /**************************************************************************/ @@ -533,6 +535,12 @@ UCHAR expected_signature = 0; for (j = 0; j < groups_len; j += 2) { group = (USHORT)((groups[j] << 8) + groups[j + 1]); +#if (NX_SECURE_TLS_TLS_1_3_ENABLED) + if (tls_session -> nx_secure_tls_1_3) + { + group = _nx_secure_tls_brainpool_group_from_wire(group); + } +#endif status = _nx_secure_tls_find_curve_method(&tls_session -> nx_secure_tls_ecc, group, &curve_method, &new_curve_priority); @@ -780,6 +788,7 @@ NX_SECURE_TLS_ECC *ecc_info; /* Get the key group. */ key_group = (USHORT)((packet_buffer[offset] << 8) + packet_buffer[offset + 1]); + key_group = _nx_secure_tls_brainpool_group_from_wire(key_group); offset = (USHORT)(offset + 2); /* Get the key length. */ @@ -1116,6 +1125,15 @@ NX_SECURE_X509_CERT *local_certificate = NX_NULL; case NX_CRYPTO_EC_SECP521R1: expected_sign_alg = NX_SECURE_TLS_SIGNATURE_ECDSA_SHA512; break; + case NX_CRYPTO_EC_BRAINPOOLP256r1: + expected_sign_alg = NX_SECURE_TLS_SIGNATURE_ECDSA_BRAINPOOLP256R1_SHA256; + break; + case NX_CRYPTO_EC_BRAINPOOLP384r1: + expected_sign_alg = NX_SECURE_TLS_SIGNATURE_ECDSA_BRAINPOOLP384R1_SHA384; + break; + case NX_CRYPTO_EC_BRAINPOOLP512r1: + expected_sign_alg = NX_SECURE_TLS_SIGNATURE_ECDSA_BRAINPOOLP512R1_SHA512; + break; default: return; } @@ -1216,6 +1234,15 @@ VOID _nx_secure_tls_get_signature_algorithm_id(UINT signature_algorithm, USHORT case NX_SECURE_TLS_SIGNATURE_ECDSA_SHA512: *signature_algorithm_id = NX_SECURE_TLS_X509_TYPE_ECDSA_SHA_512; break; + case NX_SECURE_TLS_SIGNATURE_ECDSA_BRAINPOOLP256R1_SHA256: + *signature_algorithm_id = NX_SECURE_TLS_X509_TYPE_ECDSA_SHA_256; + break; + case NX_SECURE_TLS_SIGNATURE_ECDSA_BRAINPOOLP384R1_SHA384: + *signature_algorithm_id = NX_SECURE_TLS_X509_TYPE_ECDSA_SHA_384; + break; + case NX_SECURE_TLS_SIGNATURE_ECDSA_BRAINPOOLP512R1_SHA512: + *signature_algorithm_id = NX_SECURE_TLS_X509_TYPE_ECDSA_SHA_512; + break; /* RSASSA-PSS schemes (RFC 8446 ยง4.2.3). Mapped to the same internal IDs as PKCS#1 v1.5 so the certificate cipher table lookup finds the (RSA, SHA-x) pair. PSS-vs-PKCS1 dispatch is done at signature-verify time. */ @@ -1571,6 +1598,3 @@ NX_SECURE_TLS_PSK_STORE *psk_store; return(NX_SUCCESS); } #endif - - - diff --git a/nx_secure/src/nx_secure_tls_process_serverhello_extensions.c b/nx_secure/src/nx_secure_tls_process_serverhello_extensions.c index d09a85ddd..6ef394358 100644 --- a/nx_secure/src/nx_secure_tls_process_serverhello_extensions.c +++ b/nx_secure/src/nx_secure_tls_process_serverhello_extensions.c @@ -9,6 +9,8 @@ * SPDX-License-Identifier: MIT **************************************************************************/ +/* Portions of this file were generated with AI assistance. */ + /**************************************************************************/ /**************************************************************************/ @@ -805,6 +807,7 @@ NX_SECURE_TLS_ECC *ecc_info; /* Check the key group. */ key_group = (USHORT)((ULONG)key_group | NX_CRYPTO_EC_MASK); + key_group = _nx_secure_tls_brainpool_group_from_wire(key_group); /* Loop through all supported ECC curves in this session. */ diff --git a/nx_secure/src/nx_secure_tls_send_certificate_request.c b/nx_secure/src/nx_secure_tls_send_certificate_request.c index 1a33b4d8b..9d8c15616 100644 --- a/nx_secure/src/nx_secure_tls_send_certificate_request.c +++ b/nx_secure/src/nx_secure_tls_send_certificate_request.c @@ -9,6 +9,8 @@ * SPDX-License-Identifier: MIT **************************************************************************/ +/* Portions of this file were generated with AI assistance. */ + /**************************************************************************/ /**************************************************************************/ @@ -177,6 +179,15 @@ UINT sign_alg; case (NX_CRYPTO_EC_SECP521R1 & 0x00FF): sign_alg = NX_SECURE_TLS_SIGNATURE_ECDSA_SHA512; break; + case (NX_CRYPTO_EC_BRAINPOOLP256r1 & 0x00FF): + sign_alg = NX_SECURE_TLS_SIGNATURE_ECDSA_BRAINPOOLP256R1_SHA256; + break; + case (NX_CRYPTO_EC_BRAINPOOLP384r1 & 0x00FF): + sign_alg = NX_SECURE_TLS_SIGNATURE_ECDSA_BRAINPOOLP384R1_SHA384; + break; + case (NX_CRYPTO_EC_BRAINPOOLP512r1 & 0x00FF): + sign_alg = NX_SECURE_TLS_SIGNATURE_ECDSA_BRAINPOOLP512R1_SHA512; + break; default: continue; } @@ -265,4 +276,3 @@ UINT sign_alg; return(NX_SUCCESS); } - diff --git a/nx_secure/src/nx_secure_tls_send_certificate_verify.c b/nx_secure/src/nx_secure_tls_send_certificate_verify.c index d9004107c..b9c965d54 100644 --- a/nx_secure/src/nx_secure_tls_send_certificate_verify.c +++ b/nx_secure/src/nx_secure_tls_send_certificate_verify.c @@ -123,6 +123,9 @@ const CHAR client_context[] = "TLS 1.3, client CertificateVerify\0"; /* Includes #ifdef NX_SECURE_ENABLE_ECC_CIPHERSUITE const NX_CRYPTO_METHOD *curve_method_cert; NX_SECURE_EC_PRIVATE_KEY *ec_privkey; +#if (NX_SECURE_TLS_TLS_1_3_ENABLED) +UINT brainpool_expected_curve = 0u; +#endif NX_SECURE_EC_PUBLIC_KEY *ec_pubkey; UCHAR *ecdsa_hash; NX_SECURE_EC_PRIVATE_KEY ec_hardware_privkey; @@ -212,6 +215,15 @@ NX_CRYPTO_EXTENDED_OUTPUT extended_output; case NX_SECURE_TLS_SIGNATURE_ECDSA_SHA512: signature_algorithm = NX_SECURE_TLS_X509_TYPE_ECDSA_SHA_512; break; + case NX_SECURE_TLS_SIGNATURE_ECDSA_BRAINPOOLP256R1_SHA256: + signature_algorithm = NX_SECURE_TLS_X509_TYPE_ECDSA_SHA_256; + break; + case NX_SECURE_TLS_SIGNATURE_ECDSA_BRAINPOOLP384R1_SHA384: + signature_algorithm = NX_SECURE_TLS_X509_TYPE_ECDSA_SHA_384; + break; + case NX_SECURE_TLS_SIGNATURE_ECDSA_BRAINPOOLP512R1_SHA512: + signature_algorithm = NX_SECURE_TLS_X509_TYPE_ECDSA_SHA_512; + break; case NX_SECURE_TLS_SIGNATURE_RSA_PSS_RSAE_SHA256: signature_algorithm = NX_SECURE_TLS_X509_TYPE_RSA_SHA_256; break; @@ -852,6 +864,7 @@ NX_CRYPTO_EXTENDED_OUTPUT extended_output; { data_size = handshake_hash_length; current_buffer[length] = (UCHAR)((tls_session -> nx_secure_tls_signature_algorithm) >> 8); + current_buffer[length + 1] = (UCHAR)(tls_session -> nx_secure_tls_signature_algorithm); } else #endif @@ -859,8 +872,8 @@ NX_CRYPTO_EXTENDED_OUTPUT extended_output; /* Hash size is SHA-256 hash size (32). */ data_size = 32; current_buffer[length] = NX_SECURE_TLS_HASH_ALGORITHM_SHA256; /* We only support SHA-256 right now. */ + current_buffer[length + 1] = NX_SECURE_TLS_SIGNATURE_ALGORITHM_ECDSA; } - current_buffer[length + 1] = NX_SECURE_TLS_SIGNATURE_ALGORITHM_ECDSA; /* ECDSA */ length += 2; } #endif @@ -897,6 +910,33 @@ NX_CRYPTO_EXTENDED_OUTPUT extended_output; { ec_privkey = &local_certificate -> nx_secure_x509_private_key.ec_private_key; } + +#if (NX_SECURE_TLS_TLS_1_3_ENABLED) + if (tls_session -> nx_secure_tls_1_3) + { + switch (tls_session -> nx_secure_tls_signature_algorithm) + { + case NX_SECURE_TLS_SIGNATURE_ECDSA_BRAINPOOLP256R1_SHA256: + brainpool_expected_curve = NX_CRYPTO_EC_BRAINPOOLP256r1; + break; + case NX_SECURE_TLS_SIGNATURE_ECDSA_BRAINPOOLP384R1_SHA384: + brainpool_expected_curve = NX_CRYPTO_EC_BRAINPOOLP384r1; + break; + case NX_SECURE_TLS_SIGNATURE_ECDSA_BRAINPOOLP512R1_SHA512: + brainpool_expected_curve = NX_CRYPTO_EC_BRAINPOOLP512r1; + break; + default: + break; + } + if (((brainpool_expected_curve != 0u) || + ((ec_privkey -> nx_secure_ec_named_curve >= NX_CRYPTO_EC_BRAINPOOLP256r1) && + (ec_privkey -> nx_secure_ec_named_curve <= NX_CRYPTO_EC_BRAINPOOLP512r1))) && + (brainpool_expected_curve != ec_privkey -> nx_secure_ec_named_curve)) + { + return(NX_SECURE_TLS_UNSUPPORTED_CERT_SIGN_ALG); + } + } +#endif ec_pubkey = &local_certificate -> nx_secure_x509_public_key.ec_public_key; /* Find out which named curve the local certificate is using. */ @@ -1021,4 +1061,3 @@ NX_CRYPTO_EXTENDED_OUTPUT extended_output; return(NX_NOT_SUPPORTED); #endif } - diff --git a/nx_secure/src/nx_secure_tls_send_clienthello_extensions.c b/nx_secure/src/nx_secure_tls_send_clienthello_extensions.c index ad0b98799..b5b305f7a 100644 --- a/nx_secure/src/nx_secure_tls_send_clienthello_extensions.c +++ b/nx_secure/src/nx_secure_tls_send_clienthello_extensions.c @@ -30,6 +30,47 @@ #ifndef NX_SECURE_DISABLE_X509 #define NX_SECURE_TLS_SIGNATURE_ALGORITHMS_LIST_MAX_LENGTH (0xFFFFu - 6u) +#if (NX_SECURE_TLS_TLS_1_3_ENABLED) && defined(NX_SECURE_ENABLE_ECC_CIPHERSUITE) +/* Select the TLS 1.3 signature scheme for a supported Brainpool curve. */ +static USHORT _nx_secure_tls_brainpool_signature_scheme(NX_SECURE_TLS_SESSION *tls_session, + USHORT named_curve) +{ + UINT i; + USHORT x509_type; + USHORT signature_scheme; + + switch (named_curve) + { + case (USHORT)NX_CRYPTO_EC_BRAINPOOLP256r1: + x509_type = NX_SECURE_TLS_X509_TYPE_ECDSA_SHA_256; + signature_scheme = NX_SECURE_TLS_SIGNATURE_ECDSA_BRAINPOOLP256R1_SHA256; + break; + case (USHORT)NX_CRYPTO_EC_BRAINPOOLP384r1: + x509_type = NX_SECURE_TLS_X509_TYPE_ECDSA_SHA_384; + signature_scheme = NX_SECURE_TLS_SIGNATURE_ECDSA_BRAINPOOLP384R1_SHA384; + break; + case (USHORT)NX_CRYPTO_EC_BRAINPOOLP512r1: + x509_type = NX_SECURE_TLS_X509_TYPE_ECDSA_SHA_512; + signature_scheme = NX_SECURE_TLS_SIGNATURE_ECDSA_BRAINPOOLP512R1_SHA512; + break; + default: + return(0u); + } + + for (i = 0; i < tls_session -> nx_secure_tls_crypto_table -> nx_secure_tls_x509_cipher_table_size; i++) + { + NX_SECURE_X509_CRYPTO *method = &tls_session -> nx_secure_tls_crypto_table -> nx_secure_tls_x509_cipher_table[i]; + if ((method -> nx_secure_x509_crypto_identifier == x509_type) && + (method -> nx_secure_x509_public_cipher_method != NX_NULL) && + (method -> nx_secure_x509_public_cipher_method -> nx_crypto_algorithm == NX_CRYPTO_DIGITAL_SIGNATURE_ECDSA)) + { + return(signature_scheme); + } + } + return(0u); +} +#endif + static VOID _nx_secure_tls_get_signature_algorithm(NX_SECURE_TLS_SESSION *tls_session, NX_SECURE_X509_CRYPTO *crypto_method, USHORT *signature_algorithm); @@ -365,6 +406,21 @@ NX_SECURE_X509_CRYPTO *cipher_table; } } +#if (NX_SECURE_TLS_TLS_1_3_ENABLED) && defined(NX_SECURE_ENABLE_ECC_CIPHERSUITE) + if (tls_session -> nx_secure_tls_1_3) + { + for (i = 0; i < tls_session -> nx_secure_tls_ecc.nx_secure_tls_ecc_supported_groups_count; i++) + { + signature_algorithm = _nx_secure_tls_brainpool_signature_scheme(tls_session, + tls_session -> nx_secure_tls_ecc.nx_secure_tls_ecc_supported_groups[i]); + if (signature_algorithm != 0u) + { + signature_algorithms_length += 2u; + } + } + } +#endif + if ((signature_algorithms_length > NX_SECURE_TLS_SIGNATURE_ALGORITHMS_LIST_MAX_LENGTH) || (*packet_offset > available_size) || ((available_size - *packet_offset) < (6u + signature_algorithms_length))) @@ -410,6 +466,23 @@ NX_SECURE_X509_CRYPTO *cipher_table; #endif } +#if (NX_SECURE_TLS_TLS_1_3_ENABLED) && defined(NX_SECURE_ENABLE_ECC_CIPHERSUITE) + if (tls_session -> nx_secure_tls_1_3) + { + for (i = 0; i < tls_session -> nx_secure_tls_ecc.nx_secure_tls_ecc_supported_groups_count; i++) + { + signature_algorithm = _nx_secure_tls_brainpool_signature_scheme(tls_session, + tls_session -> nx_secure_tls_ecc.nx_secure_tls_ecc_supported_groups[i]); + if (signature_algorithm != 0u) + { + packet_buffer[offset] = (UCHAR)(signature_algorithm >> 8); + packet_buffer[offset + 1] = (UCHAR)signature_algorithm; + offset += 2; + } + } + } +#endif + ext = NX_SECURE_TLS_EXTENSION_SIGNATURE_ALGORITHMS; /* Signature algorithms */ ext_len = (USHORT)(ext_len + 2); @@ -512,6 +585,12 @@ UCHAR sig_algo = 0; *signature_algorithm = 0; + if ((crypto_method -> nx_secure_x509_public_cipher_method == NX_NULL) || + (crypto_method -> nx_secure_x509_hash_method == NX_NULL)) + { + return; + } + switch (crypto_method -> nx_secure_x509_public_cipher_method -> nx_crypto_algorithm) { case NX_CRYPTO_KEY_EXCHANGE_RSA: @@ -865,6 +944,7 @@ USHORT named_curve; /* Get the curve for the key we are sending. */ named_curve = (USHORT)ecdhe_data->nx_secure_tls_ecdhe_named_curve; + named_curve = _nx_secure_tls_brainpool_group_to_wire(named_curve); /* Key length will differ for each curve. For p256, 32 octets per coordinate, plus the "legacy_form" byte. */ key_length = ecdhe_data->nx_secure_tls_ecdhe_public_key_length; @@ -1772,8 +1852,15 @@ NX_SECURE_TLS_ECC *ecc_info; for (i = 0; i < ecc_info -> nx_secure_tls_ecc_supported_groups_count; i++) { - packet_buffer[offset] = (UCHAR)((ecc_info -> nx_secure_tls_ecc_supported_groups[i] & 0xFF00) >> 8); - packet_buffer[offset + 1] = (UCHAR)(ecc_info -> nx_secure_tls_ecc_supported_groups[i] & 0x00FF); + USHORT named_group = ecc_info -> nx_secure_tls_ecc_supported_groups[i]; +#if (NX_SECURE_TLS_TLS_1_3_ENABLED) + if (tls_session -> nx_secure_tls_1_3) + { + named_group = _nx_secure_tls_brainpool_group_to_wire(named_group); + } +#endif + packet_buffer[offset] = (UCHAR)((named_group & 0xFF00) >> 8); + packet_buffer[offset + 1] = (UCHAR)(named_group & 0x00FF); offset += 2; } diff --git a/nx_secure/src/nx_secure_tls_send_serverhello_extensions.c b/nx_secure/src/nx_secure_tls_send_serverhello_extensions.c index c6132beb9..52d279e1e 100644 --- a/nx_secure/src/nx_secure_tls_send_serverhello_extensions.c +++ b/nx_secure/src/nx_secure_tls_send_serverhello_extensions.c @@ -9,6 +9,8 @@ * SPDX-License-Identifier: MIT **************************************************************************/ +/* Portions of this file were generated with AI assistance. */ + /**************************************************************************/ /**************************************************************************/ @@ -603,6 +605,7 @@ USHORT named_curve; i = tls_session -> nx_secure_tls_key_material.nx_secure_tls_ecc_key_data_selected; ecdhe_data = &(tls_session -> nx_secure_tls_key_material.nx_secure_tls_ecc_key_data[i]); named_curve = (USHORT)(ecdhe_data -> nx_secure_tls_ecdhe_named_curve); + named_curve = _nx_secure_tls_brainpool_group_to_wire(named_curve); if (tls_session -> nx_secure_tls_server_state == NX_SECURE_TLS_SERVER_STATE_SEND_HELLO_RETRY) { @@ -825,4 +828,3 @@ USHORT ext; } #endif - diff --git a/nx_secure/src/nx_secure_x509_oid_parse.c b/nx_secure/src/nx_secure_x509_oid_parse.c index c063a387e..e04f5a8fb 100644 --- a/nx_secure/src/nx_secure_x509_oid_parse.c +++ b/nx_secure/src/nx_secure_x509_oid_parse.c @@ -9,6 +9,8 @@ * SPDX-License-Identifier: MIT **************************************************************************/ +/* Portions of this file were generated with AI assistance. */ + /**************************************************************************/ /**************************************************************************/ @@ -136,6 +138,9 @@ static const UCHAR NX_SECURE_X509_OID_SECP224R1[] = {0x2B, 0x81, 0x04, 0x static const UCHAR NX_SECURE_X509_OID_SECP256R1[] = {0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x03, 0x01, 0x07}; /* ISO.USA.10045.3.1.7 - Named curve: secp256r1. */ static const UCHAR NX_SECURE_X509_OID_SECP384R1[] = {0x2B, 0x81, 0x04, 0x00, 0x22}; /* ISO.Identified Organization.Certicom.curve.34 - Named curve: secp384r1. */ static const UCHAR NX_SECURE_X509_OID_SECP521R1[] = {0x2B, 0x81, 0x04, 0x00, 0x23}; /* ISO.Identified Organization.Certicom.curve.35 - Named curve: secp521r1. */ +static const UCHAR NX_SECURE_X509_OID_BRAINPOOLP256R1[] = {0x2B, 0x24, 0x03, 0x03, 0x02, 0x08, 0x01, 0x01, 0x07}; /* RFC 5639 brainpoolP256r1. */ +static const UCHAR NX_SECURE_X509_OID_BRAINPOOLP384R1[] = {0x2B, 0x24, 0x03, 0x03, 0x02, 0x08, 0x01, 0x01, 0x0B}; /* RFC 5639 brainpoolP384r1. */ +static const UCHAR NX_SECURE_X509_OID_BRAINPOOLP512R1[] = {0x2B, 0x24, 0x03, 0x03, 0x02, 0x08, 0x01, 0x01, 0x0D}; /* RFC 5639 brainpoolP512r1. */ static const UCHAR NX_SECURE_X509_OID_ECDSA_SHA1[] = {0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x04, 0x01}; /* ISO.USA.10045.4.1 - ecdsa-with-SHA1. */ static const UCHAR NX_SECURE_X509_OID_ECDSA_SHA224[] = {0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x04, 0x03, 0x01}; /* ISO.USA.10045.4.3.1 - ecdsa-with-SHA224. */ static const UCHAR NX_SECURE_X509_OID_ECDSA_SHA256[] = {0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x04, 0x03, 0x02}; /* ISO.USA.10045.4.3.2 - ecdsa-with-SHA256. */ @@ -216,6 +221,9 @@ NX_SECURE_X509_OID_MAP _nx_secure_x509_oid_map[] = {NX_SECURE_TLS_X509_EC_SECP256R1 , NX_SECURE_X509_OID_SECP256R1 , sizeof(NX_SECURE_X509_OID_SECP256R1)}, {NX_SECURE_TLS_X509_EC_SECP384R1 , NX_SECURE_X509_OID_SECP384R1 , sizeof(NX_SECURE_X509_OID_SECP384R1)}, {NX_SECURE_TLS_X509_EC_SECP521R1 , NX_SECURE_X509_OID_SECP521R1 , sizeof(NX_SECURE_X509_OID_SECP521R1)}, + {NX_SECURE_TLS_X509_EC_BRAINPOOLP256R1 , NX_SECURE_X509_OID_BRAINPOOLP256R1 , sizeof(NX_SECURE_X509_OID_BRAINPOOLP256R1)}, + {NX_SECURE_TLS_X509_EC_BRAINPOOLP384R1 , NX_SECURE_X509_OID_BRAINPOOLP384R1 , sizeof(NX_SECURE_X509_OID_BRAINPOOLP384R1)}, + {NX_SECURE_TLS_X509_EC_BRAINPOOLP512R1 , NX_SECURE_X509_OID_BRAINPOOLP512R1 , sizeof(NX_SECURE_X509_OID_BRAINPOOLP512R1)}, {NX_SECURE_TLS_X509_TYPE_ECDSA_SHA_1 , NX_SECURE_X509_OID_ECDSA_SHA1 , sizeof(NX_SECURE_X509_OID_ECDSA_SHA1)}, {NX_SECURE_TLS_X509_TYPE_ECDSA_SHA_224 , NX_SECURE_X509_OID_ECDSA_SHA224 , sizeof(NX_SECURE_X509_OID_ECDSA_SHA224)}, {NX_SECURE_TLS_X509_TYPE_ECDSA_SHA_256 , NX_SECURE_X509_OID_ECDSA_SHA256 , sizeof(NX_SECURE_X509_OID_ECDSA_SHA256)}, @@ -296,4 +304,3 @@ UINT i; *oid_value = NX_SECURE_TLS_X509_TYPE_UNKNOWN; } - diff --git a/test/cmake/crypto/regression/CMakeLists.txt b/test/cmake/crypto/regression/CMakeLists.txt index 86d52fd2a..2763165a1 100644 --- a/test/cmake/crypto/regression/CMakeLists.txt +++ b/test/cmake/crypto/regression/CMakeLists.txt @@ -34,6 +34,7 @@ set(crypto_test_cases ${SOURCE_DIR}/nx_secure_ecdh_error_checking_test.c ${SOURCE_DIR}/nx_secure_ecdh_self_test.c ${SOURCE_DIR}/nx_secure_ecdsa_test.c + ${SOURCE_DIR}/nx_secure_brainpool_test.c ${SOURCE_DIR}/nx_secure_ecdsa_error_checking_test.c ${SOURCE_DIR}/nx_secure_ecjpake_self_test.c ${SOURCE_DIR}/nx_secure_huge_number_test.c @@ -55,11 +56,8 @@ endif() target_include_directories(test_utility PUBLIC ${SOURCE_DIR}/test) target_compile_definitions(test_utility PUBLIC BATCH_TEST CTEST) -if((NOT MSVC) AND (("${CMAKE_BUILD_TYPE}" STREQUAL "fips_build_coverage") OR ("${CMAKE_BUILD_TYPE}" STREQUAL "standalone_build"))) - # On Linux the crypto library is built separately (run.sh build_libs) and must - # be linked explicitly. On MSVC the crypto_libraries sources are compiled into - # netxduo (see ../CMakeLists.txt), so there is no standalone "crypto" target to - # link against and doing so fails with LNK1181. +if((NOT MSVC) AND ("${CMAKE_BUILD_TYPE}" STREQUAL "fips_build_coverage")) + # The Linux FIPS build uses the separately built crypto library. target_link_libraries(test_utility PUBLIC crypto) endif() diff --git a/test/regression/nx_secure_test/brainpool_certs.c b/test/regression/nx_secure_test/brainpool_certs.c new file mode 100644 index 000000000..197eac0be --- /dev/null +++ b/test/regression/nx_secure_test/brainpool_certs.c @@ -0,0 +1,109 @@ +/*************************************************************************** + * Copyright (c) 2026 Eclipse ThreadX contributors + * + * This program and the accompanying materials are made available under the + * terms of the MIT License which is available at + * https://opensource.org/licenses/MIT. + * + * AI Disclosure: This file was largely AI-generated by Codex (GPT-6-Sol). + * The AI-generated portions may be considered public domain (CC0-1.0) + * and not subject to the project's licence. The human contributor has + * reviewed and verified that the code is correct. + * + * SPDX-License-Identifier: MIT and CC0-1.0 + ***************************************************************************/ + +/* DER test certificates use the RFC 5639 brainpoolP256r1 curve. */ +static UCHAR brainpool_root_der[] = { + 0x30, 0x82, 0x01, 0xa1, 0x30, 0x82, 0x01, 0x48, 0xa0, 0x03, 0x02, 0x01, + 0x02, 0x02, 0x14, 0x02, 0x85, 0x49, 0xb8, 0x01, 0xcb, 0x51, 0x9c, 0x5c, + 0xfc, 0x84, 0x37, 0x3b, 0x7f, 0x06, 0x98, 0xa3, 0x84, 0xfe, 0xfc, 0x30, + 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x30, + 0x1e, 0x31, 0x1c, 0x30, 0x1a, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x13, + 0x42, 0x72, 0x61, 0x69, 0x6e, 0x70, 0x6f, 0x6f, 0x6c, 0x20, 0x54, 0x65, + 0x73, 0x74, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x30, 0x1e, 0x17, 0x0d, 0x32, + 0x36, 0x30, 0x39, 0x32, 0x38, 0x32, 0x30, 0x30, 0x39, 0x34, 0x38, 0x5a, + 0x17, 0x0d, 0x34, 0x36, 0x30, 0x39, 0x32, 0x33, 0x32, 0x30, 0x30, 0x39, + 0x34, 0x38, 0x5a, 0x30, 0x1e, 0x31, 0x1c, 0x30, 0x1a, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x0c, 0x13, 0x42, 0x72, 0x61, 0x69, 0x6e, 0x70, 0x6f, 0x6f, + 0x6c, 0x20, 0x54, 0x65, 0x73, 0x74, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x30, + 0x5a, 0x30, 0x14, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01, + 0x06, 0x09, 0x2b, 0x24, 0x03, 0x03, 0x02, 0x08, 0x01, 0x01, 0x07, 0x03, + 0x42, 0x00, 0x04, 0x3a, 0xa8, 0x08, 0x1b, 0xc5, 0xd0, 0x2a, 0x94, 0xe8, + 0x40, 0x29, 0xd3, 0x1d, 0x4d, 0x31, 0xdd, 0xed, 0x68, 0x5d, 0xe4, 0x96, + 0x91, 0xb5, 0x44, 0x23, 0xaa, 0xab, 0x2b, 0x25, 0xaf, 0x50, 0x8c, 0x80, + 0xc7, 0x5d, 0xf3, 0x88, 0xb7, 0x47, 0x74, 0xe7, 0x9b, 0x14, 0x8b, 0x39, + 0xaa, 0xa5, 0x7e, 0x44, 0x7e, 0xdc, 0x3d, 0x12, 0xa3, 0xe9, 0xeb, 0x98, + 0x57, 0x7a, 0xdc, 0x42, 0xeb, 0xbb, 0xb2, 0xa3, 0x63, 0x30, 0x61, 0x30, + 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0xfb, 0xe0, + 0xaf, 0x37, 0xf0, 0x64, 0x59, 0x03, 0xef, 0x21, 0x7e, 0x33, 0x5a, 0xc8, + 0xf8, 0x7c, 0x38, 0x2f, 0x33, 0xc9, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, + 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0xfb, 0xe0, 0xaf, 0x37, 0xf0, + 0x64, 0x59, 0x03, 0xef, 0x21, 0x7e, 0x33, 0x5a, 0xc8, 0xf8, 0x7c, 0x38, + 0x2f, 0x33, 0xc9, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, + 0xff, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x0e, 0x06, 0x03, + 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, + 0x30, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, + 0x03, 0x47, 0x00, 0x30, 0x44, 0x02, 0x20, 0x4e, 0x4a, 0xf1, 0xee, 0x8b, + 0x94, 0x25, 0x3f, 0xeb, 0x69, 0xf0, 0x0d, 0x19, 0x8a, 0x9b, 0xe2, 0x17, + 0x86, 0xca, 0x04, 0xe9, 0x81, 0xee, 0x4c, 0x94, 0xea, 0x14, 0x7c, 0x63, + 0xc2, 0x5c, 0xec, 0x02, 0x20, 0x01, 0xe2, 0xdb, 0x48, 0x8a, 0xbf, 0x0c, + 0x38, 0xd6, 0x50, 0x54, 0x69, 0xab, 0xf8, 0xbe, 0xcf, 0x09, 0x0f, 0x91, + 0x47, 0xff, 0x99, 0xb2, 0x44, 0x55, 0x20, 0x47, 0xd2, 0x56, 0x80, 0xba, + 0x4b, +}; + +static UCHAR brainpool_server_der[] = { + 0x30, 0x82, 0x01, 0xc1, 0x30, 0x82, 0x01, 0x68, 0xa0, 0x03, 0x02, 0x01, + 0x02, 0x02, 0x14, 0x61, 0x86, 0x04, 0x63, 0xb6, 0x79, 0x20, 0xa0, 0x62, + 0x5e, 0x23, 0xb6, 0xac, 0x54, 0x87, 0x5d, 0xba, 0x3c, 0x68, 0xca, 0x30, + 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x30, + 0x1e, 0x31, 0x1c, 0x30, 0x1a, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x13, + 0x42, 0x72, 0x61, 0x69, 0x6e, 0x70, 0x6f, 0x6f, 0x6c, 0x20, 0x54, 0x65, + 0x73, 0x74, 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x30, 0x1e, 0x17, 0x0d, 0x32, + 0x36, 0x30, 0x39, 0x32, 0x38, 0x32, 0x30, 0x30, 0x39, 0x34, 0x38, 0x5a, + 0x17, 0x0d, 0x34, 0x36, 0x30, 0x39, 0x32, 0x33, 0x32, 0x30, 0x30, 0x39, + 0x34, 0x38, 0x5a, 0x30, 0x14, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x0c, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73, + 0x74, 0x30, 0x5a, 0x30, 0x14, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, + 0x02, 0x01, 0x06, 0x09, 0x2b, 0x24, 0x03, 0x03, 0x02, 0x08, 0x01, 0x01, + 0x07, 0x03, 0x42, 0x00, 0x04, 0xa3, 0xee, 0x68, 0x8c, 0xd8, 0xc0, 0x62, + 0x1f, 0x16, 0xf0, 0x26, 0xc8, 0xea, 0xac, 0x9b, 0x4e, 0xfd, 0x5b, 0x31, + 0xeb, 0xd9, 0x6a, 0x8b, 0xdf, 0xe7, 0x55, 0x10, 0xae, 0xb8, 0xfb, 0xc1, + 0x76, 0x38, 0x3c, 0xf9, 0xac, 0x68, 0xaa, 0xbf, 0x37, 0xac, 0x6f, 0x1a, + 0xa8, 0x7d, 0x03, 0xf5, 0xc1, 0x12, 0x38, 0x23, 0x0d, 0x24, 0xcd, 0xa0, + 0x3c, 0x2b, 0x06, 0x3b, 0xa3, 0x7d, 0xee, 0x3c, 0x4c, 0xa3, 0x81, 0x8c, + 0x30, 0x81, 0x89, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, + 0xff, 0x04, 0x02, 0x30, 0x00, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, + 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x07, 0x80, 0x30, 0x13, 0x06, + 0x03, 0x55, 0x1d, 0x25, 0x04, 0x0c, 0x30, 0x0a, 0x06, 0x08, 0x2b, 0x06, + 0x01, 0x05, 0x05, 0x07, 0x03, 0x01, 0x30, 0x14, 0x06, 0x03, 0x55, 0x1d, + 0x11, 0x04, 0x0d, 0x30, 0x0b, 0x82, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, + 0x68, 0x6f, 0x73, 0x74, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, + 0x16, 0x04, 0x14, 0x80, 0x53, 0x8e, 0xc5, 0x05, 0x58, 0x9f, 0xb3, 0xc5, + 0x17, 0xd5, 0x34, 0xb7, 0x7d, 0x67, 0x9e, 0xf7, 0xdf, 0x79, 0x8a, 0x30, + 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, + 0xfb, 0xe0, 0xaf, 0x37, 0xf0, 0x64, 0x59, 0x03, 0xef, 0x21, 0x7e, 0x33, + 0x5a, 0xc8, 0xf8, 0x7c, 0x38, 0x2f, 0x33, 0xc9, 0x30, 0x0a, 0x06, 0x08, + 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x03, 0x47, 0x00, 0x30, + 0x44, 0x02, 0x20, 0x33, 0x80, 0x19, 0xe0, 0x26, 0xd2, 0x9b, 0x14, 0xab, + 0x70, 0x6c, 0x70, 0xb7, 0xe4, 0x9c, 0x25, 0xc9, 0x1e, 0xee, 0x7c, 0x98, + 0xf7, 0x91, 0xc3, 0xc4, 0x09, 0x52, 0x78, 0x4b, 0x9f, 0xf5, 0xbe, 0x02, + 0x20, 0x07, 0x9e, 0xd4, 0x2c, 0x7f, 0x22, 0x7c, 0x65, 0xd1, 0xd9, 0x1f, + 0x32, 0x53, 0x29, 0x28, 0x13, 0x51, 0x0d, 0x97, 0xa9, 0x0a, 0xec, 0x05, + 0xc2, 0xeb, 0xdf, 0x32, 0x7b, 0xfa, 0x0f, 0x83, 0xde, +}; + +static UCHAR brainpool_server_key_der[] = { + 0x30, 0x78, 0x02, 0x01, 0x01, 0x04, 0x20, 0xa6, 0x66, 0xf2, 0xa2, 0x01, + 0x1a, 0xb3, 0xda, 0x05, 0x35, 0xe6, 0xf9, 0xb0, 0xe1, 0xae, 0x02, 0x80, + 0xe9, 0x4c, 0xe7, 0x5a, 0x51, 0xc5, 0xe3, 0x4b, 0x38, 0x65, 0x4d, 0xd6, + 0x42, 0x20, 0x62, 0xa0, 0x0b, 0x06, 0x09, 0x2b, 0x24, 0x03, 0x03, 0x02, + 0x08, 0x01, 0x01, 0x07, 0xa1, 0x44, 0x03, 0x42, 0x00, 0x04, 0xa3, 0xee, + 0x68, 0x8c, 0xd8, 0xc0, 0x62, 0x1f, 0x16, 0xf0, 0x26, 0xc8, 0xea, 0xac, + 0x9b, 0x4e, 0xfd, 0x5b, 0x31, 0xeb, 0xd9, 0x6a, 0x8b, 0xdf, 0xe7, 0x55, + 0x10, 0xae, 0xb8, 0xfb, 0xc1, 0x76, 0x38, 0x3c, 0xf9, 0xac, 0x68, 0xaa, + 0xbf, 0x37, 0xac, 0x6f, 0x1a, 0xa8, 0x7d, 0x03, 0xf5, 0xc1, 0x12, 0x38, + 0x23, 0x0d, 0x24, 0xcd, 0xa0, 0x3c, 0x2b, 0x06, 0x3b, 0xa3, 0x7d, 0xee, + 0x3c, 0x4c, +}; diff --git a/test/regression/nx_secure_test/nx_secure_brainpool_test.c b/test/regression/nx_secure_test/nx_secure_brainpool_test.c new file mode 100644 index 000000000..2e40ef817 --- /dev/null +++ b/test/regression/nx_secure_test/nx_secure_brainpool_test.c @@ -0,0 +1,435 @@ +/*************************************************************************** + * Copyright (c) 2026 Eclipse ThreadX contributors + * + * This program and the accompanying materials are made available under the + * terms of the MIT License which is available at + * https://opensource.org/licenses/MIT. + * + * AI Disclosure: This file was largely AI-generated by Codex (GPT-6-Sol). + * The AI-generated portions may be considered public domain (CC0-1.0) + * and not subject to the project's licence. The human contributor has + * reviewed and verified that the code is correct. + * + * SPDX-License-Identifier: MIT and CC0-1.0 + ***************************************************************************/ + +#include +#include +#include "nx_crypto_ecdsa.h" +#include "nx_crypto_ecdh.h" +#include "nx_crypto_ec.h" +#include "tls_test_utility.h" +#ifndef NX_CRYPTO_STANDALONE_ENABLE +#include "nx_secure_tls.h" +static TX_THREAD thread_0; +#endif + +extern NX_CRYPTO_METHOD crypto_method_ecdh; +extern NX_CRYPTO_METHOD crypto_method_ec_brainpoolp256; +extern NX_CRYPTO_METHOD crypto_method_ec_brainpoolp384; +extern NX_CRYPTO_METHOD crypto_method_ec_brainpoolp512; + +static UCHAR brainpool_256_hash[] = { + 0xcd, 0x73, 0x02, 0x24, 0x10, 0x0b, 0x5e, 0x46, 0x5c, 0x36, 0x8d, 0xaf, + 0x27, 0x2a, 0x81, 0x7a, 0xe3, 0x7b, 0x8f, 0x55, 0x84, 0xec, 0x84, 0x69, + 0x3c, 0x1d, 0xfe, 0x44, 0x85, 0xa8, 0xa7, 0xe1, +}; +static UCHAR brainpool_256_pub[] = { + 0x04, 0xa6, 0x06, 0x7e, 0x83, 0x3f, 0x60, 0xfa, 0x95, 0x87, 0x91, 0xea, + 0xbf, 0xdb, 0xb0, 0x47, 0x7d, 0xd4, 0x6c, 0x02, 0xcf, 0x1b, 0xe0, 0xbf, + 0x13, 0xa4, 0x9e, 0xeb, 0xb2, 0x06, 0x49, 0xca, 0xbb, 0x01, 0x31, 0xaa, + 0x4d, 0x28, 0x4e, 0xca, 0x96, 0xee, 0xfa, 0xf0, 0x88, 0x73, 0x4a, 0x01, + 0x8a, 0xfa, 0x1a, 0x9c, 0x47, 0x17, 0x55, 0xa4, 0x72, 0x76, 0x79, 0xcb, + 0x31, 0x44, 0x96, 0x53, 0xcc, +}; +static UCHAR brainpool_256_sig[] = { + 0x30, 0x44, 0x02, 0x20, 0x7b, 0xde, 0x18, 0xee, 0x45, 0x51, 0x9a, 0x14, + 0x8f, 0x01, 0xfc, 0x12, 0xfa, 0x71, 0x4a, 0xb0, 0xa0, 0x7c, 0x88, 0xf3, + 0xae, 0xdc, 0xfc, 0xd4, 0x38, 0x68, 0x7c, 0x02, 0x85, 0x8d, 0x84, 0x3b, + 0x02, 0x20, 0x23, 0x1c, 0x78, 0xe1, 0x0e, 0x63, 0x7a, 0x8a, 0xca, 0x31, + 0x08, 0x7f, 0x5a, 0xc7, 0x5e, 0x27, 0x4e, 0xa6, 0x17, 0x9a, 0xe5, 0xa9, + 0x42, 0x28, 0x7e, 0x6d, 0x01, 0xfe, 0xc5, 0x94, 0x06, 0xba, +}; +static UCHAR brainpool_384_hash[] = { + 0xce, 0x13, 0xda, 0xf1, 0x2c, 0xba, 0x05, 0x40, 0x26, 0x3b, 0x6b, 0x9b, + 0x90, 0xbb, 0x5f, 0xf8, 0x4e, 0x25, 0xc6, 0x1f, 0x85, 0x07, 0x6d, 0xca, + 0x97, 0x69, 0xc6, 0xc8, 0x96, 0x59, 0x71, 0xe0, 0x7b, 0xa0, 0x4f, 0x00, + 0x69, 0xdb, 0x98, 0x0b, 0xed, 0x38, 0xc7, 0xe0, 0xce, 0x51, 0x01, 0xe6, +}; +static UCHAR brainpool_384_pub[] = { + 0x04, 0x6c, 0xf4, 0xaa, 0x40, 0xd8, 0xc5, 0x47, 0xdb, 0x5f, 0xb9, 0xbe, + 0xab, 0x0e, 0xa1, 0x5a, 0xa9, 0xdc, 0xfb, 0x29, 0x18, 0x37, 0x36, 0x6f, + 0x17, 0x70, 0x11, 0x5a, 0x4c, 0x90, 0x49, 0x0b, 0xf2, 0xb3, 0xfc, 0x6a, + 0x82, 0x03, 0x87, 0x6b, 0xb1, 0x7d, 0x58, 0x65, 0x48, 0x3e, 0x89, 0x7c, + 0xd0, 0x69, 0xde, 0x3f, 0xed, 0x85, 0x77, 0xa7, 0x2f, 0x35, 0x8a, 0x5b, + 0x27, 0xb3, 0x0a, 0x20, 0x95, 0x14, 0x9c, 0xc5, 0x19, 0x27, 0xf6, 0xf3, + 0x07, 0x79, 0x3b, 0x4e, 0xb5, 0xe7, 0x62, 0x07, 0x18, 0xb1, 0x39, 0x8f, + 0xfa, 0xa0, 0x2b, 0x1a, 0x5e, 0x10, 0x90, 0x66, 0x91, 0x95, 0x77, 0xbb, + 0x2d, +}; +static UCHAR brainpool_384_sig[] = { + 0x30, 0x65, 0x02, 0x30, 0x57, 0x99, 0x3a, 0x6d, 0x6d, 0xb9, 0x2c, 0x7f, + 0x75, 0x8a, 0xc9, 0x5d, 0x43, 0x5c, 0x50, 0x0a, 0x89, 0x00, 0x73, 0x98, + 0x6b, 0xf0, 0x30, 0x5f, 0xad, 0xeb, 0xcc, 0x85, 0x01, 0x90, 0x00, 0x83, + 0x1e, 0x38, 0xeb, 0x7e, 0xe8, 0x66, 0xb3, 0x2b, 0x00, 0x5c, 0xcf, 0x76, + 0x95, 0xc8, 0x30, 0xe4, 0x02, 0x31, 0x00, 0x82, 0xd7, 0xd1, 0x7a, 0x57, + 0x6d, 0x78, 0xc1, 0x5a, 0xbb, 0xd1, 0xcf, 0x44, 0xbb, 0x18, 0x1a, 0x60, + 0x68, 0x56, 0x1c, 0x59, 0x73, 0x5d, 0x74, 0xb1, 0x97, 0x26, 0xc6, 0xf7, + 0x64, 0xcb, 0xd0, 0xba, 0x09, 0xd6, 0xc0, 0x1e, 0x1a, 0x54, 0x6e, 0x41, + 0xdb, 0x88, 0x7f, 0xda, 0x89, 0xff, 0x2d, +}; +static UCHAR brainpool_512_hash[] = { + 0x70, 0x5c, 0xab, 0x16, 0x5b, 0x5f, 0x41, 0x9f, 0xfe, 0xcd, 0x74, 0x0e, + 0x4c, 0x3d, 0x04, 0x2c, 0x42, 0xd8, 0xe1, 0x41, 0x84, 0x62, 0x81, 0x69, + 0xaf, 0xa1, 0x3d, 0x79, 0xf8, 0x40, 0x45, 0x2e, 0x17, 0xeb, 0xdb, 0x8a, + 0x60, 0x08, 0x6b, 0xa8, 0xee, 0xe4, 0x5b, 0xf5, 0x5e, 0x52, 0x06, 0x0e, + 0x36, 0x7b, 0xe5, 0x18, 0x7b, 0x6e, 0x08, 0x3b, 0x6f, 0x4f, 0x6c, 0x7f, + 0xf0, 0xf7, 0x98, 0x72, +}; +static UCHAR brainpool_512_pub[] = { + 0x04, 0x2a, 0x72, 0x5e, 0x1c, 0xd1, 0xf6, 0x67, 0x5e, 0xd0, 0x4d, 0x9b, + 0x25, 0x3b, 0x37, 0x48, 0x38, 0xf6, 0x77, 0x21, 0xb3, 0x14, 0x76, 0xaa, + 0xe3, 0x90, 0x28, 0xd3, 0xd7, 0xfc, 0x08, 0xd6, 0xb1, 0x00, 0x12, 0x2c, + 0xab, 0xec, 0xa7, 0x60, 0xc7, 0xb0, 0xab, 0xc8, 0x01, 0xa7, 0xe7, 0x08, + 0x22, 0x2f, 0x3f, 0xf0, 0xc9, 0x38, 0xcf, 0x70, 0xe1, 0x3f, 0xda, 0x83, + 0x74, 0x02, 0x2d, 0x0e, 0x72, 0x58, 0x9a, 0x3c, 0x4c, 0x62, 0xb1, 0xe7, + 0xd2, 0xb6, 0xdd, 0x7c, 0xfc, 0x6d, 0x06, 0xf1, 0xf2, 0xd1, 0x9b, 0xc4, + 0xdc, 0xf0, 0x53, 0x52, 0xb4, 0x83, 0xe8, 0x6c, 0xcd, 0x0c, 0x9e, 0x7f, + 0xef, 0x26, 0x3a, 0xc0, 0x9e, 0x54, 0x5d, 0xec, 0x59, 0x06, 0xa4, 0xdc, + 0x5d, 0x0f, 0x39, 0x6e, 0x5e, 0x2e, 0xa9, 0xc9, 0xf0, 0xa7, 0x8e, 0x20, + 0x2c, 0x03, 0xce, 0x13, 0x4a, 0x44, 0xea, 0xbc, 0xc8, +}; +static UCHAR brainpool_512_sig[] = { + 0x30, 0x81, 0x84, 0x02, 0x40, 0x2b, 0x6f, 0x08, 0xe0, 0xbe, 0x4d, 0x90, + 0x52, 0x97, 0x0a, 0x5f, 0x03, 0xba, 0xf1, 0x7c, 0x89, 0xbe, 0x00, 0x34, + 0x33, 0x63, 0xb0, 0x3b, 0x33, 0x60, 0x6d, 0x7b, 0xcd, 0xcb, 0x3c, 0x62, + 0x73, 0xdb, 0xfd, 0x73, 0xbb, 0xc6, 0x2e, 0x93, 0x12, 0x99, 0xdd, 0x03, + 0xeb, 0xe7, 0x90, 0xfb, 0x0f, 0xc8, 0x50, 0x71, 0xba, 0x89, 0x59, 0xce, + 0x80, 0x35, 0x73, 0x10, 0x30, 0x9c, 0x00, 0x19, 0x57, 0x02, 0x40, 0x69, + 0xb2, 0xb5, 0x72, 0x5f, 0x48, 0xe6, 0xd5, 0x04, 0xdd, 0x77, 0x99, 0xc7, + 0x94, 0x75, 0x52, 0x0e, 0xf0, 0x0d, 0xc0, 0xbe, 0xb1, 0xc5, 0x62, 0x82, + 0x8c, 0xf7, 0x72, 0xa5, 0x94, 0xb0, 0x8b, 0x67, 0x5f, 0x1a, 0x6e, 0x84, + 0x14, 0xb7, 0x28, 0x6d, 0x13, 0x20, 0xdb, 0x49, 0x3f, 0xbc, 0x66, 0xf2, + 0x68, 0x28, 0x88, 0x7b, 0x68, 0x32, 0x98, 0xe1, 0x14, 0xce, 0x59, 0xa8, + 0x15, 0x53, 0x21, +}; + +static UCHAR brainpool_256_ecdh_priv[] = { + 0x5b, 0xf6, 0xb8, 0xf9, 0x17, 0xa0, 0xe2, 0x51, 0x41, 0xa2, 0xe0, 0x3e, + 0x13, 0xef, 0xb1, 0xf0, 0x79, 0x47, 0xe5, 0x92, 0x21, 0x01, 0x2a, 0xd8, + 0x23, 0x42, 0xf3, 0x12, 0x93, 0x44, 0xdc, 0x06, +}; +static UCHAR brainpool_256_ecdh_local_pub[] = { + 0x04, 0x3a, 0xbe, 0x53, 0xb4, 0xfd, 0x2b, 0x0b, 0xc5, 0x60, 0xca, 0x34, + 0x8d, 0xdb, 0xb6, 0x4c, 0xdc, 0x4f, 0x73, 0xd2, 0x01, 0xd9, 0xb0, 0x76, + 0x75, 0x65, 0x4c, 0xa5, 0x6c, 0xb4, 0xc5, 0xda, 0xf2, 0x46, 0xd0, 0xbc, + 0x5e, 0xec, 0x93, 0x7b, 0x66, 0xd5, 0x58, 0xe8, 0x8a, 0x00, 0x6b, 0x74, + 0x61, 0xc4, 0x34, 0x3b, 0x3a, 0x36, 0xaf, 0xb8, 0xf3, 0xad, 0xf2, 0x9d, + 0xc8, 0x8e, 0xde, 0x24, 0x80, +}; +static UCHAR brainpool_256_ecdh_remote_pub[] = { + 0x04, 0xa8, 0x95, 0x6a, 0x68, 0xdc, 0x7e, 0x8a, 0xde, 0xdb, 0xe4, 0xa1, + 0x07, 0xe1, 0x0a, 0x86, 0x86, 0x5c, 0x2f, 0xc3, 0x2f, 0x6f, 0xa1, 0x5e, + 0x82, 0x27, 0x1d, 0x2b, 0x27, 0x8e, 0xf1, 0x84, 0xfc, 0x5c, 0x8d, 0x6a, + 0x6c, 0xcb, 0xd0, 0xc6, 0xe5, 0x90, 0xd6, 0xe6, 0xe6, 0xc0, 0x71, 0x4a, + 0x9d, 0x0e, 0x6a, 0x09, 0xef, 0xab, 0xdd, 0xb6, 0x90, 0xa4, 0xde, 0x95, + 0x46, 0x3b, 0xe7, 0x8d, 0x4a, +}; +static UCHAR brainpool_256_ecdh_secret[] = { + 0x81, 0x71, 0xd2, 0xff, 0xbb, 0x11, 0x52, 0x7d, 0x37, 0x01, 0x03, 0xa6, + 0xd5, 0x90, 0x4e, 0x1e, 0xfb, 0xa4, 0xf2, 0xcc, 0x1b, 0x52, 0x17, 0xd4, + 0xa0, 0x15, 0x57, 0xc7, 0x1c, 0x8e, 0x65, 0xae, +}; +static UCHAR brainpool_384_ecdh_priv[] = { + 0x19, 0x7a, 0xf4, 0x20, 0xe9, 0x3c, 0x5d, 0x87, 0xc3, 0x08, 0xb1, 0xac, + 0x37, 0xef, 0xcc, 0x95, 0xd6, 0x9d, 0x75, 0xd3, 0x69, 0x6e, 0x9d, 0xae, + 0xca, 0x13, 0xa3, 0x88, 0x56, 0xa3, 0x57, 0x28, 0x2a, 0xf2, 0x10, 0x06, + 0xdc, 0x07, 0x99, 0xf9, 0x49, 0xd0, 0x3f, 0xab, 0x1b, 0xf6, 0xf4, 0xf5, +}; +static UCHAR brainpool_384_ecdh_local_pub[] = { + 0x04, 0x52, 0xf1, 0xc3, 0xb7, 0x2a, 0xd2, 0xd5, 0x8c, 0x6b, 0x1f, 0x94, + 0x82, 0xce, 0x3c, 0xa5, 0x28, 0xcd, 0x68, 0x98, 0xb3, 0xd2, 0xa8, 0xd5, + 0x3a, 0x3a, 0xa8, 0xfb, 0x0a, 0x68, 0x1b, 0xeb, 0xff, 0x3a, 0xb1, 0x9b, + 0xc8, 0xf7, 0xde, 0x0f, 0xdd, 0xed, 0xed, 0xf9, 0x58, 0x7d, 0x64, 0x9c, + 0x90, 0x6f, 0xcb, 0x83, 0x16, 0x47, 0x04, 0xcd, 0x44, 0xe7, 0x8b, 0xfc, + 0x07, 0xe4, 0xfd, 0x8d, 0xac, 0x37, 0x12, 0xed, 0xb0, 0xed, 0x13, 0x74, + 0xae, 0x25, 0x82, 0xd9, 0xcd, 0xde, 0x6d, 0xe4, 0x97, 0x7e, 0xb1, 0x30, + 0xc5, 0x99, 0x28, 0xd2, 0x5f, 0x8d, 0x1c, 0x01, 0x26, 0x96, 0x32, 0x82, + 0xec, +}; +static UCHAR brainpool_384_ecdh_remote_pub[] = { + 0x04, 0x83, 0x41, 0x46, 0x10, 0x60, 0x42, 0x72, 0x7a, 0xb9, 0x99, 0xfd, + 0x5d, 0x14, 0x4e, 0xa3, 0x59, 0x04, 0x04, 0x01, 0x65, 0x76, 0x53, 0xda, + 0x03, 0xbd, 0x16, 0x2c, 0x9f, 0xbb, 0x3f, 0xd0, 0x7f, 0xde, 0xbf, 0x8b, + 0xb0, 0x1b, 0xa4, 0xe0, 0xce, 0xf9, 0x79, 0xd9, 0x04, 0xbb, 0x19, 0xdd, + 0x3a, 0x08, 0xb5, 0xcf, 0x87, 0xcc, 0x7b, 0xd2, 0x04, 0xb6, 0x58, 0x8c, + 0xfe, 0xdf, 0xb7, 0xe8, 0x0b, 0x9d, 0x11, 0x41, 0x92, 0xdc, 0x84, 0xe8, + 0x87, 0x5b, 0xc9, 0x69, 0x17, 0x95, 0x4e, 0x27, 0xe2, 0x13, 0xe1, 0x2b, + 0x98, 0xd9, 0xdf, 0x71, 0x65, 0xb7, 0x56, 0x82, 0x50, 0x3b, 0x93, 0x2d, + 0x88, +}; +static UCHAR brainpool_384_ecdh_secret[] = { + 0x8b, 0x32, 0xf9, 0x18, 0x1b, 0x8a, 0xde, 0xc5, 0xe0, 0x82, 0xa5, 0xc1, + 0x00, 0xd7, 0x2c, 0x22, 0xa0, 0x07, 0xb4, 0x87, 0x1c, 0x46, 0xd4, 0xc9, + 0xdc, 0x42, 0x4f, 0x18, 0x90, 0x61, 0x51, 0x70, 0xd4, 0xb0, 0xcc, 0x48, + 0xb7, 0x56, 0x9d, 0xd4, 0x90, 0x2b, 0x19, 0x0a, 0xc7, 0xa9, 0xcd, 0xd8, +}; +static UCHAR brainpool_512_ecdh_priv[] = { + 0x36, 0x26, 0x8f, 0x91, 0x92, 0x50, 0xaf, 0xa3, 0x13, 0xa2, 0x00, 0xe4, + 0x50, 0xc6, 0x96, 0xcf, 0x24, 0xd1, 0x7b, 0x39, 0xcc, 0x7e, 0x34, 0x20, + 0xbb, 0xbb, 0x86, 0x21, 0xa2, 0xe7, 0x99, 0x26, 0x14, 0xbb, 0xb8, 0xbf, + 0x87, 0xd1, 0xaa, 0x4f, 0x77, 0xdd, 0xfe, 0x48, 0x37, 0x4b, 0x74, 0x46, + 0xe1, 0x1e, 0x0d, 0x7e, 0xca, 0xac, 0x13, 0x6a, 0xc3, 0x4c, 0x55, 0x12, + 0x39, 0xfc, 0x21, 0x8e, +}; +static UCHAR brainpool_512_ecdh_local_pub[] = { + 0x04, 0x0b, 0x3b, 0x66, 0xbc, 0x99, 0xf0, 0xc1, 0x3d, 0x57, 0xd1, 0x73, + 0xf7, 0x45, 0x85, 0xf0, 0x4e, 0x4d, 0x70, 0xe7, 0xe2, 0x3b, 0x06, 0x36, + 0x36, 0xe1, 0x11, 0x0e, 0x14, 0x50, 0xdd, 0x2d, 0xcf, 0xf4, 0xc7, 0x3a, + 0x7d, 0xa2, 0x35, 0x9a, 0x6c, 0x53, 0xb9, 0x5b, 0x84, 0xdc, 0x23, 0x2b, + 0x8a, 0x77, 0x92, 0xf4, 0x1f, 0x8e, 0xfe, 0x3d, 0xab, 0x84, 0xb4, 0xf4, + 0xba, 0x68, 0x0a, 0x6e, 0xf0, 0x0e, 0xf3, 0x0d, 0x2d, 0x28, 0x70, 0x34, + 0xfa, 0x48, 0x3f, 0x75, 0x4d, 0xea, 0xa5, 0x8c, 0xcf, 0xae, 0xc9, 0x13, + 0x80, 0x8d, 0x6d, 0x78, 0xdd, 0x43, 0xda, 0xa2, 0x39, 0xc0, 0xae, 0x24, + 0x19, 0xa4, 0x25, 0x1d, 0x7e, 0x47, 0xa4, 0x25, 0x2e, 0xf9, 0x19, 0x28, + 0x26, 0x4d, 0xa4, 0x9c, 0x7b, 0xe0, 0x87, 0x24, 0x0c, 0xfd, 0x01, 0x11, + 0x55, 0x19, 0xb2, 0x17, 0x56, 0x68, 0xc9, 0x0b, 0xf4, +}; +static UCHAR brainpool_512_ecdh_remote_pub[] = { + 0x04, 0x4f, 0x02, 0x44, 0x64, 0x87, 0xcd, 0x03, 0x48, 0x98, 0xea, 0x6d, + 0xca, 0xf7, 0xf6, 0x31, 0x97, 0x5d, 0x7c, 0x85, 0xf4, 0x35, 0x60, 0x30, + 0xc8, 0xb6, 0x0b, 0x15, 0x48, 0x5c, 0x79, 0x69, 0x73, 0x54, 0xc8, 0xd9, + 0xac, 0x00, 0x85, 0x71, 0x57, 0x65, 0x19, 0x82, 0x4b, 0x44, 0x9b, 0xa7, + 0x3d, 0xdc, 0x5f, 0xed, 0xe0, 0xc1, 0x28, 0xe8, 0x6f, 0x2c, 0x86, 0xc9, + 0xef, 0x49, 0x4a, 0x79, 0x56, 0x9f, 0xe0, 0x74, 0xb3, 0x79, 0x58, 0x67, + 0xde, 0x83, 0xec, 0x55, 0x86, 0x4a, 0x16, 0x74, 0xc0, 0xed, 0x8f, 0x0e, + 0xbd, 0x2c, 0x9f, 0x94, 0x3a, 0xa7, 0x7f, 0xf8, 0xa2, 0x05, 0x34, 0xf1, + 0xab, 0x16, 0xdd, 0x0c, 0x54, 0xf3, 0xc6, 0x15, 0x6c, 0xf5, 0xe7, 0x87, + 0xcb, 0xd3, 0x78, 0x4a, 0xb1, 0x9c, 0x63, 0xa0, 0x68, 0x19, 0x29, 0xda, + 0x26, 0x58, 0x1b, 0x62, 0x2f, 0xd1, 0x97, 0xbf, 0xda, +}; +static UCHAR brainpool_512_ecdh_secret[] = { + 0x5a, 0x88, 0x9c, 0x08, 0xb5, 0xb8, 0x6a, 0x5a, 0x0c, 0xdf, 0x0d, 0x7c, + 0x7a, 0x36, 0xfb, 0xe3, 0x92, 0x26, 0x39, 0xc6, 0x02, 0x93, 0xa9, 0xcb, + 0xae, 0xbe, 0x7c, 0x24, 0xe5, 0x8c, 0x96, 0x07, 0x30, 0x21, 0xf7, 0x04, + 0xbe, 0x7a, 0xbe, 0xbe, 0x4c, 0x4c, 0xc8, 0x9d, 0x99, 0x16, 0xc5, 0xdd, + 0xf0, 0xe8, 0x78, 0x5e, 0x76, 0x2f, 0x3b, 0x41, 0xa8, 0xaf, 0x06, 0xcb, + 0xe1, 0x1e, 0x97, 0x4d, +}; + +/* Verification vectors generated using OpenSSL from RFC 5639 domains. */ +typedef struct BRAINPOOL_TEST_VECTOR_STRUCT +{ + NX_CRYPTO_METHOD *method; + UINT curve_id; + UCHAR *hash; + UINT hash_length; + UCHAR *public_key; + UINT public_key_length; + UCHAR *signature; + UINT signature_length; +} BRAINPOOL_TEST_VECTOR; + +static BRAINPOOL_TEST_VECTOR vectors[] = +{ + {&crypto_method_ec_brainpoolp256, NX_CRYPTO_EC_BRAINPOOLP256r1, + brainpool_256_hash, sizeof(brainpool_256_hash), brainpool_256_pub, sizeof(brainpool_256_pub), + brainpool_256_sig, sizeof(brainpool_256_sig)}, + {&crypto_method_ec_brainpoolp384, NX_CRYPTO_EC_BRAINPOOLP384r1, + brainpool_384_hash, sizeof(brainpool_384_hash), brainpool_384_pub, sizeof(brainpool_384_pub), + brainpool_384_sig, sizeof(brainpool_384_sig)}, + {&crypto_method_ec_brainpoolp512, NX_CRYPTO_EC_BRAINPOOLP512r1, + brainpool_512_hash, sizeof(brainpool_512_hash), brainpool_512_pub, sizeof(brainpool_512_pub), + brainpool_512_sig, sizeof(brainpool_512_sig)} +}; + +/* ECDH vectors generated using OpenSSL from RFC 5639 domains. */ +typedef struct BRAINPOOL_ECDH_VECTOR_STRUCT +{ + UCHAR *private_key; + UCHAR *local_public_key; + UCHAR *remote_public_key; + UCHAR *shared_secret; + UINT key_length; + UINT public_key_length; +} BRAINPOOL_ECDH_VECTOR; + +static BRAINPOOL_ECDH_VECTOR ecdh_vectors[] = +{ + {brainpool_256_ecdh_priv, brainpool_256_ecdh_local_pub, + brainpool_256_ecdh_remote_pub, brainpool_256_ecdh_secret, + sizeof(brainpool_256_ecdh_priv), sizeof(brainpool_256_ecdh_local_pub)}, + {brainpool_384_ecdh_priv, brainpool_384_ecdh_local_pub, + brainpool_384_ecdh_remote_pub, brainpool_384_ecdh_secret, + sizeof(brainpool_384_ecdh_priv), sizeof(brainpool_384_ecdh_local_pub)}, + {brainpool_512_ecdh_priv, brainpool_512_ecdh_local_pub, + brainpool_512_ecdh_remote_pub, brainpool_512_ecdh_secret, + sizeof(brainpool_512_ecdh_priv), sizeof(brainpool_512_ecdh_local_pub)} +}; + +/* Verify valid signatures and reject damaged points and signatures. */ +static VOID thread_0_entry(ULONG thread_input) +{ + UINT i; + UINT status; + NX_CRYPTO_EC *curve; + HN_UBASE scratch[1000]; + UCHAR damaged_signature[160]; + UCHAR damaged_key[129]; + UCHAR shared_secret[64]; + NX_CRYPTO_ECDH ecdh; + NX_CRYPTO_EXTENDED_OUTPUT extended_output; + NX_CRYPTO_METHOD unsupported_curve_method; + + (void)thread_input; + printf("NetX Secure Test: Brainpool ECDSA Test.............................."); + + /* Reject invalid curve requests before returning a domain pointer. */ + status = vectors[0].method -> nx_crypto_operation(NX_CRYPTO_VERIFY, + NX_CRYPTO_NULL, vectors[0].method, NX_CRYPTO_NULL, 0, + NX_CRYPTO_NULL, 0, NX_CRYPTO_NULL, (UCHAR *)&curve, sizeof(curve), + NX_CRYPTO_NULL, 0, NX_CRYPTO_NULL, NX_CRYPTO_NULL); + if (status != NX_CRYPTO_NOT_SUCCESSFUL) + { + test_control_return(1); + return; + } + status = vectors[0].method -> nx_crypto_operation(NX_CRYPTO_EC_CURVE_GET, + NX_CRYPTO_NULL, NX_CRYPTO_NULL, NX_CRYPTO_NULL, 0, + NX_CRYPTO_NULL, 0, NX_CRYPTO_NULL, (UCHAR *)&curve, sizeof(curve), + NX_CRYPTO_NULL, 0, NX_CRYPTO_NULL, NX_CRYPTO_NULL); + if (status != NX_CRYPTO_NOT_SUCCESSFUL) + { + test_control_return(1); + return; + } + status = vectors[0].method -> nx_crypto_operation(NX_CRYPTO_EC_CURVE_GET, + NX_CRYPTO_NULL, vectors[0].method, NX_CRYPTO_NULL, 0, + NX_CRYPTO_NULL, 0, NX_CRYPTO_NULL, NX_CRYPTO_NULL, sizeof(curve), + NX_CRYPTO_NULL, 0, NX_CRYPTO_NULL, NX_CRYPTO_NULL); + if (status != NX_CRYPTO_NOT_SUCCESSFUL) + { + test_control_return(1); + return; + } + unsupported_curve_method = *vectors[0].method; + unsupported_curve_method.nx_crypto_algorithm = NX_CRYPTO_EC_SECP256R1; + status = vectors[0].method -> nx_crypto_operation(NX_CRYPTO_EC_CURVE_GET, + NX_CRYPTO_NULL, &unsupported_curve_method, NX_CRYPTO_NULL, 0, + NX_CRYPTO_NULL, 0, NX_CRYPTO_NULL, (UCHAR *)&curve, sizeof(curve), + NX_CRYPTO_NULL, 0, NX_CRYPTO_NULL, NX_CRYPTO_NULL); + if (status != NX_CRYPTO_NOT_SUCCESSFUL) + { + test_control_return(1); + return; + } + + for (i = 0; i < sizeof(vectors) / sizeof(vectors[0]); i++) + { + curve = NX_CRYPTO_NULL; + status = vectors[i].method -> nx_crypto_operation(NX_CRYPTO_EC_CURVE_GET, + NX_CRYPTO_NULL, vectors[i].method, NX_CRYPTO_NULL, 0, + NX_CRYPTO_NULL, 0, NX_CRYPTO_NULL, (UCHAR *)&curve, sizeof(curve), + NX_CRYPTO_NULL, 0, NX_CRYPTO_NULL, NX_CRYPTO_NULL); + if ((status != NX_CRYPTO_SUCCESS) || (curve == NX_CRYPTO_NULL) || + (curve -> nx_crypto_ec_id != vectors[i].curve_id)) + { + printf("curve method failed for %u\n", vectors[i].curve_id); + test_control_return(1); + return; + } + + status = _nx_crypto_ecdsa_verify(curve, vectors[i].hash, vectors[i].hash_length, + vectors[i].public_key, vectors[i].public_key_length, + vectors[i].signature, vectors[i].signature_length, scratch); + if (status != NX_CRYPTO_SUCCESS) + { + printf("signature verification failed for %u\n", vectors[i].curve_id); + test_control_return(1); + return; + } + + memcpy(damaged_signature, vectors[i].signature, vectors[i].signature_length); + damaged_signature[vectors[i].signature_length - 1u] ^= 1u; + status = _nx_crypto_ecdsa_verify(curve, vectors[i].hash, vectors[i].hash_length, + vectors[i].public_key, vectors[i].public_key_length, + damaged_signature, vectors[i].signature_length, scratch); + if (status == NX_CRYPTO_SUCCESS) + { + printf("damaged signature accepted for %u\n", vectors[i].curve_id); + test_control_return(1); + return; + } + + memcpy(damaged_key, vectors[i].public_key, vectors[i].public_key_length); + damaged_key[0] = 0x05u; + status = _nx_crypto_ecdsa_verify(curve, vectors[i].hash, vectors[i].hash_length, + damaged_key, vectors[i].public_key_length, + vectors[i].signature, vectors[i].signature_length, scratch); + if (status == NX_CRYPTO_SUCCESS) + { + printf("damaged public key accepted for %u\n", vectors[i].curve_id); + test_control_return(1); + return; + } + status = crypto_method_ecdh.nx_crypto_operation(NX_CRYPTO_EC_CURVE_SET, + NX_CRYPTO_NULL, &crypto_method_ecdh, NX_CRYPTO_NULL, 0, + (UCHAR *)vectors[i].method, sizeof(NX_CRYPTO_METHOD *), NX_CRYPTO_NULL, + NX_CRYPTO_NULL, 0, &ecdh, sizeof(ecdh), NX_CRYPTO_NULL, NX_CRYPTO_NULL); + if (status != NX_CRYPTO_SUCCESS) + { + printf("ECDH curve setup failed for %u\n", vectors[i].curve_id); + test_control_return(1); + return; + } + + status = crypto_method_ecdh.nx_crypto_operation(NX_CRYPTO_DH_KEY_PAIR_IMPORT, + NX_CRYPTO_NULL, &crypto_method_ecdh, + ecdh_vectors[i].private_key, (NX_CRYPTO_KEY_SIZE)(ecdh_vectors[i].key_length << 3), + ecdh_vectors[i].local_public_key, ecdh_vectors[i].public_key_length, + NX_CRYPTO_NULL, NX_CRYPTO_NULL, 0, &ecdh, sizeof(ecdh), + NX_CRYPTO_NULL, NX_CRYPTO_NULL); + if (status != NX_CRYPTO_SUCCESS) + { + printf("ECDH key import failed for %u\n", vectors[i].curve_id); + test_control_return(1); + return; + } + + extended_output.nx_crypto_extended_output_data = shared_secret; + extended_output.nx_crypto_extended_output_length_in_byte = sizeof(shared_secret); + status = crypto_method_ecdh.nx_crypto_operation(NX_CRYPTO_DH_CALCULATE, + NX_CRYPTO_NULL, &crypto_method_ecdh, NX_CRYPTO_NULL, 0, + ecdh_vectors[i].remote_public_key, ecdh_vectors[i].public_key_length, + NX_CRYPTO_NULL, (UCHAR *)&extended_output, sizeof(extended_output), + &ecdh, sizeof(ecdh), NX_CRYPTO_NULL, NX_CRYPTO_NULL); + if ((status != NX_CRYPTO_SUCCESS) || + (extended_output.nx_crypto_extended_output_actual_size != ecdh_vectors[i].key_length) || + (memcmp(shared_secret, ecdh_vectors[i].shared_secret, ecdh_vectors[i].key_length) != 0)) + { + printf("ECDH shared secret mismatch for %u\n", vectors[i].curve_id); + test_control_return(1); + return; + } + } + + printf("SUCCESS!\n"); + test_control_return(0); +} + +/* Start the regression test in a ThreadX thread or standalone process. */ +#ifdef CTEST +void test_application_define(void *first_unused_memory); +void test_application_define(void *first_unused_memory) +#else +void nx_secure_brainpool_test_application_define(void *first_unused_memory) +#endif +{ +#ifndef NX_CRYPTO_STANDALONE_ENABLE + tx_thread_create(&thread_0, "Thread 0", thread_0_entry, 0, + first_unused_memory, 4096, 16, 16, 4, TX_AUTO_START); +#else + (void)first_unused_memory; + thread_0_entry(0); +#endif +} diff --git a/test/regression/nx_secure_test/nx_secure_tls_1_3_certverify_transcript_hash_test.c b/test/regression/nx_secure_test/nx_secure_tls_1_3_certverify_transcript_hash_test.c index fc95ea8eb..391358c36 100644 --- a/test/regression/nx_secure_test/nx_secure_tls_1_3_certverify_transcript_hash_test.c +++ b/test/regression/nx_secure_test/nx_secure_tls_1_3_certverify_transcript_hash_test.c @@ -65,6 +65,7 @@ extern const NX_SECURE_TLS_CRYPTO nx_crypto_tls_ciphers_ecc; static ULONG spy_captured_length; static UINT spy_call_count; +static UINT spy_hash_succeeds; /* Stand-in for the signature scheme's hash (SHA-384, 48-byte ICV). The caller drives hashing through three separate nx_crypto_operation calls -- HASH_INITIALIZE, HASH_UPDATE, @@ -90,6 +91,10 @@ static UINT spy_hash_operation(UINT op, VOID *handler, struct NX_CRYPTO_METHOD_S spy_captured_length = input_length_in_byte; spy_call_count++; } + if (spy_hash_succeeds) + { + return(NX_CRYPTO_SUCCESS); + } return(NX_CRYPTO_NOT_SUCCESSFUL); } @@ -120,7 +125,9 @@ static NX_CRYPTO_METHOD dummy_public_cipher_method = {0}; static NX_SECURE_X509_CRYPTO mismatched_hash_cipher_table[] = { /* OID identifier, public cipher, hash method */ + {NX_SECURE_TLS_X509_TYPE_ECDSA_SHA_256, &dummy_public_cipher_method, &spy_hash_method_sha384}, {NX_SECURE_TLS_X509_TYPE_ECDSA_SHA_384, &dummy_public_cipher_method, &spy_hash_method_sha384}, + {NX_SECURE_TLS_X509_TYPE_ECDSA_SHA_512, &dummy_public_cipher_method, &spy_hash_method_sha384}, }; /* Copy of TLS_AES_128_GCM_SHA256 with a SHA-384 hash, for configuration 2. See the header @@ -176,6 +183,15 @@ NX_SECURE_X509_CERT local_certificate; NX_SECURE_X509_CERT remote_certificate; const NX_SECURE_TLS_CIPHERSUITE_INFO *sha256_ciphersuite; USHORT priority; +UINT scheme_index; +const USHORT brainpool_schemes[] = +{ + NX_SECURE_TLS_SIGNATURE_ECDSA_BRAINPOOLP256R1_SHA256, + NX_SECURE_TLS_SIGNATURE_ECDSA_BRAINPOOLP384R1_SHA384, + NX_SECURE_TLS_SIGNATURE_ECDSA_BRAINPOOLP512R1_SHA512, + NX_SECURE_TLS_SIGNATURE_ECDSA_SHA256 +}; +NX_PACKET *packet; printf("NetX Secure Test: TLS 1.3 CertificateVerify Transcript Hash Length Test.."); @@ -224,7 +240,7 @@ USHORT priority; certificate_get(..., NX_NULL, ...) only matches identity certificates -- force it. */ local_certificate.nx_secure_x509_certificate_is_identity_cert = NX_CRYPTO_TRUE; local_certificate.nx_secure_x509_cipher_table = mismatched_hash_cipher_table; - local_certificate.nx_secure_x509_cipher_table_size = 1; + local_certificate.nx_secure_x509_cipher_table_size = sizeof(mismatched_hash_cipher_table) / sizeof(mismatched_hash_cipher_table[0]); tls_session.nx_secure_tls_credentials.nx_secure_tls_certificate_store = store; tls_session.nx_secure_tls_socket_type = NX_SECURE_TLS_SESSION_TYPE_CLIENT; @@ -236,6 +252,35 @@ USHORT priority; tls_session.nx_secure_tls_session_ciphersuite = &sha384_ciphersuite; check_send_side(&tls_session, 48); + /* A certificate's private key must use the curve named by its signature scheme. */ + local_certificate.nx_secure_x509_public_algorithm = NX_SECURE_TLS_X509_TYPE_EC; + local_certificate.nx_secure_x509_private_key.ec_private_key.nx_secure_ec_named_curve = 19; + tls_session.nx_secure_tls_session_ciphersuite = sha256_ciphersuite; + spy_hash_succeeds = NX_TRUE; + status = nx_packet_allocate(&pool_0, &packet, NX_TCP_PACKET, NX_WAIT_FOREVER); + EXPECT_EQ(NX_SUCCESS, status); + for (scheme_index = 0; scheme_index < 3u; scheme_index++) + { + tls_session.nx_secure_tls_signature_algorithm = brainpool_schemes[scheme_index]; + status = _nx_secure_tls_send_certificate_verify(&tls_session, packet); + EXPECT_EQ(NX_SECURE_TLS_UNSUPPORTED_CERT_SIGN_ALG, status); + } + local_certificate.nx_secure_x509_private_key.ec_private_key.nx_secure_ec_named_curve = NX_CRYPTO_EC_BRAINPOOLP256r1; + tls_session.nx_secure_tls_signature_algorithm = brainpool_schemes[3]; + status = _nx_secure_tls_send_certificate_verify(&tls_session, packet); + EXPECT_EQ(NX_SECURE_TLS_UNSUPPORTED_CERT_SIGN_ALG, status); + local_certificate.nx_secure_x509_private_key.ec_private_key.nx_secure_ec_named_curve = NX_CRYPTO_EC_BRAINPOOLP512r1 + 1u; + status = _nx_secure_tls_send_certificate_verify(&tls_session, packet); + EXPECT_EQ(NX_CRYTPO_MISSING_ECC_CURVE, status); + + tls_session.nx_secure_tls_1_3 = NX_FALSE; + tls_session.nx_secure_tls_protocol_version = NX_SECURE_TLS_VERSION_TLS_1_2; + status = _nx_secure_tls_send_certificate_verify(&tls_session, packet); + EXPECT_EQ(NX_CRYTPO_MISSING_ECC_CURVE, status); + tls_session.nx_secure_tls_1_3 = NX_TRUE; + nx_packet_release(packet); + spy_hash_succeeds = NX_FALSE; + /* ---- Process side: _nx_secure_tls_process_certificate_verify (TLS 1.3 server). ---- */ memset(&remote_certificate, 0, sizeof(remote_certificate)); @@ -246,7 +291,7 @@ USHORT priority; status = _nx_secure_x509_store_certificate_add(&remote_certificate, &store, NX_SECURE_X509_CERT_LOCATION_REMOTE); EXPECT_EQ(NX_SUCCESS, status); remote_certificate.nx_secure_x509_cipher_table = mismatched_hash_cipher_table; - remote_certificate.nx_secure_x509_cipher_table_size = 1; + remote_certificate.nx_secure_x509_cipher_table_size = sizeof(mismatched_hash_cipher_table) / sizeof(mismatched_hash_cipher_table[0]); tls_session.nx_secure_tls_credentials.nx_secure_tls_certificate_store = store; tls_session.nx_secure_tls_socket_type = NX_SECURE_TLS_SESSION_TYPE_SERVER; diff --git a/test/regression/nx_secure_test/nx_secure_tls_1_3_provisioned_psk_test.c b/test/regression/nx_secure_test/nx_secure_tls_1_3_provisioned_psk_test.c index fc8775122..7ee056058 100644 --- a/test/regression/nx_secure_test/nx_secure_tls_1_3_provisioned_psk_test.c +++ b/test/regression/nx_secure_test/nx_secure_tls_1_3_provisioned_psk_test.c @@ -9,7 +9,9 @@ /* SPDX-License-Identifier: MIT */ /***************************************************************************/ -/* This test concentrates on TLS ECC ciphersuites negotiation. */ +/* Portions of this file were generated with AI assistance. */ + +/* This test negotiates TLS 1.3 key exchange with a Brainpool group. */ #include "nx_api.h" #include "nx_secure_tls_api.h" @@ -79,11 +81,22 @@ static UCHAR response_buffer[BUFFER_SIZE]; static UCHAR tls_packet_buffer[2][4000]; extern NX_SECURE_TLS_CIPHERSUITE_INFO _nx_crypto_ciphersuite_lookup_table_ecc[]; -extern const USHORT nx_crypto_ecc_supported_groups[]; -extern const NX_CRYPTO_METHOD *nx_crypto_ecc_curves[]; -extern const UINT nx_crypto_ecc_supported_groups_size; +extern NX_CRYPTO_METHOD crypto_method_ec_brainpoolp256; +extern NX_CRYPTO_METHOD crypto_method_ec_secp256; extern const NX_SECURE_TLS_CRYPTO nx_crypto_tls_ciphers_ecc; +static const USHORT brainpool_groups[] = +{ + (USHORT)NX_CRYPTO_EC_BRAINPOOLP256r1, + (USHORT)NX_CRYPTO_EC_SECP256R1 +}; + +static const NX_CRYPTO_METHOD *brainpool_curves[] = +{ + &crypto_method_ec_brainpoolp256, + &crypto_method_ec_secp256 +}; + static CERTIFICATE test_certs[] = { CERTIFICATE_INIT(ECTestServer2_der, ECTestServer2_key_der, ECCA2_der, NX_SECURE_X509_KEY_TYPE_EC_DER), @@ -178,9 +191,9 @@ UINT status; status = nx_secure_tls_client_psk_set(tls_session_ptr, tls_psk, sizeof(tls_psk), "Client_identity", 15, "12345678", 8); do_something_if_fail(NX_SECURE_TLS_SUCCESS == status); - status = nx_secure_tls_ecc_initialize(tls_session_ptr, nx_crypto_ecc_supported_groups, - nx_crypto_ecc_supported_groups_size, - nx_crypto_ecc_curves); + status = nx_secure_tls_ecc_initialize(tls_session_ptr, brainpool_groups, + sizeof(brainpool_groups) / sizeof(brainpool_groups[0]), + brainpool_curves); do_something_if_fail(NX_SECURE_TLS_SUCCESS == status); memset(&client_remote_cert, 0, sizeof(client_remote_cert)); @@ -217,9 +230,9 @@ UINT status; status = nx_secure_tls_psk_add(tls_session_ptr, tls_psk, sizeof(tls_psk), "Client_identity", 15, "12345678", 8); do_something_if_fail(NX_SECURE_TLS_SUCCESS == status); - status = nx_secure_tls_ecc_initialize(tls_session_ptr, nx_crypto_ecc_supported_groups, - nx_crypto_ecc_supported_groups_size, - nx_crypto_ecc_curves); + status = nx_secure_tls_ecc_initialize(tls_session_ptr, brainpool_groups, + sizeof(brainpool_groups) / sizeof(brainpool_groups[0]), + brainpool_curves); do_something_if_fail(NX_SECURE_TLS_SUCCESS == status); memset(&server_local_certificate, 0, sizeof(server_local_certificate)); @@ -268,6 +281,9 @@ NX_PACKET *packet_ptr; status = nx_secure_tls_session_start(&tls_server_session_0, &server_socket_0, NX_WAIT_FOREVER); do_something_if_fail(NX_SECURE_TLS_SUCCESS == status); + do_something_if_fail((USHORT)NX_CRYPTO_EC_BRAINPOOLP256r1 == + tls_server_session_0.nx_secure_tls_key_material.nx_secure_tls_ecc_key_data[ + tls_server_session_0.nx_secure_tls_key_material.nx_secure_tls_ecc_key_data_selected].nx_secure_tls_ecdhe_named_curve); nx_secure_tls_session_end(&tls_server_session_0, NX_IP_PERIODIC_RATE); nx_secure_tls_session_delete(&tls_server_session_0); @@ -329,6 +345,9 @@ NXD_ADDRESS server_address; /* Start TLS session. */ status = nx_secure_tls_session_start(&tls_client_session_0, &client_socket_0, NX_WAIT_FOREVER); do_something_if_fail(NX_SECURE_TLS_SUCCESS == status); + do_something_if_fail((USHORT)NX_CRYPTO_EC_BRAINPOOLP256r1 == + tls_client_session_0.nx_secure_tls_key_material.nx_secure_tls_ecc_key_data[ + tls_client_session_0.nx_secure_tls_key_material.nx_secure_tls_ecc_key_data_selected].nx_secure_tls_ecdhe_named_curve); if (!status) { diff --git a/test/regression/nx_secure_test/nx_secure_tls_clienthello_signature_algorithms_test.c b/test/regression/nx_secure_test/nx_secure_tls_clienthello_signature_algorithms_test.c index ad9d2f3f6..915c4b627 100644 --- a/test/regression/nx_secure_test/nx_secure_tls_clienthello_signature_algorithms_test.c +++ b/test/regression/nx_secure_test/nx_secure_tls_clienthello_signature_algorithms_test.c @@ -25,12 +25,12 @@ extern VOID test_control_return(UINT status); #if !defined(NX_SECURE_TLS_CLIENT_DISABLED) && !defined(NX_SECURE_DISABLE_X509) && \ - (NX_SECURE_TLS_TLS_1_3_ENABLED) + defined(NX_SECURE_ENABLE_ECC_CIPHERSUITE) && (NX_SECURE_TLS_TLS_1_3_ENABLED) #define TEST_PACKET_OFFSET 3u #define TEST_PACKET_SIZE 32u -#define TLS_1_3_EXTENSION_SIZE 20u -#define TLS_1_2_EXTENSION_SIZE 14u +#define TLS_1_3_EXTENSION_SIZE 26u +#define TLS_1_2_EXTENSION_SIZE 18u #define OVERSIZED_TABLE_ENTRY_COUNT 16383u static NX_CRYPTO_METHOD rsa_method = @@ -68,7 +68,9 @@ static NX_SECURE_X509_CRYPTO signature_methods[] = {0, &rsa_method, &sha256_method}, {0, &rsa_method, &sha384_method}, {0, &rsa_method, &sha512_method}, - {0, &ecdsa_method, &sha256_method}, + {NX_SECURE_TLS_X509_TYPE_ECDSA_SHA_256, &ecdsa_method, &sha256_method}, + {NX_SECURE_TLS_X509_TYPE_ECDSA_SHA_384, &ecdsa_method, &sha384_method}, + {NX_SECURE_TLS_X509_TYPE_ECDSA_SHA_512, &ecdsa_method, &sha512_method}, {0, &unsupported_method, &sha256_method} }; @@ -76,22 +78,76 @@ static NX_SECURE_X509_CRYPTO oversized_signature_methods[OVERSIZED_TABLE_ENTRY_C static const USHORT supported_groups[] = { - (USHORT)NX_CRYPTO_EC_SECP256R1 + (USHORT)NX_CRYPTO_EC_SECP256R1, + (USHORT)NX_CRYPTO_EC_BRAINPOOLP256r1, + (USHORT)NX_CRYPTO_EC_BRAINPOOLP384r1, + (USHORT)NX_CRYPTO_EC_BRAINPOOLP512r1 +}; + +extern NX_CRYPTO_METHOD crypto_method_ec_secp256; +extern NX_CRYPTO_METHOD crypto_method_ec_brainpoolp256; +extern NX_CRYPTO_METHOD crypto_method_ec_brainpoolp384; +extern NX_CRYPTO_METHOD crypto_method_ec_brainpoolp512; + +static const NX_CRYPTO_METHOD *supported_curve_methods[] = +{ + &crypto_method_ec_secp256, + &crypto_method_ec_brainpoolp256, + &crypto_method_ec_brainpoolp384, + &crypto_method_ec_brainpoolp512 +}; + +static const UCHAR brainpool_oids[3][9] = +{ + {0x2B, 0x24, 0x03, 0x03, 0x02, 0x08, 0x01, 0x01, 0x07}, + {0x2B, 0x24, 0x03, 0x03, 0x02, 0x08, 0x01, 0x01, 0x0B}, + {0x2B, 0x24, 0x03, 0x03, 0x02, 0x08, 0x01, 0x01, 0x0D} }; static const UCHAR expected_tls_1_3_extension[TLS_1_3_EXTENSION_SIZE] = { - 0x00, 0x0D, 0x00, 0x10, 0x00, 0x0E, + 0x00, 0x0D, 0x00, 0x16, 0x00, 0x14, 0x08, 0x04, 0x04, 0x01, 0x08, 0x05, 0x05, 0x01, 0x08, 0x06, 0x06, 0x01, - 0x04, 0x03 + 0x04, 0x03, 0x08, 0x1A, 0x08, 0x1B, 0x08, 0x1C }; static const UCHAR expected_tls_1_2_extension[TLS_1_2_EXTENSION_SIZE] = { - 0x00, 0x0D, 0x00, 0x0A, 0x00, 0x08, - 0x04, 0x01, 0x05, 0x01, 0x06, 0x01, 0x04, 0x03 + 0x00, 0x0D, 0x00, 0x0E, 0x00, 0x0C, + 0x04, 0x01, 0x05, 0x01, 0x06, 0x01, + 0x04, 0x03, 0x05, 0x03, 0x06, 0x03 +}; + +static const UCHAR expected_certificate_request[] = +{ + 0x00, 0x00, 0x0E, 0x00, 0x0D, 0x00, 0x0A, 0x00, 0x08, + 0x04, 0x03, 0x08, 0x1A, 0x08, 0x1B, 0x08, 0x1C +}; + +static NX_SECURE_X509_CERT local_brainpool_cert; +static const UINT brainpool_curve_ids[] = +{ + NX_CRYPTO_EC_BRAINPOOLP256r1, + NX_CRYPTO_EC_BRAINPOOLP384r1, + NX_CRYPTO_EC_BRAINPOOLP512r1 +}; +static const UINT expected_brainpool_signatures[] = +{ + NX_SECURE_TLS_SIGNATURE_ECDSA_BRAINPOOLP256R1_SHA256, + NX_SECURE_TLS_SIGNATURE_ECDSA_BRAINPOOLP384R1_SHA384, + NX_SECURE_TLS_SIGNATURE_ECDSA_BRAINPOOLP512R1_SHA512 +}; +static const USHORT expected_brainpool_x509_types[] = +{ + NX_SECURE_TLS_X509_TYPE_ECDSA_SHA_256, + NX_SECURE_TLS_X509_TYPE_ECDSA_SHA_384, + NX_SECURE_TLS_X509_TYPE_ECDSA_SHA_512 +}; +static UCHAR brainpool_signature_wire[] = +{ + 0x00, 0x06, 0x08, 0x1A, 0x08, 0x1B, 0x08, 0x1C }; #endif @@ -115,7 +171,7 @@ void nx_secure_tls_clienthello_signature_algorithms_test_application_define(void #endif { #if !defined(NX_SECURE_TLS_CLIENT_DISABLED) && !defined(NX_SECURE_DISABLE_X509) && \ - (NX_SECURE_TLS_TLS_1_3_ENABLED) + defined(NX_SECURE_ENABLE_ECC_CIPHERSUITE) && (NX_SECURE_TLS_TLS_1_3_ENABLED) NX_SECURE_TLS_SESSION tls_session; NX_SECURE_TLS_CRYPTO crypto_table; UCHAR packet_buffer[TEST_PACKET_SIZE]; @@ -123,6 +179,16 @@ ULONG packet_offset; USHORT extension_length; UINT status; UINT i; +UINT selected_curve; +UINT cert_curve_supported; +UINT oid_value; +USHORT ecdhe_signature_algorithm; +UCHAR groups_wire[4] = {0x00, 0x02, 0x00, 0x1F}; +NX_SECURE_TLS_HELLO_EXTENSION groups_extension; +NX_SECURE_TLS_HELLO_EXTENSION signature_extension; +NX_PACKET certificate_request_packet; +UCHAR certificate_request_data[64]; +USHORT signature_id; NX_PARAMETER_NOT_USED(first_unused_memory); @@ -138,6 +204,68 @@ UINT i; tls_session.nx_secure_tls_ecc.nx_secure_tls_ecc_supported_groups = supported_groups; tls_session.nx_secure_tls_ecc.nx_secure_tls_ecc_supported_groups_count = (USHORT)(sizeof(supported_groups) / sizeof(supported_groups[0])); + tls_session.nx_secure_tls_ecc.nx_secure_tls_ecc_curves = supported_curve_methods; + + /* A TLS 1.3 certificate request advertises each supported Brainpool scheme. */ + memset(&certificate_request_packet, 0, sizeof(certificate_request_packet)); + certificate_request_packet.nx_packet_prepend_ptr = certificate_request_data; + certificate_request_packet.nx_packet_append_ptr = certificate_request_data; + certificate_request_packet.nx_packet_data_end = certificate_request_data + sizeof(certificate_request_data); + tls_session.nx_secure_tls_protocol_version = NX_SECURE_TLS_VERSION_TLS_1_2; + status = _nx_secure_tls_send_certificate_request(&tls_session, &certificate_request_packet); + EXPECT_EQ(NX_SUCCESS, status); + EXPECT_EQ(sizeof(expected_certificate_request), certificate_request_packet.nx_packet_length); + EXPECT_EQ(0, memcmp(certificate_request_data, expected_certificate_request, + sizeof(expected_certificate_request))); + memset(&local_brainpool_cert, 0, sizeof(local_brainpool_cert)); + local_brainpool_cert.nx_secure_x509_public_algorithm = NX_SECURE_TLS_X509_TYPE_EC; + tls_session.nx_secure_tls_credentials.nx_secure_tls_active_certificate = &local_brainpool_cert; + signature_extension.nx_secure_tls_extension_id = NX_SECURE_TLS_EXTENSION_SIGNATURE_ALGORITHMS; + signature_extension.nx_secure_tls_extension_data_length = sizeof(brainpool_signature_wire); + signature_extension.nx_secure_tls_extension_data = brainpool_signature_wire; + for (i = 0; i < 3U; i++) + { + local_brainpool_cert.nx_secure_x509_private_key.ec_private_key.nx_secure_ec_named_curve = + brainpool_curve_ids[i]; + status = _nx_secure_tls_process_certificate_request(&tls_session, certificate_request_data, + sizeof(expected_certificate_request)); + EXPECT_EQ(NX_SUCCESS, status); + EXPECT_EQ(expected_brainpool_signatures[i], tls_session.nx_secure_tls_signature_algorithm); + status = _nx_secure_tls_proc_clienthello_sec_sa_extension(&tls_session, &signature_extension, + 1U, &selected_curve, 0U, &cert_curve_supported, &ecdhe_signature_algorithm, NX_NULL); + EXPECT_EQ(NX_SUCCESS, status); + EXPECT_EQ(expected_brainpool_signatures[i], tls_session.nx_secure_tls_signature_algorithm); + signature_id = 0; + _nx_secure_tls_get_signature_algorithm_id(expected_brainpool_signatures[i], &signature_id); + EXPECT_EQ(expected_brainpool_x509_types[i], signature_id); + } + tls_session.nx_secure_tls_credentials.nx_secure_tls_active_certificate = NX_NULL; + tls_session.nx_secure_tls_protocol_version = 0; + + /* RFC 8734 groups differ from the TLS 1.2 Brainpool identifiers. */ + EXPECT_EQ(0x001Fu, _nx_secure_tls_brainpool_group_to_wire((USHORT)NX_CRYPTO_EC_BRAINPOOLP256r1)); + EXPECT_EQ(0x0020u, _nx_secure_tls_brainpool_group_to_wire((USHORT)NX_CRYPTO_EC_BRAINPOOLP384r1)); + EXPECT_EQ(0x0021u, _nx_secure_tls_brainpool_group_to_wire((USHORT)NX_CRYPTO_EC_BRAINPOOLP512r1)); + EXPECT_EQ(0x0022u, _nx_secure_tls_brainpool_group_to_wire(0x0022u)); + EXPECT_EQ((USHORT)NX_CRYPTO_EC_BRAINPOOLP256r1, _nx_secure_tls_brainpool_group_from_wire(0x001Fu)); + EXPECT_EQ((USHORT)NX_CRYPTO_EC_BRAINPOOLP384r1, _nx_secure_tls_brainpool_group_from_wire(0x0020u)); + EXPECT_EQ((USHORT)NX_CRYPTO_EC_BRAINPOOLP512r1, _nx_secure_tls_brainpool_group_from_wire(0x0021u)); + + groups_extension.nx_secure_tls_extension_id = NX_SECURE_TLS_EXTENSION_EC_GROUPS; + groups_extension.nx_secure_tls_extension_data_length = sizeof(groups_wire); + groups_extension.nx_secure_tls_extension_data = groups_wire; + for (i = 0; i < 3u; i++) + { + _nx_secure_x509_oid_parse(brainpool_oids[i], sizeof(brainpool_oids[i]), &oid_value); + EXPECT_EQ((UINT)(NX_SECURE_TLS_X509_EC_BRAINPOOLP256R1 + i), oid_value); + + groups_wire[3] = (UCHAR)(0x1Fu + i); + status = _nx_secure_tls_proc_clienthello_sec_sa_extension(&tls_session, + &groups_extension, 1u, &selected_curve, 0u, &cert_curve_supported, + &ecdhe_signature_algorithm, NX_NULL); + EXPECT_EQ(NX_SUCCESS, status); + EXPECT_EQ((UINT)supported_groups[i + 1u], selected_curve); + } /* The old two-bytes-per-table-entry check accepted this buffer even though the RSA-PSS entries now require paired TLS 1.2 algorithms. */ @@ -176,6 +304,34 @@ UINT i; EXPECT_EQ(0xA5u, packet_buffer[TEST_PACKET_OFFSET - 1u]); EXPECT_EQ(0xA5u, packet_buffer[TEST_PACKET_OFFSET + TLS_1_3_EXTENSION_SIZE]); + /* Only usable ECDSA methods may advertise Brainpool signature schemes. */ + signature_methods[3].nx_secure_x509_public_cipher_method = NX_NULL; + packet_offset = TEST_PACKET_OFFSET; + extension_length = 0; + status = _nx_secure_tls_send_clienthello_sig_extension(&tls_session, packet_buffer, + &packet_offset, &extension_length, + sizeof(packet_buffer)); + EXPECT_EQ(NX_SUCCESS, status); + signature_methods[3].nx_secure_x509_public_cipher_method = &ecdsa_method; + + signature_methods[3].nx_secure_x509_hash_method = NX_NULL; + packet_offset = TEST_PACKET_OFFSET; + extension_length = 0; + status = _nx_secure_tls_send_clienthello_sig_extension(&tls_session, packet_buffer, + &packet_offset, &extension_length, + sizeof(packet_buffer)); + EXPECT_EQ(NX_SUCCESS, status); + signature_methods[3].nx_secure_x509_hash_method = &sha256_method; + + signature_methods[4].nx_secure_x509_public_cipher_method = &unsupported_method; + packet_offset = TEST_PACKET_OFFSET; + extension_length = 0; + status = _nx_secure_tls_send_clienthello_sig_extension(&tls_session, packet_buffer, + &packet_offset, &extension_length, + sizeof(packet_buffer)); + EXPECT_EQ(NX_SUCCESS, status); + signature_methods[4].nx_secure_x509_public_cipher_method = &ecdsa_method; + /* Disabling TLS 1.3 retains the original TLS 1.2-only list. */ memset(packet_buffer, 0xA5, sizeof(packet_buffer)); tls_session.nx_secure_tls_1_3 = NX_FALSE; diff --git a/test/regression/nx_secure_test/nx_secure_tls_ecc_basic_test.c b/test/regression/nx_secure_test/nx_secure_tls_ecc_basic_test.c index 884adaa06..37df5f33e 100644 --- a/test/regression/nx_secure_test/nx_secure_tls_ecc_basic_test.c +++ b/test/regression/nx_secure_test/nx_secure_tls_ecc_basic_test.c @@ -9,11 +9,16 @@ /* SPDX-License-Identifier: MIT */ /***************************************************************************/ -/* This test concentrates on TLS ciphersuite TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA. The curve used in this demo is P256. */ +/* Portions of this file were generated with AI assistance. */ + +/* This test exchanges data using an ECC certificate and key share. */ #include "nx_api.h" #include "nx_secure_tls_api.h" #include "ecc_certs.c" +#if (NX_SECURE_TLS_TLS_1_3_ENABLED) +#include "brainpool_certs.c" +#endif #include "nx_crypto_ecdh.h" extern VOID test_control_return(UINT status); @@ -62,6 +67,12 @@ static UCHAR tls_packet_buffer[2][4000]; extern const USHORT nx_crypto_ecc_supported_groups[]; extern const NX_CRYPTO_METHOD *nx_crypto_ecc_curves[]; extern const UINT nx_crypto_ecc_supported_groups_size; + +#if (NX_SECURE_TLS_TLS_1_3_ENABLED) +extern NX_CRYPTO_METHOD crypto_method_ec_brainpoolp256; +static const USHORT brainpool_groups[] = {(USHORT)NX_CRYPTO_EC_BRAINPOOLP256r1}; +static const NX_CRYPTO_METHOD *brainpool_curves[] = {&crypto_method_ec_brainpoolp256}; +#endif extern const NX_SECURE_TLS_CRYPTO nx_crypto_tls_ciphers_ecc; /* Define thread prototypes. */ @@ -156,9 +167,15 @@ UINT status; ERROR_COUNTER(); } +#if (NX_SECURE_TLS_TLS_1_3_ENABLED) + status = nx_secure_tls_ecc_initialize(tls_session_ptr, brainpool_groups, + sizeof(brainpool_groups) / sizeof(brainpool_groups[0]), + brainpool_curves); +#else status = nx_secure_tls_ecc_initialize(tls_session_ptr, nx_crypto_ecc_supported_groups, nx_crypto_ecc_supported_groups_size, nx_crypto_ecc_curves); +#endif if (status) { ERROR_COUNTER(); @@ -174,7 +191,12 @@ UINT status; ERROR_COUNTER(); } +#if (NX_SECURE_TLS_TLS_1_3_ENABLED) + status = nx_secure_x509_certificate_initialize(&client_trusted_ca, + brainpool_root_der, sizeof(brainpool_root_der), +#else status = nx_secure_x509_certificate_initialize(&client_trusted_ca, ECCA2_der, ECCA2_der_len, +#endif NX_NULL, 0, NULL, 0, NX_SECURE_X509_KEY_TYPE_NONE); if (status) @@ -210,19 +232,32 @@ UINT status; ERROR_COUNTER(); } +#if (NX_SECURE_TLS_TLS_1_3_ENABLED) + status = nx_secure_tls_ecc_initialize(tls_session_ptr, brainpool_groups, + sizeof(brainpool_groups) / sizeof(brainpool_groups[0]), + brainpool_curves); +#else status = nx_secure_tls_ecc_initialize(tls_session_ptr, nx_crypto_ecc_supported_groups, nx_crypto_ecc_supported_groups_size, nx_crypto_ecc_curves); +#endif if (status) { ERROR_COUNTER(); } memset(&server_local_certificate, 0, sizeof(server_local_certificate)); +#if (NX_SECURE_TLS_TLS_1_3_ENABLED) + status = nx_secure_x509_certificate_initialize(&server_local_certificate, + brainpool_server_der, sizeof(brainpool_server_der), + NX_NULL, 0, brainpool_server_key_der, + sizeof(brainpool_server_key_der), +#else status = nx_secure_x509_certificate_initialize(&server_local_certificate, ECTestServer2_der, ECTestServer2_der_len, NX_NULL, 0, ECTestServer2_key_der, ECTestServer2_key_der_len, +#endif NX_SECURE_X509_KEY_TYPE_EC_DER); if (status) { @@ -283,6 +318,18 @@ NX_PACKET *packet_ptr; ERROR_COUNTER(); } +#if (NX_SECURE_TLS_TLS_1_3_ENABLED) + if ((tls_server_session_0.nx_secure_tls_1_3 != NX_TRUE) || + (tls_server_session_0.nx_secure_tls_signature_algorithm != + NX_SECURE_TLS_SIGNATURE_ECDSA_BRAINPOOLP256R1_SHA256) || + (tls_server_session_0.nx_secure_tls_key_material.nx_secure_tls_ecc_key_data[ + tls_server_session_0.nx_secure_tls_key_material.nx_secure_tls_ecc_key_data_selected].nx_secure_tls_ecdhe_named_curve != + (USHORT)NX_CRYPTO_EC_BRAINPOOLP256r1)) + { + ERROR_COUNTER(); + } +#endif + status = nx_secure_tls_session_receive(&tls_server_session_0, &packet_ptr, NX_WAIT_FOREVER); if (status) { @@ -406,6 +453,12 @@ NXD_ADDRESS server_address; } /* Start TLS session. */ +#if (NX_SECURE_TLS_TLS_1_3_ENABLED) + tls_client_session_0.nx_secure_tls_1_3 = NX_TRUE; +#ifndef NX_SECURE_TLS_DISABLE_SECURE_RENEGOTIATION + tls_client_session_0.nx_secure_tls_renegotation_enabled = NX_FALSE; +#endif +#endif status = nx_secure_tls_session_start(&tls_client_session_0, &client_socket_0, NX_WAIT_FOREVER); if (status) @@ -413,6 +466,16 @@ NXD_ADDRESS server_address; ERROR_COUNTER(); } +#if (NX_SECURE_TLS_TLS_1_3_ENABLED) + if ((tls_client_session_0.nx_secure_tls_1_3 != NX_TRUE) || + (tls_client_session_0.nx_secure_tls_key_material.nx_secure_tls_ecc_key_data[ + tls_client_session_0.nx_secure_tls_key_material.nx_secure_tls_ecc_key_data_selected].nx_secure_tls_ecdhe_named_curve != + (USHORT)NX_CRYPTO_EC_BRAINPOOLP256r1)) + { + ERROR_COUNTER(); + } +#endif + /* Prepare packet to send. */ status = nx_packet_allocate(&pool_0, &packet_ptr, NX_TCP_PACKET, NX_NO_WAIT); if (status) diff --git a/test/regression/nx_secure_test/nx_secure_tls_process_certificate_verify_test.c b/test/regression/nx_secure_test/nx_secure_tls_process_certificate_verify_test.c index cb3dac5a8..800d849f7 100644 --- a/test/regression/nx_secure_test/nx_secure_tls_process_certificate_verify_test.c +++ b/test/regression/nx_secure_test/nx_secure_tls_process_certificate_verify_test.c @@ -9,6 +9,8 @@ /* SPDX-License-Identifier: MIT */ /***************************************************************************/ +// Portions of this file were generated with AI assistance. + /* This test concentrates on TLS ECC ciphersuites negotiation. */ #include "nx_api.h" @@ -114,7 +116,7 @@ static UINT test_crypto_operation_success(UINT op, /* Encrypt, Decrypt, Au VOID *packet_ptr, VOID (*nx_crypto_hw_process_callback)(VOID *packet_ptr, UINT status)) { - if(output) + if(output && output_length_in_byte >= 2u) { output[0] = 1; output[1] = 1; @@ -161,6 +163,16 @@ NX_SECURE_TLS_SESSION tls_session; UCHAR buffer[256]; NX_SECURE_X509_CERTIFICATE_STORE store; NX_SECURE_X509_CERT certificate; +#if (NX_SECURE_TLS_TLS_1_3_ENABLED) +UINT i; +UINT saved_curve; +const USHORT brainpool_schemes[] = +{ + NX_SECURE_TLS_SIGNATURE_ECDSA_BRAINPOOLP256R1_SHA256, + NX_SECURE_TLS_SIGNATURE_ECDSA_BRAINPOOLP384R1_SHA384, + NX_SECURE_TLS_SIGNATURE_ECDSA_BRAINPOOLP512R1_SHA512 +}; +#endif /* Print out test information banner. */ printf("NetX Secure Test: TLS Process Certificate Verify Test...................."); @@ -193,6 +205,19 @@ NX_SECURE_X509_CERT certificate; certificate.nx_secure_x509_cipher_table_size = 1; tls_session.nx_secure_tls_credentials.nx_secure_tls_certificate_store = store; +#if (NX_SECURE_TLS_TLS_1_3_ENABLED) + /* Unsupported Brainpool schemes must fail before signature decoding. */ + tls_session.nx_secure_tls_1_3 = NX_TRUE; + for (i = 0; i < sizeof(brainpool_schemes) / sizeof(brainpool_schemes[0]); i++) + { + buffer[0] = (UCHAR)(brainpool_schemes[i] >> 8); + buffer[1] = (UCHAR)brainpool_schemes[i]; + status = _nx_secure_tls_process_certificate_verify(&tls_session, buffer, sizeof(buffer)); + EXPECT_EQ(NX_SECURE_TLS_UNKNOWN_CERT_SIG_ALGORITHM, status); + } + tls_session.nx_secure_tls_1_3 = NX_FALSE; +#endif + status = _nx_secure_tls_process_certificate_verify(&tls_session, buffer, sizeof(buffer)); EXPECT_EQ(NX_SECURE_TLS_UNSUPPORTED_TLS_VERSION, status); @@ -242,6 +267,41 @@ NX_SECURE_X509_CERT certificate; certificate.nx_secure_x509_cipher_table_size = 1; test_x509_cipher_table->nx_secure_x509_crypto_identifier = NX_SECURE_TLS_X509_TYPE_ECDSA_SHA_256; +#if (NX_SECURE_TLS_TLS_1_3_ENABLED) + /* A Brainpool signature scheme must match the certificate's named curve. */ + tls_session.nx_secure_tls_1_3 = NX_TRUE; + test_x509_hash_method.nx_crypto_ICV_size_in_bits = 256; + test_x509_hash_method.nx_crypto_operation = test_crypto_operation_success; + buffer[0] = (UCHAR)(NX_SECURE_TLS_SIGNATURE_ECDSA_BRAINPOOLP256R1_SHA256 >> 8); + buffer[1] = (UCHAR)NX_SECURE_TLS_SIGNATURE_ECDSA_BRAINPOOLP256R1_SHA256; + buffer[2] = 0; + buffer[3] = 0; + status = _nx_secure_tls_process_certificate_verify(&tls_session, buffer, sizeof(buffer)); + EXPECT_EQ(NX_SECURE_TLS_UNSUPPORTED_CERT_SIGN_ALG, status); + + saved_curve = certificate.nx_secure_x509_public_key.ec_public_key.nx_secure_ec_named_curve; + certificate.nx_secure_x509_public_key.ec_public_key.nx_secure_ec_named_curve = NX_CRYPTO_EC_BRAINPOOLP256r1; + buffer[0] = (UCHAR)(NX_SECURE_TLS_SIGNATURE_ECDSA_SHA256 >> 8); + buffer[1] = (UCHAR)NX_SECURE_TLS_SIGNATURE_ECDSA_SHA256; + status = _nx_secure_tls_process_certificate_verify(&tls_session, buffer, sizeof(buffer)); + EXPECT_EQ(NX_SECURE_TLS_UNSUPPORTED_CERT_SIGN_ALG, status); + + buffer[0] = (UCHAR)(NX_SECURE_TLS_SIGNATURE_ECDSA_BRAINPOOLP256R1_SHA256 >> 8); + buffer[1] = (UCHAR)NX_SECURE_TLS_SIGNATURE_ECDSA_BRAINPOOLP256R1_SHA256; + status = _nx_secure_tls_process_certificate_verify(&tls_session, buffer, sizeof(buffer)); + EXPECT_EQ(NX_SECURE_TLS_UNSUPPORTED_ECC_CURVE, status); + + certificate.nx_secure_x509_public_key.ec_public_key.nx_secure_ec_named_curve = NX_CRYPTO_EC_BRAINPOOLP512r1 + 1u; + buffer[0] = (UCHAR)(NX_SECURE_TLS_SIGNATURE_ECDSA_SHA256 >> 8); + buffer[1] = (UCHAR)NX_SECURE_TLS_SIGNATURE_ECDSA_SHA256; + status = _nx_secure_tls_process_certificate_verify(&tls_session, buffer, sizeof(buffer)); + EXPECT_EQ(NX_SECURE_TLS_UNSUPPORTED_ECC_CURVE, status); + + certificate.nx_secure_x509_public_key.ec_public_key.nx_secure_ec_named_curve = saved_curve; + test_x509_hash_method.nx_crypto_operation = NX_NULL; + tls_session.nx_secure_tls_1_3 = NX_FALSE; + buffer[2] = 1; +#endif buffer[0] = 0; buffer[1] = NX_SECURE_TLS_SIGNATURE_ALGORITHM_ECDSA; status = _nx_secure_tls_process_certificate_verify(&tls_session, buffer, sizeof(buffer));