]>
git.ipfire.org Git - thirdparty/openssl.git/blob - crypto/core_algorithm.c
2 * Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved.
4 * Licensed under the Apache License 2.0 (the "License"). You may not use
5 * this file except in compliance with the License. You can obtain a copy
6 * in the file LICENSE in the source distribution or at
7 * https://www.openssl.org/source/license.html
10 #include <openssl/core.h>
11 #include <openssl/core_dispatch.h>
12 #include "internal/core.h"
13 #include "internal/property.h"
14 #include "internal/provider.h"
16 struct algorithm_data_st
{
18 int operation_id
; /* May be zero for finding them all */
19 int (*pre
)(OSSL_PROVIDER
*, int operation_id
, int no_store
, void *data
,
21 int (*reserve_store
)(int no_store
, void *data
);
22 void (*fn
)(OSSL_PROVIDER
*, const OSSL_ALGORITHM
*, int no_store
,
24 int (*unreserve_store
)(void *data
);
25 int (*post
)(OSSL_PROVIDER
*, int operation_id
, int no_store
, void *data
,
31 * Process one OSSL_ALGORITHM array, for the operation |cur_operation|,
32 * by constructing methods for all its implementations and adding those
33 * to the appropriate method store.
34 * Which method store is appropriate is given by |no_store| ("permanent"
35 * if 0, temporary if 1) and other data in |data->data|.
38 * -1 to quit adding algorithm implementations immediately
39 * 0 if not successful, but adding should continue
40 * 1 if successful so far, and adding should continue
42 static int algorithm_do_map(OSSL_PROVIDER
*provider
, const OSSL_ALGORITHM
*map
,
43 int cur_operation
, int no_store
, void *cbdata
)
45 struct algorithm_data_st
*data
= cbdata
;
48 if (!data
->reserve_store(no_store
, data
->data
))
49 /* Error, bail out! */
52 /* Do we fulfill pre-conditions? */
53 if (data
->pre
== NULL
) {
54 /* If there is no pre-condition function, assume "yes" */
56 } else if (!data
->pre(provider
, cur_operation
, no_store
, data
->data
,
58 /* Error, bail out! */
64 * If pre-condition not fulfilled don't add this set of implementations,
65 * but do continue with the next. This simply means that another thread
74 const OSSL_ALGORITHM
*thismap
;
76 for (thismap
= map
; thismap
->algorithm_names
!= NULL
; thismap
++)
77 data
->fn(provider
, thismap
, no_store
, data
->data
);
80 /* Do we fulfill post-conditions? */
81 if (data
->post
== NULL
) {
82 /* If there is no post-condition function, assume "yes" */
84 } else if (!data
->post(provider
, cur_operation
, no_store
, data
->data
,
86 /* Error, bail out! */
91 data
->unreserve_store(data
->data
);
97 * Given a provider, process one operation given by |data->operation_id|, or
98 * if that's zero, process all known operations.
99 * For each such operation, query the associated OSSL_ALGORITHM array from
100 * the provider, then process that array with |algorithm_do_map()|.
102 static int algorithm_do_this(OSSL_PROVIDER
*provider
, void *cbdata
)
104 struct algorithm_data_st
*data
= cbdata
;
105 int first_operation
= 1;
106 int last_operation
= OSSL_OP__HIGHEST
;
110 if (data
->operation_id
!= 0)
111 first_operation
= last_operation
= data
->operation_id
;
113 for (cur_operation
= first_operation
;
114 cur_operation
<= last_operation
;
116 int no_store
= 0; /* Assume caching is ok */
117 const OSSL_ALGORITHM
*map
= NULL
;
120 map
= ossl_provider_query_operation(provider
, cur_operation
,
122 ret
= algorithm_do_map(provider
, map
, cur_operation
, no_store
, data
);
123 ossl_provider_unquery_operation(provider
, cur_operation
, map
);
126 /* Hard error, bail out immediately! */
129 /* If post-condition not fulfilled, set general failure */
137 void ossl_algorithm_do_all(OSSL_LIB_CTX
*libctx
, int operation_id
,
138 OSSL_PROVIDER
*provider
,
139 int (*pre
)(OSSL_PROVIDER
*, int operation_id
,
140 int no_store
, void *data
, int *result
),
141 int (*reserve_store
)(int no_store
, void *data
),
142 void (*fn
)(OSSL_PROVIDER
*provider
,
143 const OSSL_ALGORITHM
*algo
,
144 int no_store
, void *data
),
145 int (*unreserve_store
)(void *data
),
146 int (*post
)(OSSL_PROVIDER
*, int operation_id
,
147 int no_store
, void *data
, int *result
),
150 struct algorithm_data_st cbdata
= { 0, };
152 cbdata
.libctx
= libctx
;
153 cbdata
.operation_id
= operation_id
;
155 cbdata
.reserve_store
= reserve_store
;
157 cbdata
.unreserve_store
= unreserve_store
;
161 if (provider
== NULL
) {
162 ossl_provider_doall_activated(libctx
, algorithm_do_this
, &cbdata
);
164 OSSL_LIB_CTX
*libctx2
= ossl_provider_libctx(provider
);
167 * If a provider is given, its library context MUST match the library
168 * context we're passed. If this turns out not to be true, there is
169 * a programming error in the functions up the call stack.
171 if (!ossl_assert(ossl_lib_ctx_get_concrete(libctx
)
172 == ossl_lib_ctx_get_concrete(libctx2
)))
175 cbdata
.libctx
= libctx2
;
176 algorithm_do_this(provider
, &cbdata
);
180 char *ossl_algorithm_get1_first_name(const OSSL_ALGORITHM
*algo
)
182 const char *first_name_end
= NULL
;
183 size_t first_name_len
= 0;
186 if (algo
->algorithm_names
== NULL
)
189 first_name_end
= strchr(algo
->algorithm_names
, ':');
190 if (first_name_end
== NULL
)
191 first_name_len
= strlen(algo
->algorithm_names
);
193 first_name_len
= first_name_end
- algo
->algorithm_names
;
195 ret
= OPENSSL_strndup(algo
->algorithm_names
, first_name_len
);
197 ERR_raise(ERR_LIB_EVP
, ERR_R_MALLOC_FAILURE
);