Coverage Report

Created: 2026-07-12 07:21

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
2.03M
{
21
2.03M
    EVP_MAC *mac = vmac;
22
2.03M
    int ref = 0;
23
24
2.03M
    CRYPTO_UP_REF(&mac->refcnt, &ref);
25
2.03M
    return 1;
26
2.03M
}
27
28
static void evp_mac_free(void *vmac)
29
2.10M
{
30
2.10M
    EVP_MAC *mac = vmac;
31
2.10M
    int ref = 0;
32
33
2.10M
    if (mac == NULL)
34
72.6k
        return;
35
36
2.03M
    CRYPTO_DOWN_REF(&mac->refcnt, &ref);
37
2.03M
    if (ref > 0)
38
2.03M
        return;
39
333
    OPENSSL_free(mac->type_name);
40
333
    ossl_provider_free(mac->prov);
41
333
    CRYPTO_FREE_REF(&mac->refcnt);
42
333
    OPENSSL_free(mac);
43
333
}
44
45
static void *evp_mac_new(void)
46
486
{
47
486
    EVP_MAC *mac = NULL;
48
49
486
    if ((mac = OPENSSL_zalloc(sizeof(*mac))) == NULL
50
486
        || !CRYPTO_NEW_REF(&mac->refcnt, 1)) {
51
0
        evp_mac_free(mac);
52
0
        return NULL;
53
0
    }
54
486
    return mac;
55
486
}
56
57
static void *evp_mac_from_algorithm(int name_id,
58
    const OSSL_ALGORITHM *algodef,
59
    OSSL_PROVIDER *prov, int no_store)
60
360
{
61
360
    const OSSL_DISPATCH *fns = algodef->implementation;
62
360
    EVP_MAC *mac = NULL;
63
360
    int fnmaccnt = 0, fnctxcnt = 0, mac_init_found = 0;
64
65
360
    if ((mac = evp_mac_new()) == NULL) {
66
0
        ERR_raise(ERR_LIB_EVP, ERR_R_EVP_LIB);
67
0
        goto err;
68
0
    }
69
360
    mac->name_id = name_id;
70
360
    mac->no_store = no_store;
71
72
360
    if ((mac->type_name = ossl_algorithm_get1_first_name(algodef)) == NULL)
73
0
        goto err;
74
75
360
    mac->description = algodef->algorithm_description;
76
77
3.96k
    for (; fns->function_id != 0; fns++) {
78
3.60k
        switch (fns->function_id) {
79
360
        case OSSL_FUNC_MAC_NEWCTX:
80
360
            if (mac->newctx != NULL)
81
0
                break;
82
360
            mac->newctx = OSSL_FUNC_mac_newctx(fns);
83
360
            fnctxcnt++;
84
360
            break;
85
360
        case OSSL_FUNC_MAC_DUPCTX:
86
360
            if (mac->dupctx != NULL)
87
0
                break;
88
360
            mac->dupctx = OSSL_FUNC_mac_dupctx(fns);
89
360
            break;
90
360
        case OSSL_FUNC_MAC_FREECTX:
91
360
            if (mac->freectx != NULL)
92
0
                break;
93
360
            mac->freectx = OSSL_FUNC_mac_freectx(fns);
94
360
            fnctxcnt++;
95
360
            break;
96
360
        case OSSL_FUNC_MAC_INIT:
97
360
            if (mac->init != NULL)
98
0
                break;
99
360
            mac->init = OSSL_FUNC_mac_init(fns);
100
360
            mac_init_found = 1;
101
360
            break;
102
360
        case OSSL_FUNC_MAC_UPDATE:
103
360
            if (mac->update != NULL)
104
0
                break;
105
360
            mac->update = OSSL_FUNC_mac_update(fns);
106
360
            fnmaccnt++;
107
360
            break;
108
360
        case OSSL_FUNC_MAC_FINAL:
109
360
            if (mac->final != NULL)
110
0
                break;
111
360
            mac->final = OSSL_FUNC_mac_final(fns);
112
360
            fnmaccnt++;
113
360
            break;
114
80
        case OSSL_FUNC_MAC_GETTABLE_PARAMS:
115
80
            if (mac->gettable_params != NULL)
116
0
                break;
117
80
            mac->gettable_params = OSSL_FUNC_mac_gettable_params(fns);
118
80
            break;
119
280
        case OSSL_FUNC_MAC_GETTABLE_CTX_PARAMS:
120
280
            if (mac->gettable_ctx_params != NULL)
121
0
                break;
122
280
            mac->gettable_ctx_params = OSSL_FUNC_mac_gettable_ctx_params(fns);
123
280
            break;
124
360
        case OSSL_FUNC_MAC_SETTABLE_CTX_PARAMS:
125
360
            if (mac->settable_ctx_params != NULL)
126
0
                break;
127
360
            mac->settable_ctx_params = OSSL_FUNC_mac_settable_ctx_params(fns);
128
360
            break;
129
80
        case OSSL_FUNC_MAC_GET_PARAMS:
130
80
            if (mac->get_params != NULL)
131
0
                break;
132
80
            mac->get_params = OSSL_FUNC_mac_get_params(fns);
133
80
            break;
134
280
        case OSSL_FUNC_MAC_GET_CTX_PARAMS:
135
280
            if (mac->get_ctx_params != NULL)
136
0
                break;
137
280
            mac->get_ctx_params = OSSL_FUNC_mac_get_ctx_params(fns);
138
280
            break;
139
360
        case OSSL_FUNC_MAC_SET_CTX_PARAMS:
140
360
            if (mac->set_ctx_params != NULL)
141
0
                break;
142
360
            mac->set_ctx_params = OSSL_FUNC_mac_set_ctx_params(fns);
143
360
            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
3.60k
        }
151
3.60k
    }
152
360
    fnmaccnt += mac_init_found;
153
360
    if (fnmaccnt != 3
154
360
        || 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
360
    if (prov != NULL && !ossl_provider_up_ref(prov))
165
0
        goto err;
166
167
360
    mac->prov = prov;
168
169
360
    return mac;
170
171
0
err:
172
0
    evp_mac_free(mac);
173
0
    return NULL;
174
360
}
175
176
EVP_MAC *EVP_MAC_fetch(OSSL_LIB_CTX *libctx, const char *algorithm,
177
    const char *properties)
178
418k
{
179
418k
    return evp_generic_fetch(libctx, OSSL_OP_MAC, algorithm, properties,
180
418k
        evp_mac_from_algorithm, evp_mac_up_ref,
181
418k
        evp_mac_free);
182
418k
}
183
184
int EVP_MAC_up_ref(EVP_MAC *mac)
185
566k
{
186
#ifdef OPENSSL_NO_CACHED_FETCH
187
    return evp_mac_up_ref(mac);
188
#else
189
566k
    if (mac->no_store != 0)
190
0
        return evp_mac_up_ref(mac);
191
566k
    return 1;
192
566k
#endif
193
566k
}
194
195
void EVP_MAC_free(EVP_MAC *mac)
196
705k
{
197
#ifdef OPENSSL_NO_CACHED_FETCH
198
    evp_mac_free(mac);
199
#else
200
705k
    if (mac != NULL && (mac->no_store != 0))
201
0
        evp_mac_free(mac);
202
705k
#endif
203
705k
}
204
205
const OSSL_PROVIDER *EVP_MAC_get0_provider(const EVP_MAC *mac)
206
152k
{
207
152k
    return mac->prov;
208
152k
}
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
152k
{
229
152k
    void *alg;
230
231
152k
    if (mac->settable_ctx_params == NULL)
232
0
        return NULL;
233
152k
    alg = ossl_provider_ctx(EVP_MAC_get0_provider(mac));
234
152k
    return mac->settable_ctx_params(NULL, alg);
235
152k
}
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
8
{
261
8
    struct EVP_MAC_do_all_provided_thunk t;
262
263
8
    t.fn = fn;
264
8
    t.arg = arg;
265
8
    evp_generic_do_all(libctx, OSSL_OP_MAC,
266
8
        EVP_MAC_do_all_provided_thunk, &t,
267
8
        evp_mac_from_algorithm, evp_mac_up_ref, evp_mac_free);
268
8
}
269
270
EVP_MAC *evp_mac_fetch_from_prov(OSSL_PROVIDER *prov,
271
    const char *algorithm,
272
    const char *properties)
273
13
{
274
13
    return evp_generic_fetch_from_prov(prov, OSSL_OP_MAC,
275
13
        algorithm, properties,
276
13
        evp_mac_from_algorithm,
277
13
        evp_mac_up_ref,
278
13
        evp_mac_free);
279
13
}