aboutsummaryrefslogtreecommitdiffstats
path: root/doc/internal
diff options
context:
space:
mode:
authorRichard Levitte <levitte@openssl.org>2019-02-08 17:01:56 +0100
committerRichard Levitte <levitte@openssl.org>2019-03-18 14:27:02 +0100
commitc13d2ab439a9dcbbf22ef85a00603142b0a37779 (patch)
tree626fc5adbbc472ef6053da0ac08c4409e519bc16 /doc/internal
parenta383083194b882a904ae66fcf74ebc348602407c (diff)
downloadopenssl-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.pod232
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