Coverage Report

Created: 2026-07-16 06:59

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/openssl/crypto/evp/mac_meth.c
Line
Count
Source
1
/*
2
 * Copyright 2022-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/evp.h>
11
#include <openssl/err.h>
12
#include <openssl/core.h>
13
#include <openssl/core_dispatch.h>
14
#include "internal/provider.h"
15
#include "internal/core.h"
16
#include "crypto/evp.h"
17
#include "evp_local.h"
18
19
static int evp_mac_up_ref(void *vmac)
20
0
{
21
0
    EVP_MAC *mac = vmac;
22
0
    int ref = 0;
23
24
0
    CRYPTO_UP_REF(&mac->refcnt, &ref);
25
0
    return 1;
26
0
}
27
28
static void evp_mac_free(void *vmac)
29
0
{
30
0
    EVP_MAC *mac = vmac;
31
0
    int ref = 0;
32
33
0
    if (mac == NULL)
34
0
        return;
35
36
0
    CRYPTO_DOWN_REF(&mac->refcnt, &ref);
37
0
    if (ref > 0)
38
0
        return;
39
0
    OPENSSL_free(mac->type_name);
40
0
    ossl_provider_free(mac->prov);
41
0
    CRYPTO_FREE_REF(&mac->refcnt);
42
0
    OPENSSL_free(mac);
43
0
}
44
45
static void *evp_mac_new(void)
46
0
{
47
0
    EVP_MAC *mac = NULL;
48
49
0
    if ((mac = OPENSSL_zalloc(sizeof(*mac))) == NULL
50
0
        || !CRYPTO_NEW_REF(&mac->refcnt, 1)) {
51
0
        evp_mac_free(mac);
52
0
        return NULL;
53
0
    }
54
0
    return mac;
55
0
}
56
57
static void *evp_mac_from_algorithm(int name_id,
58
    const OSSL_ALGORITHM *algodef,
59
    OSSL_PROVIDER *prov, int no_store)
60
0
{
61
0
    const OSSL_DISPATCH *fns = algodef->implementation;
62
0
    EVP_MAC *mac = NULL;
63
0
    int fnmaccnt = 0, fnctxcnt = 0, mac_init_found = 0;
64
65
0
    if ((mac = evp_mac_new()) == NULL) {
66
0
        ERR_raise(ERR_LIB_EVP, ERR_R_EVP_LIB);
67
0
        goto err;
68
0
    }
69
0
    mac->name_id = name_id;
70
0
    mac->no_store = no_store;
71
72
0
    if ((mac->type_name = ossl_algorithm_get1_first_name(algodef)) == NULL)
73
0
        goto err;
74
75
0
    mac->description = algodef->algorithm_description;
76
77
0
    for (; fns->function_id != 0; fns++) {
78
0
        switch (fns->function_id) {
79
0
        case OSSL_FUNC_MAC_NEWCTX:
80
0
            if (mac->newctx != NULL)
81
0
                break;
82
0
            mac->newctx = OSSL_FUNC_mac_newctx(fns);
83
0
            fnctxcnt++;
84
0
            break;
85
0
        case OSSL_FUNC_MAC_DUPCTX:
86
0
            if (mac->dupctx != NULL)
87
0
                break;
88
0
            mac->dupctx = OSSL_FUNC_mac_dupctx(fns);
89
0
            break;
90
0
        case OSSL_FUNC_MAC_FREECTX:
91
0
            if (mac->freectx != NULL)
92
0
                break;
93
0
            mac->freectx = OSSL_FUNC_mac_freectx(fns);
94
0
            fnctxcnt++;
95
0
            break;
96
0
        case OSSL_FUNC_MAC_INIT:
97
0
            if (mac->init != NULL)
98
0
                break;
99
0
            mac->init = OSSL_FUNC_mac_init(fns);
100
0
            mac_init_found = 1;
101
0
            break;
102
0
        case OSSL_FUNC_MAC_UPDATE:
103
0
            if (mac->update != NULL)
104
0
                break;
105
0
            mac->update = OSSL_FUNC_mac_update(fns);
106
0
            fnmaccnt++;
107
0
            break;
108
0
        case OSSL_FUNC_MAC_FINAL:
109
0
            if (mac->final != NULL)
110
0
                break;
111
0
            mac->final = OSSL_FUNC_mac_final(fns);
112
0
            fnmaccnt++;
113
0
            break;
114
0
        case OSSL_FUNC_MAC_GETTABLE_PARAMS:
115
0
            if (mac->gettable_params != NULL)
116
0
                break;
117
0
            mac->gettable_params = OSSL_FUNC_mac_gettable_params(fns);
118
0
            break;
119
0
        case OSSL_FUNC_MAC_GETTABLE_CTX_PARAMS:
120
0
            if (mac->gettable_ctx_params != NULL)
121
0
                break;
122
0
            mac->gettable_ctx_params = OSSL_FUNC_mac_gettable_ctx_params(fns);
123
0
            break;
124
0
        case OSSL_FUNC_MAC_SETTABLE_CTX_PARAMS:
125
0
            if (mac->settable_ctx_params != NULL)
126
0
                break;
127
0
            mac->settable_ctx_params = OSSL_FUNC_mac_settable_ctx_params(fns);
128
0
            break;
129
0
        case OSSL_FUNC_MAC_GET_PARAMS:
130
0
            if (mac->get_params != NULL)
131
0
                break;
132
0
            mac->get_params = OSSL_FUNC_mac_get_params(fns);
133
0
            break;
134
0
        case OSSL_FUNC_MAC_GET_CTX_PARAMS:
135
0
            if (mac->get_ctx_params != NULL)
136
0
                break;
137
0
            mac->get_ctx_params = OSSL_FUNC_mac_get_ctx_params(fns);
138
0
            break;
139
0
        case OSSL_FUNC_MAC_SET_CTX_PARAMS:
140
0
            if (mac->set_ctx_params != NULL)
141
0
                break;
142
0
            mac->set_ctx_params = OSSL_FUNC_mac_set_ctx_params(fns);
143
0
            break;
144
0
        case OSSL_FUNC_MAC_INIT_SKEY:
145
0
            if (mac->init_skey != NULL)
146
0
                break;
147
0
            mac->init_skey = OSSL_FUNC_mac_init_skey(fns);
148
0
            mac_init_found = 1;
149
0
            break;
150
0
        }
151
0
    }
152
0
    fnmaccnt += mac_init_found;
153
0
    if (fnmaccnt != 3
154
0
        || fnctxcnt != 2) {
155
        /*
156
         * In order to be a consistent set of functions we must have at least
157
         * a complete set of "mac" functions, and a complete set of context
158
         * management functions, as well as the size function.
159
         */
160
0
        ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_PROVIDER_FUNCTIONS);
161
0
        goto err;
162
0
    }
163
164
0
    if (prov != NULL && !ossl_provider_up_ref(prov))
165
0
        goto err;
166
167
0
    mac->prov = prov;
168
169
0
    return mac;
170
171
0
err:
172
0
    evp_mac_free(mac);
173
0
    return NULL;
174
0
}
175
176
EVP_MAC *EVP_MAC_fetch(OSSL_LIB_CTX *libctx, const char *algorithm,
177
    const char *properties)
178
0
{
179
0
    return evp_generic_fetch(libctx, OSSL_OP_MAC, algorithm, properties,
180
0
        evp_mac_from_algorithm, evp_mac_up_ref,
181
0
        evp_mac_free);
182
0
}
183
184
int EVP_MAC_up_ref(EVP_MAC *mac)
185
0
{
186
#ifdef OPENSSL_NO_CACHED_FETCH
187
    return evp_mac_up_ref(mac);
188
#else
189
0
    if (mac->no_store != 0)
190
0
        return evp_mac_up_ref(mac);
191
0
    return 1;
192
0
#endif
193
0
}
194
195
void EVP_MAC_free(EVP_MAC *mac)
196
0
{
197
#ifdef OPENSSL_NO_CACHED_FETCH
198
    evp_mac_free(mac);
199
#else
200
0
    if (mac != NULL && (mac->no_store != 0))
201
0
        evp_mac_free(mac);
202
0
#endif
203
0
}
204
205
const OSSL_PROVIDER *EVP_MAC_get0_provider(const EVP_MAC *mac)
206
0
{
207
0
    return mac->prov;
208
0
}
209
210
const OSSL_PARAM *EVP_MAC_gettable_params(const EVP_MAC *mac)
211
0
{
212
0
    if (mac->gettable_params == NULL)
213
0
        return NULL;
214
0
    return mac->gettable_params(ossl_provider_ctx(EVP_MAC_get0_provider(mac)));
215
0
}
216
217
const OSSL_PARAM *EVP_MAC_gettable_ctx_params(const EVP_MAC *mac)
218
0
{
219
0
    void *alg;
220
221
0
    if (mac->gettable_ctx_params == NULL)
222
0
        return NULL;
223
0
    alg = ossl_provider_ctx(EVP_MAC_get0_provider(mac));
224
0
    return mac->gettable_ctx_params(NULL, alg);
225
0
}
226
227
const OSSL_PARAM *EVP_MAC_settable_ctx_params(const EVP_MAC *mac)
228
0
{
229
0
    void *alg;
230
231
0
    if (mac->settable_ctx_params == NULL)
232
0
        return NULL;
233
0
    alg = ossl_provider_ctx(EVP_MAC_get0_provider(mac));
234
0
    return mac->settable_ctx_params(NULL, alg);
235
0
}
236
237
const OSSL_PARAM *EVP_MAC_CTX_gettable_params(EVP_MAC_CTX *ctx)
238
0
{
239
0
    void *alg;
240
241
0
    if (ctx->meth->gettable_ctx_params == NULL)
242
0
        return NULL;
243
0
    alg = ossl_provider_ctx(EVP_MAC_get0_provider(ctx->meth));
244
0
    return ctx->meth->gettable_ctx_params(ctx->algctx, alg);
245
0
}
246
247
const OSSL_PARAM *EVP_MAC_CTX_settable_params(EVP_MAC_CTX *ctx)
248
0
{
249
0
    void *alg;
250
251
0
    if (ctx->meth->settable_ctx_params == NULL)
252
0
        return NULL;
253
0
    alg = ossl_provider_ctx(EVP_MAC_get0_provider(ctx->meth));
254
0
    return ctx->meth->settable_ctx_params(ctx->algctx, alg);
255
0
}
256
257
void EVP_MAC_do_all_provided(OSSL_LIB_CTX *libctx,
258
    void (*fn)(EVP_MAC *mac, void *arg),
259
    void *arg)
260
0
{
261
0
    struct EVP_MAC_do_all_provided_thunk t;
262
263
0
    t.fn = fn;
264
0
    t.arg = arg;
265
0
    evp_generic_do_all(libctx, OSSL_OP_MAC,
266
0
        EVP_MAC_do_all_provided_thunk, &t,
267
0
        evp_mac_from_algorithm, evp_mac_up_ref, evp_mac_free);
268
0
}
269
270
EVP_MAC *evp_mac_fetch_from_prov(OSSL_PROVIDER *prov,
271
    const char *algorithm,
272
    const char *properties)
273
0
{
274
0
    return evp_generic_fetch_from_prov(prov, OSSL_OP_MAC,
275
0
        algorithm, properties,
276
0
        evp_mac_from_algorithm,
277
0
        evp_mac_up_ref,
278
0
        evp_mac_free);
279
0
}