Coverage Report

Created: 2026-05-30 06:06

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/openssl/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
#include <stdbool.h>
11
#include <openssl/crypto.h>
12
#include <openssl/evp.h>
13
#include <openssl/core_dispatch.h>
14
#include <openssl/core_names.h>
15
#include <openssl/params.h>
16
#include <openssl/err.h>
17
#include <openssl/proverr.h>
18
#include "prov/implementations.h"
19
#include "prov/provider_ctx.h"
20
#include "prov/macsignature.h"
21
#include "prov/providercommon.h"
22
#include "prov/securitycheck.h"
23
#include "internal/fips.h"
24
#include "internal/common.h"
25
26
#ifndef FIPS_MODULE
27
#define mac_legacy_get_ctx_params_decoder
28
#define mac_legacy_set_ctx_params_decoder
29
#endif
30
#include "providers/implementations/signature/mac_legacy_sig.inc"
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
0
{
60
0
    PROV_MAC_CTX *pmacctx;
61
0
    EVP_MAC *mac = NULL;
62
63
0
    if (!ossl_prov_is_running())
64
0
        return NULL;
65
66
0
    pmacctx = OPENSSL_zalloc(sizeof(PROV_MAC_CTX));
67
0
    if (pmacctx == NULL)
68
0
        return NULL;
69
70
0
    pmacctx->libctx = PROV_LIBCTX_OF(provctx);
71
0
    if (propq != NULL && (pmacctx->propq = OPENSSL_strdup(propq)) == NULL)
72
0
        goto err;
73
74
0
    mac = EVP_MAC_fetch(pmacctx->libctx, macname, propq);
75
0
    if (mac == NULL)
76
0
        goto err;
77
78
0
    pmacctx->macctx = EVP_MAC_CTX_new(mac);
79
0
    if (pmacctx->macctx == NULL)
80
0
        goto err;
81
82
0
    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
0
    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
0
}
96
97
#define MAC_NEWCTX(funcname, macname)                                      \
98
    static void *mac_##funcname##_newctx(void *provctx, const char *propq) \
99
0
    {                                                                      \
100
0
        return mac_newctx(provctx, propq, macname);                        \
101
0
    }
Unexecuted instantiation: mac_legacy_sig.c:mac_hmac_newctx
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, size_t keylen)
114
{
115
    int approved = ossl_mac_check_key_size(keylen);
116
117
    if (!approved) {
118
        if (!OSSL_FIPS_IND_ON_UNAPPROVED(macctx, OSSL_FIPS_IND_SETTABLE0,
119
                macctx->libctx, "HMAC", "keysize",
120
                FIPS_CONFIG_HMAC_KEY_CHECK)) {
121
            ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY_LENGTH);
122
            return 0;
123
        }
124
    }
125
    return 1;
126
}
127
#endif
128
129
static int mac_digest_sign_init(void *vpmacctx, const char *mdname, void *vkey,
130
    const OSSL_PARAM params[])
131
0
{
132
0
    PROV_MAC_CTX *pmacctx = (PROV_MAC_CTX *)vpmacctx;
133
0
    const char *ciphername = NULL;
134
135
0
    if (!ossl_prov_is_running()
136
0
        || pmacctx == NULL)
137
0
        return 0;
138
139
0
    if (pmacctx->key == NULL && vkey == NULL) {
140
0
        ERR_raise(ERR_LIB_PROV, PROV_R_NO_KEY_SET);
141
0
        return 0;
142
0
    }
143
144
0
    if (vkey != NULL) {
145
0
        if (!ossl_mac_key_up_ref(vkey))
146
0
            return 0;
147
0
        ossl_mac_key_free(pmacctx->key);
148
0
        pmacctx->key = vkey;
149
0
    }
150
151
0
    if (pmacctx->key->cipher.cipher != NULL)
152
0
        ciphername = EVP_CIPHER_get0_name(pmacctx->key->cipher.cipher);
153
154
0
    if (!ossl_prov_set_macctx(pmacctx->macctx,
155
0
            ciphername,
156
0
            mdname,
157
0
            pmacctx->key->properties, params))
158
0
        return 0;
159
160
#ifdef FIPS_MODULE
161
    if (pmacctx->hmac_keysize_check
162
        && !hmac_check_key(pmacctx, pmacctx->key->priv_key, pmacctx->key->priv_key_len))
163
        return 0;
164
#endif
165
0
    if (!EVP_MAC_init(pmacctx->macctx, pmacctx->key->priv_key,
166
0
            pmacctx->key->priv_key_len, NULL))
167
0
        return 0;
168
169
0
    return 1;
170
0
}
171
172
int mac_digest_sign_update(void *vpmacctx, const unsigned char *data,
173
    size_t datalen)
174
0
{
175
0
    PROV_MAC_CTX *pmacctx = (PROV_MAC_CTX *)vpmacctx;
176
177
0
    if (pmacctx == NULL || pmacctx->macctx == NULL)
178
0
        return 0;
179
180
0
    return EVP_MAC_update(pmacctx->macctx, data, datalen);
181
0
}
182
183
int mac_digest_sign_final(void *vpmacctx, unsigned char *mac, size_t *maclen,
184
    size_t macsize)
185
0
{
186
0
    PROV_MAC_CTX *pmacctx = (PROV_MAC_CTX *)vpmacctx;
187
188
0
    if (!ossl_prov_is_running() || pmacctx == NULL || pmacctx->macctx == NULL)
189
0
        return 0;
190
191
0
    return EVP_MAC_final(pmacctx->macctx, mac, maclen, macsize);
192
0
}
193
194
static void mac_freectx(void *vpmacctx)
195
0
{
196
0
    PROV_MAC_CTX *ctx = (PROV_MAC_CTX *)vpmacctx;
197
198
0
    OPENSSL_free(ctx->propq);
199
0
    EVP_MAC_CTX_free(ctx->macctx);
200
0
    ossl_mac_key_free(ctx->key);
201
0
    OPENSSL_free(ctx);
202
0
}
203
204
static void *mac_dupctx(void *vpmacctx)
205
0
{
206
0
    PROV_MAC_CTX *srcctx = (PROV_MAC_CTX *)vpmacctx;
207
0
    PROV_MAC_CTX *dstctx;
208
209
0
    if (!ossl_prov_is_running())
210
0
        return NULL;
211
212
0
    dstctx = OPENSSL_zalloc(sizeof(*srcctx));
213
0
    if (dstctx == NULL)
214
0
        return NULL;
215
216
0
    *dstctx = *srcctx;
217
0
    dstctx->propq = NULL;
218
0
    dstctx->key = NULL;
219
0
    dstctx->macctx = NULL;
220
221
0
    if (srcctx->propq != NULL && (dstctx->propq = OPENSSL_strdup(srcctx->propq)) == NULL)
222
0
        goto err;
223
224
0
    if (srcctx->key != NULL && !ossl_mac_key_up_ref(srcctx->key))
225
0
        goto err;
226
0
    dstctx->key = srcctx->key;
227
228
0
    if (srcctx->macctx != NULL) {
229
0
        dstctx->macctx = EVP_MAC_CTX_dup(srcctx->macctx);
230
0
        if (dstctx->macctx == NULL)
231
0
            goto err;
232
0
    }
233
234
0
    return dstctx;
235
0
err:
236
0
    mac_freectx(dstctx);
237
0
    return NULL;
238
0
}
239
240
static int mac_set_ctx_params(void *vpmacctx, const OSSL_PARAM params[])
241
0
{
242
0
    PROV_MAC_CTX *ctx = (PROV_MAC_CTX *)vpmacctx;
243
244
#ifdef FIPS_MODULE
245
    if (ctx->hmac_keysize_check) {
246
        struct mac_legacy_set_ctx_params_st p;
247
248
        if (!mac_legacy_set_ctx_params_decoder(params, &p))
249
            return 0;
250
        if (!OSSL_FIPS_IND_SET_CTX_FROM_PARAM(ctx, OSSL_FIPS_IND_SETTABLE0, p.ind_k))
251
            return 0;
252
        if (p.key != NULL) {
253
            if (p.key->data_type != OSSL_PARAM_OCTET_STRING)
254
                return 0;
255
            if (!hmac_check_key(ctx, p.key->data, p.key->data_size))
256
                return 0;
257
        }
258
    }
259
#endif
260
0
    return EVP_MAC_CTX_set_params(ctx->macctx, params);
261
0
}
262
263
static const OSSL_PARAM *mac_settable_ctx_params(ossl_unused void *ctx,
264
    void *provctx,
265
    const char *macname)
266
0
{
267
0
    EVP_MAC *mac = EVP_MAC_fetch(PROV_LIBCTX_OF(provctx), macname,
268
0
        NULL);
269
0
    const OSSL_PARAM *params;
270
271
0
    if (mac == NULL)
272
0
        return NULL;
273
274
0
    params = EVP_MAC_settable_ctx_params(mac);
275
0
    EVP_MAC_free(mac);
276
277
0
    return params;
278
0
}
279
280
static const OSSL_PARAM *mac_gettable_ctx_params(ossl_unused void *vctx,
281
    ossl_unused void *provctx)
282
0
{
283
0
    return mac_legacy_get_ctx_params_list;
284
0
}
285
286
static int mac_get_ctx_params(void *vctx, OSSL_PARAM params[])
287
0
{
288
0
    PROV_MAC_CTX *ctx = vctx;
289
290
0
    if (ctx == NULL)
291
0
        return 0;
292
293
#ifdef FIPS_MODULE
294
    struct mac_legacy_get_ctx_params_st p;
295
296
    if (!mac_legacy_get_ctx_params_decoder(params, &p))
297
        return 0;
298
    if (p.ind != NULL) {
299
        int approved = OSSL_FIPS_IND_GET(ctx)->approved;
300
        if (!OSSL_PARAM_set_int(p.ind, approved))
301
            return 0;
302
    }
303
#endif
304
0
    return 1;
305
0
}
306
307
#define MAC_SETTABLE_CTX_PARAMS(funcname, macname)                           \
308
    static const OSSL_PARAM *mac_##funcname##_settable_ctx_params(void *ctx, \
309
        void *provctx)                                                       \
310
0
    {                                                                        \
311
0
        return mac_settable_ctx_params(ctx, provctx, macname);               \
312
0
    }
Unexecuted instantiation: mac_legacy_sig.c:mac_hmac_settable_ctx_params
Unexecuted instantiation: mac_legacy_sig.c:mac_siphash_settable_ctx_params
Unexecuted instantiation: mac_legacy_sig.c:mac_poly1305_settable_ctx_params
Unexecuted instantiation: mac_legacy_sig.c:mac_cmac_settable_ctx_params
313
314
MAC_SETTABLE_CTX_PARAMS(hmac, "HMAC")
315
MAC_SETTABLE_CTX_PARAMS(siphash, "SIPHASH")
316
MAC_SETTABLE_CTX_PARAMS(poly1305, "POLY1305")
317
MAC_SETTABLE_CTX_PARAMS(cmac, "CMAC")
318
319
#define MAC_SIGNATURE_FUNCTIONS(funcname)                                        \
320
    const OSSL_DISPATCH ossl_mac_legacy_##funcname##_signature_functions[] = {   \
321
        { OSSL_FUNC_SIGNATURE_NEWCTX, (void (*)(void))mac_##funcname##_newctx }, \
322
        { OSSL_FUNC_SIGNATURE_DIGEST_SIGN_INIT,                                  \
323
            (void (*)(void))mac_digest_sign_init },                              \
324
        { OSSL_FUNC_SIGNATURE_DIGEST_SIGN_UPDATE,                                \
325
            (void (*)(void))mac_digest_sign_update },                            \
326
        { OSSL_FUNC_SIGNATURE_DIGEST_SIGN_FINAL,                                 \
327
            (void (*)(void))mac_digest_sign_final },                             \
328
        { OSSL_FUNC_SIGNATURE_FREECTX, (void (*)(void))mac_freectx },            \
329
        { OSSL_FUNC_SIGNATURE_DUPCTX, (void (*)(void))mac_dupctx },              \
330
        { OSSL_FUNC_SIGNATURE_SET_CTX_PARAMS,                                    \
331
            (void (*)(void))mac_set_ctx_params },                                \
332
        { OSSL_FUNC_SIGNATURE_SETTABLE_CTX_PARAMS,                               \
333
            (void (*)(void))mac_##funcname##_settable_ctx_params },              \
334
        { OSSL_FUNC_SIGNATURE_GET_CTX_PARAMS,                                    \
335
            (void (*)(void))mac_get_ctx_params },                                \
336
        { OSSL_FUNC_SIGNATURE_GETTABLE_CTX_PARAMS,                               \
337
            (void (*)(void))mac_gettable_ctx_params },                           \
338
        OSSL_DISPATCH_END                                                        \
339
    };
340
341
MAC_SIGNATURE_FUNCTIONS(hmac)
342
MAC_SIGNATURE_FUNCTIONS(siphash)
343
MAC_SIGNATURE_FUNCTIONS(poly1305)
344
MAC_SIGNATURE_FUNCTIONS(cmac)