Coverage Report

Created: 2026-06-09 06:11

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/iterated_hash.h>
21
#include <isc/md.h>
22
#include <isc/ossl_wrap.h>
23
#include <isc/thread.h>
24
#include <isc/util.h>
25
26
#if OPENSSL_VERSION_NUMBER < 0x30000000L
27
28
#include <openssl/sha.h>
29
30
int
31
isc_iterated_hash(unsigned char *out, const unsigned int hashalg,
32
      const int iterations, const unsigned char *salt,
33
      const int saltlength, const unsigned char *in,
34
      const int inlength) {
35
  REQUIRE(out != NULL);
36
37
  int n = 0;
38
  size_t len;
39
  const unsigned char *buf;
40
  SHA_CTX ctx;
41
42
  if (hashalg != 1) {
43
    return 0;
44
  }
45
46
  buf = in;
47
  len = inlength;
48
49
  do {
50
    if (SHA1_Init(&ctx) != 1) {
51
      ERR_clear_error();
52
      return 0;
53
    }
54
55
    if (SHA1_Update(&ctx, buf, len) != 1) {
56
      ERR_clear_error();
57
      return 0;
58
    }
59
60
    if (SHA1_Update(&ctx, salt, saltlength) != 1) {
61
      ERR_clear_error();
62
      return 0;
63
    }
64
65
    if (SHA1_Final(out, &ctx) != 1) {
66
      ERR_clear_error();
67
      return 0;
68
    }
69
70
    buf = out;
71
    len = SHA_DIGEST_LENGTH;
72
  } while (n++ < iterations);
73
74
  return SHA_DIGEST_LENGTH;
75
}
76
77
void
78
isc__iterated_hash_initialize(void) {
79
  /* empty */
80
}
81
82
void
83
isc__iterated_hash_shutdown(void) {
84
  /* empty */
85
}
86
87
#else /* HAVE_SHA1_INIT */
88
89
#include <openssl/evp.h>
90
91
static thread_local bool initialized = false;
92
static thread_local EVP_MD_CTX *mdctx = NULL;
93
static thread_local EVP_MD_CTX *basectx = NULL;
94
95
int
96
isc_iterated_hash(unsigned char *out, const unsigned int hashalg,
97
      const int iterations, const unsigned char *salt,
98
      const int saltlength, const unsigned char *in,
99
0
      const int inlength) {
100
0
  REQUIRE(out != NULL);
101
0
  REQUIRE(mdctx != NULL);
102
0
  REQUIRE(basectx != NULL);
103
104
0
  int n = 0;
105
0
  size_t len;
106
0
  unsigned int outlength = 0;
107
0
  const unsigned char *buf;
108
109
0
  if (hashalg != 1) {
110
0
    return 0;
111
0
  }
112
113
0
  buf = in;
114
0
  len = inlength;
115
0
  do {
116
0
    if (EVP_MD_CTX_copy_ex(mdctx, basectx) != 1) {
117
0
      goto fail;
118
0
    }
119
120
0
    if (EVP_DigestUpdate(mdctx, buf, len) != 1) {
121
0
      goto fail;
122
0
    }
123
124
0
    if (EVP_DigestUpdate(mdctx, salt, saltlength) != 1) {
125
0
      goto fail;
126
0
    }
127
128
0
    if (EVP_DigestFinal_ex(mdctx, out, &outlength) != 1) {
129
0
      goto fail;
130
0
    }
131
132
0
    buf = out;
133
0
    len = outlength;
134
0
  } while (n++ < iterations);
135
136
0
  return outlength;
137
138
0
fail:
139
0
  ERR_clear_error();
140
0
  return 0;
141
0
}
142
143
void
144
22
isc__iterated_hash_initialize(void) {
145
22
  if (initialized) {
146
0
    return;
147
0
  }
148
149
22
  basectx = EVP_MD_CTX_new();
150
22
  INSIST(basectx != NULL);
151
22
  mdctx = EVP_MD_CTX_new();
152
22
  INSIST(mdctx != NULL);
153
154
22
  RUNTIME_CHECK(EVP_DigestInit_ex(basectx, isc__crypto_md[ISC_MD_SHA1],
155
22
          NULL) == 1);
156
22
  initialized = true;
157
22
}
158
159
void
160
0
isc__iterated_hash_shutdown(void) {
161
0
  if (!initialized) {
162
0
    return;
163
0
  }
164
165
0
  REQUIRE(mdctx != NULL);
166
0
  EVP_MD_CTX_free(mdctx);
167
0
  mdctx = NULL;
168
0
  REQUIRE(basectx != NULL);
169
0
  EVP_MD_CTX_free(basectx);
170
0
  basectx = NULL;
171
172
  initialized = false;
173
0
}
174
175
#endif /* HAVE_SHA1_INIT */