Coverage Report

Created: 2025-12-14 06:31

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/bind9/lib/isc/iterated_hash.c
Line
Count
Source
1
/*
2
 * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
3
 *
4
 * SPDX-License-Identifier: MPL-2.0
5
 *
6
 * This Source Code Form is subject to the terms of the Mozilla Public
7
 * License, v. 2.0. If a copy of the MPL was not distributed with this
8
 * file, you can obtain one at https://mozilla.org/MPL/2.0/.
9
 *
10
 * See the COPYRIGHT file distributed with this work for additional
11
 * information regarding copyright ownership.
12
 */
13
14
#include <stdbool.h>
15
#include <stdio.h>
16
17
#include <openssl/err.h>
18
#include <openssl/opensslv.h>
19
20
#include <isc/crypto.h>
21
#include <isc/iterated_hash.h>
22
#include <isc/thread.h>
23
#include <isc/util.h>
24
25
#if OPENSSL_VERSION_NUMBER < 0x30000000L
26
27
#include <openssl/sha.h>
28
29
int
30
isc_iterated_hash(unsigned char *out, const unsigned int hashalg,
31
      const int iterations, const unsigned char *salt,
32
      const int saltlength, const unsigned char *in,
33
      const int inlength) {
34
  REQUIRE(out != NULL);
35
36
  int n = 0;
37
  size_t len;
38
  const unsigned char *buf;
39
  SHA_CTX ctx;
40
41
  if (hashalg != 1) {
42
    return 0;
43
  }
44
45
  buf = in;
46
  len = inlength;
47
48
  do {
49
    if (SHA1_Init(&ctx) != 1) {
50
      ERR_clear_error();
51
      return 0;
52
    }
53
54
    if (SHA1_Update(&ctx, buf, len) != 1) {
55
      ERR_clear_error();
56
      return 0;
57
    }
58
59
    if (SHA1_Update(&ctx, salt, saltlength) != 1) {
60
      ERR_clear_error();
61
      return 0;
62
    }
63
64
    if (SHA1_Final(out, &ctx) != 1) {
65
      ERR_clear_error();
66
      return 0;
67
    }
68
69
    buf = out;
70
    len = SHA_DIGEST_LENGTH;
71
  } while (n++ < iterations);
72
73
  return SHA_DIGEST_LENGTH;
74
}
75
76
void
77
isc__iterated_hash_initialize(void) {
78
  /* empty */
79
}
80
81
void
82
isc__iterated_hash_shutdown(void) {
83
  /* empty */
84
}
85
86
#else /* HAVE_SHA1_INIT */
87
88
#include <openssl/evp.h>
89
90
static thread_local bool initialized = false;
91
static thread_local EVP_MD_CTX *mdctx = NULL;
92
static thread_local EVP_MD_CTX *basectx = NULL;
93
94
int
95
isc_iterated_hash(unsigned char *out, const unsigned int hashalg,
96
      const int iterations, const unsigned char *salt,
97
      const int saltlength, const unsigned char *in,
98
0
      const int inlength) {
99
0
  REQUIRE(out != NULL);
100
0
  REQUIRE(mdctx != NULL);
101
0
  REQUIRE(basectx != NULL);
102
103
0
  int n = 0;
104
0
  size_t len;
105
0
  unsigned int outlength = 0;
106
0
  const unsigned char *buf;
107
108
0
  if (hashalg != 1) {
109
0
    return 0;
110
0
  }
111
112
0
  buf = in;
113
0
  len = inlength;
114
0
  do {
115
0
    if (EVP_MD_CTX_copy_ex(mdctx, basectx) != 1) {
116
0
      goto fail;
117
0
    }
118
119
0
    if (EVP_DigestUpdate(mdctx, buf, len) != 1) {
120
0
      goto fail;
121
0
    }
122
123
0
    if (EVP_DigestUpdate(mdctx, salt, saltlength) != 1) {
124
0
      goto fail;
125
0
    }
126
127
0
    if (EVP_DigestFinal_ex(mdctx, out, &outlength) != 1) {
128
0
      goto fail;
129
0
    }
130
131
0
    buf = out;
132
0
    len = outlength;
133
0
  } while (n++ < iterations);
134
135
0
  return outlength;
136
137
0
fail:
138
0
  ERR_clear_error();
139
0
  return 0;
140
0
}
141
142
void
143
22
isc__iterated_hash_initialize(void) {
144
22
  if (initialized) {
145
0
    return;
146
0
  }
147
148
22
  basectx = EVP_MD_CTX_new();
149
22
  INSIST(basectx != NULL);
150
22
  mdctx = EVP_MD_CTX_new();
151
22
  INSIST(mdctx != NULL);
152
153
22
  RUNTIME_CHECK(EVP_DigestInit_ex(basectx, isc__crypto_sha1, NULL) == 1);
154
22
  initialized = true;
155
22
}
156
157
void
158
0
isc__iterated_hash_shutdown(void) {
159
0
  if (!initialized) {
160
0
    return;
161
0
  }
162
163
0
  REQUIRE(mdctx != NULL);
164
0
  EVP_MD_CTX_free(mdctx);
165
0
  mdctx = NULL;
166
0
  REQUIRE(basectx != NULL);
167
0
  EVP_MD_CTX_free(basectx);
168
0
  basectx = NULL;
169
170
  initialized = false;
171
0
}
172
173
#endif /* HAVE_SHA1_INIT */