Richard Levitte | a883c02 | 2019-07-10 23:11:27 +0200 | [diff] [blame] | 1 | /* |
Matt Caswell | 8020d79 | 2021-03-11 13:27:36 +0000 | [diff] [blame] | 2 | * Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved. |
Richard Levitte | a883c02 | 2019-07-10 23:11:27 +0200 | [diff] [blame] | 3 | * |
| 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 |
| 8 | */ |
| 9 | |
| 10 | #include <openssl/core.h> |
Dr. Matthias St. Pierre | 23c48d9 | 2020-06-21 01:21:19 +0200 | [diff] [blame] | 11 | #include <openssl/core_dispatch.h> |
Richard Levitte | a883c02 | 2019-07-10 23:11:27 +0200 | [diff] [blame] | 12 | #include "internal/core.h" |
| 13 | #include "internal/property.h" |
| 14 | #include "internal/provider.h" |
| 15 | |
| 16 | struct algorithm_data_st { |
Dr. Matthias St. Pierre | b425001 | 2020-10-15 12:55:50 +0300 | [diff] [blame] | 17 | OSSL_LIB_CTX *libctx; |
Richard Levitte | a883c02 | 2019-07-10 23:11:27 +0200 | [diff] [blame] | 18 | int operation_id; /* May be zero for finding them all */ |
Richard Levitte | 5a29b62 | 2020-05-15 15:56:05 +0200 | [diff] [blame] | 19 | int (*pre)(OSSL_PROVIDER *, int operation_id, void *data, int *result); |
Richard Levitte | a883c02 | 2019-07-10 23:11:27 +0200 | [diff] [blame] | 20 | void (*fn)(OSSL_PROVIDER *, const OSSL_ALGORITHM *, int no_store, |
| 21 | void *data); |
Richard Levitte | 5a29b62 | 2020-05-15 15:56:05 +0200 | [diff] [blame] | 22 | int (*post)(OSSL_PROVIDER *, int operation_id, int no_store, void *data, |
| 23 | int *result); |
Richard Levitte | a883c02 | 2019-07-10 23:11:27 +0200 | [diff] [blame] | 24 | void *data; |
| 25 | }; |
| 26 | |
| 27 | static int algorithm_do_this(OSSL_PROVIDER *provider, void *cbdata) |
| 28 | { |
| 29 | struct algorithm_data_st *data = cbdata; |
| 30 | int no_store = 0; /* Assume caching is ok */ |
| 31 | int first_operation = 1; |
| 32 | int last_operation = OSSL_OP__HIGHEST; |
| 33 | int cur_operation; |
Todd Short | 1010e4a | 2020-09-01 14:50:03 -0400 | [diff] [blame] | 34 | int ok = 1; |
Richard Levitte | a883c02 | 2019-07-10 23:11:27 +0200 | [diff] [blame] | 35 | |
| 36 | if (data->operation_id != 0) |
| 37 | first_operation = last_operation = data->operation_id; |
| 38 | |
| 39 | for (cur_operation = first_operation; |
| 40 | cur_operation <= last_operation; |
| 41 | cur_operation++) { |
Richard Levitte | 5a29b62 | 2020-05-15 15:56:05 +0200 | [diff] [blame] | 42 | const OSSL_ALGORITHM *map = NULL; |
| 43 | int ret; |
Richard Levitte | a883c02 | 2019-07-10 23:11:27 +0200 | [diff] [blame] | 44 | |
Richard Levitte | 5a29b62 | 2020-05-15 15:56:05 +0200 | [diff] [blame] | 45 | /* Do we fulfill pre-conditions? */ |
| 46 | if (data->pre == NULL) { |
| 47 | /* If there is no pre-condition function, assume "yes" */ |
| 48 | ret = 1; |
| 49 | } else { |
| 50 | if (!data->pre(provider, cur_operation, data->data, &ret)) |
| 51 | /* Error, bail out! */ |
| 52 | return 0; |
| 53 | } |
| 54 | |
| 55 | /* If pre-condition not fulfilled, go to the next operation */ |
| 56 | if (!ret) |
| 57 | continue; |
| 58 | |
| 59 | map = ossl_provider_query_operation(provider, cur_operation, |
| 60 | &no_store); |
Richard Levitte | dd76b90 | 2020-07-03 14:12:54 +0200 | [diff] [blame] | 61 | if (map != NULL) { |
Petr Gotthard | d7970dd | 2021-05-15 23:29:34 +0200 | [diff] [blame] | 62 | const OSSL_ALGORITHM *thismap; |
Richard Levitte | a883c02 | 2019-07-10 23:11:27 +0200 | [diff] [blame] | 63 | |
Petr Gotthard | d7970dd | 2021-05-15 23:29:34 +0200 | [diff] [blame] | 64 | for (thismap = map; thismap->algorithm_names != NULL; thismap++) |
Richard Levitte | dd76b90 | 2020-07-03 14:12:54 +0200 | [diff] [blame] | 65 | data->fn(provider, thismap, no_store, data->data); |
Richard Levitte | a883c02 | 2019-07-10 23:11:27 +0200 | [diff] [blame] | 66 | } |
Pauli | b0001d0 | 2020-09-25 10:19:19 +1000 | [diff] [blame] | 67 | ossl_provider_unquery_operation(provider, cur_operation, map); |
Richard Levitte | 5a29b62 | 2020-05-15 15:56:05 +0200 | [diff] [blame] | 68 | |
| 69 | /* Do we fulfill post-conditions? */ |
| 70 | if (data->post == NULL) { |
| 71 | /* If there is no post-condition function, assume "yes" */ |
| 72 | ret = 1; |
| 73 | } else { |
| 74 | if (!data->post(provider, cur_operation, no_store, data->data, |
| 75 | &ret)) |
| 76 | /* Error, bail out! */ |
| 77 | return 0; |
| 78 | } |
| 79 | |
Todd Short | 1010e4a | 2020-09-01 14:50:03 -0400 | [diff] [blame] | 80 | /* If post-condition not fulfilled, set general failure */ |
| 81 | if (!ret) |
| 82 | ok = 0; |
Richard Levitte | a883c02 | 2019-07-10 23:11:27 +0200 | [diff] [blame] | 83 | } |
| 84 | |
| 85 | return ok; |
| 86 | } |
| 87 | |
Dr. Matthias St. Pierre | b425001 | 2020-10-15 12:55:50 +0300 | [diff] [blame] | 88 | void ossl_algorithm_do_all(OSSL_LIB_CTX *libctx, int operation_id, |
Richard Levitte | a883c02 | 2019-07-10 23:11:27 +0200 | [diff] [blame] | 89 | OSSL_PROVIDER *provider, |
Richard Levitte | 5a29b62 | 2020-05-15 15:56:05 +0200 | [diff] [blame] | 90 | int (*pre)(OSSL_PROVIDER *, int operation_id, |
| 91 | void *data, int *result), |
Richard Levitte | a883c02 | 2019-07-10 23:11:27 +0200 | [diff] [blame] | 92 | void (*fn)(OSSL_PROVIDER *provider, |
| 93 | const OSSL_ALGORITHM *algo, |
| 94 | int no_store, void *data), |
Richard Levitte | 5a29b62 | 2020-05-15 15:56:05 +0200 | [diff] [blame] | 95 | int (*post)(OSSL_PROVIDER *, int operation_id, |
| 96 | int no_store, void *data, int *result), |
Richard Levitte | a883c02 | 2019-07-10 23:11:27 +0200 | [diff] [blame] | 97 | void *data) |
| 98 | { |
Richard Levitte | 5a29b62 | 2020-05-15 15:56:05 +0200 | [diff] [blame] | 99 | struct algorithm_data_st cbdata = { 0, }; |
Richard Levitte | a883c02 | 2019-07-10 23:11:27 +0200 | [diff] [blame] | 100 | |
| 101 | cbdata.libctx = libctx; |
| 102 | cbdata.operation_id = operation_id; |
Richard Levitte | 5a29b62 | 2020-05-15 15:56:05 +0200 | [diff] [blame] | 103 | cbdata.pre = pre; |
Richard Levitte | a883c02 | 2019-07-10 23:11:27 +0200 | [diff] [blame] | 104 | cbdata.fn = fn; |
Richard Levitte | 5a29b62 | 2020-05-15 15:56:05 +0200 | [diff] [blame] | 105 | cbdata.post = post; |
Richard Levitte | a883c02 | 2019-07-10 23:11:27 +0200 | [diff] [blame] | 106 | cbdata.data = data; |
| 107 | |
Richard Levitte | cfce50f | 2021-09-30 09:32:57 +0200 | [diff] [blame] | 108 | if (provider == NULL) { |
Pauli | 8f08957 | 2021-03-10 19:37:02 +1000 | [diff] [blame] | 109 | ossl_provider_doall_activated(libctx, algorithm_do_this, &cbdata); |
Richard Levitte | cfce50f | 2021-09-30 09:32:57 +0200 | [diff] [blame] | 110 | } else { |
| 111 | OSSL_LIB_CTX *libctx2 = ossl_provider_libctx(provider); |
| 112 | |
| 113 | /* |
| 114 | * If a provider is given, its library context MUST match the library |
| 115 | * context we're passed. If this turns out not to be true, there is |
| 116 | * a programming error in the functions up the call stack. |
| 117 | */ |
| 118 | if (!ossl_assert(ossl_lib_ctx_get_concrete(libctx) |
| 119 | == ossl_lib_ctx_get_concrete(libctx2))) |
| 120 | return; |
| 121 | |
| 122 | cbdata.libctx = libctx2; |
Richard Levitte | a883c02 | 2019-07-10 23:11:27 +0200 | [diff] [blame] | 123 | algorithm_do_this(provider, &cbdata); |
Richard Levitte | cfce50f | 2021-09-30 09:32:57 +0200 | [diff] [blame] | 124 | } |
Richard Levitte | a883c02 | 2019-07-10 23:11:27 +0200 | [diff] [blame] | 125 | } |
Tomas Mraz | 6c9bc25 | 2021-04-16 16:22:03 +0200 | [diff] [blame] | 126 | |
| 127 | char *ossl_algorithm_get1_first_name(const OSSL_ALGORITHM *algo) |
| 128 | { |
| 129 | const char *first_name_end = NULL; |
| 130 | size_t first_name_len = 0; |
| 131 | char *ret; |
| 132 | |
| 133 | if (algo->algorithm_names == NULL) |
| 134 | return NULL; |
| 135 | |
| 136 | first_name_end = strchr(algo->algorithm_names, ':'); |
| 137 | if (first_name_end == NULL) |
| 138 | first_name_len = strlen(algo->algorithm_names); |
| 139 | else |
| 140 | first_name_len = first_name_end - algo->algorithm_names; |
| 141 | |
| 142 | ret = OPENSSL_strndup(algo->algorithm_names, first_name_len); |
| 143 | if (ret == NULL) |
| 144 | ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); |
| 145 | return ret; |
| 146 | } |