diff options
author | Richard Levitte <levitte@openssl.org> | 2019-02-08 17:01:56 +0100 |
---|---|---|
committer | Richard Levitte <levitte@openssl.org> | 2019-03-18 14:27:02 +0100 |
commit | c13d2ab439a9dcbbf22ef85a00603142b0a37779 (patch) | |
tree | 626fc5adbbc472ef6053da0ac08c4409e519bc16 /doc/internal | |
parent | a383083194b882a904ae66fcf74ebc348602407c (diff) | |
download | openssl-c13d2ab439a9dcbbf22ef85a00603142b0a37779.tar.gz |
Add generic EVP method fetcher
This is an interface between Core dispatch table fetching and
EVP_{method}_fetch(). All that's needed from the diverse method
fetchers are the functions to create a method structure from a
dispatch table, a function that ups the method reference counter and a
function to free the method (in case of failure).
This routine is internal to the EVP API andis therefore only made
accessible within crypto/evp, by including evp_locl.h
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/8341)
Diffstat (limited to 'doc/internal')
-rw-r--r-- | doc/internal/man3/evp_generic_fetch.pod | 232 |
1 files changed, 232 insertions, 0 deletions
diff --git a/doc/internal/man3/evp_generic_fetch.pod b/doc/internal/man3/evp_generic_fetch.pod new file mode 100644 index 0000000000..b871cd1fee --- /dev/null +++ b/doc/internal/man3/evp_generic_fetch.pod @@ -0,0 +1,232 @@ +=pod + +=head1 NAME + +evp_generic_fetch - generic algorithm fetcher and method creator for EVP + +=head1 SYNOPSIS + + /* Only for EVP source */ + #include "evp_locl.h" + + void *evp_generic_fetch(OPENSSL_CTX *libctx, int operation_id, + const char *algorithm, const char *properties, + void *(*new_method)(int nid, const OSSL_DISPATCH *fns, + OSSL_PROVIDER *prov), + int (*upref_method)(void *), + void (*free_method)(void *)); + +=head1 DESCRIPTION + +evp_generic_fetch() calls ossl_method_construct() with the given +C<libctx>, C<operation_id>, C<algorithm>, and C<properties> and uses +it to create an EVP method with the help of the functions +C<new_method>, C<upref_method>, and C<free_method>. + +The three functions are supposed to: + +=over 4 + +=item new_method() + +creates an internal method from function pointers found in the +dispatch table C<fns>. + +=item upref_method() + +increments the reference counter for the given method, if there is +one. + +=item free_method() + +frees the given method. + +=back + +=head1 RETURN VALUES + +evp_generic_fetch() returns a method on success, or B<NULL> on error. + +=head1 EXAMPLES + +This is a short example of the fictitious EVP API and operation called +C<EVP_FOO>. + +To begin with, let's assume something like this in +C<include/openssl/core_numbers.h>: + + #define OSSL_OP_FOO 100 + + #define OSSL_OP_FOO_NEWCTX_FUNC 2001 + #define OSSL_OP_FOO_INIT 2002 + #define OSSL_OP_FOO_OPERATE 2003 + #define OSSL_OP_FOO_CLEANCTX_FUNC 2004 + #define OSSL_OP_FOO_FREECTX_FUNC 2005 + OSSL_CORE_MAKE_FUNC(void *,OP_foo_newctx,(void)) + OSSL_CORE_MAKE_FUNC(int,OP_foo_init,(void *vctx)) + OSSL_CORE_MAKE_FUNC(int,OP_foo_operate,(void *vctx, + unsigned char *out, size_t *out_l, + unsigned char *in, size_t in_l)) + OSSL_CORE_MAKE_FUNC(void,OP_foo_cleanctx,(void *vctx)) + OSSL_CORE_MAKE_FUNC(void,OP_foo_freectx,(void *vctx)) + +And here's the implementation of the FOO method fetcher: + + /* typedef struct evp_foo_st EVP_FOO */ + struct evp_foo_st { + OSSL_PROVIDER *prov; + int nid; + CRYPTO_REF_COUNT refcnt; + OSSL_OP_foo_newctx_fn *newctx; + OSSL_OP_foo_init_fn *init; + OSSL_OP_foo_operate_fn *operate; + OSSL_OP_foo_cleanctx_fn *cleanctx; + OSSL_OP_foo_freectx_fn *freectx; + }; + + /* + * In this example, we have a public method creator and destructor. + * It's not absolutely necessary, but is in the spirit of OpenSSL. + */ + EVP_FOO *EVP_FOO_meth_from_dispatch(int foo_type, const OSSL_DISPATCH *fns, + OSSL_PROVIDER *prov) + { + EVP_FOO *foo = NULL; + + if ((foo = OPENSSL_zalloc(sizeof(*foo))) == NULL) + return NULL; + + for (; fns->function_id != 0; fns++) { + switch (fns->function_id) { + case OSSL_OP_FOO_NEWCTX_FUNC: + foo->newctx = OSSL_get_OP_foo_newctx(fns); + break; + case OSSL_OP_FOO_INIT: + foo->init = OSSL_get_OP_foo_init(fns); + break; + case OSSL_OP_FOO_OPERATE: + foo->operate = OSSL_get_OP_foo_operate(fns); + break; + case OSSL_OP_FOO_CLEANCTX_FUNC: + foo->cleanctx = OSSL_get_OP_foo_cleanctx(fns); + break; + case OSSL_OP_FOO_FREECTX_FUNC: + foo->freectx = OSSL_get_OP_foo_freectx(fns); + break; + } + } + foo->nid = foo_type; + foo->prov = prov; + if (prov) + ossl_provider_upref(prov); + + return foo; + } + + EVP_FOO_meth_free(EVP_FOO *foo) + { + if (foo != NULL) { + OSSL_PROVIDER *prov = foo->prov; + + OPENSSL_free(foo); + ossl_provider_free(prov); + } + } + + static void *foo_from_dispatch(int nid, const OSSL_DISPATCH *fns, + OSSL_PROVIDER *prov) + { + return EVP_FOO_meth_from_dispatch(nid, fns, prov); + } + + static int foo_upref(void *vfoo) + { + EVP_FOO *foo = vfoo; + int ref = 0; + + CRYPTO_UP_REF(&foo->refcnt, &ref, foo_lock); + return 1; + } + + static void foo_free(void *vfoo) + { + EVP_FOO_meth_free(vfoo); + } + + EVP_FOO *EVP_FOO_fetch(OPENSSL_CTX *ctx, + const char *algorithm, + const char *properties) + { + return evp_generic_fetch(ctx, OSSL_OP_FOO, algorithm, properties, + foo_from_dispatch, foo_upref, foo_free); + } + +And finally, the library functions: + + /* typedef struct evp_foo_st EVP_FOO_CTX */ + struct evp_foo_ctx_st { + const EVP_FOO *foo; + void *provctx; /* corresponding provider context */ + }; + + int EVP_FOO_CTX_reset(EVP_FOO_CTX *c) + { + if (c == NULL) + return 1; + if (c->foo != NULL && c->foo->cleanctx != NULL) + c->foo->cleanctx(c->provctx); + return 1; + } + + EVP_FOO_CTX *EVP_FOO_CTX_new(void) + { + return OPENSSL_zalloc(sizeof(EVP_FOO_CTX)); + } + + void EVP_FOO_CTX_free(EVP_FOO_CTX *c) + { + EVP_FOO_CTX_reset(c); + c->foo->freectx(c->provctx); + OPENSSL_free(c); + } + + int EVP_FooInit(EVP_FOO_CTX *c, const EVP_FOO *foo) + { + int ok = 1; + + c->foo = foo; + if (c->provctx == NULL) + c->provctx = c->foo->newctx(); + + ok = c->foo->init(c->provctx); + + return ok; + } + + int EVP_FooOperate(EVP_FOO_CTX *c, unsigned char *out, size_t *outl, + const unsigned char *in, size_t inl) + { + int ok = 1; + + ok = c->foo->update(c->provctx, out, inl, &outl, in, inl); + return ok; + } + +=head1 SEE ALSO + +L<ossl_method_construct> + +=head1 HISTORY + +The functions described here were all added in OpenSSL 3.0. + +=head1 COPYRIGHT + +Copyright 2019 The OpenSSL Project Authors. All Rights Reserved. + +Licensed under the Apache License 2.0 (the "License"). You may not use +this file except in compliance with the License. You can obtain a copy +in the file LICENSE in the source distribution or at +L<https://www.openssl.org/source/license.html>. + +=cut |