Coverage Report

Created: 2026-10-28 06:28

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/openssl36/providers/implementations/signature/mac_legacy_sig.c
Line
Count
Source
1
/*
2
 * Copyright 2019-2026 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
/* We need to use some engine deprecated APIs */
11
#define OPENSSL_SUPPRESS_DEPRECATED
12
13
#include <stdbool.h>
14
#include <openssl/crypto.h>
15
#include <openssl/evp.h>
16
#include <openssl/core_dispatch.h>
17
#include <openssl/core_names.h>
18
#include <openssl/params.h>
19
#include <openssl/err.h>
20
#include <openssl/proverr.h>
21
#ifndef FIPS_MODULE
22
#include <openssl/engine.h>
23
#endif
24
#include "prov/implementations.h"
25
#include "prov/provider_ctx.h"
26
#include "prov/macsignature.h"
27
#include "prov/providercommon.h"
28
#include "prov/securitycheck.h"
29
#include "internal/fips.h"
30
#include "internal/common.h"
31
32
#ifndef FIPS_MODULE
33
#define mac_legacy_get_ctx_params_decoder
34
#define mac_legacy_set_ctx_params_decoder
35
#endif
36
#include "providers/implementations/signature/mac_legacy_sig.inc"
37
38
static OSSL_FUNC_signature_newctx_fn mac_hmac_newctx;
39
static OSSL_FUNC_signature_newctx_fn mac_siphash_newctx;
40
static OSSL_FUNC_signature_newctx_fn mac_poly1305_newctx;
41
static OSSL_FUNC_signature_newctx_fn mac_cmac_newctx;
42
static OSSL_FUNC_signature_digest_sign_init_fn mac_digest_sign_init;
43
static OSSL_FUNC_signature_digest_sign_update_fn mac_digest_sign_update;
44
static OSSL_FUNC_signature_digest_sign_final_fn mac_digest_sign_final;
45
static OSSL_FUNC_signature_freectx_fn mac_freectx;
46
static OSSL_FUNC_signature_dupctx_fn mac_dupctx;
47
static OSSL_FUNC_signature_set_ctx_params_fn mac_set_ctx_params;
48
static OSSL_FUNC_signature_settable_ctx_params_fn mac_hmac_settable_ctx_params;
49
static OSSL_FUNC_signature_settable_ctx_params_fn mac_siphash_settable_ctx_params;
50
static OSSL_FUNC_signature_settable_ctx_params_fn mac_poly1305_settable_ctx_params;
51
static OSSL_FUNC_signature_settable_ctx_params_fn mac_cmac_settable_ctx_params;
52
53
typedef struct {
54
    OSSL_LIB_CTX *libctx;
55
    char *propq;
56
    MAC_KEY *key;
57
    EVP_MAC_CTX *macctx;
58
#ifdef FIPS_MODULE
59
    bool hmac_keysize_check;
60
    OSSL_FIPS_IND_DECLARE
61
#endif
62
} PROV_MAC_CTX;
63
64
static void *mac_newctx(void *provctx, const char *propq, const char *macname)
65
26.1k
{
66
26.1k
    PROV_MAC_CTX *pmacctx;
67
26.1k
    EVP_MAC *mac = NULL;
68
69
26.1k
    if (!ossl_prov_is_running())
70
0
        return NULL;
71
72
26.1k
    pmacctx = OPENSSL_zalloc(sizeof(PROV_MAC_CTX));
73
26.1k
    if (pmacctx == NULL)
74
0
        return NULL;
75
76
26.1k
    pmacctx->libctx = PROV_LIBCTX_OF(provctx);
77
26.1k
    if (propq != NULL && (pmacctx->propq = OPENSSL_strdup(propq)) == NULL)
78
0
        goto err;
79
80
26.1k
    mac = EVP_MAC_fetch(pmacctx->libctx, macname, propq);
81
26.1k
    if (mac == NULL)
82
0
        goto err;
83
84
26.1k
    pmacctx->macctx = EVP_MAC_CTX_new(mac);
85
26.1k
    if (pmacctx->macctx == NULL)
86
0
        goto err;
87
88
26.1k
    EVP_MAC_free(mac);
89
#ifdef FIPS_MODULE
90
    pmacctx->hmac_keysize_check = (strcmp(macname, "HMAC") == 0);
91
    /* Set FIPS indicator to approved */
92
    OSSL_FIPS_IND_INIT(pmacctx)
93
#endif
94
26.1k
    return pmacctx;
95
96
0
err:
97
0
    OPENSSL_free(pmacctx->propq);
98
0
    OPENSSL_free(pmacctx);
99
0
    EVP_MAC_free(mac);
100
0
    return NULL;
101
26.1k
}
102
103
#define MAC_NEWCTX(funcname, macname)                                      \
104
    static void *mac_##funcname##_newctx(void *provctx, const char *propq) \
105
26.1k
    {                                                                      \
106
26.1k
        return mac_newctx(provctx, propq, macname);                        \
107
26.1k
    }
mac_legacy_sig.c:mac_hmac_newctx
Line
Count
Source
105
26.1k
    {                                                                      \
106
26.1k
        return mac_newctx(provctx, propq, macname);                        \
107
26.1k
    }
Unexecuted instantiation: mac_legacy_sig.c:mac_siphash_newctx
Unexecuted instantiation: mac_legacy_sig.c:mac_poly1305_newctx
Unexecuted instantiation: mac_legacy_sig.c:mac_cmac_newctx
108
109
MAC_NEWCTX(hmac, "HMAC")
110
MAC_NEWCTX(siphash, "SIPHASH")
111
MAC_NEWCTX(poly1305, "POLY1305")
112
MAC_NEWCTX(cmac, "CMAC")
113
114
#ifdef FIPS_MODULE
115
/*
116
 * The fips indicator check is done at this level because HMAC will be created
117
 * as an 'internal' sub-algorithm which will not perform the tests in hmac_prov.c
118
 */
119
static int hmac_check_key(PROV_MAC_CTX *macctx, const unsigned char *key,
120
    size_t keylen)
121
{
122
    int approved = ossl_mac_check_key_size(keylen);
123
124
    if (!approved) {
125
        if (!OSSL_FIPS_IND_ON_UNAPPROVED(macctx, OSSL_FIPS_IND_SETTABLE0,
126
                macctx->libctx, "HMAC", "keysize",
127
                ossl_fips_config_hmac_key_check)) {
128
            ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY_LENGTH);
129
            return 0;
130
        }
131
    }
132
    return 1;
133
}
134
#endif
135
136
static int mac_digest_sign_init(void *vpmacctx, const char *mdname, void *vkey,
137
    const OSSL_PARAM params[])
138
14.1k
{
139
14.1k
    PROV_MAC_CTX *pmacctx = (PROV_MAC_CTX *)vpmacctx;
140
14.1k
    const char *ciphername = NULL, *engine = NULL;
141
142
14.1k
    if (!ossl_prov_is_running()
143
14.1k
        || pmacctx == NULL)
144
0
        return 0;
145
146
14.1k
    if (pmacctx->key == NULL && vkey == NULL) {
147
0
        ERR_raise(ERR_LIB_PROV, PROV_R_NO_KEY_SET);
148
0
        return 0;
149
0
    }
150
151
14.1k
    if (vkey != NULL) {
152
14.1k
        if (!ossl_mac_key_up_ref(vkey))
153
0
            return 0;
154
14.1k
        ossl_mac_key_free(pmacctx->key);
155
14.1k
        pmacctx->key = vkey;
156
14.1k
    }
157
158
14.1k
    if (pmacctx->key->cipher.cipher != NULL)
159
0
        ciphername = (char *)EVP_CIPHER_get0_name(pmacctx->key->cipher.cipher);
160
14.1k
#if !defined(OPENSSL_NO_ENGINE) && !defined(FIPS_MODULE)
161
14.1k
    if (pmacctx->key->cipher.engine != NULL)
162
0
        engine = (char *)ENGINE_get_id(pmacctx->key->cipher.engine);
163
14.1k
#endif
164
165
14.1k
    if (!ossl_prov_set_macctx(pmacctx->macctx,
166
14.1k
            (char *)ciphername,
167
14.1k
            (char *)mdname,
168
14.1k
            (char *)engine,
169
14.1k
            pmacctx->key->properties))
170
0
        return 0;
171
172
#ifdef FIPS_MODULE
173
    if (pmacctx->hmac_keysize_check
174
        && !hmac_check_key(pmacctx, pmacctx->key->priv_key,
175
            pmacctx->key->priv_key_len))
176
        return 0;
177
#endif
178
14.1k
    if (!EVP_MAC_init(pmacctx->macctx, pmacctx->key->priv_key,
179
14.1k
            pmacctx->key->priv_key_len, params))
180
0
        return 0;
181
182
14.1k
    return 1;
183
14.1k
}
184
185
int mac_digest_sign_update(void *vpmacctx, const unsigned char *data,
186
    size_t datalen)
187
1.68M
{
188
1.68M
    PROV_MAC_CTX *pmacctx = (PROV_MAC_CTX *)vpmacctx;
189
190
1.68M
    if (pmacctx == NULL || pmacctx->macctx == NULL)
191
0
        return 0;
192
193
1.68M
    return EVP_MAC_update(pmacctx->macctx, data, datalen);
194
1.68M
}
195
196
int mac_digest_sign_final(void *vpmacctx, unsigned char *mac, size_t *maclen,
197
    size_t macsize)
198
844k
{
199
844k
    PROV_MAC_CTX *pmacctx = (PROV_MAC_CTX *)vpmacctx;
200
201
844k
    if (!ossl_prov_is_running() || pmacctx == NULL || pmacctx->macctx == NULL)
202
0
        return 0;
203
204
844k
    return EVP_MAC_final(pmacctx->macctx, mac, maclen, macsize);
205
844k
}
206
207
static void mac_freectx(void *vpmacctx)
208
1.71M
{
209
1.71M
    PROV_MAC_CTX *ctx = (PROV_MAC_CTX *)vpmacctx;
210
211
1.71M
    OPENSSL_free(ctx->propq);
212
1.71M
    EVP_MAC_CTX_free(ctx->macctx);
213
1.71M
    ossl_mac_key_free(ctx->key);
214
1.71M
    OPENSSL_free(ctx);
215
1.71M
}
216
217
static void *mac_dupctx(void *vpmacctx)
218
1.68M
{
219
1.68M
    PROV_MAC_CTX *srcctx = (PROV_MAC_CTX *)vpmacctx;
220
1.68M
    PROV_MAC_CTX *dstctx;
221
222
1.68M
    if (!ossl_prov_is_running())
223
0
        return NULL;
224
225
1.68M
    dstctx = OPENSSL_zalloc(sizeof(*srcctx));
226
1.68M
    if (dstctx == NULL)
227
0
        return NULL;
228
229
1.68M
    *dstctx = *srcctx;
230
1.68M
    dstctx->propq = NULL;
231
1.68M
    dstctx->key = NULL;
232
1.68M
    dstctx->macctx = NULL;
233
234
1.68M
    if (srcctx->propq != NULL && (dstctx->propq = OPENSSL_strdup(srcctx->propq)) == NULL)
235
0
        goto err;
236
237
1.68M
    if (srcctx->key != NULL && !ossl_mac_key_up_ref(srcctx->key))
238
0
        goto err;
239
1.68M
    dstctx->key = srcctx->key;
240
241
1.68M
    if (srcctx->macctx != NULL) {
242
1.68M
        dstctx->macctx = EVP_MAC_CTX_dup(srcctx->macctx);
243
1.68M
        if (dstctx->macctx == NULL)
244
0
            goto err;
245
1.68M
    }
246
247
1.68M
    return dstctx;
248
0
err:
249
0
    mac_freectx(dstctx);
250
0
    return NULL;
251
1.68M
}
252
253
static int mac_set_ctx_params(void *vpmacctx, const OSSL_PARAM params[])
254
221k
{
255
221k
    PROV_MAC_CTX *ctx = (PROV_MAC_CTX *)vpmacctx;
256
257
#ifdef FIPS_MODULE
258
    if (ctx->hmac_keysize_check) {
259
        struct mac_legacy_set_ctx_params_st p;
260
261
        if (!mac_legacy_set_ctx_params_decoder(params, &p))
262
            return 0;
263
        if (!OSSL_FIPS_IND_SET_CTX_FROM_PARAM(ctx, OSSL_FIPS_IND_SETTABLE0,
264
                p.ind_k))
265
            return 0;
266
        if (p.key != NULL) {
267
            if (p.key->data_type != OSSL_PARAM_OCTET_STRING)
268
                return 0;
269
            if (!hmac_check_key(ctx, p.key->data, p.key->data_size))
270
                return 0;
271
        }
272
    }
273
#endif
274
221k
    return EVP_MAC_CTX_set_params(ctx->macctx, params);
275
221k
}
276
277
static const OSSL_PARAM *mac_settable_ctx_params(ossl_unused void *ctx,
278
    void *provctx,
279
    const char *macname)
280
47
{
281
47
    EVP_MAC *mac = EVP_MAC_fetch(PROV_LIBCTX_OF(provctx), macname,
282
47
        NULL);
283
47
    const OSSL_PARAM *params;
284
285
47
    if (mac == NULL)
286
0
        return NULL;
287
288
47
    params = EVP_MAC_settable_ctx_params(mac);
289
47
    EVP_MAC_free(mac);
290
291
47
    return params;
292
47
}
293
294
static const OSSL_PARAM *mac_gettable_ctx_params(ossl_unused void *vctx,
295
    ossl_unused void *provctx)
296
0
{
297
0
    return mac_legacy_get_ctx_params_list;
298
0
}
299
300
static int mac_get_ctx_params(void *vctx, OSSL_PARAM params[])
301
0
{
302
0
    PROV_MAC_CTX *ctx = vctx;
303
#ifdef FIPS_MODULE
304
    struct mac_legacy_get_ctx_params_st p;
305
#endif
306
307
0
    if (ctx == NULL)
308
0
        return 0;
309
310
#ifdef FIPS_MODULE
311
    if (!mac_legacy_get_ctx_params_decoder(params, &p))
312
        return 0;
313
    if (p.ind != NULL) {
314
        int approved = OSSL_FIPS_IND_GET(ctx)->approved;
315
316
        /* Internal HMAC delegates its indicator checks to this wrapper. */
317
        if (!ctx->hmac_keysize_check) {
318
            int mac_approved = 0;
319
            OSSL_PARAM mac_params[2];
320
321
            mac_params[0] = OSSL_PARAM_construct_int(
322
                OSSL_MAC_PARAM_FIPS_APPROVED_INDICATOR, &mac_approved);
323
            mac_params[1] = OSSL_PARAM_construct_end();
324
325
            if (!EVP_MAC_CTX_get_params(ctx->macctx, mac_params)
326
                || !OSSL_PARAM_modified(mac_params))
327
                return 0;
328
            approved &= mac_approved;
329
        }
330
        if (!OSSL_PARAM_set_int(p.ind, approved))
331
            return 0;
332
    }
333
#endif
334
0
    return 1;
335
0
}
336
337
#define MAC_SETTABLE_CTX_PARAMS(funcname, macname)                           \
338
    static const OSSL_PARAM *mac_##funcname##_settable_ctx_params(void *ctx, \
339
        void *provctx)                                                       \
340
47
    {                                                                        \
341
47
        return mac_settable_ctx_params(ctx, provctx, macname);               \
342
47
    }
mac_legacy_sig.c:mac_hmac_settable_ctx_params
Line
Count
Source
340
10
    {                                                                        \
341
10
        return mac_settable_ctx_params(ctx, provctx, macname);               \
342
10
    }
mac_legacy_sig.c:mac_siphash_settable_ctx_params
Line
Count
Source
340
12
    {                                                                        \
341
12
        return mac_settable_ctx_params(ctx, provctx, macname);               \
342
12
    }
mac_legacy_sig.c:mac_poly1305_settable_ctx_params
Line
Count
Source
340
14
    {                                                                        \
341
14
        return mac_settable_ctx_params(ctx, provctx, macname);               \
342
14
    }
mac_legacy_sig.c:mac_cmac_settable_ctx_params
Line
Count
Source
340
11
    {                                                                        \
341
11
        return mac_settable_ctx_params(ctx, provctx, macname);               \
342
11
    }
343
344
MAC_SETTABLE_CTX_PARAMS(hmac, "HMAC")
345
MAC_SETTABLE_CTX_PARAMS(siphash, "SIPHASH")
346
MAC_SETTABLE_CTX_PARAMS(poly1305, "POLY1305")
347
MAC_SETTABLE_CTX_PARAMS(cmac, "CMAC")
348
349
#define MAC_SIGNATURE_FUNCTIONS(funcname)                                        \
350
    const OSSL_DISPATCH ossl_mac_legacy_##funcname##_signature_functions[] = {   \
351
        { OSSL_FUNC_SIGNATURE_NEWCTX, (void (*)(void))mac_##funcname##_newctx }, \
352
        { OSSL_FUNC_SIGNATURE_DIGEST_SIGN_INIT,                                  \
353
            (void (*)(void))mac_digest_sign_init },                              \
354
        { OSSL_FUNC_SIGNATURE_DIGEST_SIGN_UPDATE,                                \
355
            (void (*)(void))mac_digest_sign_update },                            \
356
        { OSSL_FUNC_SIGNATURE_DIGEST_SIGN_FINAL,                                 \
357
            (void (*)(void))mac_digest_sign_final },                             \
358
        { OSSL_FUNC_SIGNATURE_FREECTX, (void (*)(void))mac_freectx },            \
359
        { OSSL_FUNC_SIGNATURE_DUPCTX, (void (*)(void))mac_dupctx },              \
360
        { OSSL_FUNC_SIGNATURE_SET_CTX_PARAMS,                                    \
361
            (void (*)(void))mac_set_ctx_params },                                \
362
        { OSSL_FUNC_SIGNATURE_SETTABLE_CTX_PARAMS,                               \
363
            (void (*)(void))mac_##funcname##_settable_ctx_params },              \
364
        { OSSL_FUNC_SIGNATURE_GET_CTX_PARAMS,                                    \
365
            (void (*)(void))mac_get_ctx_params },                                \
366
        { OSSL_FUNC_SIGNATURE_GETTABLE_CTX_PARAMS,                               \
367
            (void (*)(void))mac_gettable_ctx_params },                           \
368
        OSSL_DISPATCH_END                                                        \
369
    };
370
371
MAC_SIGNATURE_FUNCTIONS(hmac)
372
MAC_SIGNATURE_FUNCTIONS(siphash)
373
MAC_SIGNATURE_FUNCTIONS(poly1305)
374
MAC_SIGNATURE_FUNCTIONS(cmac)