From d34fd89a754fb934fdc7978669e17d9b1e9ee654 Mon Sep 17 00:00:00 2001 From: xjin776_comcast Date: Sat, 7 Feb 2026 22:07:39 -0500 Subject: [PATCH] Add RSA-only mode to SecAPI3 provider for TLS mTLS compatibility New Features: - Add sa_provider_set_rsa_only_mode() API for RSA-only provider mode - Export sa_provider_init() for OSSL_PROVIDER_add_builtin() registration - In RSA-only mode, only RSA keymgmt/signature exposed; EC/DH/ciphers/digests fall through to default provider - Enables TLS mTLS: RSA cert signing via SecAPI3, ECDH key exchange via default provider Bug Fixes: - sa_crypto_cipher_process.c: Remove debug ERROR log from production code - sa_process_common_encryption.c: Use local subsample_length_s array for param1 - ta.c: Fix EC-ElGamal unwrap parameter struct handling - ta.c: Fix common encryption subsample_length size check --- reference/src/client/include/sa_provider.h | 35 +++++++++++++ reference/src/client/src/sa_provider.c | 50 ++++++++++++++++++- .../clientimpl/src/sa_crypto_cipher_process.c | 1 - .../src/sa_process_common_encryption.c | 2 +- reference/src/taimpl/src/internal/ta.c | 9 ++-- 5 files changed, 90 insertions(+), 7 deletions(-) diff --git a/reference/src/client/include/sa_provider.h b/reference/src/client/include/sa_provider.h index 466f08e5..35a87189 100644 --- a/reference/src/client/include/sa_provider.h +++ b/reference/src/client/include/sa_provider.h @@ -182,6 +182,7 @@ extern "C" { #include #if OPENSSL_VERSION_NUMBER >= 0x30000000 #include +#include /** * The provider ID used to register the SecApi 3 provider. @@ -215,6 +216,40 @@ extern "C" { */ OSSL_LIB_CTX* sa_get_provider(); +/** + * Enable or disable RSA-only mode for the SecAPI3 provider. + * + * When enabled (enable=1), the provider only exposes RSA keymgmt and RSA signature + * operations. All other operations (EC, DH, ECDH, ciphers, digests, MACs, KDFs) + * are not provided, allowing them to be handled by the default provider. + * + * This mode is essential for TLS mTLS where: + * - RSA client certificate signing needs SecAPI3 (for secure key access) + * - ECDH key exchange needs the default provider (ephemeral keys) + * + * MUST be called BEFORE OSSL_PROVIDER_load() to take effect. + * + * @param enable 1 to enable RSA-only mode, 0 for full SecAPI3 mode + */ +void sa_provider_set_rsa_only_mode(int enable); + +/** + * Provider init function for direct registration with OSSL_PROVIDER_add_builtin. + * Use this to register SecAPI3 provider in the default lib_ctx for SSL/TLS operations. + * + * Example: + * -------- + * ``` + * sa_provider_set_rsa_only_mode(1); // Enable RSA-only for TLS mTLS + * OSSL_PROVIDER_add_builtin(NULL, "secapi3", sa_provider_init); + * OSSL_PROVIDER_load(NULL, "default"); // for EC/DH/ciphers/digests + * OSSL_PROVIDER_load(NULL, "secapi3"); // for RSA signing only + * SSL_CTX* ssl_ctx = SSL_CTX_new(TLS_client_method()); // uses default lib_ctx + * ``` + */ +int sa_provider_init(const OSSL_CORE_HANDLE* handle, const OSSL_DISPATCH* in, + const OSSL_DISPATCH** out, void** provctx); + #endif #ifdef __cplusplus diff --git a/reference/src/client/src/sa_provider.c b/reference/src/client/src/sa_provider.c index 026eec89..3fda2a8a 100644 --- a/reference/src/client/src/sa_provider.c +++ b/reference/src/client/src/sa_provider.c @@ -39,11 +39,19 @@ static OSSL_LIB_CTX* lib_ctx = NULL; static OSSL_PROVIDER* sa_provider = NULL; static OSSL_PROVIDER* base_provider = NULL; +// Flag to enable RSA-only mode (excludes EC/DH keymgmt and keyexch) +// This is needed for TLS mTLS where ECDH should use the default provider +static int sa_provider_rsa_only_mode = 0; + +void sa_provider_set_rsa_only_mode(int enable) { + sa_provider_rsa_only_mode = enable; +} + static OSSL_FUNC_provider_teardown_fn sa_provider_teardown; static OSSL_FUNC_provider_get_params_fn sa_provider_get_params; static OSSL_FUNC_provider_gettable_params_fn sa_provider_gettable_params; static OSSL_FUNC_provider_query_operation_fn sa_provider_query_operation; -static OSSL_provider_init_fn sa_provider_init; +OSSL_provider_init_fn sa_provider_init; extern const OSSL_ALGORITHM sa_provider_asym_ciphers[]; extern const OSSL_ALGORITHM sa_provider_ciphers[]; @@ -118,27 +126,65 @@ static const OSSL_ALGORITHM* sa_provider_query_operation( *no_store = 0; switch (operation_id) { case OSSL_OP_ASYM_CIPHER: + // In RSA-only mode, don't provide asymmetric ciphers (not needed for TLS signing) + if (sa_provider_rsa_only_mode) + return NULL; return sa_provider_asym_ciphers; case OSSL_OP_CIPHER: + // In RSA-only mode, let default provider handle symmetric ciphers + if (sa_provider_rsa_only_mode) + return NULL; return sa_provider_ciphers; case OSSL_OP_DIGEST: + // In RSA-only mode, let default provider handle digests + if (sa_provider_rsa_only_mode) + return NULL; return sa_provider_digests; case OSSL_OP_KDF: + // In RSA-only mode, let default provider handle KDFs + if (sa_provider_rsa_only_mode) + return NULL; return sa_provider_kdfs; case OSSL_OP_KEYEXCH: + // In RSA-only mode, don't provide keyexch (ECDH/DH) - let default provider handle + if (sa_provider_rsa_only_mode) + return NULL; return sa_provider_keyexchs; case OSSL_OP_KEYMGMT: + // In RSA-only mode, only provide RSA keymgmt (first entry in array) + if (sa_provider_rsa_only_mode) { + // Create a filtered array with only RSA (first entry) + NULL terminator + static OSSL_ALGORITHM keymgmt_rsa_only[2] = {{0}}; + if (keymgmt_rsa_only[0].algorithm_names == NULL) { + keymgmt_rsa_only[0] = sa_provider_keymgmt[0]; // RSA entry + keymgmt_rsa_only[1].algorithm_names = NULL; // terminator + } + return keymgmt_rsa_only; + } return sa_provider_keymgmt; case OSSL_OP_MAC: + // In RSA-only mode, let default provider handle MACs + if (sa_provider_rsa_only_mode) + return NULL; return sa_provider_macs; case OSSL_OP_SIGNATURE: + // In RSA-only mode, only provide RSA signature (first entry in array) + if (sa_provider_rsa_only_mode) { + // Create a filtered array with only RSA (first entry) + NULL terminator + static OSSL_ALGORITHM sig_rsa_only[2] = {{0}}; + if (sig_rsa_only[0].algorithm_names == NULL) { + sig_rsa_only[0] = sa_provider_signatures[0]; // RSA entry + sig_rsa_only[1].algorithm_names = NULL; // terminator + } + return sig_rsa_only; + } return sa_provider_signatures; default: @@ -154,7 +200,7 @@ static const OSSL_DISPATCH sa_provider_dispatch_table[] = { {OSSL_FUNC_PROVIDER_QUERY_OPERATION, (void (*)(void)) sa_provider_query_operation}, {0, NULL}}; -static int sa_provider_init( +int sa_provider_init( const OSSL_CORE_HANDLE* handle, const OSSL_DISPATCH* in, const OSSL_DISPATCH** out, diff --git a/reference/src/clientimpl/src/sa_crypto_cipher_process.c b/reference/src/clientimpl/src/sa_crypto_cipher_process.c index a9a62c48..471e6006 100644 --- a/reference/src/clientimpl/src/sa_crypto_cipher_process.c +++ b/reference/src/clientimpl/src/sa_crypto_cipher_process.c @@ -159,7 +159,6 @@ sa_status sa_crypto_cipher_process( #endif // ENABLE_SVP *bytes_to_process = cipher_process->bytes_to_process; - ERROR("bytes_to_process = %d\n", cipher_process->bytes_to_process); } while (false); RELEASE_COMMAND(cipher_process); diff --git a/reference/src/clientimpl/src/sa_process_common_encryption.c b/reference/src/clientimpl/src/sa_process_common_encryption.c index 811c884c..2cb09e2f 100644 --- a/reference/src/clientimpl/src/sa_process_common_encryption.c +++ b/reference/src/clientimpl/src/sa_process_common_encryption.c @@ -117,7 +117,7 @@ sa_status sa_process_common_encryption( subsample_length_s[j].bytes_of_protected_data = samples[i].subsample_lengths[j].bytes_of_protected_data; } - CREATE_PARAM(param1, samples[i].subsample_lengths, param1_size); + CREATE_PARAM(param1, subsample_length_s, param1_size); uint32_t param1_type = TA_PARAM_IN; size_t param2_size; uint32_t param2_type; diff --git a/reference/src/taimpl/src/internal/ta.c b/reference/src/taimpl/src/internal/ta.c index 5ff94f54..d5df2415 100644 --- a/reference/src/taimpl/src/internal/ta.c +++ b/reference/src/taimpl/src/internal/ta.c @@ -483,6 +483,7 @@ static sa_status ta_invoke_key_unwrap( sa_unwrap_parameters_chacha20_s parameters_chacha_20_s; sa_unwrap_parameters_chacha20_poly1305_s parameters_chacha_20_poly_1305_s; sa_unwrap_parameters_rsa_oaep_s parameters_rsa_oaep_s; + sa_unwrap_parameters_ec_elgamal_s parameters_ec_elgamal_s; sa_unwrap_parameters_aes_cbc parameters_aes_cbc; sa_unwrap_parameters_aes_ctr parameters_aes_ctr; sa_unwrap_parameters_aes_gcm parameters_aes_gcm; @@ -608,8 +609,10 @@ static sa_status ta_invoke_key_unwrap( return SA_STATUS_INVALID_PARAMETER; } - memcpy(¶meters_ec_elgamal, params[2].mem_ref, params[2].mem_ref_size); - algorithm_parameters = params[2].mem_ref; + memcpy(¶meters_ec_elgamal_s, params[2].mem_ref, params[2].mem_ref_size); + parameters_ec_elgamal.offset = parameters_ec_elgamal_s.offset; + parameters_ec_elgamal.key_length = parameters_ec_elgamal_s.key_length; + algorithm_parameters = ¶meters_ec_elgamal; break; case SA_CIPHER_ALGORITHM_RSA_OAEP: @@ -1826,7 +1829,7 @@ static sa_status ta_invoke_process_common_encryption( sa_sample sample; do { sample.subsample_count = process_common_encryption->subsample_count; - if (params[1].mem_ref_size != sizeof(sa_subsample_length) * sample.subsample_count) { + if (params[1].mem_ref_size != sizeof(sa_subsample_length_s) * sample.subsample_count) { ERROR("params[1].mem_ref_size is invalid"); return SA_STATUS_INVALID_PARAMETER; }