Coverage Report

Created: 2026-02-22 06:11

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/openssl/providers/implementations/digests/sha2_prov.c
Line
Count
Source
1
/*
2
 * Copyright 2019-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
/*
11
 * SHA low level APIs are deprecated for public use, but still ok for
12
 * internal use.
13
 */
14
#include "internal/deprecated.h"
15
16
#include <openssl/byteorder.h>
17
#include <openssl/crypto.h>
18
#include <openssl/core_dispatch.h>
19
#include <openssl/evp.h>
20
#include <openssl/err.h>
21
#include <openssl/sha.h>
22
#include <openssl/params.h>
23
#include <openssl/proverr.h>
24
#include <openssl/core_names.h>
25
#include "prov/digestcommon.h"
26
#include "prov/implementations.h"
27
#include "crypto/sha.h"
28
#include "internal/common.h"
29
#include "providers/implementations/digests/sha2_prov.inc"
30
31
#define SHA2_FLAGS PROV_DIGEST_FLAG_ALGID_ABSENT
32
33
extern int SHA1_Update_thunk(void *ctx, const unsigned char *data, size_t sz);
34
extern int SHA256_Update_thunk(void *ctx, const unsigned char *data, size_t sz);
35
extern int SHA512_Update_thunk(void *ctx, const unsigned char *data, size_t sz);
36
37
/* Special set_params method for SSL3 */
38
static int sha1_set_ctx_params(void *vctx, const OSSL_PARAM params[])
39
140
{
40
140
    struct sha1_set_ctx_params_st p;
41
140
    SHA_CTX *ctx = (SHA_CTX *)vctx;
42
43
140
    if (ossl_unlikely(ctx == NULL || !sha1_set_ctx_params_decoder(params, &p)))
44
0
        return 0;
45
46
140
    if (p.ssl3_ms != NULL)
47
0
        return ossl_sha1_ctrl(ctx, EVP_CTRL_SSL3_MASTER_SECRET,
48
0
            (int)p.ssl3_ms->data_size, p.ssl3_ms->data);
49
50
140
    return 1;
51
140
}
52
53
static const OSSL_PARAM *sha1_settable_ctx_params(ossl_unused void *ctx,
54
    ossl_unused void *provctx)
55
0
{
56
0
    return sha1_set_ctx_params_list;
57
0
}
58
59
static const unsigned char sha256magic[] = "SHA256v1";
60
0
#define SHA256MAGIC_LEN (sizeof(sha256magic) - 1)
61
#define SHA256_SERIALIZATION_LEN                      \
62
0
    (                                                 \
63
0
        SHA256MAGIC_LEN /* magic */                   \
64
0
        + sizeof(uint32_t) /* c->md_len */            \
65
0
        + sizeof(uint32_t) /* c->num */               \
66
0
        + sizeof(uint32_t) * 8 /* c->h */             \
67
0
        + sizeof(uint32_t) * 2 /* c->Nl + c->Nh */    \
68
0
        + sizeof(uint32_t) * SHA_LBLOCK /* c->data */ \
69
0
    )
70
71
static int SHA256_Serialize(SHA256_CTX *c, unsigned char *out,
72
    size_t *outlen)
73
0
{
74
0
    unsigned char *p;
75
0
    unsigned long i;
76
77
0
    if (out == NULL) {
78
0
        if (outlen == NULL)
79
0
            return 0;
80
81
0
        *outlen = SHA256_SERIALIZATION_LEN;
82
0
        return 1;
83
0
    }
84
85
0
    if (outlen != NULL && *outlen < SHA256_SERIALIZATION_LEN)
86
0
        return 0;
87
88
0
    p = out;
89
90
    /* Magic code */
91
0
    memcpy(p, sha256magic, SHA256MAGIC_LEN);
92
0
    p += SHA256MAGIC_LEN;
93
94
    /* md_len */
95
0
    p = OPENSSL_store_u32_le(p, c->md_len);
96
97
    /* num */
98
0
    p = OPENSSL_store_u32_le(p, c->num);
99
100
    /* h */
101
0
    for (i = 0; i < sizeof(c->h) / sizeof(SHA_LONG); i++)
102
0
        p = OPENSSL_store_u32_le(p, c->h[i]);
103
104
    /* Nl, Nh */
105
0
    p = OPENSSL_store_u32_le(p, c->Nl);
106
0
    p = OPENSSL_store_u32_le(p, c->Nh);
107
108
    /* data */
109
0
    for (i = 0; i < SHA_LBLOCK; i++)
110
0
        p = OPENSSL_store_u32_le(p, c->data[i]);
111
112
0
    if (outlen != NULL)
113
0
        *outlen = SHA256_SERIALIZATION_LEN;
114
115
0
    return 1;
116
0
}
117
118
/*
119
 * This function only performs basic input sanity checks and is not
120
 * built to handle malicious input data. Only trusted input should be
121
 * fed to this function
122
 */
123
static int SHA256_Deserialize(SHA256_CTX *c, const unsigned char *in,
124
    size_t inlen)
125
0
{
126
0
    const unsigned char *p;
127
0
    uint32_t val;
128
0
    unsigned long i;
129
130
0
    if (c == NULL || in == NULL || inlen != SHA256_SERIALIZATION_LEN)
131
0
        return 0;
132
133
    /* Magic code check */
134
0
    if (memcmp(in, sha256magic, SHA256MAGIC_LEN) != 0)
135
0
        return 0;
136
137
0
    p = in + SHA256MAGIC_LEN;
138
139
    /* md_len check */
140
0
    p = OPENSSL_load_u32_le(&val, p);
141
0
    if ((unsigned int)val != c->md_len) {
142
0
        return 0;
143
0
    }
144
145
    /* num check */
146
0
    p = OPENSSL_load_u32_le(&val, p);
147
0
    if (val >= sizeof(c->data))
148
0
        return 0;
149
0
    c->num = (unsigned int)val;
150
151
    /* h */
152
0
    for (i = 0; i < (sizeof(c->h) / sizeof(SHA_LONG)); i++) {
153
0
        p = OPENSSL_load_u32_le(&val, p);
154
0
        c->h[i] = (SHA_LONG)val;
155
0
    }
156
157
    /* Nl, Nh */
158
0
    p = OPENSSL_load_u32_le(&val, p);
159
0
    c->Nl = (SHA_LONG)val;
160
0
    p = OPENSSL_load_u32_le(&val, p);
161
0
    c->Nh = (SHA_LONG)val;
162
163
    /* data */
164
0
    for (i = 0; i < SHA_LBLOCK; i++) {
165
0
        p = OPENSSL_load_u32_le(&val, p);
166
0
        c->data[i] = (SHA_LONG)val;
167
0
    }
168
169
0
    return 1;
170
0
}
171
172
static const unsigned char sha512magic[] = "SHA512v1";
173
0
#define SHA512MAGIC_LEN (sizeof(sha512magic) - 1)
174
#define SHA512_SERIALIZATION_LEN                   \
175
0
    (                                              \
176
0
        SHA512MAGIC_LEN /* magic */                \
177
0
        + sizeof(uint32_t) /* c->md_len */         \
178
0
        + sizeof(uint32_t) /* c->num */            \
179
0
        + sizeof(uint64_t) * 8 /* c->h */          \
180
0
        + sizeof(uint64_t) * 2 /* c->Nl + c->Nh */ \
181
0
        + SHA512_CBLOCK /* c->u.d/c->u.p */        \
182
0
    )
183
184
static int SHA512_Serialize(SHA512_CTX *c, unsigned char *out,
185
    size_t *outlen)
186
0
{
187
0
    unsigned char *p;
188
0
    unsigned long i;
189
190
0
    if (out == NULL) {
191
0
        if (outlen == NULL)
192
0
            return 0;
193
194
0
        *outlen = SHA512_SERIALIZATION_LEN;
195
0
        return 1;
196
0
    }
197
198
0
    if (outlen != NULL && *outlen < SHA512_SERIALIZATION_LEN)
199
0
        return 0;
200
201
0
    p = out;
202
203
    /* Magic code */
204
0
    memcpy(p, sha512magic, SHA512MAGIC_LEN);
205
0
    p += SHA512MAGIC_LEN;
206
207
    /* md_len */
208
0
    p = OPENSSL_store_u32_le(p, c->md_len);
209
210
    /* num */
211
0
    p = OPENSSL_store_u32_le(p, c->num);
212
213
    /* h */
214
0
    for (i = 0; i < sizeof(c->h) / sizeof(SHA_LONG64); i++)
215
0
        p = OPENSSL_store_u64_le(p, c->h[i]);
216
217
    /* Nl, Nh */
218
0
    p = OPENSSL_store_u64_le(p, c->Nl);
219
0
    p = OPENSSL_store_u64_le(p, c->Nh);
220
221
    /* data */
222
0
    memcpy(p, c->u.p, SHA512_CBLOCK);
223
0
    p += SHA512_CBLOCK;
224
225
0
    if (outlen != NULL)
226
0
        *outlen = SHA512_SERIALIZATION_LEN;
227
228
0
    return 1;
229
0
}
230
231
/*
232
 * This function only performs basic input sanity checks and is not
233
 * built to handle malicious input data. Only trusted input should be
234
 * fed to this function
235
 */
236
static int SHA512_Deserialize(SHA512_CTX *c, const unsigned char *in,
237
    size_t inlen)
238
0
{
239
0
    const unsigned char *p;
240
0
    uint32_t val32;
241
0
    uint64_t val;
242
0
    unsigned long i;
243
244
0
    if (c == NULL || in == NULL || inlen != SHA512_SERIALIZATION_LEN)
245
0
        return 0;
246
247
    /* Magic code */
248
0
    if (memcmp(in, sha512magic, SHA512MAGIC_LEN) != 0)
249
0
        return 0;
250
251
0
    p = in + SHA512MAGIC_LEN;
252
253
    /* md_len check */
254
0
    p = OPENSSL_load_u32_le(&val32, p);
255
0
    if ((unsigned int)val32 != c->md_len)
256
0
        return 0;
257
258
    /* num check */
259
0
    p = OPENSSL_load_u32_le(&val32, p);
260
0
    if (val32 >= sizeof(c->u.d))
261
0
        return 0;
262
0
    c->num = (unsigned int)val32;
263
264
    /* h */
265
0
    for (i = 0; i < (sizeof(c->h) / sizeof(SHA_LONG64)); i++) {
266
0
        p = OPENSSL_load_u64_le(&val, p);
267
0
        c->h[i] = (SHA_LONG64)val;
268
0
    }
269
270
    /* Nl, Nh */
271
0
    p = OPENSSL_load_u64_le(&val, p);
272
0
    c->Nl = (SHA_LONG64)val;
273
0
    p = OPENSSL_load_u64_le(&val, p);
274
0
    c->Nh = (SHA_LONG64)val;
275
276
    /* data */
277
0
    memcpy(c->u.p, p, SHA512_CBLOCK);
278
0
    p += SHA512_CBLOCK;
279
280
0
    return 1;
281
0
}
282
283
/* ossl_sha1_functions */
284
0
IMPLEMENT_digest_functions_with_settable_ctx(
Unexecuted instantiation: sha2_prov.c:sha1_newctx
Unexecuted instantiation: sha2_prov.c:sha1_dupctx
285
0
    sha1, SHA_CTX, SHA_CBLOCK, SHA_DIGEST_LENGTH, SHA2_FLAGS,
286
0
    SHA1_Init, SHA1_Update_thunk, SHA1_Final,
287
0
    sha1_settable_ctx_params, sha1_set_ctx_params)
288
0
289
0
/* ossl_sha224_functions */
290
0
IMPLEMENT_digest_functions_with_serialize(sha224, SHA256_CTX,
Unexecuted instantiation: sha2_prov.c:sha224_newctx
Unexecuted instantiation: sha2_prov.c:sha224_dupctx
291
0
    SHA256_CBLOCK, SHA224_DIGEST_LENGTH,
292
0
    SHA2_FLAGS, SHA224_Init,
293
0
    SHA256_Update_thunk, SHA224_Final,
294
0
    SHA256_Serialize, SHA256_Deserialize)
295
0
296
0
/* ossl_sha256_functions */
297
0
IMPLEMENT_digest_functions_with_serialize(sha256, SHA256_CTX,
Unexecuted instantiation: sha2_prov.c:sha256_newctx
Unexecuted instantiation: sha2_prov.c:sha256_dupctx
298
0
    SHA256_CBLOCK, SHA256_DIGEST_LENGTH,
299
0
    SHA2_FLAGS, SHA256_Init,
300
0
    SHA256_Update_thunk, SHA256_Final,
301
0
    SHA256_Serialize, SHA256_Deserialize)
302
0
/* ossl_sha256_192_internal_functions */
303
0
IMPLEMENT_digest_functions_with_serialize(sha256_192_internal, SHA256_CTX,
Unexecuted instantiation: sha2_prov.c:sha256_192_internal_newctx
Unexecuted instantiation: sha2_prov.c:sha256_192_internal_dupctx
304
0
    SHA256_CBLOCK, SHA256_192_DIGEST_LENGTH,
305
0
    SHA2_FLAGS, ossl_sha256_192_init,
306
0
    SHA256_Update_thunk, SHA256_Final,
307
0
    SHA256_Serialize, SHA256_Deserialize)
308
0
/* ossl_sha384_functions */
309
0
IMPLEMENT_digest_functions_with_serialize(sha384, SHA512_CTX,
Unexecuted instantiation: sha2_prov.c:sha384_newctx
Unexecuted instantiation: sha2_prov.c:sha384_dupctx
310
0
    SHA512_CBLOCK, SHA384_DIGEST_LENGTH,
311
0
    SHA2_FLAGS, SHA384_Init,
312
0
    SHA512_Update_thunk, SHA384_Final,
313
0
    SHA512_Serialize, SHA512_Deserialize)
314
0
315
0
/* ossl_sha512_functions */
316
0
IMPLEMENT_digest_functions_with_serialize(sha512, SHA512_CTX,
Unexecuted instantiation: sha2_prov.c:sha512_newctx
Unexecuted instantiation: sha2_prov.c:sha512_dupctx
317
0
    SHA512_CBLOCK, SHA512_DIGEST_LENGTH,
318
0
    SHA2_FLAGS, SHA512_Init,
319
0
    SHA512_Update_thunk, SHA512_Final,
320
0
    SHA512_Serialize, SHA512_Deserialize)
321
0
322
0
/* ossl_sha512_224_functions */
323
0
IMPLEMENT_digest_functions_with_serialize(sha512_224, SHA512_CTX,
Unexecuted instantiation: sha2_prov.c:sha512_224_newctx
Unexecuted instantiation: sha2_prov.c:sha512_224_dupctx
324
0
    SHA512_CBLOCK, SHA224_DIGEST_LENGTH,
325
0
    SHA2_FLAGS, sha512_224_init,
326
0
    SHA512_Update_thunk, SHA512_Final,
327
0
    SHA512_Serialize, SHA512_Deserialize)
328
0
329
0
/* ossl_sha512_256_functions */
330
IMPLEMENT_digest_functions_with_serialize(sha512_256, SHA512_CTX,
Unexecuted instantiation: sha2_prov.c:sha512_256_newctx
Unexecuted instantiation: sha2_prov.c:sha512_256_dupctx
331
    SHA512_CBLOCK, SHA256_DIGEST_LENGTH,
332
    SHA2_FLAGS, sha512_256_init,
333
    SHA512_Update_thunk, SHA512_Final,
334
    SHA512_Serialize, SHA512_Deserialize)