From 6095a863faf68ee41ddf510b0f6b05a45ec6efc3 Mon Sep 17 00:00:00 2001 From: Tim Ruffing Date: Mon, 4 Mar 2019 13:09:45 +0100 Subject: [PATCH 1/5] Replace CHECKs for no_precomp ctx by ARG_CHECKs without a return --- src/secp256k1.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/secp256k1.c b/src/secp256k1.c index 627ebe75e668d..077ca780d70c4 100644 --- a/src/secp256k1.c +++ b/src/secp256k1.c @@ -27,6 +27,12 @@ } \ } while(0) +#define ARG_CHECK_NO_RETURN(cond) do { \ + if (EXPECT(!(cond), 0)) { \ + secp256k1_callback_call(&ctx->illegal_callback, #cond); \ + } \ +} while(0) + static void default_illegal_callback_fn(const char* str, void* data) { (void)data; fprintf(stderr, "[libsecp256k1] illegal argument: %s\n", str); @@ -162,7 +168,7 @@ secp256k1_context* secp256k1_context_clone(const secp256k1_context* ctx) { } void secp256k1_context_preallocated_destroy(secp256k1_context* ctx) { - CHECK(ctx != secp256k1_context_no_precomp); + ARG_CHECK_NO_RETURN(ctx != secp256k1_context_no_precomp); if (ctx != NULL) { secp256k1_ecmult_context_clear(&ctx->ecmult_ctx); secp256k1_ecmult_gen_context_clear(&ctx->ecmult_gen_ctx); @@ -177,7 +183,7 @@ void secp256k1_context_destroy(secp256k1_context* ctx) { } void secp256k1_context_set_illegal_callback(secp256k1_context* ctx, void (*fun)(const char* message, void* data), const void* data) { - CHECK(ctx != secp256k1_context_no_precomp); + ARG_CHECK_NO_RETURN(ctx != secp256k1_context_no_precomp); if (fun == NULL) { fun = default_illegal_callback_fn; } @@ -186,7 +192,7 @@ void secp256k1_context_set_illegal_callback(secp256k1_context* ctx, void (*fun)( } void secp256k1_context_set_error_callback(secp256k1_context* ctx, void (*fun)(const char* message, void* data), const void* data) { - CHECK(ctx != secp256k1_context_no_precomp); + ARG_CHECK_NO_RETURN(ctx != secp256k1_context_no_precomp); if (fun == NULL) { fun = default_error_callback_fn; } From 5db782e6556b7162d04cc2ae042d84ee9057369b Mon Sep 17 00:00:00 2001 From: Tim Ruffing Date: Mon, 4 Mar 2019 15:36:35 +0100 Subject: [PATCH 2/5] Allow usage of external default callbacks --- configure.ac | 42 ++++++++++++++++++++++++++---------------- include/secp256k1.h | 28 ++++++++++++++++++++++++---- src/secp256k1.c | 17 ++++++++++------- 3 files changed, 60 insertions(+), 27 deletions(-) diff --git a/configure.ac b/configure.ac index a4b08038e1204..b8340b7de13c7 100644 --- a/configure.ac +++ b/configure.ac @@ -134,6 +134,11 @@ AC_ARG_ENABLE(module_recovery, [enable_module_recovery=$enableval], [enable_module_recovery=no]) +AC_ARG_ENABLE(external_default_callbacks, + AS_HELP_STRING([--enable-external-default-callbacks],[enable external default callback functions (default is no)]), + [use_external_default_callbacks=$enableval], + [use_external_default_callbacks=no]) + AC_ARG_ENABLE(jni, AS_HELP_STRING([--enable-jni],[enable libsecp256k1_jni [default=no]]), [use_jni=$enableval], @@ -493,6 +498,10 @@ if test x"$use_external_asm" = x"yes"; then AC_DEFINE(USE_EXTERNAL_ASM, 1, [Define this symbol if an external (non-inline) assembly implementation is used]) fi +if test x"$use_external_default_callbacks" = x"yes"; then + AC_DEFINE(USE_EXTERNAL_DEFAULT_CALLBACKS, 1, [Define this symbol if an external implementation of the default callbacks is used]) +fi + if test x"$enable_experimental" = x"yes"; then AC_MSG_NOTICE([******]) AC_MSG_NOTICE([WARNING: experimental build]) @@ -535,22 +544,23 @@ AC_OUTPUT echo echo "Build Options:" -echo " with endomorphism = $use_endomorphism" -echo " with ecmult precomp = $set_precomp" -echo " with jni = $use_jni" -echo " with benchmarks = $use_benchmark" -echo " with coverage = $enable_coverage" -echo " module ecdh = $enable_module_ecdh" -echo " module recovery = $enable_module_recovery" +echo " with endomorphism = $use_endomorphism" +echo " with ecmult precomp = $set_precomp" +echo " with external callbacks = $use_external_default_callbacks" +echo " with jni = $use_jni" +echo " with benchmarks = $use_benchmark" +echo " with coverage = $enable_coverage" +echo " module ecdh = $enable_module_ecdh" +echo " module recovery = $enable_module_recovery" echo -echo " asm = $set_asm" -echo " bignum = $set_bignum" -echo " field = $set_field" -echo " scalar = $set_scalar" -echo " ecmult window size = $set_ecmult_window" +echo " asm = $set_asm" +echo " bignum = $set_bignum" +echo " field = $set_field" +echo " scalar = $set_scalar" +echo " ecmult window size = $set_ecmult_window" echo -echo " CC = $CC" -echo " CFLAGS = $CFLAGS" -echo " CPPFLAGS = $CPPFLAGS" -echo " LDFLAGS = $LDFLAGS" +echo " CC = $CC" +echo " CFLAGS = $CFLAGS" +echo " CPPFLAGS = $CPPFLAGS" +echo " LDFLAGS = $LDFLAGS" echo diff --git a/include/secp256k1.h b/include/secp256k1.h index 278ea6178fb7e..3e90b1bc7b967 100644 --- a/include/secp256k1.h +++ b/include/secp256k1.h @@ -247,11 +247,28 @@ SECP256K1_API void secp256k1_context_destroy( * to cause a crash, though its return value and output arguments are * undefined. * + * When this function has not been called (or called with fn==NULL), then the + * default handler will be used. The library provides a default handler which + * writes the message to stderr and calls abort. This default handler can be + * replaced at link time if the preprocessor macro + * USE_EXTERNAL_DEFAULT_CALLBACKS is defined, which is the case if the build + * has been configured with --enable-external-default-callbacks. Then the + * following two symbols must be provided to link against: + * - void secp256k1_default_illegal_callback_fn(const char* message, void* data); + * - void secp256k1_default_error_callback_fn(const char* message, void* data); + * The library can call these default handlers even before a proper callback data + * pointer could have been set using secp256k1_context_set_illegal_callback or + * secp256k1_context_set_illegal_callback, e.g., when the creation of a context + * fails. In this case, the corresponding default handler will be called with + * the data pointer argument set to NULL. + * * Args: ctx: an existing context object (cannot be NULL) * In: fun: a pointer to a function to call when an illegal argument is - * passed to the API, taking a message and an opaque pointer - * (NULL restores a default handler that calls abort). + * passed to the API, taking a message and an opaque pointer. + * (NULL restores the default handler.) * data: the opaque pointer to pass to fun above. + * + * See also secp256k1_context_set_error_callback. */ SECP256K1_API void secp256k1_context_set_illegal_callback( secp256k1_context* ctx, @@ -271,9 +288,12 @@ SECP256K1_API void secp256k1_context_set_illegal_callback( * * Args: ctx: an existing context object (cannot be NULL) * In: fun: a pointer to a function to call when an internal error occurs, - * taking a message and an opaque pointer (NULL restores a default - * handler that calls abort). + * taking a message and an opaque pointer (NULL restores the + * default handler, see secp256k1_context_set_illegal_callback + * for details). * data: the opaque pointer to pass to fun above. + * + * See also secp256k1_context_set_illegal_callback. */ SECP256K1_API void secp256k1_context_set_error_callback( secp256k1_context* ctx, diff --git a/src/secp256k1.c b/src/secp256k1.c index 077ca780d70c4..866c2e4936e96 100644 --- a/src/secp256k1.c +++ b/src/secp256k1.c @@ -33,29 +33,32 @@ } \ } while(0) +#ifndef USE_EXTERNAL_DEFAULT_CALLBACKS static void default_illegal_callback_fn(const char* str, void* data) { (void)data; fprintf(stderr, "[libsecp256k1] illegal argument: %s\n", str); abort(); } - -static const secp256k1_callback default_illegal_callback = { - default_illegal_callback_fn, - NULL -}; - static void default_error_callback_fn(const char* str, void* data) { (void)data; fprintf(stderr, "[libsecp256k1] internal consistency check failed: %s\n", str); abort(); } +#else +void default_illegal_callback_fn(const char* str, void* data); +void default_error_callback_fn(const char* str, void* data); +#endif + +static const secp256k1_callback default_illegal_callback = { + default_illegal_callback_fn, + NULL +}; static const secp256k1_callback default_error_callback = { default_error_callback_fn, NULL }; - struct secp256k1_context_struct { secp256k1_ecmult_context ecmult_ctx; secp256k1_ecmult_gen_context ecmult_gen_ctx; From 908bdce64ecb6fbee9d560e11143a19c5b3fa862 Mon Sep 17 00:00:00 2001 From: Tim Ruffing Date: Mon, 4 Mar 2019 16:11:35 +0100 Subject: [PATCH 3/5] Include stdio.h and stdlib.h explicitly in secp256k1.c --- src/secp256k1.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/secp256k1.c b/src/secp256k1.c index 866c2e4936e96..6a2e63c4d65b8 100644 --- a/src/secp256k1.c +++ b/src/secp256k1.c @@ -34,6 +34,8 @@ } while(0) #ifndef USE_EXTERNAL_DEFAULT_CALLBACKS +#include +#include static void default_illegal_callback_fn(const char* str, void* data) { (void)data; fprintf(stderr, "[libsecp256k1] illegal argument: %s\n", str); From 77defd2c3b2102a499856d1535d7069556cce843 Mon Sep 17 00:00:00 2001 From: Tim Ruffing Date: Sat, 9 Mar 2019 11:41:21 +0100 Subject: [PATCH 4/5] Add secp256k1_ prefix to default callback functions --- src/secp256k1.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/secp256k1.c b/src/secp256k1.c index 6a2e63c4d65b8..6954e1bcf7951 100644 --- a/src/secp256k1.c +++ b/src/secp256k1.c @@ -36,28 +36,28 @@ #ifndef USE_EXTERNAL_DEFAULT_CALLBACKS #include #include -static void default_illegal_callback_fn(const char* str, void* data) { +static void secp256k1_default_illegal_callback_fn(const char* str, void* data) { (void)data; fprintf(stderr, "[libsecp256k1] illegal argument: %s\n", str); abort(); } -static void default_error_callback_fn(const char* str, void* data) { +static void secp256k1_default_error_callback_fn(const char* str, void* data) { (void)data; fprintf(stderr, "[libsecp256k1] internal consistency check failed: %s\n", str); abort(); } #else -void default_illegal_callback_fn(const char* str, void* data); -void default_error_callback_fn(const char* str, void* data); +void secp256k1_default_illegal_callback_fn(const char* str, void* data); +void secp256k1_default_error_callback_fn(const char* str, void* data); #endif static const secp256k1_callback default_illegal_callback = { - default_illegal_callback_fn, + secp256k1_default_illegal_callback_fn, NULL }; static const secp256k1_callback default_error_callback = { - default_error_callback_fn, + secp256k1_default_error_callback_fn, NULL }; @@ -71,8 +71,8 @@ struct secp256k1_context_struct { static const secp256k1_context secp256k1_context_no_precomp_ = { { 0 }, { 0 }, - { default_illegal_callback_fn, 0 }, - { default_error_callback_fn, 0 } + { secp256k1_default_illegal_callback_fn, 0 }, + { secp256k1_default_error_callback_fn, 0 } }; const secp256k1_context *secp256k1_context_no_precomp = &secp256k1_context_no_precomp_; @@ -190,7 +190,7 @@ void secp256k1_context_destroy(secp256k1_context* ctx) { void secp256k1_context_set_illegal_callback(secp256k1_context* ctx, void (*fun)(const char* message, void* data), const void* data) { ARG_CHECK_NO_RETURN(ctx != secp256k1_context_no_precomp); if (fun == NULL) { - fun = default_illegal_callback_fn; + fun = secp256k1_default_illegal_callback_fn; } ctx->illegal_callback.fn = fun; ctx->illegal_callback.data = data; @@ -199,7 +199,7 @@ void secp256k1_context_set_illegal_callback(secp256k1_context* ctx, void (*fun)( void secp256k1_context_set_error_callback(secp256k1_context* ctx, void (*fun)(const char* message, void* data), const void* data) { ARG_CHECK_NO_RETURN(ctx != secp256k1_context_no_precomp); if (fun == NULL) { - fun = default_error_callback_fn; + fun = secp256k1_default_error_callback_fn; } ctx->error_callback.fn = fun; ctx->error_callback.data = data; From e49f7991c2619940f6c53b006b65fc8a6a554108 Mon Sep 17 00:00:00 2001 From: Tim Ruffing Date: Mon, 18 Mar 2019 16:20:07 +0100 Subject: [PATCH 5/5] Add missing #(un)defines to base-config.h --- src/basic-config.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/basic-config.h b/src/basic-config.h index 840cddc767c43..3a3969d3001d6 100644 --- a/src/basic-config.h +++ b/src/basic-config.h @@ -12,6 +12,8 @@ #undef USE_ASM_X86_64 #undef USE_ECMULT_STATIC_PRECOMPUTATION #undef USE_ENDOMORPHISM +#undef USE_EXTERNAL_ASM +#undef USE_EXTERNAL_DEFAULT_CALLBACKS #undef USE_FIELD_10X26 #undef USE_FIELD_5X52 #undef USE_FIELD_INV_BUILTIN