1 /*
2  * Copyright 2019-2025 The OpenSSL Project Authors. All Rights Reserved.
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/provider.h>
11 #include <openssl/types.h>
12 
13 typedef struct {
14     /*
15      * References to the underlying cipher implementation.  |cipher| caches
16      * the cipher, always.  |alloc_cipher| only holds a reference to an
17      * explicitly fetched cipher.
18      */
19     const EVP_CIPHER *cipher;   /* cipher */
20     EVP_CIPHER *alloc_cipher;   /* fetched cipher */
21 
22     /* Conditions for legacy EVP_CIPHER uses */
23     ENGINE *engine;             /* cipher engine */
24 } PROV_CIPHER;
25 
26 typedef struct {
27     /*
28      * References to the underlying digest implementation.  |md| caches
29      * the digest, always.  |alloc_md| only holds a reference to an explicitly
30      * fetched digest.
31      */
32     const EVP_MD *md;           /* digest */
33     EVP_MD *alloc_md;           /* fetched digest */
34 
35     /* Conditions for legacy EVP_MD uses */
36     ENGINE *engine;             /* digest engine */
37 } PROV_DIGEST;
38 
39 /* Cipher functions */
40 /*
41  * Load a cipher from the specified parameters with the specified context.
42  * The params "properties", "engine" and "cipher" are used to determine the
43  * implementation used.  If a provider cannot be found, it falls back to trying
44  * non-provider based implementations.
45  */
46 int ossl_prov_cipher_load_from_params(PROV_CIPHER *pc,
47                                       const OSSL_PARAM params[],
48                                       OSSL_LIB_CTX *ctx);
49 int ossl_prov_cipher_load(PROV_CIPHER *pc, const OSSL_PARAM *cipher,
50                           const OSSL_PARAM *propq, const OSSL_PARAM *engine,
51                           OSSL_LIB_CTX *ctx);
52 
53 /* Reset the PROV_CIPHER fields and free any allocated cipher reference */
54 void ossl_prov_cipher_reset(PROV_CIPHER *pc);
55 
56 /* Clone a PROV_CIPHER structure into a second */
57 int ossl_prov_cipher_copy(PROV_CIPHER *dst, const PROV_CIPHER *src);
58 
59 /* Query the cipher and associated engine (if any) */
60 const EVP_CIPHER *ossl_prov_cipher_cipher(const PROV_CIPHER *pc);
61 ENGINE *ossl_prov_cipher_engine(const PROV_CIPHER *pc);
62 
63 /* Digest functions */
64 
65 /*
66  * Fetch a digest from the specified libctx using the provided mdname and
67  * propquery. Store the result in the PROV_DIGEST and return the fetched md.
68  */
69 const EVP_MD *ossl_prov_digest_fetch(PROV_DIGEST *pd, OSSL_LIB_CTX *libctx,
70                                      const char *mdname, const char *propquery);
71 
72 /*
73  * Load a digest from the specified parameters with the specified context.
74  * The params "properties", "engine" and "digest" are used to determine the
75  * implementation used.  If a provider cannot be found, it falls back to trying
76  * non-provider based implementations.
77  */
78 int ossl_prov_digest_load_from_params(PROV_DIGEST *pd,
79                                       const OSSL_PARAM params[],
80                                       OSSL_LIB_CTX *ctx);
81 int ossl_prov_digest_load(PROV_DIGEST *pd,const OSSL_PARAM *digest,
82                           const OSSL_PARAM *propq, const OSSL_PARAM *engine,
83                           OSSL_LIB_CTX *ctx);
84 
85 /* Reset the PROV_DIGEST fields and free any allocated digest reference */
86 void ossl_prov_digest_reset(PROV_DIGEST *pd);
87 
88 /* Clone a PROV_DIGEST structure into a second */
89 int ossl_prov_digest_copy(PROV_DIGEST *dst, const PROV_DIGEST *src);
90 
91 /* Query the digest and associated engine (if any) */
92 const EVP_MD *ossl_prov_digest_md(const PROV_DIGEST *pd);
93 ENGINE *ossl_prov_digest_engine(const PROV_DIGEST *pd);
94 
95 /* Set a specific md, resets current digests first */
96 void ossl_prov_digest_set_md(PROV_DIGEST *pd, EVP_MD *md);
97 
98 /*
99  * Set the various parameters on an EVP_MAC_CTX from the supplied arguments.
100  * If any of the supplied ciphername/mdname etc are NULL then the values
101  * from the supplied params (if non NULL) are used instead.
102  */
103 int ossl_prov_macctx_load(EVP_MAC_CTX **macctx,
104                           const OSSL_PARAM *pmac, const OSSL_PARAM *pcipher,
105                           const OSSL_PARAM *pdigest, const OSSL_PARAM *propq,
106                           const OSSL_PARAM *pengine,
107                           const char *macname, const char *ciphername,
108                           const char *mdname, OSSL_LIB_CTX *libctx);
109 
110 int ossl_prov_set_macctx(EVP_MAC_CTX *macctx,
111                          const char *ciphername,
112                          const char *mdname,
113                          const char *engine,
114                          const char *properties);
115 
116 /* MAC functions */
117 /*
118  * Load an EVP_MAC_CTX* from the specified parameters with the specified
119  * library context.
120  * The params "mac" and "properties" are used to determine the implementation
121  * used, and the parameters "digest", "cipher", "engine" and "properties" are
122  * passed to the MAC via the created MAC context if they are given.
123  * If there is already a created MAC context, it will be replaced if the "mac"
124  * parameter is found, otherwise it will simply be used as is, and passed the
125  * parameters to pilfer as it sees fit.
126  *
127  * As an option, a MAC name may be explicitly given, and if it is, the "mac"
128  * parameter will be ignored.
129  * Similarly, as an option, a cipher name or a digest name may be explicitly
130  * given, and if any of them is, the "digest" and "cipher" parameters are
131  * ignored.
132  */
133 int ossl_prov_macctx_load_from_params(EVP_MAC_CTX **macctx,
134                                       const OSSL_PARAM params[],
135                                       const char *macname,
136                                       const char *ciphername,
137                                       const char *mdname,
138                                       OSSL_LIB_CTX *ctx);
139 
140 typedef struct ag_capable_st {
141     OSSL_ALGORITHM alg;
142     int (*capable)(void);
143 } OSSL_ALGORITHM_CAPABLE;
144 
145 /*
146  * Dynamically select algorithms by calling a capable() method.
147  * If this method is NULL or the method returns 1 then the algorithm is added.
148  */
149 void ossl_prov_cache_exported_algorithms(const OSSL_ALGORITHM_CAPABLE *in,
150                                          OSSL_ALGORITHM *out);
151 
152 /* Duplicate a lump of memory safely */
153 int ossl_prov_memdup(const void *src, size_t src_len,
154                      unsigned char **dest, size_t *dest_len);
155