Coverage Report

Created: 2026-10-28 06:28

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