Latest update

This commit is contained in:
2019-04-01 00:21:15 +09:00
parent c03e0c45f8
commit 48ec086472
209 changed files with 7552 additions and 2495 deletions
+232
View File
@@ -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
+13 -1
View File
@@ -49,6 +49,11 @@ functions given by the sub-system specific method creator through
C<mcm> and the data in C<mcm_data> (which is passed by
ossl_method_construct()).
This function assumes that the sub-system method creator implements
reference counting and acts accordingly (i.e. it will call the
sub-system destruct() method to decrement the reference count when
appropriate).
=head2 Structures
A central part of constructing a sub-system specific method is to give
@@ -82,6 +87,8 @@ The method to be looked up should be identified with data from C<data>
(which is the C<mcm_data> that was passed to ossl_construct_method())
and the provided property query C<propquery>.
This function is expected to increment the method's reference count.
=item put()
Places the C<method> created by the construct() function (see below)
@@ -96,6 +103,8 @@ The method should be associated with the given property definition
C<propdef> and any identification data given through C<data> (which is
the C<mcm_data> that was passed to ossl_construct_method()).
This function is expected to increment the C<method>'s reference count.
=item construct()
Constructs a sub-system method given a dispatch table C<fns>.
@@ -106,9 +115,12 @@ is recommended.
If such a reference is kept, the I<provider object> reference counter
must be incremented, using ossl_provider_upref().
This function is expected to set the method's reference count to 1.
=item desctruct()
Destruct the given C<method>.
Decrement the C<method>'s reference count, and destruct it when
the reference count reaches zero.
=back
+18 -8
View File
@@ -4,7 +4,8 @@
ossl_provider_find, ossl_provider_new, ossl_provider_upref,
ossl_provider_free, ossl_provider_add_module_location,
ossl_provider_activate, ossl_provider_forall_loaded,
ossl_provider_set_fallback, ossl_provider_activate,
ossl_provider_forall_loaded,
ossl_provider_name, ossl_provider_dso,
ossl_provider_module_name, ossl_provider_module_path,
ossl_provider_teardown, ossl_provider_get_param_types,
@@ -23,6 +24,7 @@ ossl_provider_get_params, ossl_provider_query_operation
/* Setters */
int ossl_provider_add_module_location(OSSL_PROVIDER *prov, const char *loc);
int ossl_provider_set_fallback(OSSL_PROVIDER *prov);
/* Load and initialize the Provider */
int ossl_provider_activate(OSSL_PROVIDER *prov);
@@ -71,7 +73,7 @@ times as ossl_provider_activate() has.
ossl_provider_find() finds an existing I<provider object> in the
I<provider object> store by C<name>.
The I<provider object> it finds gets it's reference count
The I<provider object> it finds gets its reference count
incremented.
ossl_provider_new() creates a new I<provider object> and stores it in
@@ -84,14 +86,20 @@ To indicate a built-in provider, the C<init_function> argument must
point at the provider initialization function for that provider.
ossl_provider_free() decrements a I<provider object>'s reference
counter; if it drops to one, the I<provider object> will be
inactivated (it's teardown function is called) but kept in the store;
if it drops down to zero, the associated module will be unloaded if
one was loaded, and the I<provider object> will be freed.
counter; if it drops below 2, the I<provider object> is assumed to
have fallen out of use and will be inactivated (its teardown function
is called); if it drops down to zero, the I<provider object> is
assumed to have been taken out of the store, and the associated module
will be unloaded if one was loaded, and the I<provider object> will be
freed.
ossl_provider_add_module_location() adds a location to look for a
provider module.
ossl_provider_set_fallback() marks an available provider as fallback.
Note that after this call, the I<provider object> pointer that was
used can simply be dropped, but not freed.
ossl_provider_activate() "activates" the provider for the given
I<provider object>.
What "activates" means depends on what type of I<provider object> it
@@ -115,6 +123,8 @@ be located in that module, and called.
ossl_provider_forall_loaded() iterates over all the currently
"activated" providers, and calls C<cb> for each of them.
If no providers have been "activated" yet, it tries to activate all
available fallback providers and tries another iteration.
ossl_provider_name() returns the name that was given with
ossl_provider_new().
@@ -178,8 +188,8 @@ it has been incremented.
ossl_provider_free() doesn't return any value.
ossl_provider_add_module_location() and ossl_provider_activate()
return 1 on success, or 0 on error.
ossl_provider_add_module_location(), ossl_provider_set_fallback() and
ossl_provider_activate() return 1 on success, or 0 on error.
ossl_provider_name(), ossl_provider_dso(),
ossl_provider_module_name(), and ossl_provider_module_path() return a