1e1051a39Sopenharmony_ci/*
2e1051a39Sopenharmony_ci * Copyright 2001-2021 The OpenSSL Project Authors. All Rights Reserved.
3e1051a39Sopenharmony_ci *
4e1051a39Sopenharmony_ci * Licensed under the Apache License 2.0 (the "License").  You may not use
5e1051a39Sopenharmony_ci * this file except in compliance with the License.  You can obtain a copy
6e1051a39Sopenharmony_ci * in the file LICENSE in the source distribution or at
7e1051a39Sopenharmony_ci * https://www.openssl.org/source/license.html
8e1051a39Sopenharmony_ci */
9e1051a39Sopenharmony_ci
10e1051a39Sopenharmony_ci/* We need to use some engine deprecated APIs */
11e1051a39Sopenharmony_ci#define OPENSSL_SUPPRESS_DEPRECATED
12e1051a39Sopenharmony_ci
13e1051a39Sopenharmony_ci#include "eng_local.h"
14e1051a39Sopenharmony_ci
15e1051a39Sopenharmony_cistatic ENGINE_TABLE *cipher_table = NULL;
16e1051a39Sopenharmony_ci
17e1051a39Sopenharmony_civoid ENGINE_unregister_ciphers(ENGINE *e)
18e1051a39Sopenharmony_ci{
19e1051a39Sopenharmony_ci    engine_table_unregister(&cipher_table, e);
20e1051a39Sopenharmony_ci}
21e1051a39Sopenharmony_ci
22e1051a39Sopenharmony_cistatic void engine_unregister_all_ciphers(void)
23e1051a39Sopenharmony_ci{
24e1051a39Sopenharmony_ci    engine_table_cleanup(&cipher_table);
25e1051a39Sopenharmony_ci}
26e1051a39Sopenharmony_ci
27e1051a39Sopenharmony_ciint ENGINE_register_ciphers(ENGINE *e)
28e1051a39Sopenharmony_ci{
29e1051a39Sopenharmony_ci    if (e->ciphers) {
30e1051a39Sopenharmony_ci        const int *nids;
31e1051a39Sopenharmony_ci        int num_nids = e->ciphers(e, NULL, &nids, 0);
32e1051a39Sopenharmony_ci        if (num_nids > 0)
33e1051a39Sopenharmony_ci            return engine_table_register(&cipher_table,
34e1051a39Sopenharmony_ci                                         engine_unregister_all_ciphers, e,
35e1051a39Sopenharmony_ci                                         nids, num_nids, 0);
36e1051a39Sopenharmony_ci    }
37e1051a39Sopenharmony_ci    return 1;
38e1051a39Sopenharmony_ci}
39e1051a39Sopenharmony_ci
40e1051a39Sopenharmony_civoid ENGINE_register_all_ciphers(void)
41e1051a39Sopenharmony_ci{
42e1051a39Sopenharmony_ci    ENGINE *e;
43e1051a39Sopenharmony_ci
44e1051a39Sopenharmony_ci    for (e = ENGINE_get_first(); e; e = ENGINE_get_next(e))
45e1051a39Sopenharmony_ci        ENGINE_register_ciphers(e);
46e1051a39Sopenharmony_ci}
47e1051a39Sopenharmony_ci
48e1051a39Sopenharmony_ciint ENGINE_set_default_ciphers(ENGINE *e)
49e1051a39Sopenharmony_ci{
50e1051a39Sopenharmony_ci    if (e->ciphers) {
51e1051a39Sopenharmony_ci        const int *nids;
52e1051a39Sopenharmony_ci        int num_nids = e->ciphers(e, NULL, &nids, 0);
53e1051a39Sopenharmony_ci        if (num_nids > 0)
54e1051a39Sopenharmony_ci            return engine_table_register(&cipher_table,
55e1051a39Sopenharmony_ci                                         engine_unregister_all_ciphers, e,
56e1051a39Sopenharmony_ci                                         nids, num_nids, 1);
57e1051a39Sopenharmony_ci    }
58e1051a39Sopenharmony_ci    return 1;
59e1051a39Sopenharmony_ci}
60e1051a39Sopenharmony_ci
61e1051a39Sopenharmony_ci/*
62e1051a39Sopenharmony_ci * Exposed API function to get a functional reference from the implementation
63e1051a39Sopenharmony_ci * table (ie. try to get a functional reference from the tabled structural
64e1051a39Sopenharmony_ci * references) for a given cipher 'nid'
65e1051a39Sopenharmony_ci */
66e1051a39Sopenharmony_ciENGINE *ENGINE_get_cipher_engine(int nid)
67e1051a39Sopenharmony_ci{
68e1051a39Sopenharmony_ci    return ossl_engine_table_select(&cipher_table, nid,
69e1051a39Sopenharmony_ci                                    OPENSSL_FILE, OPENSSL_LINE);
70e1051a39Sopenharmony_ci}
71e1051a39Sopenharmony_ci
72e1051a39Sopenharmony_ci/* Obtains a cipher implementation from an ENGINE functional reference */
73e1051a39Sopenharmony_ciconst EVP_CIPHER *ENGINE_get_cipher(ENGINE *e, int nid)
74e1051a39Sopenharmony_ci{
75e1051a39Sopenharmony_ci    const EVP_CIPHER *ret;
76e1051a39Sopenharmony_ci    ENGINE_CIPHERS_PTR fn = ENGINE_get_ciphers(e);
77e1051a39Sopenharmony_ci    if (!fn || !fn(e, &ret, NULL, nid)) {
78e1051a39Sopenharmony_ci        ERR_raise(ERR_LIB_ENGINE, ENGINE_R_UNIMPLEMENTED_CIPHER);
79e1051a39Sopenharmony_ci        return NULL;
80e1051a39Sopenharmony_ci    }
81e1051a39Sopenharmony_ci    return ret;
82e1051a39Sopenharmony_ci}
83e1051a39Sopenharmony_ci
84e1051a39Sopenharmony_ci/* Gets the cipher callback from an ENGINE structure */
85e1051a39Sopenharmony_ciENGINE_CIPHERS_PTR ENGINE_get_ciphers(const ENGINE *e)
86e1051a39Sopenharmony_ci{
87e1051a39Sopenharmony_ci    return e->ciphers;
88e1051a39Sopenharmony_ci}
89e1051a39Sopenharmony_ci
90e1051a39Sopenharmony_ci/* Sets the cipher callback in an ENGINE structure */
91e1051a39Sopenharmony_ciint ENGINE_set_ciphers(ENGINE *e, ENGINE_CIPHERS_PTR f)
92e1051a39Sopenharmony_ci{
93e1051a39Sopenharmony_ci    e->ciphers = f;
94e1051a39Sopenharmony_ci    return 1;
95e1051a39Sopenharmony_ci}
96