Coverage Report

Created: 2026-09-12 06:55

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/openssl41/providers/implementations/ciphers/cipher_tdes_common.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
/*
11
 * DES low level APIs are deprecated for public use, but still ok for internal
12
 * use.
13
 */
14
#include "internal/deprecated.h"
15
16
#include <openssl/rand.h>
17
#include <openssl/proverr.h>
18
#include "prov/ciphercommon.h"
19
#include "cipher_tdes.h"
20
#include "prov/implementations.h"
21
#include "prov/providercommon.h"
22
23
struct tdes_get_param_list_st {
24
    struct ossl_cipher_get_param_list_st common;
25
    OSSL_PARAM *decrypt;
26
};
27
28
struct tdes_get_ctx_param_list_st {
29
    struct ossl_cipher_get_ctx_param_list_st common;
30
    OSSL_PARAM *rand;
31
#ifdef FIPS_MODULE
32
    OSSL_PARAM *ind;
33
#endif
34
};
35
36
struct tdes_set_ctx_param_list_st {
37
    struct ossl_cipher_set_ctx_param_list_st common;
38
#ifdef FIPS_MODULE
39
    OSSL_PARAM *ind;
40
#endif
41
};
42
43
#define tdes_get_params_st tdes_get_param_list_st
44
#define tdes_get_ctx_params_st tdes_get_ctx_param_list_st
45
#define tdes_set_ctx_params_st tdes_set_ctx_param_list_st
46
47
#include "providers/implementations/ciphers/cipher_tdes.inc"
48
49
void *ossl_tdes_newctx(void *provctx, int mode, size_t kbits, size_t blkbits,
50
    size_t ivbits, uint64_t flags, const PROV_CIPHER_HW *hw)
51
3.94k
{
52
3.94k
    PROV_TDES_CTX *tctx;
53
54
3.94k
    CIPHER_PROV_CHECK(provctx, DES_EDE3_ECB);
55
56
3.94k
    tctx = OPENSSL_zalloc(sizeof(*tctx));
57
3.94k
    if (tctx != NULL) {
58
3.94k
        OSSL_FIPS_IND_INIT(tctx)
59
3.94k
        ossl_cipher_generic_initkey(tctx, kbits, blkbits, ivbits, mode, flags,
60
3.94k
            hw, provctx);
61
3.94k
    }
62
3.94k
    return tctx;
63
3.94k
}
64
65
void *ossl_tdes_dupctx(void *ctx)
66
204
{
67
204
    PROV_TDES_CTX *in = (PROV_TDES_CTX *)ctx;
68
204
    PROV_TDES_CTX *ret;
69
70
204
    if (!ossl_prov_is_running())
71
0
        return NULL;
72
73
204
    ret = OPENSSL_malloc(sizeof(*ret));
74
204
    if (ret == NULL)
75
0
        return NULL;
76
204
    OSSL_FIPS_IND_COPY(ret, in)
77
204
    in->base.hw->copyctx(&ret->base, &in->base);
78
79
204
    return ret;
80
204
}
81
82
void ossl_tdes_freectx(void *vctx)
83
4.15k
{
84
4.15k
    PROV_TDES_CTX *ctx = (PROV_TDES_CTX *)vctx;
85
86
4.15k
    ossl_cipher_generic_reset_ctx((PROV_CIPHER_CTX *)vctx);
87
4.15k
    OPENSSL_clear_free(ctx, sizeof(*ctx));
88
4.15k
}
89
90
#ifdef FIPS_MODULE
91
static int tdes_encrypt_check_approved(PROV_TDES_CTX *ctx, int enc)
92
{
93
    /* Triple-DES encryption is not approved in FIPS 140-3 */
94
    if (enc
95
        && !OSSL_FIPS_IND_ON_UNAPPROVED(ctx, OSSL_FIPS_IND_SETTABLE0,
96
            ctx->base.libctx, "Triple-DES", "Encryption",
97
            FIPS_CONFIG_TDES_ENCRYPT_DISABLED))
98
        return 0;
99
    return 1;
100
}
101
#endif
102
103
static int tdes_init(void *vctx, const unsigned char *key, size_t keylen,
104
    const unsigned char *iv, size_t ivlen,
105
    const OSSL_PARAM params[], int enc)
106
4.18k
{
107
4.18k
    PROV_CIPHER_CTX *ctx = (PROV_CIPHER_CTX *)vctx;
108
109
4.18k
    if (!ossl_prov_is_running())
110
0
        return 0;
111
112
4.18k
    ctx->num = 0;
113
4.18k
    ctx->bufsz = 0;
114
4.18k
    ctx->enc = enc;
115
116
4.18k
    if (iv != NULL) {
117
4.09k
        if (!ossl_cipher_generic_initiv(ctx, iv, ivlen))
118
0
            return 0;
119
4.09k
    } else if (ctx->iv_set
120
0
        && (ctx->mode == EVP_CIPH_CBC_MODE
121
0
            || ctx->mode == EVP_CIPH_CFB_MODE
122
0
            || ctx->mode == EVP_CIPH_OFB_MODE)) {
123
        /* reset IV to keep compatibility with 1.1.1 */
124
0
        memcpy(ctx->iv, ctx->oiv, ctx->ivlen);
125
0
    }
126
127
4.18k
    if (key != NULL) {
128
3.98k
        if (keylen != ctx->keylen) {
129
0
            ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY_LENGTH);
130
0
            return 0;
131
0
        }
132
3.98k
        if (!ctx->hw->init(ctx, key, ctx->keylen))
133
0
            return 0;
134
3.98k
        ctx->key_set = 1;
135
3.98k
    }
136
4.18k
    if (!ossl_tdes_set_ctx_params(ctx, params))
137
0
        return 0;
138
#ifdef FIPS_MODULE
139
    if (!tdes_encrypt_check_approved((PROV_TDES_CTX *)ctx, enc))
140
        return 0;
141
#endif
142
4.18k
    return 1;
143
4.18k
}
144
145
int ossl_tdes_einit(void *vctx, const unsigned char *key, size_t keylen,
146
    const unsigned char *iv, size_t ivlen,
147
    const OSSL_PARAM params[])
148
1.58k
{
149
1.58k
    return tdes_init(vctx, key, keylen, iv, ivlen, params, 1);
150
1.58k
}
151
152
int ossl_tdes_dinit(void *vctx, const unsigned char *key, size_t keylen,
153
    const unsigned char *iv, size_t ivlen,
154
    const OSSL_PARAM params[])
155
2.59k
{
156
2.59k
    return tdes_init(vctx, key, keylen, iv, ivlen, params, 0);
157
2.59k
}
158
159
static int tdes_generatekey(PROV_CIPHER_CTX *ctx, void *ptr)
160
0
{
161
0
    DES_cblock *deskey = ptr;
162
0
    size_t kl = ctx->keylen;
163
164
0
    if (kl == 0 || RAND_priv_bytes_ex(ctx->libctx, ptr, kl, 0) <= 0)
165
0
        return 0;
166
0
    DES_set_odd_parity(deskey);
167
0
    if (kl >= 16) {
168
0
        DES_set_odd_parity(deskey + 1);
169
0
        if (kl >= 24)
170
0
            DES_set_odd_parity(deskey + 2);
171
0
    }
172
0
    return 1;
173
0
}
174
175
const OSSL_PARAM *ossl_tdes_gettable_ctx_params(ossl_unused void *cctx,
176
    ossl_unused void *provctx)
177
770
{
178
770
    return tdes_get_ctx_params_list;
179
770
}
180
181
int ossl_tdes_get_ctx_params(void *vctx, OSSL_PARAM params[])
182
30.4k
{
183
30.4k
    PROV_CIPHER_CTX *ctx = (PROV_CIPHER_CTX *)vctx;
184
30.4k
    struct tdes_get_ctx_param_list_st p;
185
186
30.4k
    if (ctx == NULL || !tdes_get_ctx_params_decoder(params, &p))
187
0
        return 0;
188
189
30.4k
    if (!ossl_cipher_common_get_ctx_params(ctx, &p.common))
190
0
        return 0;
191
192
30.4k
    if (p.rand != NULL && !tdes_generatekey(ctx, p.rand->data)) {
193
0
        ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GENERATE_KEY);
194
0
        return 0;
195
0
    }
196
30.4k
    if (!OSSL_FIPS_IND_GET_CTX_FROM_PARAM((PROV_TDES_CTX *)vctx, p.ind))
197
0
        return 0;
198
30.4k
    return 1;
199
30.4k
}
200
201
const OSSL_PARAM *ossl_tdes_settable_ctx_params(ossl_unused void *cctx,
202
    ossl_unused void *provctx)
203
47
{
204
47
    return tdes_set_ctx_params_list;
205
47
}
206
207
int ossl_tdes_set_ctx_params(void *vctx, const OSSL_PARAM params[])
208
2.08k
{
209
2.08k
    PROV_TDES_CTX *ctx = (PROV_TDES_CTX *)vctx;
210
2.08k
    struct tdes_set_ctx_param_list_st p;
211
212
2.08k
    if (ctx == NULL || !tdes_set_ctx_params_decoder(params, &p))
213
0
        return 0;
214
2.08k
    if (!OSSL_FIPS_IND_SET_CTX_FROM_PARAM(ctx, OSSL_FIPS_IND_SETTABLE0, p.ind))
215
0
        return 0;
216
217
2.08k
    return ossl_cipher_common_set_ctx_params(&ctx->base, &p.common);
218
2.08k
}
219
220
const OSSL_PARAM *ossl_tdes_gettable_params(ossl_unused void *provctx)
221
0
{
222
0
    return tdes_get_params_list;
223
0
}
224
225
int ossl_tdes_get_params(OSSL_PARAM params[], unsigned int md, uint64_t flags,
226
    size_t kbits, size_t blkbits, size_t ivbits)
227
29.1k
{
228
#ifdef FIPS_MODULE
229
    const int decrypt_only = 1;
230
#else
231
29.1k
    const int decrypt_only = 0;
232
29.1k
#endif
233
29.1k
    struct tdes_get_param_list_st p;
234
235
29.1k
    if (!tdes_get_params_decoder(params, &p))
236
0
        return 0;
237
238
29.1k
    if (p.decrypt != NULL && !OSSL_PARAM_set_int(p.decrypt, decrypt_only)) {
239
0
        ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
240
0
        return 0;
241
0
    }
242
243
29.1k
    return ossl_cipher_common_get_params(&p.common, md, flags, kbits, blkbits,
244
29.1k
        ivbits);
245
29.1k
}