| 
									
										
										
										
											2019-07-11 05:11:27 +08:00
										 |  |  | /*
 | 
					
						
							| 
									
										
										
										
											2021-03-11 21:27:36 +08:00
										 |  |  |  * Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved. | 
					
						
							| 
									
										
										
										
											2019-07-11 05:11:27 +08:00
										 |  |  |  * | 
					
						
							|  |  |  |  * 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 | 
					
						
							|  |  |  |  * https://www.openssl.org/source/license.html
 | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <openssl/core.h>
 | 
					
						
							| 
									
										
										
										
											2020-06-21 07:21:19 +08:00
										 |  |  | #include <openssl/core_dispatch.h>
 | 
					
						
							| 
									
										
										
										
											2019-07-11 05:11:27 +08:00
										 |  |  | #include "internal/core.h"
 | 
					
						
							|  |  |  | #include "internal/property.h"
 | 
					
						
							|  |  |  | #include "internal/provider.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | struct algorithm_data_st { | 
					
						
							| 
									
										
										
										
											2020-10-15 17:55:50 +08:00
										 |  |  |     OSSL_LIB_CTX *libctx; | 
					
						
							| 
									
										
										
										
											2019-07-11 05:11:27 +08:00
										 |  |  |     int operation_id;            /* May be zero for finding them all */ | 
					
						
							| 
									
										
										
										
											2020-05-15 21:56:05 +08:00
										 |  |  |     int (*pre)(OSSL_PROVIDER *, int operation_id, void *data, int *result); | 
					
						
							| 
									
										
										
										
											2019-07-11 05:11:27 +08:00
										 |  |  |     void (*fn)(OSSL_PROVIDER *, const OSSL_ALGORITHM *, int no_store, | 
					
						
							|  |  |  |                void *data); | 
					
						
							| 
									
										
										
										
											2020-05-15 21:56:05 +08:00
										 |  |  |     int (*post)(OSSL_PROVIDER *, int operation_id, int no_store, void *data, | 
					
						
							|  |  |  |                 int *result); | 
					
						
							| 
									
										
										
										
											2019-07-11 05:11:27 +08:00
										 |  |  |     void *data; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int algorithm_do_this(OSSL_PROVIDER *provider, void *cbdata) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     struct algorithm_data_st *data = cbdata; | 
					
						
							|  |  |  |     int no_store = 0;    /* Assume caching is ok */ | 
					
						
							|  |  |  |     int first_operation = 1; | 
					
						
							|  |  |  |     int last_operation = OSSL_OP__HIGHEST; | 
					
						
							|  |  |  |     int cur_operation; | 
					
						
							| 
									
										
										
										
											2020-09-02 02:50:03 +08:00
										 |  |  |     int ok = 1; | 
					
						
							| 
									
										
										
										
											2019-07-11 05:11:27 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if (data->operation_id != 0) | 
					
						
							|  |  |  |         first_operation = last_operation = data->operation_id; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for (cur_operation = first_operation; | 
					
						
							|  |  |  |          cur_operation <= last_operation; | 
					
						
							|  |  |  |          cur_operation++) { | 
					
						
							| 
									
										
										
										
											2020-05-15 21:56:05 +08:00
										 |  |  |         const OSSL_ALGORITHM *map = NULL; | 
					
						
							|  |  |  |         int ret; | 
					
						
							| 
									
										
										
										
											2019-07-11 05:11:27 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-15 21:56:05 +08:00
										 |  |  |         /* Do we fulfill pre-conditions? */ | 
					
						
							|  |  |  |         if (data->pre == NULL) { | 
					
						
							|  |  |  |             /* If there is no pre-condition function, assume "yes" */ | 
					
						
							|  |  |  |             ret = 1; | 
					
						
							|  |  |  |         } else { | 
					
						
							|  |  |  |             if (!data->pre(provider, cur_operation, data->data, &ret)) | 
					
						
							|  |  |  |                 /* Error, bail out! */ | 
					
						
							|  |  |  |                 return 0; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         /* If pre-condition not fulfilled, go to the next operation */ | 
					
						
							|  |  |  |         if (!ret) | 
					
						
							|  |  |  |             continue; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         map = ossl_provider_query_operation(provider, cur_operation, | 
					
						
							|  |  |  |                                             &no_store); | 
					
						
							| 
									
										
										
										
											2020-07-03 20:12:54 +08:00
										 |  |  |         if (map != NULL) { | 
					
						
							|  |  |  |             while (map->algorithm_names != NULL) { | 
					
						
							|  |  |  |                 const OSSL_ALGORITHM *thismap = map++; | 
					
						
							| 
									
										
										
										
											2019-07-11 05:11:27 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-03 20:12:54 +08:00
										 |  |  |                 data->fn(provider, thismap, no_store, data->data); | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2019-07-11 05:11:27 +08:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2020-09-25 08:19:19 +08:00
										 |  |  |         ossl_provider_unquery_operation(provider, cur_operation, map); | 
					
						
							| 
									
										
										
										
											2020-05-15 21:56:05 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |         /* Do we fulfill post-conditions? */ | 
					
						
							|  |  |  |         if (data->post == NULL) { | 
					
						
							|  |  |  |             /* If there is no post-condition function, assume "yes" */ | 
					
						
							|  |  |  |             ret = 1; | 
					
						
							|  |  |  |         } else { | 
					
						
							|  |  |  |             if (!data->post(provider, cur_operation, no_store, data->data, | 
					
						
							|  |  |  |                             &ret)) | 
					
						
							|  |  |  |                 /* Error, bail out! */ | 
					
						
							|  |  |  |                 return 0; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-02 02:50:03 +08:00
										 |  |  |         /* If post-condition not fulfilled, set general failure */ | 
					
						
							|  |  |  |         if (!ret) | 
					
						
							|  |  |  |             ok = 0; | 
					
						
							| 
									
										
										
										
											2019-07-11 05:11:27 +08:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return ok; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-15 17:55:50 +08:00
										 |  |  | void ossl_algorithm_do_all(OSSL_LIB_CTX *libctx, int operation_id, | 
					
						
							| 
									
										
										
										
											2019-07-11 05:11:27 +08:00
										 |  |  |                            OSSL_PROVIDER *provider, | 
					
						
							| 
									
										
										
										
											2020-05-15 21:56:05 +08:00
										 |  |  |                            int (*pre)(OSSL_PROVIDER *, int operation_id, | 
					
						
							|  |  |  |                                       void *data, int *result), | 
					
						
							| 
									
										
										
										
											2019-07-11 05:11:27 +08:00
										 |  |  |                            void (*fn)(OSSL_PROVIDER *provider, | 
					
						
							|  |  |  |                                       const OSSL_ALGORITHM *algo, | 
					
						
							|  |  |  |                                       int no_store, void *data), | 
					
						
							| 
									
										
										
										
											2020-05-15 21:56:05 +08:00
										 |  |  |                            int (*post)(OSSL_PROVIDER *, int operation_id, | 
					
						
							|  |  |  |                                        int no_store, void *data, int *result), | 
					
						
							| 
									
										
										
										
											2019-07-11 05:11:27 +08:00
										 |  |  |                            void *data) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2020-05-15 21:56:05 +08:00
										 |  |  |     struct algorithm_data_st cbdata = { 0, }; | 
					
						
							| 
									
										
										
										
											2019-07-11 05:11:27 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     cbdata.libctx = libctx; | 
					
						
							|  |  |  |     cbdata.operation_id = operation_id; | 
					
						
							| 
									
										
										
										
											2020-05-15 21:56:05 +08:00
										 |  |  |     cbdata.pre = pre; | 
					
						
							| 
									
										
										
										
											2019-07-11 05:11:27 +08:00
										 |  |  |     cbdata.fn = fn; | 
					
						
							| 
									
										
										
										
											2020-05-15 21:56:05 +08:00
										 |  |  |     cbdata.post = post; | 
					
						
							| 
									
										
										
										
											2019-07-11 05:11:27 +08:00
										 |  |  |     cbdata.data = data; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (provider == NULL) | 
					
						
							| 
									
										
										
										
											2021-03-10 17:37:02 +08:00
										 |  |  |         ossl_provider_doall_activated(libctx, algorithm_do_this, &cbdata); | 
					
						
							| 
									
										
										
										
											2019-07-11 05:11:27 +08:00
										 |  |  |     else | 
					
						
							|  |  |  |         algorithm_do_this(provider, &cbdata); | 
					
						
							|  |  |  | } |