From 9cb198ef55728afa957bb58ae67f14be8b9a072d Mon Sep 17 00:00:00 2001 From: Shubham Mittal Date: Mon, 19 Aug 2024 00:17:16 -0700 Subject: [PATCH 01/26] refactor engine API and memory around METHOD structs --- crypto/engine/engine.c | 51 +++++++++----------------------- crypto/fipsmodule/ec/ec_key.c | 15 ++-------- crypto/fipsmodule/ec/internal.h | 2 +- crypto/fipsmodule/rsa/internal.h | 2 +- crypto/fipsmodule/rsa/rsa.c | 5 +--- crypto/fipsmodule/rsa/rsa_impl.c | 1 - include/openssl/ec_key.h | 2 -- include/openssl/engine.h | 48 ++++++++---------------------- include/openssl/rsa.h | 2 -- 9 files changed, 32 insertions(+), 96 deletions(-) diff --git a/crypto/engine/engine.c b/crypto/engine/engine.c index 3b5bf5220a..ea7ec7ba22 100644 --- a/crypto/engine/engine.c +++ b/crypto/engine/engine.c @@ -39,53 +39,30 @@ int ENGINE_free(ENGINE *engine) { return 1; } -// set_method takes a pointer to a method and its given size and sets -// |*out_member| to point to it. This function might want to be extended in the -// future to support making a copy of the method so that a stable ABI for -// ENGINEs can be supported. But, for the moment, all *_METHODS must be -// static. -static int set_method(void **out_member, const void *method, size_t method_size, - size_t compiled_size) { - const struct openssl_method_common_st *common = method; - if (method_size != compiled_size || !common->is_static) { - return 0; +int ENGINE_set_RSA(ENGINE *engine, const RSA_METHOD *method) { + if(engine) { + engine->rsa_method = (RSA_METHOD *)method; + return 1; } - *out_member = (void*) method; - return 1; -} - -int ENGINE_set_RSA_method(ENGINE *engine, const RSA_METHOD *method, - size_t method_size) { - return set_method((void **)&engine->rsa_method, method, method_size, - sizeof(RSA_METHOD)); + return 0; } -RSA_METHOD *ENGINE_get_RSA_method(const ENGINE *engine) { +const RSA_METHOD *ENGINE_get_RSA(const ENGINE *engine) { return engine->rsa_method; } -int ENGINE_set_ECDSA_method(ENGINE *engine, const ECDSA_METHOD *method, - size_t method_size) { - return set_method((void **)&engine->ecdsa_method, method, method_size, - sizeof(ECDSA_METHOD)); -} - -ECDSA_METHOD *ENGINE_get_ECDSA_method(const ENGINE *engine) { - return engine->ecdsa_method; -} +int ENGINE_set_ECDSA(ENGINE *engine, const ECDSA_METHOD *method) { + if(engine) { + engine->ecdsa_method = (ECDSA_METHOD *)method; + return 1; + } -void METHOD_ref(void *method_in) { - assert(((struct openssl_method_common_st*) method_in)->is_static); + return 0; } -void METHOD_unref(void *method_in) { - struct openssl_method_common_st *method = method_in; - - if (method == NULL) { - return; - } - assert(method->is_static); +const ECDSA_METHOD *ENGINE_get_ECDSA(const ENGINE *engine) { + return engine->ecdsa_method; } OPENSSL_DECLARE_ERROR_REASON(ENGINE, OPERATION_NOT_SUPPORTED) diff --git a/crypto/fipsmodule/ec/ec_key.c b/crypto/fipsmodule/ec/ec_key.c index 7f1d72cacc..b305a4f389 100644 --- a/crypto/fipsmodule/ec/ec_key.c +++ b/crypto/fipsmodule/ec/ec_key.c @@ -111,10 +111,7 @@ EC_KEY *EC_KEY_new_method(const ENGINE *engine) { } if (engine) { - ret->ecdsa_meth = ENGINE_get_ECDSA_method(engine); - } - if (ret->ecdsa_meth) { - METHOD_ref(ret->ecdsa_meth); + ret->ecdsa_meth = ENGINE_get_ECDSA(engine); } ret->conv_form = POINT_CONVERSION_UNCOMPRESSED; @@ -124,9 +121,6 @@ EC_KEY *EC_KEY_new_method(const ENGINE *engine) { if (ret->ecdsa_meth && ret->ecdsa_meth->init && !ret->ecdsa_meth->init(ret)) { CRYPTO_free_ex_data(g_ec_ex_data_class_bss_get(), ret, &ret->ex_data); - if (ret->ecdsa_meth) { - METHOD_unref(ret->ecdsa_meth); - } OPENSSL_free(ret); return NULL; } @@ -156,11 +150,8 @@ void EC_KEY_free(EC_KEY *r) { return; } - if (r->ecdsa_meth) { - if (r->ecdsa_meth->finish) { - r->ecdsa_meth->finish(r); - } - METHOD_unref(r->ecdsa_meth); + if (r->ecdsa_meth && r->ecdsa_meth->finish) { + r->ecdsa_meth->finish(r); } CRYPTO_free_ex_data(g_ec_ex_data_class_bss_get(), r, &r->ex_data); diff --git a/crypto/fipsmodule/ec/internal.h b/crypto/fipsmodule/ec/internal.h index ed33ddbdb2..e932b2a6ce 100644 --- a/crypto/fipsmodule/ec/internal.h +++ b/crypto/fipsmodule/ec/internal.h @@ -766,7 +766,7 @@ struct ec_key_st { CRYPTO_refcount_t references; - ECDSA_METHOD *ecdsa_meth; + const ECDSA_METHOD *ecdsa_meth; CRYPTO_EX_DATA ex_data; } /* EC_KEY */; diff --git a/crypto/fipsmodule/rsa/internal.h b/crypto/fipsmodule/rsa/internal.h index 2b4420417a..e668af0f89 100644 --- a/crypto/fipsmodule/rsa/internal.h +++ b/crypto/fipsmodule/rsa/internal.h @@ -70,7 +70,7 @@ extern "C" { typedef struct bn_blinding_st BN_BLINDING; struct rsa_st { - RSA_METHOD *meth; + const RSA_METHOD *meth; BIGNUM *n; BIGNUM *e; diff --git a/crypto/fipsmodule/rsa/rsa.c b/crypto/fipsmodule/rsa/rsa.c index 5cea886b57..c17ce78383 100644 --- a/crypto/fipsmodule/rsa/rsa.c +++ b/crypto/fipsmodule/rsa/rsa.c @@ -217,13 +217,12 @@ RSA *RSA_new_method(const ENGINE *engine) { } if (engine) { - rsa->meth = ENGINE_get_RSA_method(engine); + rsa->meth = ENGINE_get_RSA(engine); } if (rsa->meth == NULL) { rsa->meth = (RSA_METHOD *) RSA_default_method(); } - METHOD_ref(rsa->meth); rsa->references = 1; rsa->flags = rsa->meth->flags; @@ -233,7 +232,6 @@ RSA *RSA_new_method(const ENGINE *engine) { if (rsa->meth->init && !rsa->meth->init(rsa)) { CRYPTO_free_ex_data(g_rsa_ex_data_class_bss_get(), rsa, &rsa->ex_data); CRYPTO_MUTEX_cleanup(&rsa->lock); - METHOD_unref(rsa->meth); OPENSSL_free(rsa); return NULL; } @@ -266,7 +264,6 @@ void RSA_free(RSA *rsa) { if (rsa->meth->finish) { rsa->meth->finish(rsa); } - METHOD_unref(rsa->meth); CRYPTO_free_ex_data(g_rsa_ex_data_class_bss_get(), rsa, &rsa->ex_data); diff --git a/crypto/fipsmodule/rsa/rsa_impl.c b/crypto/fipsmodule/rsa/rsa_impl.c index b97d08b53a..6114b4eed3 100644 --- a/crypto/fipsmodule/rsa/rsa_impl.c +++ b/crypto/fipsmodule/rsa/rsa_impl.c @@ -1278,5 +1278,4 @@ DEFINE_METHOD_FUNCTION(RSA_METHOD, RSA_default_method) { // drop unused functions. The wrapper functions will select the appropriate // |rsa_default_*| implementation. OPENSSL_memset(out, 0, sizeof(RSA_METHOD)); - out->common.is_static = 1; } diff --git a/include/openssl/ec_key.h b/include/openssl/ec_key.h index 2badaa6ce2..10a5f9429a 100644 --- a/include/openssl/ec_key.h +++ b/include/openssl/ec_key.h @@ -289,8 +289,6 @@ OPENSSL_EXPORT void *EC_KEY_get_ex_data(const EC_KEY *r, int idx); // ecdsa_method_st is a structure of function pointers for implementing ECDSA. // See engine.h. struct ecdsa_method_st { - struct openssl_method_common_st common; - void *app_data; int (*init)(EC_KEY *key); diff --git a/include/openssl/engine.h b/include/openssl/engine.h index bdedd14b0c..00c669d763 100644 --- a/include/openssl/engine.h +++ b/include/openssl/engine.h @@ -46,37 +46,23 @@ OPENSSL_EXPORT int ENGINE_free(ENGINE *engine); // Method accessors. // -// Method accessors take a method pointer and the size of the structure. The -// size allows for ABI compatibility in the case that the method structure is -// extended with extra elements at the end. Methods are always copied by the -// set functions. +// Method accessors take a method pointer and set it on the |ENGINE| object. +// AWS-LC does not take ownership of the |method| pointer. The consumer +// must free the |method| pointer after all objects referencing it are +// freed. // -// Set functions return one on success and zero on allocation failure. +// Set functions return one on success and zero for failure when +// |engine| is NULL. -OPENSSL_EXPORT int ENGINE_set_RSA_method(ENGINE *engine, - const RSA_METHOD *method, - size_t method_size); -OPENSSL_EXPORT RSA_METHOD *ENGINE_get_RSA_method(const ENGINE *engine); +OPENSSL_EXPORT int ENGINE_set_RSA(ENGINE *engine, + const RSA_METHOD *method); -OPENSSL_EXPORT int ENGINE_set_ECDSA_method(ENGINE *engine, - const ECDSA_METHOD *method, - size_t method_size); -OPENSSL_EXPORT ECDSA_METHOD *ENGINE_get_ECDSA_method(const ENGINE *engine); +OPENSSL_EXPORT const RSA_METHOD *ENGINE_get_RSA(const ENGINE *engine); +OPENSSL_EXPORT int ENGINE_set_ECDSA(ENGINE *engine, + const ECDSA_METHOD *method); -// Generic method functions. -// -// These functions take a void* type but actually operate on all method -// structures. - -// METHOD_ref increments the reference count of |method|. This is a no-op for -// now because all methods are currently static. -void METHOD_ref(void *method); - -// METHOD_unref decrements the reference count of |method| and frees it if the -// reference count drops to zero. This is a no-op for now because all methods -// are currently static. -void METHOD_unref(void *method); +OPENSSL_EXPORT const ECDSA_METHOD *ENGINE_get_ECDSA(const ENGINE *engine); // Deprecated functions. @@ -86,16 +72,6 @@ void METHOD_unref(void *method); OPENSSL_EXPORT void ENGINE_cleanup(void); -// Private functions. - -// openssl_method_common_st contains the common part of all method structures. -// This must be the first member of all method structures. -struct openssl_method_common_st { - int references; // dummy – not used. - char is_static; -}; - - #if defined(__cplusplus) } // extern C diff --git a/include/openssl/rsa.h b/include/openssl/rsa.h index ba7f6fa2d3..d7e7a20168 100644 --- a/include/openssl/rsa.h +++ b/include/openssl/rsa.h @@ -830,8 +830,6 @@ OPENSSL_EXPORT RSA *RSA_new_method_no_e(const ENGINE *engine, const BIGNUM *n); struct rsa_meth_st { - struct openssl_method_common_st common; - void *app_data; int (*init)(RSA *rsa); From 9c1b425a0bc24b858131a6b0d290c7cad94b7e79 Mon Sep 17 00:00:00 2001 From: Shubham Mittal Date: Mon, 19 Aug 2024 20:10:41 -0700 Subject: [PATCH 02/26] added check in RSA_free and removed old comment --- crypto/engine/engine.c | 1 - crypto/fipsmodule/rsa/rsa.c | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/crypto/engine/engine.c b/crypto/engine/engine.c index ea7ec7ba22..f610c360a7 100644 --- a/crypto/engine/engine.c +++ b/crypto/engine/engine.c @@ -34,7 +34,6 @@ struct engine_st { ENGINE *ENGINE_new(void) { return OPENSSL_zalloc(sizeof(ENGINE)); } int ENGINE_free(ENGINE *engine) { - // Methods are currently required to be static so are not unref'ed. OPENSSL_free(engine); return 1; } diff --git a/crypto/fipsmodule/rsa/rsa.c b/crypto/fipsmodule/rsa/rsa.c index c17ce78383..1976c617a6 100644 --- a/crypto/fipsmodule/rsa/rsa.c +++ b/crypto/fipsmodule/rsa/rsa.c @@ -261,7 +261,7 @@ void RSA_free(RSA *rsa) { return; } - if (rsa->meth->finish) { + if (rsa->meth && rsa->meth->finish) { rsa->meth->finish(rsa); } From d9ce0016458ec872aa1f010591d9b8d628e7a88a Mon Sep 17 00:00:00 2001 From: Shubham Mittal Date: Mon, 19 Aug 2024 20:20:09 -0700 Subject: [PATCH 03/26] updated documentation --- crypto/fipsmodule/rsa/internal.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/crypto/fipsmodule/rsa/internal.h b/crypto/fipsmodule/rsa/internal.h index e668af0f89..1e09f1400a 100644 --- a/crypto/fipsmodule/rsa/internal.h +++ b/crypto/fipsmodule/rsa/internal.h @@ -128,6 +128,8 @@ struct rsa_st { // Default implementations of RSA operations. +// RSA_default_method returns a zero initialized |RSA_METHOD| object. The +// wrapper functions will select the appropriate |rsa_default_*| implementation. const RSA_METHOD *RSA_default_method(void); size_t rsa_default_size(const RSA *rsa); From 534e93ecf0368fc07bdc79d2e2f84136e6cfe53b Mon Sep 17 00:00:00 2001 From: Shubham Mittal Date: Thu, 25 Jul 2024 12:54:02 -0700 Subject: [PATCH 04/26] removed ECDSA_METHOD and first batch of EC_KEY_METHOD replacement --- crypto/ecdsa_extra/ecdsa_asn1.c | 5 +- crypto/engine/engine.c | 11 ++-- crypto/fipsmodule/ec/ec_key.c | 112 ++++++++++++++++++++++++++++++-- crypto/fipsmodule/ec/internal.h | 42 +++++++++++- crypto/fipsmodule/ecdsa/ecdsa.c | 15 +++-- include/openssl/base.h | 2 +- include/openssl/ec_key.h | 72 ++++++++++++-------- include/openssl/engine.h | 8 +-- 8 files changed, 213 insertions(+), 54 deletions(-) diff --git a/crypto/ecdsa_extra/ecdsa_asn1.c b/crypto/ecdsa_extra/ecdsa_asn1.c index 320d521661..a0b9dd8af5 100644 --- a/crypto/ecdsa_extra/ecdsa_asn1.c +++ b/crypto/ecdsa_extra/ecdsa_asn1.c @@ -72,8 +72,9 @@ size_t ECDSA_size(const EC_KEY *key) { } size_t group_order_size; - if (key->ecdsa_meth && key->ecdsa_meth->group_order_size) { - group_order_size = key->ecdsa_meth->group_order_size(key); + // EC_KEY_METHOD doesn't offer this so remove and revert to default beahvior??? + if (key->eckey_method && key->eckey_method->group_order_size) { + group_order_size = key->eckey_method->group_order_size(key); } else { const EC_GROUP *group = EC_KEY_get0_group(key); if (group == NULL) { diff --git a/crypto/engine/engine.c b/crypto/engine/engine.c index f610c360a7..7a4ccdb454 100644 --- a/crypto/engine/engine.c +++ b/crypto/engine/engine.c @@ -24,11 +24,12 @@ #include #include "../internal.h" +#include "../crypto/fipsmodule/ec/internal.h" struct engine_st { RSA_METHOD *rsa_method; - ECDSA_METHOD *ecdsa_method; + EC_KEY_METHOD *eckey_method; }; ENGINE *ENGINE_new(void) { return OPENSSL_zalloc(sizeof(ENGINE)); } @@ -51,17 +52,17 @@ const RSA_METHOD *ENGINE_get_RSA(const ENGINE *engine) { return engine->rsa_method; } -int ENGINE_set_ECDSA(ENGINE *engine, const ECDSA_METHOD *method) { +int ENGINE_set_EC(ENGINE *engine, const EC_KEY_METHOD *method) { if(engine) { - engine->ecdsa_method = (ECDSA_METHOD *)method; + engine->eckey_method = (EC_KEY_METHOD *)method; return 1; } return 0; } -const ECDSA_METHOD *ENGINE_get_ECDSA(const ENGINE *engine) { - return engine->ecdsa_method; +const EC_KEY_METHOD *ENGINE_get_EC(const ENGINE *engine) { + return engine->eckey_method; } OPENSSL_DECLARE_ERROR_REASON(ENGINE, OPERATION_NOT_SUPPORTED) diff --git a/crypto/fipsmodule/ec/ec_key.c b/crypto/fipsmodule/ec/ec_key.c index b305a4f389..7368ca6dda 100644 --- a/crypto/fipsmodule/ec/ec_key.c +++ b/crypto/fipsmodule/ec/ec_key.c @@ -111,7 +111,8 @@ EC_KEY *EC_KEY_new_method(const ENGINE *engine) { } if (engine) { - ret->ecdsa_meth = ENGINE_get_ECDSA(engine); + // Cast away const + ret->eckey_method = (EC_KEY_METHOD *) ENGINE_get_EC(engine); } ret->conv_form = POINT_CONVERSION_UNCOMPRESSED; @@ -119,7 +120,7 @@ EC_KEY *EC_KEY_new_method(const ENGINE *engine) { CRYPTO_new_ex_data(&ret->ex_data); - if (ret->ecdsa_meth && ret->ecdsa_meth->init && !ret->ecdsa_meth->init(ret)) { + if (ret->eckey_method && ret->eckey_method->init && !ret->eckey_method->init(ret)) { CRYPTO_free_ex_data(g_ec_ex_data_class_bss_get(), ret, &ret->ex_data); OPENSSL_free(ret); return NULL; @@ -150,8 +151,8 @@ void EC_KEY_free(EC_KEY *r) { return; } - if (r->ecdsa_meth && r->ecdsa_meth->finish) { - r->ecdsa_meth->finish(r); + if (r->eckey_method && r->eckey_method->finish) { + r->eckey_method->finish(r); } CRYPTO_free_ex_data(g_ec_ex_data_class_bss_get(), r, &r->ex_data); @@ -194,8 +195,9 @@ int EC_KEY_up_ref(EC_KEY *r) { return 1; } +// This flag is gone with ECDSA_METHOD, do we duplicate in EC_KEY_METHOD or just remove this int EC_KEY_is_opaque(const EC_KEY *key) { - return key->ecdsa_meth && (key->ecdsa_meth->flags & ECDSA_FLAG_OPAQUE); + return key->eckey_method && (key->eckey_method->flags & ECDSA_FLAG_OPAQUE); } const EC_GROUP *EC_KEY_get0_group(const EC_KEY *key) { return key->group; } @@ -562,3 +564,103 @@ void *EC_KEY_get_ex_data(const EC_KEY *d, int idx) { } void EC_KEY_set_asn1_flag(EC_KEY *key, int flag) {} + +EC_KEY_METHOD *EC_KEY_OpenSSL(void) { + EC_KEY_METHOD *ret; + + ret = OPENSSL_zalloc(sizeof(EC_KEY_METHOD)); + if(ret == NULL) { + OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE); + return NULL; + } + + return ret; +} + +EC_KEY_METHOD *EC_KEY_METHOD_new(const EC_KEY_METHOD *eckey_meth) { + EC_KEY_METHOD *ret = EC_KEY_OpenSSL(); + + if(eckey_meth) { + *ret = *eckey_meth; + } + return ret; +} + +void EC_KEY_METHOD_free(EC_KEY_METHOD *eckey_meth) { + if(eckey_meth != NULL) { + OPENSSL_free(eckey_meth); + } +} + +int EC_KEY_set_method(EC_KEY *ec, EC_KEY_METHOD *meth) { + if(ec == NULL || meth == NULL) { + OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + // Only certain fields are supported as of now + if(meth->compute_key || meth->copy || meth->keygen || meth->set_group || + meth->set_private || meth->set_public || meth->verify || + meth->verify_sig) { + OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; + } + + ec->eckey_method = meth; + return 1; +} + +EC_KEY_METHOD *EC_KEY_get_method(EC_KEY *ec) { + if(ec == NULL) { + OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER); + return NULL; + } + + return ec->eckey_method; +} + +void EC_KEY_METHOD_set_init(EC_KEY_METHOD *meth, + int (*init)(EC_KEY *key), + void (*finish)(EC_KEY *key), + int (*copy)(EC_KEY *dest, const EC_KEY *src), + int (*set_group)(EC_KEY *key, const EC_GROUP *grp), + int (*set_private)(EC_KEY *key, + const BIGNUM *priv_key), + int (*set_public)(EC_KEY *key, + const EC_POINT *pub_key)) { + if(meth == NULL) { + OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER); + return; + } + + assert(!copy && !set_group && !set_private && !set_public); + if(copy || set_group || set_private || set_public) { + OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + abort(); + } + + meth->init = init; + meth->finish = finish; +} + +void EC_KEY_METHOD_set_sign(EC_KEY_METHOD *meth, + int (*sign)(int type, const uint8_t *digest, + unsigned int digest_len, uint8_t *sig, + unsigned int *siglen, const BIGNUM *k_inv, + const BIGNUM *r, EC_KEY *eckey), + int (*sign_setup)(EC_KEY *eckey, BN_CTX *ctx_in, + BIGNUM **kinvp, BIGNUM **rp), + ECDSA_SIG *(*sign_sig)(const uint8_t *digest, + unsigned int digest_len, + const BIGNUM *in_kinv, const BIGNUM *in_r, + EC_KEY *eckey)) { + + if(meth == NULL) { + OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER); + return; + } + + meth->sign = sign; + meth->sign_sig = sign_sig; + meth->sign_setup = sign_setup; +} diff --git a/crypto/fipsmodule/ec/internal.h b/crypto/fipsmodule/ec/internal.h index e932b2a6ce..4257bb4662 100644 --- a/crypto/fipsmodule/ec/internal.h +++ b/crypto/fipsmodule/ec/internal.h @@ -745,6 +745,46 @@ const EC_METHOD *EC_GFp_nistp521_method(void); // x86-64 optimized P256. See http://eprint.iacr.org/2013/816. const EC_METHOD *EC_GFp_nistz256_method(void); + +// EC_KEY METHOD + +// ec_key_method_st is a structure of function pointers implementing EC_KEY +// operations. Currently, AWS-LC only allows consumers to set certain fields. +struct ec_key_method_st { + int (*init)(EC_KEY *key); + void (*finish)(EC_KEY *key); + + // AWS-LC doesn't support custom values for EC_KEY operations + // as of now. |k_inv| and |r| must be NULL parameters. + // |type| is ignored in OpenSSL, we pass in 0 for it + int (*sign)(int type, const uint8_t *digest, unsigned int digest_len, + uint8_t *sig, unsigned int *siglen, const BIGNUM *k_inv, + const BIGNUM *r, EC_KEY *eckey); + ECDSA_SIG *(*sign_sig)(const uint8_t *digest, unsigned int digest_len, + const BIGNUM *in_kinv, const BIGNUM *in_r, + EC_KEY *eckey); + + // Currently AWS-LC only supports |ECDSA_FLAG_OPAQUE| + int flags; + + // Fields not supported by AWS-LC for now, must be set to NULL + int (*copy)(EC_KEY *dest, const EC_KEY *src); + int (*set_group)(EC_KEY *key, const EC_GROUP *group); + int (*set_private)(EC_KEY *key, const BIGNUM *priv_key); + int (*sign_setup)(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **k_inv, + BIGNUM **r); + + int (*set_public)(EC_KEY *key, const EC_POINT *pub_key); + int (*keygen)(EC_KEY *key); + int (*compute_key)(unsigned char **out, size_t *out_len, + const EC_POINT *pub_key, const EC_KEY *ecdh); + + int (*verify)(int type, const uint8_t *digest, unsigned int digest_len, + const uint8_t *sig, unsigned int sig_len, EC_KEY *eckey); + int (*verify_sig)(const uint8_t *digest, unsigned int digest_len, + const ECDSA_SIG *sig, EC_KEY *eckey); +}; + // An EC_WRAPPED_SCALAR is an |EC_SCALAR| with a parallel |BIGNUM| // representation. It exists to support the |EC_KEY_get0_private_key| API. typedef struct { @@ -766,7 +806,7 @@ struct ec_key_st { CRYPTO_refcount_t references; - const ECDSA_METHOD *ecdsa_meth; + const EC_KEY_METHOD *eckey_method; CRYPTO_EX_DATA ex_data; } /* EC_KEY */; diff --git a/crypto/fipsmodule/ecdsa/ecdsa.c b/crypto/fipsmodule/ecdsa/ecdsa.c index 5a946ed94a..efb5415b6b 100644 --- a/crypto/fipsmodule/ecdsa/ecdsa.c +++ b/crypto/fipsmodule/ecdsa/ecdsa.c @@ -273,7 +273,7 @@ ECDSA_SIG *ecdsa_sign_with_nonce_for_known_answer_test(const uint8_t *digest, const EC_KEY *eckey, const uint8_t *nonce, size_t nonce_len) { - if (eckey->ecdsa_meth && eckey->ecdsa_meth->sign) { + if (eckey->eckey_method && eckey->eckey_method->sign) { OPENSSL_PUT_ERROR(ECDSA, ECDSA_R_NOT_IMPLEMENTED); return NULL; } @@ -309,9 +309,9 @@ ECDSA_SIG *ECDSA_do_sign(const uint8_t *digest, size_t digest_len, const EC_KEY *eckey) { boringssl_ensure_ecc_self_test(); - if (eckey->ecdsa_meth && eckey->ecdsa_meth->sign) { - OPENSSL_PUT_ERROR(ECDSA, ECDSA_R_NOT_IMPLEMENTED); - return NULL; + if (eckey->eckey_method && eckey->eckey_method->sign_sig) { + return eckey->eckey_method->sign_sig(digest, digest_len, NULL, NULL, + (EC_KEY *)eckey); } const EC_GROUP *group = EC_KEY_get0_group(eckey); @@ -376,9 +376,10 @@ ECDSA_SIG *ECDSA_do_sign(const uint8_t *digest, size_t digest_len, // FIPS compliance. int ECDSA_sign(int type, const uint8_t *digest, size_t digest_len, uint8_t *sig, unsigned int *sig_len, const EC_KEY *eckey) { - if (eckey->ecdsa_meth && eckey->ecdsa_meth->sign) { - return eckey->ecdsa_meth->sign(digest, digest_len, sig, sig_len, - (EC_KEY*) eckey /* cast away const */); + if (eckey->eckey_method && eckey->eckey_method->sign) { + return eckey->eckey_method->sign(type, digest, digest_len, sig, sig_len, + NULL, NULL, + (EC_KEY*) eckey /* cast away const */); } int ret = 0; diff --git a/include/openssl/base.h b/include/openssl/base.h index ee74072159..7b1934cb84 100644 --- a/include/openssl/base.h +++ b/include/openssl/base.h @@ -325,7 +325,7 @@ typedef struct dsa_st DSA; typedef struct ec_group_st EC_GROUP; typedef struct ec_key_st EC_KEY; typedef struct ec_point_st EC_POINT; -typedef struct ecdsa_method_st ECDSA_METHOD; +typedef struct ec_key_method_st EC_KEY_METHOD; typedef struct ecdsa_sig_st ECDSA_SIG; typedef struct engine_st ENGINE; typedef struct env_md_ctx_st EVP_MD_CTX; diff --git a/include/openssl/ec_key.h b/include/openssl/ec_key.h index 10a5f9429a..22a386e4c7 100644 --- a/include/openssl/ec_key.h +++ b/include/openssl/ec_key.h @@ -279,34 +279,6 @@ OPENSSL_EXPORT int EC_KEY_set_ex_data(EC_KEY *r, int idx, void *arg); OPENSSL_EXPORT void *EC_KEY_get_ex_data(const EC_KEY *r, int idx); -// ECDSA method. - -// ECDSA_FLAG_OPAQUE specifies that this ECDSA_METHOD does not expose its key -// material. This may be set if, for instance, it is wrapping some other crypto -// API, like a platform key store. -#define ECDSA_FLAG_OPAQUE 1 - -// ecdsa_method_st is a structure of function pointers for implementing ECDSA. -// See engine.h. -struct ecdsa_method_st { - void *app_data; - - int (*init)(EC_KEY *key); - int (*finish)(EC_KEY *key); - - // group_order_size returns the number of bytes needed to represent the order - // of the group. This is used to calculate the maximum size of an ECDSA - // signature in |ECDSA_size|. - size_t (*group_order_size)(const EC_KEY *key); - - // sign matches the arguments and behaviour of |ECDSA_sign|. - int (*sign)(const uint8_t *digest, size_t digest_len, uint8_t *sig, - unsigned int *sig_len, EC_KEY *eckey); - - int flags; -}; - - // Deprecated functions. // d2i_ECPrivateKey parses a DER-encoded ECPrivateKey structure (RFC 5915) from @@ -356,6 +328,50 @@ OPENSSL_EXPORT EC_KEY *o2i_ECPublicKey(EC_KEY **out_key, const uint8_t **inp, OPENSSL_EXPORT int i2o_ECPublicKey(const EC_KEY *key, unsigned char **outp); +// EC_KEY_METHOD + +// ECDSA_FLAG_OPAQUE specifies that this EC_KEY_METHOD does not expose its key +// material. This may be set if, for instance, it is wrapping some other crypto +// API, like a platform key store. +#define ECDSA_FLAG_OPAQUE 1 + +EC_KEY_METHOD *EC_KEY_OpenSSL(void); + +EC_KEY_METHOD *EC_KEY_METHOD_new(const EC_KEY_METHOD *eckey_meth); + +void EC_KEY_METHOD_free(EC_KEY_METHOD *eckey_meth); + +int EC_KEY_set_method(EC_KEY *ec, EC_KEY_METHOD *meth); + +EC_KEY_METHOD *EC_KEY_get_method(EC_KEY *ec); + +// Can only set init finish, otherwise abort. All other fields must be NULL. +void EC_KEY_METHOD_set_init(EC_KEY_METHOD *meth, + int (*init)(EC_KEY *key), + void (*finish)(EC_KEY *key), + int (*copy)(EC_KEY *dest, const EC_KEY *src), + int (*set_group)(EC_KEY *key, const EC_GROUP *grp), + int (*set_private)(EC_KEY *key, + const BIGNUM *priv_key), + int (*set_public)(EC_KEY *key, + const EC_POINT *pub_key)); + +// Can set all three, Still have to figure out sign_setup behavior. +void EC_KEY_METHOD_set_sign(EC_KEY_METHOD *meth, + int (*sign)(int type, const uint8_t *digest, + unsigned int digest_len, uint8_t *sig, + unsigned int *siglen, + const BIGNUM *k_inv, + const BIGNUM *r, EC_KEY *eckey), + int (*sign_setup)(EC_KEY *eckey, BN_CTX *ctx_in, + BIGNUM **kinvp, BIGNUM **rp), + ECDSA_SIG *(*sign_sig)(const uint8_t *digest, + unsigned int digest_len, + const BIGNUM *in_kinv, + const BIGNUM *in_r, + EC_KEY *eckey)); + + // General No-op Functions [Deprecated]. // EC_KEY_set_asn1_flag does nothing. AWS-LC only supports diff --git a/include/openssl/engine.h b/include/openssl/engine.h index 00c669d763..beaca578a3 100644 --- a/include/openssl/engine.h +++ b/include/openssl/engine.h @@ -54,15 +54,13 @@ OPENSSL_EXPORT int ENGINE_free(ENGINE *engine); // Set functions return one on success and zero for failure when // |engine| is NULL. -OPENSSL_EXPORT int ENGINE_set_RSA(ENGINE *engine, - const RSA_METHOD *method); +OPENSSL_EXPORT int ENGINE_set_RSA(ENGINE *engine, const RSA_METHOD *method); OPENSSL_EXPORT const RSA_METHOD *ENGINE_get_RSA(const ENGINE *engine); -OPENSSL_EXPORT int ENGINE_set_ECDSA(ENGINE *engine, - const ECDSA_METHOD *method); +OPENSSL_EXPORT int ENGINE_set_EC(ENGINE *engine, const EC_KEY_METHOD *method); -OPENSSL_EXPORT const ECDSA_METHOD *ENGINE_get_ECDSA(const ENGINE *engine); +OPENSSL_EXPORT const EC_KEY_METHOD *ENGINE_get_EC(const ENGINE *engine); // Deprecated functions. From 76633ab0f95c42c1e63b3fb3f9b8934143b44b6f Mon Sep 17 00:00:00 2001 From: Shubham Mittal Date: Thu, 8 Aug 2024 19:23:54 -0700 Subject: [PATCH 05/26] updated documentation for EC_KEY_METHOD api --- crypto/fipsmodule/ec/ec_key.c | 23 ++++++++------ include/openssl/ec_key.h | 59 ++++++++++++++++++++++------------- 2 files changed, 51 insertions(+), 31 deletions(-) diff --git a/crypto/fipsmodule/ec/ec_key.c b/crypto/fipsmodule/ec/ec_key.c index 7368ca6dda..251f092819 100644 --- a/crypto/fipsmodule/ec/ec_key.c +++ b/crypto/fipsmodule/ec/ec_key.c @@ -565,7 +565,7 @@ void *EC_KEY_get_ex_data(const EC_KEY *d, int idx) { void EC_KEY_set_asn1_flag(EC_KEY *key, int flag) {} -EC_KEY_METHOD *EC_KEY_OpenSSL(void) { +EC_KEY_METHOD *EC_KEY_METHOD_new(const EC_KEY_METHOD *eckey_meth) { EC_KEY_METHOD *ret; ret = OPENSSL_zalloc(sizeof(EC_KEY_METHOD)); @@ -574,18 +574,16 @@ EC_KEY_METHOD *EC_KEY_OpenSSL(void) { return NULL; } - return ret; -} - -EC_KEY_METHOD *EC_KEY_METHOD_new(const EC_KEY_METHOD *eckey_meth) { - EC_KEY_METHOD *ret = EC_KEY_OpenSSL(); - if(eckey_meth) { *ret = *eckey_meth; } return ret; } +EC_KEY_METHOD *EC_KEY_OpenSSL(void) { + return EC_KEY_METHOD_new(NULL); +} + void EC_KEY_METHOD_free(EC_KEY_METHOD *eckey_meth) { if(eckey_meth != NULL) { OPENSSL_free(eckey_meth); @@ -598,10 +596,10 @@ int EC_KEY_set_method(EC_KEY *ec, EC_KEY_METHOD *meth) { return 0; } - // Only certain fields are supported as of now + // These fields are currently not supported by AWS-LC and cannot be set if(meth->compute_key || meth->copy || meth->keygen || meth->set_group || meth->set_private || meth->set_public || meth->verify || - meth->verify_sig) { + meth->verify_sig || meth->sign_setup) { OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); return 0; } @@ -660,7 +658,12 @@ void EC_KEY_METHOD_set_sign(EC_KEY_METHOD *meth, return; } + // Setting this field is currently not supported by AWS-LC + if(sign_setup) { + OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + abort(); + } + meth->sign = sign; meth->sign_sig = sign_sig; - meth->sign_setup = sign_setup; } diff --git a/include/openssl/ec_key.h b/include/openssl/ec_key.h index 22a386e4c7..4daad8dc76 100644 --- a/include/openssl/ec_key.h +++ b/include/openssl/ec_key.h @@ -328,25 +328,40 @@ OPENSSL_EXPORT EC_KEY *o2i_ECPublicKey(EC_KEY **out_key, const uint8_t **inp, OPENSSL_EXPORT int i2o_ECPublicKey(const EC_KEY *key, unsigned char **outp); -// EC_KEY_METHOD - -// ECDSA_FLAG_OPAQUE specifies that this EC_KEY_METHOD does not expose its key -// material. This may be set if, for instance, it is wrapping some other crypto -// API, like a platform key store. -#define ECDSA_FLAG_OPAQUE 1 - -EC_KEY_METHOD *EC_KEY_OpenSSL(void); - -EC_KEY_METHOD *EC_KEY_METHOD_new(const EC_KEY_METHOD *eckey_meth); - -void EC_KEY_METHOD_free(EC_KEY_METHOD *eckey_meth); - -int EC_KEY_set_method(EC_KEY *ec, EC_KEY_METHOD *meth); - -EC_KEY_METHOD *EC_KEY_get_method(EC_KEY *ec); - -// Can only set init finish, otherwise abort. All other fields must be NULL. -void EC_KEY_METHOD_set_init(EC_KEY_METHOD *meth, +// EC_KEY_METHOD functions + +// EC_KEY_OpenSSL returns a newly allocated EC_KEY_METHOD structure that is +// zero-initialized. This is different from OpenSSL which returns function +// pointers to the default implementations within the |EC_KEY_METHOD| struct. +// We do not do this to make it easier for the compiler/linker to drop unused +// functions. The wrapper functions will select the appropriate +// |eckey_default_*| implementation. +OPENSSL_EXPORT EC_KEY_METHOD *EC_KEY_OpenSSL(void); + +// EC_KEY_METHOD_new returns a newly allocated |EC_KEY_METHOD| object. If the +// input parameter |eckey_meth| is non-NULL, the function pointers within the +// returned |EC_KEY_METHOD| object will be initialized to the values from +// |eckey_meth|. If |eckey_meth| is NULL, the returned object will be +// zero-initialized. +OPENSSL_EXPORT EC_KEY_METHOD *EC_KEY_METHOD_new(const EC_KEY_METHOD *eckey_meth); + +// EC_KEY_METHOD_free frees the memory associated with |eckey_meth| +OPENSSL_EXPORT void EC_KEY_METHOD_free(EC_KEY_METHOD *eckey_meth); + +// EC_KEY_set_method sets |meth| on |ec|. Currently, AWS-LC does not support +// setting the compute_key, copy, keygen, set_group, set_private, set_public, +// verify, verify_sig fields. These must be NULL or the function will fail. +// Returns zero on failure and one on success. +OPENSSL_EXPORT int EC_KEY_set_method(EC_KEY *ec, EC_KEY_METHOD *meth); + +// EC_KEY_get_method returns the |EC_KEY_METHOD| object associated with |ec|. +OPENSSL_EXPORT EC_KEY_METHOD *EC_KEY_get_method(EC_KEY *ec); + +// EC_KEY_METHOD_set_init sets function pointers on |meth|. AWS-LC currently +// only supports setting the |init| and |finish| fields. |copy|, |set_group|, +// |set_private|, and |set_public| must be set to NULL otherwise the function +// will abort. +OPENSSL_EXPORT void EC_KEY_METHOD_set_init(EC_KEY_METHOD *meth, int (*init)(EC_KEY *key), void (*finish)(EC_KEY *key), int (*copy)(EC_KEY *dest, const EC_KEY *src), @@ -356,8 +371,10 @@ void EC_KEY_METHOD_set_init(EC_KEY_METHOD *meth, int (*set_public)(EC_KEY *key, const EC_POINT *pub_key)); -// Can set all three, Still have to figure out sign_setup behavior. -void EC_KEY_METHOD_set_sign(EC_KEY_METHOD *meth, +// EC_KEY_METHOD_set_sign sets function pointers on |meth|. AWS-LC currently +// supports setting |sign| and |sign_sig|. |sign_setup| must be set to NULL +// otherwise the function aborts. +OPENSSL_EXPORT void EC_KEY_METHOD_set_sign(EC_KEY_METHOD *meth, int (*sign)(int type, const uint8_t *digest, unsigned int digest_len, uint8_t *sig, unsigned int *siglen, From b458ac2586e83cb52d87b85d081ff8867863f736 Mon Sep 17 00:00:00 2001 From: Shubham Mittal Date: Fri, 9 Aug 2024 15:17:27 -0700 Subject: [PATCH 06/26] refactored EC_KEY_is_opaque and updated documentation --- crypto/fipsmodule/ec/ec_key.c | 1 - crypto/fipsmodule/ec/internal.h | 16 +++++++++------- include/openssl/ec_key.h | 8 +++++++- 3 files changed, 16 insertions(+), 9 deletions(-) diff --git a/crypto/fipsmodule/ec/ec_key.c b/crypto/fipsmodule/ec/ec_key.c index 251f092819..78e3153c5f 100644 --- a/crypto/fipsmodule/ec/ec_key.c +++ b/crypto/fipsmodule/ec/ec_key.c @@ -195,7 +195,6 @@ int EC_KEY_up_ref(EC_KEY *r) { return 1; } -// This flag is gone with ECDSA_METHOD, do we duplicate in EC_KEY_METHOD or just remove this int EC_KEY_is_opaque(const EC_KEY *key) { return key->eckey_method && (key->eckey_method->flags & ECDSA_FLAG_OPAQUE); } diff --git a/crypto/fipsmodule/ec/internal.h b/crypto/fipsmodule/ec/internal.h index 4257bb4662..9f96150b44 100644 --- a/crypto/fipsmodule/ec/internal.h +++ b/crypto/fipsmodule/ec/internal.h @@ -756,29 +756,31 @@ struct ec_key_method_st { // AWS-LC doesn't support custom values for EC_KEY operations // as of now. |k_inv| and |r| must be NULL parameters. - // |type| is ignored in OpenSSL, we pass in 0 for it + // The |type| parameter is ignored in OpenSSL, we pass in zero for it int (*sign)(int type, const uint8_t *digest, unsigned int digest_len, uint8_t *sig, unsigned int *siglen, const BIGNUM *k_inv, const BIGNUM *r, EC_KEY *eckey); + + // AWS-LC doesn't support custom values for EC_KEY operations + // as of now. |k_inv| and |r| must be NULL parameters. ECDSA_SIG *(*sign_sig)(const uint8_t *digest, unsigned int digest_len, const BIGNUM *in_kinv, const BIGNUM *in_r, EC_KEY *eckey); - // Currently AWS-LC only supports |ECDSA_FLAG_OPAQUE| + // Currently, |EC_KEY_METHOD| only supports |ECDSA_FLAG_OPAQUE|. It is + // not set by default. int flags; - // Fields not supported by AWS-LC for now, must be set to NULL + // AWS-LC currently does not support these fields, must be NULL + int (*sign_setup)(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **k_inv, + BIGNUM **r); int (*copy)(EC_KEY *dest, const EC_KEY *src); int (*set_group)(EC_KEY *key, const EC_GROUP *group); int (*set_private)(EC_KEY *key, const BIGNUM *priv_key); - int (*sign_setup)(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **k_inv, - BIGNUM **r); - int (*set_public)(EC_KEY *key, const EC_POINT *pub_key); int (*keygen)(EC_KEY *key); int (*compute_key)(unsigned char **out, size_t *out_len, const EC_POINT *pub_key, const EC_KEY *ecdh); - int (*verify)(int type, const uint8_t *digest, unsigned int digest_len, const uint8_t *sig, unsigned int sig_len, EC_KEY *eckey); int (*verify_sig)(const uint8_t *digest, unsigned int digest_len, diff --git a/include/openssl/ec_key.h b/include/openssl/ec_key.h index 4daad8dc76..428438ec0e 100644 --- a/include/openssl/ec_key.h +++ b/include/openssl/ec_key.h @@ -328,7 +328,13 @@ OPENSSL_EXPORT EC_KEY *o2i_ECPublicKey(EC_KEY **out_key, const uint8_t **inp, OPENSSL_EXPORT int i2o_ECPublicKey(const EC_KEY *key, unsigned char **outp); -// EC_KEY_METHOD functions +// EC_KEY_METHOD + +// ECDSA_FLAG_OPAQUE specifies that this EC_KEY_METHOD does not expose its key +// material. This may be set if, for instance, it is wrapping some other crypto +// API, like a platform key store. +// This was supported in ECDSA_METHOD previously. +#define ECDSA_FLAG_OPAQUE 1 // EC_KEY_OpenSSL returns a newly allocated EC_KEY_METHOD structure that is // zero-initialized. This is different from OpenSSL which returns function From e236789a89eecc591f0b539b3222d38894cf2dc3 Mon Sep 17 00:00:00 2001 From: Shubham Mittal Date: Fri, 9 Aug 2024 15:38:32 -0700 Subject: [PATCH 07/26] refactored ECDSA_size as a result of removing ECDSA_METHOD. We don't support *group_order_size custom functionality anymore --- crypto/ecdsa_extra/ecdsa_asn1.c | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/crypto/ecdsa_extra/ecdsa_asn1.c b/crypto/ecdsa_extra/ecdsa_asn1.c index a0b9dd8af5..503e8c7462 100644 --- a/crypto/ecdsa_extra/ecdsa_asn1.c +++ b/crypto/ecdsa_extra/ecdsa_asn1.c @@ -72,18 +72,13 @@ size_t ECDSA_size(const EC_KEY *key) { } size_t group_order_size; - // EC_KEY_METHOD doesn't offer this so remove and revert to default beahvior??? - if (key->eckey_method && key->eckey_method->group_order_size) { - group_order_size = key->eckey_method->group_order_size(key); - } else { - const EC_GROUP *group = EC_KEY_get0_group(key); - if (group == NULL) { - return 0; - } - - group_order_size = BN_num_bytes(EC_GROUP_get0_order(group)); + const EC_GROUP *group = EC_KEY_get0_group(key); + if (group == NULL) { + return 0; } + group_order_size = BN_num_bytes(EC_GROUP_get0_order(group)); + return ECDSA_SIG_max_len(group_order_size); } From ca4676522aea86b9eb5f4b6678133e2d1575f34e Mon Sep 17 00:00:00 2001 From: Shubham Mittal Date: Fri, 9 Aug 2024 16:40:39 -0700 Subject: [PATCH 08/26] changed param type from unsigned int to int to match OpenSSL --- crypto/fipsmodule/ec/ec_key.c | 4 ++-- crypto/fipsmodule/ec/internal.h | 4 ++-- crypto/fipsmodule/ecdsa/ecdsa.c | 4 ++-- include/openssl/ec_key.h | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/crypto/fipsmodule/ec/ec_key.c b/crypto/fipsmodule/ec/ec_key.c index 78e3153c5f..75d7b27365 100644 --- a/crypto/fipsmodule/ec/ec_key.c +++ b/crypto/fipsmodule/ec/ec_key.c @@ -642,13 +642,13 @@ void EC_KEY_METHOD_set_init(EC_KEY_METHOD *meth, void EC_KEY_METHOD_set_sign(EC_KEY_METHOD *meth, int (*sign)(int type, const uint8_t *digest, - unsigned int digest_len, uint8_t *sig, + int digest_len, uint8_t *sig, unsigned int *siglen, const BIGNUM *k_inv, const BIGNUM *r, EC_KEY *eckey), int (*sign_setup)(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp), ECDSA_SIG *(*sign_sig)(const uint8_t *digest, - unsigned int digest_len, + int digest_len, const BIGNUM *in_kinv, const BIGNUM *in_r, EC_KEY *eckey)) { diff --git a/crypto/fipsmodule/ec/internal.h b/crypto/fipsmodule/ec/internal.h index 9f96150b44..1f5e4b44f8 100644 --- a/crypto/fipsmodule/ec/internal.h +++ b/crypto/fipsmodule/ec/internal.h @@ -757,13 +757,13 @@ struct ec_key_method_st { // AWS-LC doesn't support custom values for EC_KEY operations // as of now. |k_inv| and |r| must be NULL parameters. // The |type| parameter is ignored in OpenSSL, we pass in zero for it - int (*sign)(int type, const uint8_t *digest, unsigned int digest_len, + int (*sign)(int type, const uint8_t *digest, int digest_len, uint8_t *sig, unsigned int *siglen, const BIGNUM *k_inv, const BIGNUM *r, EC_KEY *eckey); // AWS-LC doesn't support custom values for EC_KEY operations // as of now. |k_inv| and |r| must be NULL parameters. - ECDSA_SIG *(*sign_sig)(const uint8_t *digest, unsigned int digest_len, + ECDSA_SIG *(*sign_sig)(const uint8_t *digest, int digest_len, const BIGNUM *in_kinv, const BIGNUM *in_r, EC_KEY *eckey); diff --git a/crypto/fipsmodule/ecdsa/ecdsa.c b/crypto/fipsmodule/ecdsa/ecdsa.c index efb5415b6b..26a642e363 100644 --- a/crypto/fipsmodule/ecdsa/ecdsa.c +++ b/crypto/fipsmodule/ecdsa/ecdsa.c @@ -310,7 +310,7 @@ ECDSA_SIG *ECDSA_do_sign(const uint8_t *digest, size_t digest_len, boringssl_ensure_ecc_self_test(); if (eckey->eckey_method && eckey->eckey_method->sign_sig) { - return eckey->eckey_method->sign_sig(digest, digest_len, NULL, NULL, + return eckey->eckey_method->sign_sig(digest, (int)digest_len, NULL, NULL, (EC_KEY *)eckey); } @@ -377,7 +377,7 @@ ECDSA_SIG *ECDSA_do_sign(const uint8_t *digest, size_t digest_len, int ECDSA_sign(int type, const uint8_t *digest, size_t digest_len, uint8_t *sig, unsigned int *sig_len, const EC_KEY *eckey) { if (eckey->eckey_method && eckey->eckey_method->sign) { - return eckey->eckey_method->sign(type, digest, digest_len, sig, sig_len, + return eckey->eckey_method->sign(type, digest, (int)digest_len, sig, sig_len, NULL, NULL, (EC_KEY*) eckey /* cast away const */); } diff --git a/include/openssl/ec_key.h b/include/openssl/ec_key.h index 428438ec0e..fcd2249f94 100644 --- a/include/openssl/ec_key.h +++ b/include/openssl/ec_key.h @@ -382,14 +382,14 @@ OPENSSL_EXPORT void EC_KEY_METHOD_set_init(EC_KEY_METHOD *meth, // otherwise the function aborts. OPENSSL_EXPORT void EC_KEY_METHOD_set_sign(EC_KEY_METHOD *meth, int (*sign)(int type, const uint8_t *digest, - unsigned int digest_len, uint8_t *sig, + int digest_len, uint8_t *sig, unsigned int *siglen, const BIGNUM *k_inv, const BIGNUM *r, EC_KEY *eckey), int (*sign_setup)(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp), ECDSA_SIG *(*sign_sig)(const uint8_t *digest, - unsigned int digest_len, + int digest_len, const BIGNUM *in_kinv, const BIGNUM *in_r, EC_KEY *eckey)); From 0630da8c216ca9b73469968542a1977a31609923 Mon Sep 17 00:00:00 2001 From: Shubham Mittal Date: Mon, 19 Aug 2024 23:36:19 -0700 Subject: [PATCH 09/26] added function to set flags on EC_KEY_METHOD --- crypto/fipsmodule/ec/ec_key.c | 9 +++++++++ include/openssl/ec_key.h | 9 +++++++-- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/crypto/fipsmodule/ec/ec_key.c b/crypto/fipsmodule/ec/ec_key.c index 75d7b27365..476f41403a 100644 --- a/crypto/fipsmodule/ec/ec_key.c +++ b/crypto/fipsmodule/ec/ec_key.c @@ -666,3 +666,12 @@ void EC_KEY_METHOD_set_sign(EC_KEY_METHOD *meth, meth->sign = sign; meth->sign_sig = sign_sig; } + +int EC_KEY_METHOD_set_flags(EC_KEY_METHOD *meth, int flags) { + if(!meth || flags != ECDSA_FLAG_OPAQUE) { + return 0; + } + + meth->flags |= flags; + return 1; +} diff --git a/include/openssl/ec_key.h b/include/openssl/ec_key.h index fcd2249f94..3cf7ce45f1 100644 --- a/include/openssl/ec_key.h +++ b/include/openssl/ec_key.h @@ -332,8 +332,9 @@ OPENSSL_EXPORT int i2o_ECPublicKey(const EC_KEY *key, unsigned char **outp); // ECDSA_FLAG_OPAQUE specifies that this EC_KEY_METHOD does not expose its key // material. This may be set if, for instance, it is wrapping some other crypto -// API, like a platform key store. -// This was supported in ECDSA_METHOD previously. +// API, like a platform key store. Use |EC_KEY_METHOD_set_flag| to set +// this flag on an |EC_KEY_METHOD|. +// This was supported in ECDSA_METHOD previously and is not set by default. #define ECDSA_FLAG_OPAQUE 1 // EC_KEY_OpenSSL returns a newly allocated EC_KEY_METHOD structure that is @@ -394,6 +395,10 @@ OPENSSL_EXPORT void EC_KEY_METHOD_set_sign(EC_KEY_METHOD *meth, const BIGNUM *in_r, EC_KEY *eckey)); +// EC_KEY_METHOD_set_flags sets |flags| on |meth|. Currently, the only supported +// flag is |ECDSA_FLAG_OPAQUE|. Returns zero on failure and one on success. +OPENSSL_EXPORT int EC_KEY_METHOD_set_flags(EC_KEY_METHOD *meth, int flags); + // General No-op Functions [Deprecated]. From 9b17db0afc7b4f0840a8634b7a20a23d1b6ea45d Mon Sep 17 00:00:00 2001 From: Shubham Mittal Date: Mon, 19 Aug 2024 23:55:54 -0700 Subject: [PATCH 10/26] changed func sig --- crypto/fipsmodule/ec/ec_key.c | 2 +- include/openssl/ec_key.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/crypto/fipsmodule/ec/ec_key.c b/crypto/fipsmodule/ec/ec_key.c index 476f41403a..e899ce7705 100644 --- a/crypto/fipsmodule/ec/ec_key.c +++ b/crypto/fipsmodule/ec/ec_key.c @@ -607,7 +607,7 @@ int EC_KEY_set_method(EC_KEY *ec, EC_KEY_METHOD *meth) { return 1; } -EC_KEY_METHOD *EC_KEY_get_method(EC_KEY *ec) { +const EC_KEY_METHOD *EC_KEY_get_method(const EC_KEY *ec) { if(ec == NULL) { OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER); return NULL; diff --git a/include/openssl/ec_key.h b/include/openssl/ec_key.h index 3cf7ce45f1..5f922b0462 100644 --- a/include/openssl/ec_key.h +++ b/include/openssl/ec_key.h @@ -362,7 +362,7 @@ OPENSSL_EXPORT void EC_KEY_METHOD_free(EC_KEY_METHOD *eckey_meth); OPENSSL_EXPORT int EC_KEY_set_method(EC_KEY *ec, EC_KEY_METHOD *meth); // EC_KEY_get_method returns the |EC_KEY_METHOD| object associated with |ec|. -OPENSSL_EXPORT EC_KEY_METHOD *EC_KEY_get_method(EC_KEY *ec); +OPENSSL_EXPORT const EC_KEY_METHOD *EC_KEY_get_method(const EC_KEY *ec); // EC_KEY_METHOD_set_init sets function pointers on |meth|. AWS-LC currently // only supports setting the |init| and |finish| fields. |copy|, |set_group|, From 0686e44d2506439983213e780e1804235904a586 Mon Sep 17 00:00:00 2001 From: Shubham Mittal Date: Tue, 20 Aug 2024 00:39:54 -0700 Subject: [PATCH 11/26] test for EC_KEY_METHOD --- crypto/fipsmodule/ec/ec_test.cc | 103 ++++++++++++++++++++++++++++++++ 1 file changed, 103 insertions(+) diff --git a/crypto/fipsmodule/ec/ec_test.cc b/crypto/fipsmodule/ec/ec_test.cc index 6b8d0a82db..cca54378ae 100644 --- a/crypto/fipsmodule/ec/ec_test.cc +++ b/crypto/fipsmodule/ec/ec_test.cc @@ -25,6 +25,9 @@ #include #include #include +#include +#include +#include #include #include #include @@ -2413,3 +2416,103 @@ TEST(ECTest, FelemBytes) { ASSERT_EQ(test_group.get()->field.N.width, expected_felem_words); } } + +static ECDSA_SIG * ecdsa_sign_sig(const unsigned char *dgst, int dgstlen, + const BIGNUM *in_kinv, const BIGNUM *in_r, + EC_KEY *ec) { + // To track whether custom implementation was called + EC_KEY_set_ex_data(ec, 1, (void*)"ecdsa_sign_sig"); + return nullptr; +} + +static int ecdsa_sign(int type, const unsigned char *dgst, int dgstlen, + unsigned char *sig, unsigned int *siglen, + const BIGNUM *kinv, const BIGNUM *r, EC_KEY *ec) { + + ECDSA_SIG *ret = ECDSA_do_sign(dgst, dgstlen, ec); + if (!ret) { + *siglen = 0; + return 0; + } + + CBB cbb; + CBB_init_fixed(&cbb, sig, ECDSA_size(ec)); + size_t len; + if (!ECDSA_SIG_marshal(&cbb, ret) || + !CBB_finish(&cbb, nullptr, &len)) { + OPENSSL_PUT_ERROR(ECDSA, ECDSA_R_ENCODE_ERROR); + *siglen = 0; + return 0; + } + + *siglen = (unsigned)len; + + // To track whether custom implementation was called + EC_KEY_set_ex_data(ec, 0, (void*)"ecdsa_sign"); + + return 1; +} + +static void openvpn_extkey_ec_finish(EC_KEY *ec) +{ + const EC_KEY_METHOD *ec_meth = EC_KEY_get_method(ec); + EC_KEY_METHOD_free((EC_KEY_METHOD *) ec_meth); +} + +TEST(ECTest, ECKEYMETHOD) { + EC_KEY *ec = EC_KEY_new(); + ASSERT_TRUE(ec); + + // Should get freed with EC_KEY once assigned through + // |openvpn_extkey_ec_finish| + EC_KEY_METHOD *ec_method; + ec_method = EC_KEY_METHOD_new(EC_KEY_OpenSSL()); + ASSERT_TRUE(ec_method); + + // Can only set these fields + EC_KEY_METHOD_set_init(ec_method, nullptr, openvpn_extkey_ec_finish, + nullptr, nullptr, nullptr, nullptr); + // Checking Sign + EC_KEY_METHOD_set_sign(ec_method, ecdsa_sign, nullptr, nullptr); + + bssl::UniquePtr group(EC_GROUP_new_by_curve_name(NID_secp224r1)); + ASSERT_TRUE(group.get()); + ASSERT_TRUE(EC_KEY_set_group(ec, group.get())); + ASSERT_TRUE(EC_KEY_generate_key(ec)); + + ASSERT_TRUE(EC_KEY_set_method(ec, ec_method)); + ASSERT_TRUE(EC_KEY_check_key(ec)); + + bssl::UniquePtr ec_key(EVP_PKEY_new()); + ASSERT_TRUE(ec_key.get()); + EVP_PKEY_assign_EC_KEY(ec_key.get(), ec); + bssl::UniquePtr ec_key_ctx(EVP_PKEY_CTX_new(ec_key.get(), NULL)); + ASSERT_TRUE(ec_key_ctx.get()); + + // Do a signature, should call custom openvpn_extkey_ec_finish + uint8_t digest[20]; + ASSERT_TRUE(RAND_bytes(digest, 20)); + CONSTTIME_DECLASSIFY(digest, 20); + std::vector signature(ECDSA_size(ec)); + size_t sig_len = ECDSA_size(ec); + ASSERT_TRUE(EVP_PKEY_sign_init(ec_key_ctx.get())); + ASSERT_TRUE(EVP_PKEY_sign(ec_key_ctx.get(), signature.data(), + &sig_len, digest, 20)); + signature.resize(sig_len); + + ASSERT_EQ(EC_KEY_get_ex_data(ec, 0), (void *)"ecdsa_sign"); + // Verify the signature + EXPECT_TRUE(ECDSA_verify(0, digest, 20, signature.data(), signature.size(), + ec)); + + // Now test the sign_sig pointer + EC_KEY_METHOD_set_sign(ec_method, nullptr, nullptr, ecdsa_sign_sig); + + ECDSA_do_sign(digest, 20, ec); + ASSERT_EQ(EC_KEY_get_ex_data(ec, 1), (void *)"ecdsa_sign_sig"); + + // Flags + ASSERT_FALSE(EC_KEY_is_opaque(ec)); + EC_KEY_METHOD_set_flags(ec_method, ECDSA_FLAG_OPAQUE); + ASSERT_TRUE(EC_KEY_is_opaque(ec)); +} From 43a7315f544bb52558aaa84418701dd1e45feac8 Mon Sep 17 00:00:00 2001 From: Shubham Mittal Date: Tue, 20 Aug 2024 02:09:39 -0700 Subject: [PATCH 12/26] added static default eckey meth --- crypto/fipsmodule/ec/ec_key.c | 19 +++++++++++++++---- include/openssl/ec_key.h | 10 +++++++--- 2 files changed, 22 insertions(+), 7 deletions(-) diff --git a/crypto/fipsmodule/ec/ec_key.c b/crypto/fipsmodule/ec/ec_key.c index e899ce7705..b4670ddc5e 100644 --- a/crypto/fipsmodule/ec/ec_key.c +++ b/crypto/fipsmodule/ec/ec_key.c @@ -115,6 +115,10 @@ EC_KEY *EC_KEY_new_method(const ENGINE *engine) { ret->eckey_method = (EC_KEY_METHOD *) ENGINE_get_EC(engine); } + if(ret->eckey_method == NULL) { + ret->eckey_method = EC_KEY_OpenSSL(); + } + ret->conv_form = POINT_CONVERSION_UNCOMPRESSED; ret->references = 1; @@ -564,6 +568,17 @@ void *EC_KEY_get_ex_data(const EC_KEY *d, int idx) { void EC_KEY_set_asn1_flag(EC_KEY *key, int flag) {} +static EC_KEY_METHOD *default_ec_key_meth; + +const EC_KEY_METHOD *EC_KEY_get_default_method(void) { + OPENSSL_memset(default_ec_key_meth, 0, sizeof(EC_KEY_METHOD)); + return default_ec_key_meth; +} + +const EC_KEY_METHOD *EC_KEY_OpenSSL(void) { + return EC_KEY_get_default_method(); +} + EC_KEY_METHOD *EC_KEY_METHOD_new(const EC_KEY_METHOD *eckey_meth) { EC_KEY_METHOD *ret; @@ -579,10 +594,6 @@ EC_KEY_METHOD *EC_KEY_METHOD_new(const EC_KEY_METHOD *eckey_meth) { return ret; } -EC_KEY_METHOD *EC_KEY_OpenSSL(void) { - return EC_KEY_METHOD_new(NULL); -} - void EC_KEY_METHOD_free(EC_KEY_METHOD *eckey_meth) { if(eckey_meth != NULL) { OPENSSL_free(eckey_meth); diff --git a/include/openssl/ec_key.h b/include/openssl/ec_key.h index 5f922b0462..7432042f3c 100644 --- a/include/openssl/ec_key.h +++ b/include/openssl/ec_key.h @@ -337,13 +337,17 @@ OPENSSL_EXPORT int i2o_ECPublicKey(const EC_KEY *key, unsigned char **outp); // This was supported in ECDSA_METHOD previously and is not set by default. #define ECDSA_FLAG_OPAQUE 1 -// EC_KEY_OpenSSL returns a newly allocated EC_KEY_METHOD structure that is +// EC_KEY_get_default_method returns a reference to the default +// |EC_KEY| implementation. The returned |EC_KEY_METHOD| object is // zero-initialized. This is different from OpenSSL which returns function // pointers to the default implementations within the |EC_KEY_METHOD| struct. // We do not do this to make it easier for the compiler/linker to drop unused // functions. The wrapper functions will select the appropriate -// |eckey_default_*| implementation. -OPENSSL_EXPORT EC_KEY_METHOD *EC_KEY_OpenSSL(void); +// |ec_key_default_*| implementation. +const EC_KEY_METHOD *EC_KEY_get_default_method(void); + +// EC_KEY_OpenSSL calls |EC_KEY_get_default_method|. +OPENSSL_EXPORT const EC_KEY_METHOD *EC_KEY_OpenSSL(void); // EC_KEY_METHOD_new returns a newly allocated |EC_KEY_METHOD| object. If the // input parameter |eckey_meth| is non-NULL, the function pointers within the From 3429da09c0c556fac1ac1c7e19ddb28795739063 Mon Sep 17 00:00:00 2001 From: Shubham Mittal Date: Tue, 20 Aug 2024 15:56:15 -0700 Subject: [PATCH 13/26] cleaned up comments and code, changed static allocation --- crypto/engine/engine.c | 18 ++++++++++-------- crypto/fipsmodule/ec/ec_key.c | 11 ++++++----- crypto/fipsmodule/ec/internal.h | 4 ++-- include/openssl/ec_key.h | 2 +- 4 files changed, 19 insertions(+), 16 deletions(-) diff --git a/crypto/engine/engine.c b/crypto/engine/engine.c index 7a4ccdb454..95a1bbd988 100644 --- a/crypto/engine/engine.c +++ b/crypto/engine/engine.c @@ -40,12 +40,13 @@ int ENGINE_free(ENGINE *engine) { } int ENGINE_set_RSA(ENGINE *engine, const RSA_METHOD *method) { - if(engine) { - engine->rsa_method = (RSA_METHOD *)method; - return 1; + if(!engine) { + OPENSSL_PUT_ERROR(ENGINE, ERR_R_PASSED_NULL_PARAMETER); + return 0; } - return 0; + engine->rsa_method = (RSA_METHOD *)method; + return 1; } const RSA_METHOD *ENGINE_get_RSA(const ENGINE *engine) { @@ -53,12 +54,13 @@ const RSA_METHOD *ENGINE_get_RSA(const ENGINE *engine) { } int ENGINE_set_EC(ENGINE *engine, const EC_KEY_METHOD *method) { - if(engine) { - engine->eckey_method = (EC_KEY_METHOD *)method; - return 1; + if(!engine) { + OPENSSL_PUT_ERROR(ENGINE, ERR_R_PASSED_NULL_PARAMETER); + return 0; } - return 0; + engine->eckey_method = (EC_KEY_METHOD *)method; + return 1; } const EC_KEY_METHOD *ENGINE_get_EC(const ENGINE *engine) { diff --git a/crypto/fipsmodule/ec/ec_key.c b/crypto/fipsmodule/ec/ec_key.c index b4670ddc5e..74f8f18887 100644 --- a/crypto/fipsmodule/ec/ec_key.c +++ b/crypto/fipsmodule/ec/ec_key.c @@ -116,7 +116,7 @@ EC_KEY *EC_KEY_new_method(const ENGINE *engine) { } if(ret->eckey_method == NULL) { - ret->eckey_method = EC_KEY_OpenSSL(); + ret->eckey_method = EC_KEY_get_default_method(); } ret->conv_form = POINT_CONVERSION_UNCOMPRESSED; @@ -568,11 +568,11 @@ void *EC_KEY_get_ex_data(const EC_KEY *d, int idx) { void EC_KEY_set_asn1_flag(EC_KEY *key, int flag) {} -static EC_KEY_METHOD *default_ec_key_meth; +static EC_KEY_METHOD default_ec_key_meth; const EC_KEY_METHOD *EC_KEY_get_default_method(void) { - OPENSSL_memset(default_ec_key_meth, 0, sizeof(EC_KEY_METHOD)); - return default_ec_key_meth; + OPENSSL_memset(&default_ec_key_meth, 0, sizeof(EC_KEY_METHOD)); + return &default_ec_key_meth; } const EC_KEY_METHOD *EC_KEY_OpenSSL(void) { @@ -600,7 +600,7 @@ void EC_KEY_METHOD_free(EC_KEY_METHOD *eckey_meth) { } } -int EC_KEY_set_method(EC_KEY *ec, EC_KEY_METHOD *meth) { +int EC_KEY_set_method(EC_KEY *ec, const EC_KEY_METHOD *meth) { if(ec == NULL || meth == NULL) { OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER); return 0; @@ -641,6 +641,7 @@ void EC_KEY_METHOD_set_init(EC_KEY_METHOD *meth, return; } + // Setting these fields is currently not supported by AWS-LC assert(!copy && !set_group && !set_private && !set_public); if(copy || set_group || set_private || set_public) { OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); diff --git a/crypto/fipsmodule/ec/internal.h b/crypto/fipsmodule/ec/internal.h index 1f5e4b44f8..dca52cdd08 100644 --- a/crypto/fipsmodule/ec/internal.h +++ b/crypto/fipsmodule/ec/internal.h @@ -781,9 +781,9 @@ struct ec_key_method_st { int (*keygen)(EC_KEY *key); int (*compute_key)(unsigned char **out, size_t *out_len, const EC_POINT *pub_key, const EC_KEY *ecdh); - int (*verify)(int type, const uint8_t *digest, unsigned int digest_len, + int (*verify)(int type, const uint8_t *digest, int digest_len, const uint8_t *sig, unsigned int sig_len, EC_KEY *eckey); - int (*verify_sig)(const uint8_t *digest, unsigned int digest_len, + int (*verify_sig)(const uint8_t *digest, int digest_len, const ECDSA_SIG *sig, EC_KEY *eckey); }; diff --git a/include/openssl/ec_key.h b/include/openssl/ec_key.h index 7432042f3c..2ea979f27b 100644 --- a/include/openssl/ec_key.h +++ b/include/openssl/ec_key.h @@ -363,7 +363,7 @@ OPENSSL_EXPORT void EC_KEY_METHOD_free(EC_KEY_METHOD *eckey_meth); // setting the compute_key, copy, keygen, set_group, set_private, set_public, // verify, verify_sig fields. These must be NULL or the function will fail. // Returns zero on failure and one on success. -OPENSSL_EXPORT int EC_KEY_set_method(EC_KEY *ec, EC_KEY_METHOD *meth); +OPENSSL_EXPORT int EC_KEY_set_method(EC_KEY *ec, const EC_KEY_METHOD *meth); // EC_KEY_get_method returns the |EC_KEY_METHOD| object associated with |ec|. OPENSSL_EXPORT const EC_KEY_METHOD *EC_KEY_get_method(const EC_KEY *ec); From f7fe3b46243359df775eee8ea8f88127b132d9b3 Mon Sep 17 00:00:00 2001 From: Shubham Mittal Date: Tue, 20 Aug 2024 16:12:03 -0700 Subject: [PATCH 14/26] added more assertions --- crypto/fipsmodule/ec/ec_test.cc | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/crypto/fipsmodule/ec/ec_test.cc b/crypto/fipsmodule/ec/ec_test.cc index cca54378ae..9bb58c6dc5 100644 --- a/crypto/fipsmodule/ec/ec_test.cc +++ b/crypto/fipsmodule/ec/ec_test.cc @@ -2463,23 +2463,27 @@ TEST(ECTest, ECKEYMETHOD) { EC_KEY *ec = EC_KEY_new(); ASSERT_TRUE(ec); - // Should get freed with EC_KEY once assigned through - // |openvpn_extkey_ec_finish| EC_KEY_METHOD *ec_method; ec_method = EC_KEY_METHOD_new(EC_KEY_OpenSSL()); ASSERT_TRUE(ec_method); + // We zero initialize the default struct + ASSERT_FALSE(ec_method->finish && ec_method->sign); // Can only set these fields EC_KEY_METHOD_set_init(ec_method, nullptr, openvpn_extkey_ec_finish, nullptr, nullptr, nullptr, nullptr); + ASSERT_TRUE(ec_method->finish); // Checking Sign EC_KEY_METHOD_set_sign(ec_method, ecdsa_sign, nullptr, nullptr); + ASSERT_TRUE(ec_method->sign); bssl::UniquePtr group(EC_GROUP_new_by_curve_name(NID_secp224r1)); ASSERT_TRUE(group.get()); ASSERT_TRUE(EC_KEY_set_group(ec, group.get())); ASSERT_TRUE(EC_KEY_generate_key(ec)); + // Should get freed with EC_KEY once assigned through + // |openvpn_extkey_ec_finish| ASSERT_TRUE(EC_KEY_set_method(ec, ec_method)); ASSERT_TRUE(EC_KEY_check_key(ec)); @@ -2507,6 +2511,7 @@ TEST(ECTest, ECKEYMETHOD) { // Now test the sign_sig pointer EC_KEY_METHOD_set_sign(ec_method, nullptr, nullptr, ecdsa_sign_sig); + ASSERT_TRUE(ec_method->sign_sig && !ec_method->sign); ECDSA_do_sign(digest, 20, ec); ASSERT_EQ(EC_KEY_get_ex_data(ec, 1), (void *)"ecdsa_sign_sig"); From 9bda4bbc2cc5fafef62c3b599c1e9175ae42de86 Mon Sep 17 00:00:00 2001 From: Shubham Mittal Date: Wed, 21 Aug 2024 17:34:49 -0700 Subject: [PATCH 15/26] changed default init for EC_KEY_METHOD for deterministic FIPS hash --- crypto/fipsmodule/ec/ec_key.c | 10 +++++----- include/openssl/ec_key.h | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/crypto/fipsmodule/ec/ec_key.c b/crypto/fipsmodule/ec/ec_key.c index 74f8f18887..e632d24e2d 100644 --- a/crypto/fipsmodule/ec/ec_key.c +++ b/crypto/fipsmodule/ec/ec_key.c @@ -568,11 +568,11 @@ void *EC_KEY_get_ex_data(const EC_KEY *d, int idx) { void EC_KEY_set_asn1_flag(EC_KEY *key, int flag) {} -static EC_KEY_METHOD default_ec_key_meth; - -const EC_KEY_METHOD *EC_KEY_get_default_method(void) { - OPENSSL_memset(&default_ec_key_meth, 0, sizeof(EC_KEY_METHOD)); - return &default_ec_key_meth; +DEFINE_METHOD_FUNCTION(EC_KEY_METHOD, EC_KEY_get_default_method) { + // All of the methods are NULL to make it easier for the compiler/linker to + // drop unused functions. The wrapper functions will select the appropriate + // |rsa_default_*| implementation. + OPENSSL_memset(out, 0, sizeof(EC_KEY_METHOD)); } const EC_KEY_METHOD *EC_KEY_OpenSSL(void) { diff --git a/include/openssl/ec_key.h b/include/openssl/ec_key.h index 2ea979f27b..dc6dc0c65c 100644 --- a/include/openssl/ec_key.h +++ b/include/openssl/ec_key.h @@ -344,7 +344,7 @@ OPENSSL_EXPORT int i2o_ECPublicKey(const EC_KEY *key, unsigned char **outp); // We do not do this to make it easier for the compiler/linker to drop unused // functions. The wrapper functions will select the appropriate // |ec_key_default_*| implementation. -const EC_KEY_METHOD *EC_KEY_get_default_method(void); +OPENSSL_EXPORT const EC_KEY_METHOD *EC_KEY_get_default_method(void); // EC_KEY_OpenSSL calls |EC_KEY_get_default_method|. OPENSSL_EXPORT const EC_KEY_METHOD *EC_KEY_OpenSSL(void); From 2e2d6f3133e3a76c56b5ea8d1fc626409b579e5f Mon Sep 17 00:00:00 2001 From: Shubham Mittal Date: Wed, 21 Aug 2024 18:34:25 -0700 Subject: [PATCH 16/26] fixed memory leak in test --- crypto/fipsmodule/ec/ec_test.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/crypto/fipsmodule/ec/ec_test.cc b/crypto/fipsmodule/ec/ec_test.cc index 9bb58c6dc5..b7225dd00b 100644 --- a/crypto/fipsmodule/ec/ec_test.cc +++ b/crypto/fipsmodule/ec/ec_test.cc @@ -2440,6 +2440,7 @@ static int ecdsa_sign(int type, const unsigned char *dgst, int dgstlen, size_t len; if (!ECDSA_SIG_marshal(&cbb, ret) || !CBB_finish(&cbb, nullptr, &len)) { + ECDSA_SIG_free(ret); OPENSSL_PUT_ERROR(ECDSA, ECDSA_R_ENCODE_ERROR); *siglen = 0; return 0; @@ -2450,6 +2451,7 @@ static int ecdsa_sign(int type, const unsigned char *dgst, int dgstlen, // To track whether custom implementation was called EC_KEY_set_ex_data(ec, 0, (void*)"ecdsa_sign"); + ECDSA_SIG_free(ret); return 1; } From 3ce0ec8df28414c2afa7408cbc8dbf30a2e49828 Mon Sep 17 00:00:00 2001 From: Shubham Mittal Date: Wed, 21 Aug 2024 18:37:40 -0700 Subject: [PATCH 17/26] removed cast for string --- crypto/fipsmodule/ec/ec_test.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crypto/fipsmodule/ec/ec_test.cc b/crypto/fipsmodule/ec/ec_test.cc index b7225dd00b..b32a5b3476 100644 --- a/crypto/fipsmodule/ec/ec_test.cc +++ b/crypto/fipsmodule/ec/ec_test.cc @@ -2506,7 +2506,7 @@ TEST(ECTest, ECKEYMETHOD) { &sig_len, digest, 20)); signature.resize(sig_len); - ASSERT_EQ(EC_KEY_get_ex_data(ec, 0), (void *)"ecdsa_sign"); + ASSERT_EQ(EC_KEY_get_ex_data(ec, 0), "ecdsa_sign"); // Verify the signature EXPECT_TRUE(ECDSA_verify(0, digest, 20, signature.data(), signature.size(), ec)); @@ -2516,7 +2516,7 @@ TEST(ECTest, ECKEYMETHOD) { ASSERT_TRUE(ec_method->sign_sig && !ec_method->sign); ECDSA_do_sign(digest, 20, ec); - ASSERT_EQ(EC_KEY_get_ex_data(ec, 1), (void *)"ecdsa_sign_sig"); + ASSERT_EQ(EC_KEY_get_ex_data(ec, 1), "ecdsa_sign_sig"); // Flags ASSERT_FALSE(EC_KEY_is_opaque(ec)); From f885475ac968e5412fc62a1e418803f7c904cf31 Mon Sep 17 00:00:00 2001 From: Shubham Mittal Date: Wed, 21 Aug 2024 18:58:49 -0700 Subject: [PATCH 18/26] using ASSERT_STREQ for string literals instead of comapring pointers --- crypto/fipsmodule/ec/ec_test.cc | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/crypto/fipsmodule/ec/ec_test.cc b/crypto/fipsmodule/ec/ec_test.cc index b32a5b3476..e9bd5ec545 100644 --- a/crypto/fipsmodule/ec/ec_test.cc +++ b/crypto/fipsmodule/ec/ec_test.cc @@ -2506,7 +2506,8 @@ TEST(ECTest, ECKEYMETHOD) { &sig_len, digest, 20)); signature.resize(sig_len); - ASSERT_EQ(EC_KEY_get_ex_data(ec, 0), "ecdsa_sign"); + ASSERT_STREQ(static_cast(EC_KEY_get_ex_data(ec, 0)) + , "ecdsa_sign"); // Verify the signature EXPECT_TRUE(ECDSA_verify(0, digest, 20, signature.data(), signature.size(), ec)); @@ -2516,7 +2517,8 @@ TEST(ECTest, ECKEYMETHOD) { ASSERT_TRUE(ec_method->sign_sig && !ec_method->sign); ECDSA_do_sign(digest, 20, ec); - ASSERT_EQ(EC_KEY_get_ex_data(ec, 1), "ecdsa_sign_sig"); + ASSERT_STREQ(static_cast(EC_KEY_get_ex_data(ec, 1)), + "ecdsa_sign_sig"); // Flags ASSERT_FALSE(EC_KEY_is_opaque(ec)); From fca25676f1a11b951f6047df752e8e65c99b46d8 Mon Sep 17 00:00:00 2001 From: Shubham Mittal Date: Thu, 22 Aug 2024 17:24:22 -0700 Subject: [PATCH 19/26] updated patch file to account for sign_setup --- .../openvpn_patch/aws-lc-openvpn2-6-x.patch | 28 +++++++++++++------ 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/tests/ci/integration/openvpn_patch/aws-lc-openvpn2-6-x.patch b/tests/ci/integration/openvpn_patch/aws-lc-openvpn2-6-x.patch index 25e87f4832..aa15367e1b 100644 --- a/tests/ci/integration/openvpn_patch/aws-lc-openvpn2-6-x.patch +++ b/tests/ci/integration/openvpn_patch/aws-lc-openvpn2-6-x.patch @@ -1,8 +1,8 @@ diff --git a/src/openvpn/crypto_openssl.c b/src/openvpn/crypto_openssl.c -index fbc95ff7..e174ed76 100644 +index fe1254f8..9ca3d36f 100644 --- a/src/openvpn/crypto_openssl.c +++ b/src/openvpn/crypto_openssl.c -@@ -1398,7 +1398,7 @@ memcmp_constant_time(const void *a, const void *b, size_t size) +@@ -1374,7 +1374,7 @@ memcmp_constant_time(const void *a, const void *b, size_t size) return CRYPTO_memcmp(a, b, size); } @@ -11,7 +11,7 @@ index fbc95ff7..e174ed76 100644 bool ssl_tls1_PRF(const uint8_t *seed, int seed_len, const uint8_t *secret, int secret_len, uint8_t *output, int output_len) -@@ -1478,7 +1478,12 @@ tls1_P_hash(const EVP_MD *md, const unsigned char *sec, +@@ -1454,7 +1454,12 @@ tls1_P_hash(const EVP_MD *md, const unsigned char *sec, int ret = false; chunk = EVP_MD_size(md); @@ -25,7 +25,7 @@ index fbc95ff7..e174ed76 100644 ctx = md_ctx_new(); ctx_tmp = md_ctx_new(); diff --git a/src/openvpn/openssl_compat.h b/src/openvpn/openssl_compat.h -index c9fa7196..a48ef391 100644 +index f487b1bc..b299c4a1 100644 --- a/src/openvpn/openssl_compat.h +++ b/src/openvpn/openssl_compat.h @@ -75,7 +75,7 @@ X509_OBJECT_free(X509_OBJECT *obj) @@ -38,10 +38,22 @@ index c9fa7196..a48ef391 100644 #endif diff --git a/src/openvpn/ssl_openssl.c b/src/openvpn/ssl_openssl.c -index 2595f878..cf99c3ec 100644 +index 23e76231..cab58ff4 100644 --- a/src/openvpn/ssl_openssl.c +++ b/src/openvpn/ssl_openssl.c -@@ -1658,8 +1658,10 @@ tls_ctx_load_ca(struct tls_root_ctx *ctx, const char *ca_file, +@@ -1431,7 +1431,11 @@ tls_ctx_use_external_ec_key(struct tls_root_ctx *ctx, EVP_PKEY *pkey) + + /* Among init methods, we only need the finish method */ + EC_KEY_METHOD_set_init(ec_method, NULL, openvpn_extkey_ec_finish, NULL, NULL, NULL, NULL); ++#ifdef OPENSSL_IS_AWSLC ++ EC_KEY_METHOD_set_sign(ec_method, ecdsa_sign, NULL, ecdsa_sign_sig); ++#else + EC_KEY_METHOD_set_sign(ec_method, ecdsa_sign, ecdsa_sign_setup, ecdsa_sign_sig); ++#endif + + ec = EC_KEY_dup(EVP_PKEY_get0_EC_KEY(pkey)); + if (!ec) +@@ -1658,8 +1662,10 @@ tls_ctx_load_ca(struct tls_root_ctx *ctx, const char *ca_file, sk_X509_INFO_pop_free(info_stack, X509_INFO_free); } @@ -52,7 +64,7 @@ index 2595f878..cf99c3ec 100644 SSL_CTX_set_client_CA_list(ctx->ctx, cert_names); } -@@ -1672,7 +1674,6 @@ tls_ctx_load_ca(struct tls_root_ctx *ctx, const char *ca_file, +@@ -1672,7 +1678,6 @@ tls_ctx_load_ca(struct tls_root_ctx *ctx, const char *ca_file, if (tls_server) { @@ -60,7 +72,7 @@ index 2595f878..cf99c3ec 100644 if (cnum != added) { crypto_msg(M_FATAL, "Cannot load CA certificate file %s (only %d " -@@ -2234,7 +2235,7 @@ show_available_tls_ciphers_list(const char *cipher_list, +@@ -2234,7 +2239,7 @@ show_available_tls_ciphers_list(const char *cipher_list, crypto_msg(M_FATAL, "Cannot create SSL object"); } From 89d7b7575b710e4f11a0e37129a44ad310989955 Mon Sep 17 00:00:00 2001 From: Shubham Mittal Date: Tue, 27 Aug 2024 23:44:30 -0700 Subject: [PATCH 20/26] removed unsused fields and updated documentation --- crypto/fipsmodule/ec/ec_key.c | 14 +++++--------- crypto/fipsmodule/ec/internal.h | 14 ++++++-------- include/openssl/ec_key.h | 30 +++++++++++++++++++----------- 3 files changed, 30 insertions(+), 28 deletions(-) diff --git a/crypto/fipsmodule/ec/ec_key.c b/crypto/fipsmodule/ec/ec_key.c index e632d24e2d..1d61ed62ef 100644 --- a/crypto/fipsmodule/ec/ec_key.c +++ b/crypto/fipsmodule/ec/ec_key.c @@ -568,15 +568,12 @@ void *EC_KEY_get_ex_data(const EC_KEY *d, int idx) { void EC_KEY_set_asn1_flag(EC_KEY *key, int flag) {} -DEFINE_METHOD_FUNCTION(EC_KEY_METHOD, EC_KEY_get_default_method) { - // All of the methods are NULL to make it easier for the compiler/linker to - // drop unused functions. The wrapper functions will select the appropriate - // |rsa_default_*| implementation. +DEFINE_METHOD_FUNCTION(EC_KEY_METHOD, EC_KEY_OpenSSL) { OPENSSL_memset(out, 0, sizeof(EC_KEY_METHOD)); } -const EC_KEY_METHOD *EC_KEY_OpenSSL(void) { - return EC_KEY_get_default_method(); +const EC_KEY_METHOD *EC_KEY_get_default_method(void) { + return EC_KEY_OpenSSL(); } EC_KEY_METHOD *EC_KEY_METHOD_new(const EC_KEY_METHOD *eckey_meth) { @@ -607,9 +604,8 @@ int EC_KEY_set_method(EC_KEY *ec, const EC_KEY_METHOD *meth) { } // These fields are currently not supported by AWS-LC and cannot be set - if(meth->compute_key || meth->copy || meth->keygen || meth->set_group || - meth->set_private || meth->set_public || meth->verify || - meth->verify_sig || meth->sign_setup) { + if(meth->copy || meth->set_group || meth->set_private || meth->set_public + || meth->sign_setup) { OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); return 0; } diff --git a/crypto/fipsmodule/ec/internal.h b/crypto/fipsmodule/ec/internal.h index dca52cdd08..a2d953a9a1 100644 --- a/crypto/fipsmodule/ec/internal.h +++ b/crypto/fipsmodule/ec/internal.h @@ -749,7 +749,12 @@ const EC_METHOD *EC_GFp_nistz256_method(void); // EC_KEY METHOD // ec_key_method_st is a structure of function pointers implementing EC_KEY -// operations. Currently, AWS-LC only allows consumers to set certain fields. +// operations. Currently, AWS-LC only allows consumers to use the |init|, +// |finish|, |sign|, |sign_sig|, and |flag| fields. +// +// We do not support the |verify|, |verify_sig|, |compute_key|, or |keygen| +// fields at all. If this struct is made public in the future, to maintain +// OpenSSL compatability and match the struct size, they should be added in. struct ec_key_method_st { int (*init)(EC_KEY *key); void (*finish)(EC_KEY *key); @@ -778,13 +783,6 @@ struct ec_key_method_st { int (*set_group)(EC_KEY *key, const EC_GROUP *group); int (*set_private)(EC_KEY *key, const BIGNUM *priv_key); int (*set_public)(EC_KEY *key, const EC_POINT *pub_key); - int (*keygen)(EC_KEY *key); - int (*compute_key)(unsigned char **out, size_t *out_len, - const EC_POINT *pub_key, const EC_KEY *ecdh); - int (*verify)(int type, const uint8_t *digest, int digest_len, - const uint8_t *sig, unsigned int sig_len, EC_KEY *eckey); - int (*verify_sig)(const uint8_t *digest, int digest_len, - const ECDSA_SIG *sig, EC_KEY *eckey); }; // An EC_WRAPPED_SCALAR is an |EC_SCALAR| with a parallel |BIGNUM| diff --git a/include/openssl/ec_key.h b/include/openssl/ec_key.h index dc6dc0c65c..6c56fecd00 100644 --- a/include/openssl/ec_key.h +++ b/include/openssl/ec_key.h @@ -338,30 +338,38 @@ OPENSSL_EXPORT int i2o_ECPublicKey(const EC_KEY *key, unsigned char **outp); #define ECDSA_FLAG_OPAQUE 1 // EC_KEY_get_default_method returns a reference to the default -// |EC_KEY| implementation. The returned |EC_KEY_METHOD| object is -// zero-initialized. This is different from OpenSSL which returns function -// pointers to the default implementations within the |EC_KEY_METHOD| struct. -// We do not do this to make it easier for the compiler/linker to drop unused -// functions. The wrapper functions will select the appropriate -// |ec_key_default_*| implementation. +// |EC_KEY| implementation. All |EC_KEY| objects are initialized with the +// returned struct. This function currently calls |EC_KEY_OpenSSL| since AWS-LC +// does not support changing/setting the default method. OPENSSL_EXPORT const EC_KEY_METHOD *EC_KEY_get_default_method(void); -// EC_KEY_OpenSSL calls |EC_KEY_get_default_method|. +// EC_KEY_OpenSSL returns a reference to the default |EC_KEY| implementation. +// The returned |EC_KEY_METHOD| object is statically allocated. The application +// should not free this struct. +// +// This struct is also zero-initialized. This is different from OpenSSL which +// returns function pointers to the default implementations within the +// |EC_KEY_METHOD| struct. We do not do this to make it easier for the +// compiler/linker to drop unused functions. The wrapper functions will select +// the appropriate |ec_key_default_*| implementation. OPENSSL_EXPORT const EC_KEY_METHOD *EC_KEY_OpenSSL(void); // EC_KEY_METHOD_new returns a newly allocated |EC_KEY_METHOD| object. If the // input parameter |eckey_meth| is non-NULL, the function pointers within the // returned |EC_KEY_METHOD| object will be initialized to the values from // |eckey_meth|. If |eckey_meth| is NULL, the returned object will be -// zero-initialized. +// initialized using the value returned from |EC_KEY_get_default_method|. OPENSSL_EXPORT EC_KEY_METHOD *EC_KEY_METHOD_new(const EC_KEY_METHOD *eckey_meth); // EC_KEY_METHOD_free frees the memory associated with |eckey_meth| OPENSSL_EXPORT void EC_KEY_METHOD_free(EC_KEY_METHOD *eckey_meth); -// EC_KEY_set_method sets |meth| on |ec|. Currently, AWS-LC does not support -// setting the compute_key, copy, keygen, set_group, set_private, set_public, -// verify, verify_sig fields. These must be NULL or the function will fail. +// EC_KEY_set_method sets |meth| on |ec|. While we provide setters to set +// the |copy|, |set_group|, |set_private|, |set_public|, and |sign_setup| +// fields, we do not support the associated functionality and these pointers +// should be set to NULL. We do not support the |verify|, |verify_sig|, or +// |keygen| fields yet. +// // Returns zero on failure and one on success. OPENSSL_EXPORT int EC_KEY_set_method(EC_KEY *ec, const EC_KEY_METHOD *meth); From 46ccb04b6eaf30f16ba7229b2bc23bb90059cda8 Mon Sep 17 00:00:00 2001 From: Shubham Mittal Date: Wed, 28 Aug 2024 11:23:24 -0700 Subject: [PATCH 21/26] added static asserts for params that should not be set --- crypto/fipsmodule/ec/ec_key.c | 5 +-- include/openssl/ec_key.h | 77 +++++++++++++++++++++++------------ 2 files changed, 53 insertions(+), 29 deletions(-) diff --git a/crypto/fipsmodule/ec/ec_key.c b/crypto/fipsmodule/ec/ec_key.c index 1d61ed62ef..1d89d6da19 100644 --- a/crypto/fipsmodule/ec/ec_key.c +++ b/crypto/fipsmodule/ec/ec_key.c @@ -623,7 +623,7 @@ const EC_KEY_METHOD *EC_KEY_get_method(const EC_KEY *ec) { return ec->eckey_method; } -void EC_KEY_METHOD_set_init(EC_KEY_METHOD *meth, +void EC_KEY_METHOD_set_init_impl(EC_KEY_METHOD *meth, int (*init)(EC_KEY *key), void (*finish)(EC_KEY *key), int (*copy)(EC_KEY *dest, const EC_KEY *src), @@ -638,7 +638,6 @@ void EC_KEY_METHOD_set_init(EC_KEY_METHOD *meth, } // Setting these fields is currently not supported by AWS-LC - assert(!copy && !set_group && !set_private && !set_public); if(copy || set_group || set_private || set_public) { OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); abort(); @@ -648,7 +647,7 @@ void EC_KEY_METHOD_set_init(EC_KEY_METHOD *meth, meth->finish = finish; } -void EC_KEY_METHOD_set_sign(EC_KEY_METHOD *meth, +void EC_KEY_METHOD_set_sign_impl(EC_KEY_METHOD *meth, int (*sign)(int type, const uint8_t *digest, int digest_len, uint8_t *sig, unsigned int *siglen, const BIGNUM *k_inv, diff --git a/include/openssl/ec_key.h b/include/openssl/ec_key.h index 6c56fecd00..634d9ae5f9 100644 --- a/include/openssl/ec_key.h +++ b/include/openssl/ec_key.h @@ -376,36 +376,61 @@ OPENSSL_EXPORT int EC_KEY_set_method(EC_KEY *ec, const EC_KEY_METHOD *meth); // EC_KEY_get_method returns the |EC_KEY_METHOD| object associated with |ec|. OPENSSL_EXPORT const EC_KEY_METHOD *EC_KEY_get_method(const EC_KEY *ec); -// EC_KEY_METHOD_set_init sets function pointers on |meth|. AWS-LC currently -// only supports setting the |init| and |finish| fields. |copy|, |set_group|, -// |set_private|, and |set_public| must be set to NULL otherwise the function -// will abort. -OPENSSL_EXPORT void EC_KEY_METHOD_set_init(EC_KEY_METHOD *meth, - int (*init)(EC_KEY *key), - void (*finish)(EC_KEY *key), - int (*copy)(EC_KEY *dest, const EC_KEY *src), - int (*set_group)(EC_KEY *key, const EC_GROUP *grp), - int (*set_private)(EC_KEY *key, - const BIGNUM *priv_key), - int (*set_public)(EC_KEY *key, - const EC_POINT *pub_key)); - -// EC_KEY_METHOD_set_sign sets function pointers on |meth|. AWS-LC currently -// supports setting |sign| and |sign_sig|. |sign_setup| must be set to NULL -// otherwise the function aborts. -OPENSSL_EXPORT void EC_KEY_METHOD_set_sign(EC_KEY_METHOD *meth, - int (*sign)(int type, const uint8_t *digest, +#ifdef __cplusplus +#define IS_NULL(ptr) ((ptr) == nullptr) +#else +#define IS_NULL(ptr) ((ptr) == NULL) +#endif + +// EC_KEY_METHOD_set_sign_impl sets function pointers on |meth|. +// AWS-LC currently supports setting |sign| and |sign_sig|. |sign_setup| must +// be set to NULL in order to compile with AWS-LC. At runtime, if |sign_setup| +// is not a NULL field, the function aborts. +OPENSSL_EXPORT void EC_KEY_METHOD_set_sign_impl(EC_KEY_METHOD *meth, + int (*sign)(int type, const uint8_t *digest, int digest_len, uint8_t *sig, unsigned int *siglen, const BIGNUM *k_inv, const BIGNUM *r, EC_KEY *eckey), - int (*sign_setup)(EC_KEY *eckey, BN_CTX *ctx_in, - BIGNUM **kinvp, BIGNUM **rp), - ECDSA_SIG *(*sign_sig)(const uint8_t *digest, - int digest_len, - const BIGNUM *in_kinv, - const BIGNUM *in_r, - EC_KEY *eckey)); + int (*sign_setup)(EC_KEY *eckey, BN_CTX *ctx_in, + BIGNUM **kinvp, BIGNUM **rp), + ECDSA_SIG *(*sign_sig)(const uint8_t *digest, + int digest_len, + const BIGNUM *in_kinv, + const BIGNUM *in_r, + EC_KEY *eckey)); + + +#define EC_KEY_METHOD_set_sign(meth, sign, sign_setup, sign_sig) \ + static_assert(IS_NULL(sign_setup), \ + "EC_KEY_METHOD's sign_setup field must be NULL"); \ + EC_KEY_METHOD_set_sign_impl(meth, sign, sign_setup, sign_sig); + +// EC_KEY_METHOD_set_init_impl sets function pointers on |meth|. AWS-LC +// currently only supports setting the |init| and |finish| fields. |copy|, +// |set_group|, |set_private|, and |set_public| must be set to NULL to +// compile with AWS-LC. If these fields have non-NULL values at runtime, the +// function will abort. +OPENSSL_EXPORT void EC_KEY_METHOD_set_init_impl(EC_KEY_METHOD *meth, + int (*init)(EC_KEY *key), + void (*finish)(EC_KEY *key), + int (*copy)(EC_KEY *dest, + const EC_KEY *src), + int (*set_group)(EC_KEY *key, + const EC_GROUP *grp), + int (*set_private)(EC_KEY *key, + const BIGNUM *priv_key), + int (*set_public)(EC_KEY *key, + const EC_POINT *pub_key)); + +#define EC_KEY_METHOD_set_init(meth, init, finish, copy, set_group, \ + set_private, set_public) \ + static_assert(IS_NULL(copy) && IS_NULL(set_group) && \ + IS_NULL(set_private) && IS_NULL(set_public), \ + "EC_KEY_METHOD's copy, set_group, set_private, and " \ + "set_public fields must be NULL"); \ + EC_KEY_METHOD_set_init_impl(meth, init, finish, copy, set_group, \ + set_private, set_public); // EC_KEY_METHOD_set_flags sets |flags| on |meth|. Currently, the only supported // flag is |ECDSA_FLAG_OPAQUE|. Returns zero on failure and one on success. From 404312c6fac4306cbe49f94417904bb7da3d15bf Mon Sep 17 00:00:00 2001 From: Shubham Mittal Date: Wed, 28 Aug 2024 12:19:32 -0700 Subject: [PATCH 22/26] removed unused params and updated documetnation --- crypto/fipsmodule/ec/ec_key.c | 27 ++-------------- include/openssl/ec_key.h | 58 +++++++++++++++-------------------- 2 files changed, 27 insertions(+), 58 deletions(-) diff --git a/crypto/fipsmodule/ec/ec_key.c b/crypto/fipsmodule/ec/ec_key.c index 1d89d6da19..24bc22dbf6 100644 --- a/crypto/fipsmodule/ec/ec_key.c +++ b/crypto/fipsmodule/ec/ec_key.c @@ -623,37 +623,22 @@ const EC_KEY_METHOD *EC_KEY_get_method(const EC_KEY *ec) { return ec->eckey_method; } -void EC_KEY_METHOD_set_init_impl(EC_KEY_METHOD *meth, - int (*init)(EC_KEY *key), - void (*finish)(EC_KEY *key), - int (*copy)(EC_KEY *dest, const EC_KEY *src), - int (*set_group)(EC_KEY *key, const EC_GROUP *grp), - int (*set_private)(EC_KEY *key, - const BIGNUM *priv_key), - int (*set_public)(EC_KEY *key, - const EC_POINT *pub_key)) { +void EC_KEY_METHOD_set_init_awslc(EC_KEY_METHOD *meth, int (*init)(EC_KEY *key), + void (*finish)(EC_KEY *key)) { if(meth == NULL) { OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER); return; } - // Setting these fields is currently not supported by AWS-LC - if(copy || set_group || set_private || set_public) { - OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); - abort(); - } - meth->init = init; meth->finish = finish; } -void EC_KEY_METHOD_set_sign_impl(EC_KEY_METHOD *meth, +void EC_KEY_METHOD_set_sign_awslc(EC_KEY_METHOD *meth, int (*sign)(int type, const uint8_t *digest, int digest_len, uint8_t *sig, unsigned int *siglen, const BIGNUM *k_inv, const BIGNUM *r, EC_KEY *eckey), - int (*sign_setup)(EC_KEY *eckey, BN_CTX *ctx_in, - BIGNUM **kinvp, BIGNUM **rp), ECDSA_SIG *(*sign_sig)(const uint8_t *digest, int digest_len, const BIGNUM *in_kinv, const BIGNUM *in_r, @@ -664,12 +649,6 @@ void EC_KEY_METHOD_set_sign_impl(EC_KEY_METHOD *meth, return; } - // Setting this field is currently not supported by AWS-LC - if(sign_setup) { - OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); - abort(); - } - meth->sign = sign; meth->sign_sig = sign_sig; } diff --git a/include/openssl/ec_key.h b/include/openssl/ec_key.h index 634d9ae5f9..a97ace52b6 100644 --- a/include/openssl/ec_key.h +++ b/include/openssl/ec_key.h @@ -364,11 +364,10 @@ OPENSSL_EXPORT EC_KEY_METHOD *EC_KEY_METHOD_new(const EC_KEY_METHOD *eckey_meth) // EC_KEY_METHOD_free frees the memory associated with |eckey_meth| OPENSSL_EXPORT void EC_KEY_METHOD_free(EC_KEY_METHOD *eckey_meth); -// EC_KEY_set_method sets |meth| on |ec|. While we provide setters to set -// the |copy|, |set_group|, |set_private|, |set_public|, and |sign_setup| -// fields, we do not support the associated functionality and these pointers -// should be set to NULL. We do not support the |verify|, |verify_sig|, or -// |keygen| fields yet. +// EC_KEY_set_method sets |meth| on |ec|. We do not support setting the +// |copy|, |set_group|, |set_private|, |set_public|, and |sign_setup| +// fields and these pointers should be set to NULL. We do not support the +// |verify|, |verify_sig|, or |keygen| fields yet. // // Returns zero on failure and one on success. OPENSSL_EXPORT int EC_KEY_set_method(EC_KEY *ec, const EC_KEY_METHOD *meth); @@ -382,55 +381,46 @@ OPENSSL_EXPORT const EC_KEY_METHOD *EC_KEY_get_method(const EC_KEY *ec); #define IS_NULL(ptr) ((ptr) == NULL) #endif -// EC_KEY_METHOD_set_sign_impl sets function pointers on |meth|. -// AWS-LC currently supports setting |sign| and |sign_sig|. |sign_setup| must -// be set to NULL in order to compile with AWS-LC. At runtime, if |sign_setup| -// is not a NULL field, the function aborts. -OPENSSL_EXPORT void EC_KEY_METHOD_set_sign_impl(EC_KEY_METHOD *meth, +// EC_KEY_METHOD_set_sign_awslc sets the |sign| and |sign_sig| pointers on +// |meth|. +OPENSSL_EXPORT void EC_KEY_METHOD_set_sign_awslc(EC_KEY_METHOD *meth, int (*sign)(int type, const uint8_t *digest, int digest_len, uint8_t *sig, unsigned int *siglen, const BIGNUM *k_inv, const BIGNUM *r, EC_KEY *eckey), - int (*sign_setup)(EC_KEY *eckey, BN_CTX *ctx_in, - BIGNUM **kinvp, BIGNUM **rp), ECDSA_SIG *(*sign_sig)(const uint8_t *digest, - int digest_len, - const BIGNUM *in_kinv, - const BIGNUM *in_r, - EC_KEY *eckey)); + int digest_len, + const BIGNUM *in_kinv, + const BIGNUM *in_r, + EC_KEY *eckey)); +// EC_KEY_METHOD_set_sign sets function pointers on |meth|. AWS-LC currently +// supports setting |sign| and |sign_sig|. |sign_setup| must be set to NULL in +// order to compile with AWS-LC. #define EC_KEY_METHOD_set_sign(meth, sign, sign_setup, sign_sig) \ static_assert(IS_NULL(sign_setup), \ "EC_KEY_METHOD's sign_setup field must be NULL"); \ - EC_KEY_METHOD_set_sign_impl(meth, sign, sign_setup, sign_sig); + EC_KEY_METHOD_set_sign_awslc(meth, sign, sign_sig); -// EC_KEY_METHOD_set_init_impl sets function pointers on |meth|. AWS-LC -// currently only supports setting the |init| and |finish| fields. |copy|, -// |set_group|, |set_private|, and |set_public| must be set to NULL to -// compile with AWS-LC. If these fields have non-NULL values at runtime, the -// function will abort. -OPENSSL_EXPORT void EC_KEY_METHOD_set_init_impl(EC_KEY_METHOD *meth, +// EC_KEY_METHOD_set_init_awslc sets the |init| and |finish| pointers on |meth|. +OPENSSL_EXPORT void EC_KEY_METHOD_set_init_awslc(EC_KEY_METHOD *meth, int (*init)(EC_KEY *key), - void (*finish)(EC_KEY *key), - int (*copy)(EC_KEY *dest, - const EC_KEY *src), - int (*set_group)(EC_KEY *key, - const EC_GROUP *grp), - int (*set_private)(EC_KEY *key, - const BIGNUM *priv_key), - int (*set_public)(EC_KEY *key, - const EC_POINT *pub_key)); + void (*finish)(EC_KEY *key)); + +// EC_KEY_METHOD_set_init sets function pointers on |meth|. AWS-LC +// currently only supports setting the |init| and |finish| fields. |copy|, +// |set_group|, |set_private|, and |set_public| cannot be set yet and must +// be NULL. #define EC_KEY_METHOD_set_init(meth, init, finish, copy, set_group, \ set_private, set_public) \ static_assert(IS_NULL(copy) && IS_NULL(set_group) && \ IS_NULL(set_private) && IS_NULL(set_public), \ "EC_KEY_METHOD's copy, set_group, set_private, and " \ "set_public fields must be NULL"); \ - EC_KEY_METHOD_set_init_impl(meth, init, finish, copy, set_group, \ - set_private, set_public); + EC_KEY_METHOD_set_init_awslc(meth, init, finish); // EC_KEY_METHOD_set_flags sets |flags| on |meth|. Currently, the only supported // flag is |ECDSA_FLAG_OPAQUE|. Returns zero on failure and one on success. From 63ca96353ef9e58ef38df5c87a1e82d71a977083 Mon Sep 17 00:00:00 2001 From: Shubham Mittal Date: Wed, 28 Aug 2024 13:49:23 -0700 Subject: [PATCH 23/26] using OPENSSL_STATIC_ASSERT and removed IS_NULL macro --- crypto/fipsmodule/ec/ec_test.cc | 8 ++++---- include/openssl/ec_key.h | 17 +++++------------ 2 files changed, 9 insertions(+), 16 deletions(-) diff --git a/crypto/fipsmodule/ec/ec_test.cc b/crypto/fipsmodule/ec/ec_test.cc index e9bd5ec545..ab86698f09 100644 --- a/crypto/fipsmodule/ec/ec_test.cc +++ b/crypto/fipsmodule/ec/ec_test.cc @@ -2472,11 +2472,11 @@ TEST(ECTest, ECKEYMETHOD) { ASSERT_FALSE(ec_method->finish && ec_method->sign); // Can only set these fields - EC_KEY_METHOD_set_init(ec_method, nullptr, openvpn_extkey_ec_finish, - nullptr, nullptr, nullptr, nullptr); + EC_KEY_METHOD_set_init(ec_method, NULL, openvpn_extkey_ec_finish, + NULL, NULL, NULL, NULL); ASSERT_TRUE(ec_method->finish); // Checking Sign - EC_KEY_METHOD_set_sign(ec_method, ecdsa_sign, nullptr, nullptr); + EC_KEY_METHOD_set_sign(ec_method, ecdsa_sign, NULL, NULL); ASSERT_TRUE(ec_method->sign); bssl::UniquePtr group(EC_GROUP_new_by_curve_name(NID_secp224r1)); @@ -2513,7 +2513,7 @@ TEST(ECTest, ECKEYMETHOD) { ec)); // Now test the sign_sig pointer - EC_KEY_METHOD_set_sign(ec_method, nullptr, nullptr, ecdsa_sign_sig); + EC_KEY_METHOD_set_sign(ec_method, NULL, NULL, ecdsa_sign_sig); ASSERT_TRUE(ec_method->sign_sig && !ec_method->sign); ECDSA_do_sign(digest, 20, ec); diff --git a/include/openssl/ec_key.h b/include/openssl/ec_key.h index a97ace52b6..aa0359411d 100644 --- a/include/openssl/ec_key.h +++ b/include/openssl/ec_key.h @@ -375,12 +375,6 @@ OPENSSL_EXPORT int EC_KEY_set_method(EC_KEY *ec, const EC_KEY_METHOD *meth); // EC_KEY_get_method returns the |EC_KEY_METHOD| object associated with |ec|. OPENSSL_EXPORT const EC_KEY_METHOD *EC_KEY_get_method(const EC_KEY *ec); -#ifdef __cplusplus -#define IS_NULL(ptr) ((ptr) == nullptr) -#else -#define IS_NULL(ptr) ((ptr) == NULL) -#endif - // EC_KEY_METHOD_set_sign_awslc sets the |sign| and |sign_sig| pointers on // |meth|. OPENSSL_EXPORT void EC_KEY_METHOD_set_sign_awslc(EC_KEY_METHOD *meth, @@ -400,8 +394,8 @@ OPENSSL_EXPORT void EC_KEY_METHOD_set_sign_awslc(EC_KEY_METHOD *meth, // supports setting |sign| and |sign_sig|. |sign_setup| must be set to NULL in // order to compile with AWS-LC. #define EC_KEY_METHOD_set_sign(meth, sign, sign_setup, sign_sig) \ - static_assert(IS_NULL(sign_setup), \ - "EC_KEY_METHOD's sign_setup field must be NULL"); \ + OPENSSL_STATIC_ASSERT((sign_setup) == NULL, \ + EC_KEY_METHOD_sign_setup_field_must_be_NULL); \ EC_KEY_METHOD_set_sign_awslc(meth, sign, sign_sig); // EC_KEY_METHOD_set_init_awslc sets the |init| and |finish| pointers on |meth|. @@ -416,10 +410,9 @@ OPENSSL_EXPORT void EC_KEY_METHOD_set_init_awslc(EC_KEY_METHOD *meth, // be NULL. #define EC_KEY_METHOD_set_init(meth, init, finish, copy, set_group, \ set_private, set_public) \ - static_assert(IS_NULL(copy) && IS_NULL(set_group) && \ - IS_NULL(set_private) && IS_NULL(set_public), \ - "EC_KEY_METHOD's copy, set_group, set_private, and " \ - "set_public fields must be NULL"); \ + OPENSSL_STATIC_ASSERT((copy) == NULL && (set_group) == NULL && \ + (set_private) == NULL && (set_public) == NULL, \ + EC_KEY_METHOD_copy_set_group_set_private_and_set_public_fields_must_be_NULL);\ EC_KEY_METHOD_set_init_awslc(meth, init, finish); // EC_KEY_METHOD_set_flags sets |flags| on |meth|. Currently, the only supported From 6c1f2e7b56a0fc59340dee746115f1aff95e5266 Mon Sep 17 00:00:00 2001 From: Shubham Mittal Date: Thu, 29 Aug 2024 10:17:14 -0700 Subject: [PATCH 24/26] commented out more unsused fields --- crypto/fipsmodule/ec/internal.h | 20 ++++++---- crypto/fipsmodule/tls/tlsprf_test_vectors.txt | 39 +++++++++++++++++++ 2 files changed, 52 insertions(+), 7 deletions(-) create mode 100644 crypto/fipsmodule/tls/tlsprf_test_vectors.txt diff --git a/crypto/fipsmodule/ec/internal.h b/crypto/fipsmodule/ec/internal.h index a2d953a9a1..3dcaad077e 100644 --- a/crypto/fipsmodule/ec/internal.h +++ b/crypto/fipsmodule/ec/internal.h @@ -776,13 +776,19 @@ struct ec_key_method_st { // not set by default. int flags; - // AWS-LC currently does not support these fields, must be NULL - int (*sign_setup)(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **k_inv, - BIGNUM **r); - int (*copy)(EC_KEY *dest, const EC_KEY *src); - int (*set_group)(EC_KEY *key, const EC_GROUP *group); - int (*set_private)(EC_KEY *key, const BIGNUM *priv_key); - int (*set_public)(EC_KEY *key, const EC_POINT *pub_key); + // AWS-LC currently does not support these fields directly. However, they + // are left commented out here because the associated setter functions still + // technically include support for them in their signatures. + // Note: Compile-time checks (static asserts) are in place to ensure that + // these fields cannot be set by consumers, enforcing the requirement that + // NULL must be passed for these parameters. + + // int (*sign_setup)(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **k_inv, + // BIGNUM **r); + // int (*copy)(EC_KEY *dest, const EC_KEY *src); + // int (*set_group)(EC_KEY *key, const EC_GROUP *group); + // int (*set_private)(EC_KEY *key, const BIGNUM *priv_key); + // int (*set_public)(EC_KEY *key, const EC_POINT *pub_key); }; // An EC_WRAPPED_SCALAR is an |EC_SCALAR| with a parallel |BIGNUM| diff --git a/crypto/fipsmodule/tls/tlsprf_test_vectors.txt b/crypto/fipsmodule/tls/tlsprf_test_vectors.txt new file mode 100644 index 0000000000..998b6a6b23 --- /dev/null +++ b/crypto/fipsmodule/tls/tlsprf_test_vectors.txt @@ -0,0 +1,39 @@ +# Generating 88 bytes of pseudo-randomness using TLS1.2PRF-SHA224 +Secret = e18828740352b530d69b34c6597dea2e +Seclen = 16 +Seed = f5a3fe6d34e2e28560fdcaf6823f9091 +SeedLen = 16 +Label = 74657374206c6162656c +LabelLen = 10 +Output = 224d8af3c0453393a9779789d21cf7da5ee62ae6b617873d489428efc8dd58d1566e7029e2ca3a5ecd355dc64d4d927e2fbd78c4233e8604b14749a77a92a70fddf614bc0df623d798604e4ca5512794d802a258e82f86cf +OutLen = 88 + +# Generating 100 bytes of pseudo-randomness using TLS1.2PRF-SHA256 +Secret = 9bbe436ba940f017b17652849a71db35 +Seclen = 16 +Seed = a0ba9f936cda311827a6f796ffd5198c +SeedLen = 16 +Label = 74657374206c6162656c +LabelLen = 10 +Output = e3f229ba727be17b8d122620557cd453c2aab21d07c3d495329b52d4e61edb5a6b301791e90d35c9c9a46b4e14baf9af0fa022f7077def17abfd3797c0564bab4fbc91666e9def9b97fce34f796789baa48082d122ee42c5a72e5a5110fff70187347b66 +OutLen = 100 + +# Generating 196 bytes of pseudo-randomness using TLS1.2PRF-SHA512 +Secret = b0323523c1853599584d88568bbb05eb +Seclen = 16 +Seed = d4640e12e4bcdbfb437f03e6ae418ee5 +SeedLen = 16 +Label = 74657374206c6162656c +LabelLen = 10 +Output = 1261f588c798c5c201ff036e7a9cb5edcd7fe3f94c669a122a4638d7d508b283042df6789875c7147e906d868bc75c45e20eb40c1cf4a1713b27371f68432592f7dc8ea8ef223e12ea8507841311bf68653d0cfc4056d811f025c45ddfa6e6fec702f054b409d6f28dd0a3233e498da41a3e75c5630eedbe22fe254e33a1b0e9f6b9826675bec7d01a845658dc9c397545401d40b9f46c7a400ee1b8f81ca0a60d1a397a1028bff5d2ef5066126842fb8da4197632bdb54ff6633f86bbc836e640d4d898 +OutLen = 196 + +# Generating 148 bytes of pseudo-randomness using TLS1.2PRF-SHA384 +Secret = b80b733d6ceefcdc71566ea48e5567df +Seclen = 16 +Seed = cd665cf6a8447dd6ff8b27555edb7465 +SeedLen = 16 +Label = 74657374206c6162656c +LabelLen = 10 +Output = 7b0c18e9ced410ed1804f2cfa34a336a1c14dffb4900bb5fd7942107e81c83cde9ca0faa60be9fe34f82b1233c9146a0e534cb400fed2700884f9dc236f80edd8bfa961144c9e8d792eca722a7b32fc3d416d473ebc2c5fd4abfdad05d9184259b5bf8cd4d90fa0d31e2dec479e4f1a26066f2eea9a69236a3e52655c9e9aee691c8f3a26854308d5eaa3be85e0990703d73e56f +OutLen = 148 \ No newline at end of file From c687981be3cd698f8b2cbd196c13b118960b6e20 Mon Sep 17 00:00:00 2001 From: Shubham Mittal Date: Thu, 29 Aug 2024 10:26:28 -0700 Subject: [PATCH 25/26] fixed set_method and removed old fields --- crypto/fipsmodule/ec/ec_key.c | 7 ---- crypto/fipsmodule/ec/internal.h | 1 - crypto/fipsmodule/tls/tlsprf_test_vectors.txt | 39 ------------------- 3 files changed, 47 deletions(-) delete mode 100644 crypto/fipsmodule/tls/tlsprf_test_vectors.txt diff --git a/crypto/fipsmodule/ec/ec_key.c b/crypto/fipsmodule/ec/ec_key.c index 24bc22dbf6..730729ee3c 100644 --- a/crypto/fipsmodule/ec/ec_key.c +++ b/crypto/fipsmodule/ec/ec_key.c @@ -603,13 +603,6 @@ int EC_KEY_set_method(EC_KEY *ec, const EC_KEY_METHOD *meth) { return 0; } - // These fields are currently not supported by AWS-LC and cannot be set - if(meth->copy || meth->set_group || meth->set_private || meth->set_public - || meth->sign_setup) { - OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); - return 0; - } - ec->eckey_method = meth; return 1; } diff --git a/crypto/fipsmodule/ec/internal.h b/crypto/fipsmodule/ec/internal.h index 3dcaad077e..0b63b09256 100644 --- a/crypto/fipsmodule/ec/internal.h +++ b/crypto/fipsmodule/ec/internal.h @@ -782,7 +782,6 @@ struct ec_key_method_st { // Note: Compile-time checks (static asserts) are in place to ensure that // these fields cannot be set by consumers, enforcing the requirement that // NULL must be passed for these parameters. - // int (*sign_setup)(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **k_inv, // BIGNUM **r); // int (*copy)(EC_KEY *dest, const EC_KEY *src); diff --git a/crypto/fipsmodule/tls/tlsprf_test_vectors.txt b/crypto/fipsmodule/tls/tlsprf_test_vectors.txt deleted file mode 100644 index 998b6a6b23..0000000000 --- a/crypto/fipsmodule/tls/tlsprf_test_vectors.txt +++ /dev/null @@ -1,39 +0,0 @@ -# Generating 88 bytes of pseudo-randomness using TLS1.2PRF-SHA224 -Secret = e18828740352b530d69b34c6597dea2e -Seclen = 16 -Seed = f5a3fe6d34e2e28560fdcaf6823f9091 -SeedLen = 16 -Label = 74657374206c6162656c -LabelLen = 10 -Output = 224d8af3c0453393a9779789d21cf7da5ee62ae6b617873d489428efc8dd58d1566e7029e2ca3a5ecd355dc64d4d927e2fbd78c4233e8604b14749a77a92a70fddf614bc0df623d798604e4ca5512794d802a258e82f86cf -OutLen = 88 - -# Generating 100 bytes of pseudo-randomness using TLS1.2PRF-SHA256 -Secret = 9bbe436ba940f017b17652849a71db35 -Seclen = 16 -Seed = a0ba9f936cda311827a6f796ffd5198c -SeedLen = 16 -Label = 74657374206c6162656c -LabelLen = 10 -Output = e3f229ba727be17b8d122620557cd453c2aab21d07c3d495329b52d4e61edb5a6b301791e90d35c9c9a46b4e14baf9af0fa022f7077def17abfd3797c0564bab4fbc91666e9def9b97fce34f796789baa48082d122ee42c5a72e5a5110fff70187347b66 -OutLen = 100 - -# Generating 196 bytes of pseudo-randomness using TLS1.2PRF-SHA512 -Secret = b0323523c1853599584d88568bbb05eb -Seclen = 16 -Seed = d4640e12e4bcdbfb437f03e6ae418ee5 -SeedLen = 16 -Label = 74657374206c6162656c -LabelLen = 10 -Output = 1261f588c798c5c201ff036e7a9cb5edcd7fe3f94c669a122a4638d7d508b283042df6789875c7147e906d868bc75c45e20eb40c1cf4a1713b27371f68432592f7dc8ea8ef223e12ea8507841311bf68653d0cfc4056d811f025c45ddfa6e6fec702f054b409d6f28dd0a3233e498da41a3e75c5630eedbe22fe254e33a1b0e9f6b9826675bec7d01a845658dc9c397545401d40b9f46c7a400ee1b8f81ca0a60d1a397a1028bff5d2ef5066126842fb8da4197632bdb54ff6633f86bbc836e640d4d898 -OutLen = 196 - -# Generating 148 bytes of pseudo-randomness using TLS1.2PRF-SHA384 -Secret = b80b733d6ceefcdc71566ea48e5567df -Seclen = 16 -Seed = cd665cf6a8447dd6ff8b27555edb7465 -SeedLen = 16 -Label = 74657374206c6162656c -LabelLen = 10 -Output = 7b0c18e9ced410ed1804f2cfa34a336a1c14dffb4900bb5fd7942107e81c83cde9ca0faa60be9fe34f82b1233c9146a0e534cb400fed2700884f9dc236f80edd8bfa961144c9e8d792eca722a7b32fc3d416d473ebc2c5fd4abfdad05d9184259b5bf8cd4d90fa0d31e2dec479e4f1a26066f2eea9a69236a3e52655c9e9aee691c8f3a26854308d5eaa3be85e0990703d73e56f -OutLen = 148 \ No newline at end of file From cbe8a5a360d6dc97deee39bc05213d6722079721 Mon Sep 17 00:00:00 2001 From: Shubham Mittal Date: Thu, 29 Aug 2024 16:24:45 -0700 Subject: [PATCH 26/26] updated documentation --- crypto/fipsmodule/ec/internal.h | 15 +++++++++------ include/openssl/ec_key.h | 14 ++++++++------ 2 files changed, 17 insertions(+), 12 deletions(-) diff --git a/crypto/fipsmodule/ec/internal.h b/crypto/fipsmodule/ec/internal.h index 0b63b09256..649911aad4 100644 --- a/crypto/fipsmodule/ec/internal.h +++ b/crypto/fipsmodule/ec/internal.h @@ -746,11 +746,12 @@ const EC_METHOD *EC_GFp_nistp521_method(void); const EC_METHOD *EC_GFp_nistz256_method(void); -// EC_KEY METHOD +// EC_KEY_METHOD // ec_key_method_st is a structure of function pointers implementing EC_KEY // operations. Currently, AWS-LC only allows consumers to use the |init|, -// |finish|, |sign|, |sign_sig|, and |flag| fields. +// |finish|, |sign|, |sign_sig|, and |flag| fields. This struct replaces the +// older variant |ECDSA_METHOD|. // // We do not support the |verify|, |verify_sig|, |compute_key|, or |keygen| // fields at all. If this struct is made public in the future, to maintain @@ -761,13 +762,15 @@ struct ec_key_method_st { // AWS-LC doesn't support custom values for EC_KEY operations // as of now. |k_inv| and |r| must be NULL parameters. - // The |type| parameter is ignored in OpenSSL, we pass in zero for it + // The |type| parameter is ignored in OpenSSL, we pass in zero for it. + // |sign| is invoked in |ECDSA_sign|. int (*sign)(int type, const uint8_t *digest, int digest_len, uint8_t *sig, unsigned int *siglen, const BIGNUM *k_inv, const BIGNUM *r, EC_KEY *eckey); // AWS-LC doesn't support custom values for EC_KEY operations - // as of now. |k_inv| and |r| must be NULL parameters. + // as of now. |k_inv| and |r| must be NULL parameters. |sign_sig| is + // invoked in |ECDSA_do_sign|. ECDSA_SIG *(*sign_sig)(const uint8_t *digest, int digest_len, const BIGNUM *in_kinv, const BIGNUM *in_r, EC_KEY *eckey); @@ -777,8 +780,8 @@ struct ec_key_method_st { int flags; // AWS-LC currently does not support these fields directly. However, they - // are left commented out here because the associated setter functions still - // technically include support for them in their signatures. + // are left commented out here because the associated setter + // functions (macros) still include support for them in their signatures. // Note: Compile-time checks (static asserts) are in place to ensure that // these fields cannot be set by consumers, enforcing the requirement that // NULL must be passed for these parameters. diff --git a/include/openssl/ec_key.h b/include/openssl/ec_key.h index aa0359411d..3a826ba87a 100644 --- a/include/openssl/ec_key.h +++ b/include/openssl/ec_key.h @@ -329,12 +329,13 @@ OPENSSL_EXPORT int i2o_ECPublicKey(const EC_KEY *key, unsigned char **outp); // EC_KEY_METHOD +// This struct replaces the old |ECDSA_METHOD| struct. // ECDSA_FLAG_OPAQUE specifies that this EC_KEY_METHOD does not expose its key // material. This may be set if, for instance, it is wrapping some other crypto // API, like a platform key store. Use |EC_KEY_METHOD_set_flag| to set -// this flag on an |EC_KEY_METHOD|. -// This was supported in ECDSA_METHOD previously and is not set by default. +// this flag on an |EC_KEY_METHOD|. It is not set by default. +// This was supported in ECDSA_METHOD previously. #define ECDSA_FLAG_OPAQUE 1 // EC_KEY_get_default_method returns a reference to the default @@ -350,8 +351,9 @@ OPENSSL_EXPORT const EC_KEY_METHOD *EC_KEY_get_default_method(void); // This struct is also zero-initialized. This is different from OpenSSL which // returns function pointers to the default implementations within the // |EC_KEY_METHOD| struct. We do not do this to make it easier for the -// compiler/linker to drop unused functions. The wrapper functions will select -// the appropriate |ec_key_default_*| implementation. +// compiler/linker to drop unused functions. The wrapper functions for a given +// operation (e.g. |ECDSA_sign| corresponds to the |sign| field in +// |EC_KEY_METHOD|) will select the appropriate default implementation. OPENSSL_EXPORT const EC_KEY_METHOD *EC_KEY_OpenSSL(void); // EC_KEY_METHOD_new returns a newly allocated |EC_KEY_METHOD| object. If the @@ -366,8 +368,8 @@ OPENSSL_EXPORT void EC_KEY_METHOD_free(EC_KEY_METHOD *eckey_meth); // EC_KEY_set_method sets |meth| on |ec|. We do not support setting the // |copy|, |set_group|, |set_private|, |set_public|, and |sign_setup| -// fields and these pointers should be set to NULL. We do not support the -// |verify|, |verify_sig|, or |keygen| fields yet. +// fields in |ec| and these pointers should be set to NULL. We do not support +// the |verify|, |verify_sig|, or |keygen| fields yet. // // Returns zero on failure and one on success. OPENSSL_EXPORT int EC_KEY_set_method(EC_KEY *ec, const EC_KEY_METHOD *meth);