Coverage Report

Created: 2025-11-24 06:17

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/bind9/lib/isc/md.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 <stdio.h>
15
16
#include <openssl/err.h>
17
#include <openssl/evp.h>
18
#include <openssl/opensslv.h>
19
20
#include <isc/md.h>
21
#include <isc/util.h>
22
23
#include "openssl_shim.h"
24
25
isc_md_t *
26
2
isc_md_new(void) {
27
2
  isc_md_t *md = EVP_MD_CTX_new();
28
2
  RUNTIME_CHECK(md != NULL);
29
2
  return md;
30
2
}
31
32
void
33
2
isc_md_free(isc_md_t *md) {
34
2
  if (md == NULL) {
35
0
    return;
36
0
  }
37
38
2
  EVP_MD_CTX_free(md);
39
2
}
40
41
isc_result_t
42
2
isc_md_init(isc_md_t *md, const isc_md_type_t *md_type) {
43
2
  REQUIRE(md != NULL);
44
45
2
  if (md_type == NULL) {
46
0
    return ISC_R_NOTIMPLEMENTED;
47
0
  }
48
49
2
  if (EVP_DigestInit_ex(md, md_type, NULL) != 1) {
50
0
    ERR_clear_error();
51
0
    return ISC_R_CRYPTOFAILURE;
52
0
  }
53
54
2
  return ISC_R_SUCCESS;
55
2
}
56
57
isc_result_t
58
0
isc_md_reset(isc_md_t *md) {
59
0
  REQUIRE(md != NULL);
60
61
0
  if (EVP_MD_CTX_reset(md) != 1) {
62
0
    ERR_clear_error();
63
0
    return ISC_R_CRYPTOFAILURE;
64
0
  }
65
66
0
  return ISC_R_SUCCESS;
67
0
}
68
69
isc_result_t
70
2
isc_md_update(isc_md_t *md, const unsigned char *buf, const size_t len) {
71
2
  REQUIRE(md != NULL);
72
73
2
  if (buf == NULL || len == 0) {
74
0
    return ISC_R_SUCCESS;
75
0
  }
76
77
2
  if (EVP_DigestUpdate(md, buf, len) != 1) {
78
0
    ERR_clear_error();
79
0
    return ISC_R_CRYPTOFAILURE;
80
0
  }
81
82
2
  return ISC_R_SUCCESS;
83
2
}
84
85
isc_result_t
86
2
isc_md_final(isc_md_t *md, unsigned char *digest, unsigned int *digestlen) {
87
2
  REQUIRE(md != NULL);
88
2
  REQUIRE(digest != NULL);
89
90
2
  if (EVP_DigestFinal_ex(md, digest, digestlen) != 1) {
91
0
    ERR_clear_error();
92
0
    return ISC_R_CRYPTOFAILURE;
93
0
  }
94
95
2
  return ISC_R_SUCCESS;
96
2
}
97
98
const isc_md_type_t *
99
0
isc_md_get_md_type(isc_md_t *md) {
100
0
  REQUIRE(md != NULL);
101
102
0
  return EVP_MD_CTX_get0_md(md);
103
0
}
104
105
size_t
106
0
isc_md_get_size(isc_md_t *md) {
107
0
  REQUIRE(md != NULL);
108
109
0
  return EVP_MD_CTX_size(md);
110
0
}
111
112
size_t
113
0
isc_md_get_block_size(isc_md_t *md) {
114
0
  REQUIRE(md != NULL);
115
116
0
  return EVP_MD_CTX_block_size(md);
117
0
}
118
119
size_t
120
2.81k
isc_md_type_get_size(const isc_md_type_t *md_type) {
121
2.81k
  STATIC_ASSERT(ISC_MAX_MD_SIZE >= EVP_MAX_MD_SIZE,
122
2.81k
          "Change ISC_MAX_MD_SIZE to be greater than or equal to "
123
2.81k
          "EVP_MAX_MD_SIZE");
124
2.81k
  if (md_type != NULL) {
125
2.81k
    return (size_t)EVP_MD_size(md_type);
126
2.81k
  }
127
128
0
  return ISC_MAX_MD_SIZE;
129
2.81k
}
130
131
size_t
132
49
isc_md_type_get_block_size(const isc_md_type_t *md_type) {
133
49
  STATIC_ASSERT(ISC_MAX_MD_SIZE >= EVP_MAX_MD_SIZE,
134
49
          "Change ISC_MAX_MD_SIZE to be greater than or equal to "
135
49
          "EVP_MAX_MD_SIZE");
136
49
  if (md_type != NULL) {
137
49
    return (size_t)EVP_MD_block_size(md_type);
138
49
  }
139
140
0
  return ISC_MAX_MD_SIZE;
141
49
}
142
143
isc_result_t
144
isc_md(const isc_md_type_t *md_type, const unsigned char *buf, const size_t len,
145
2
       unsigned char *digest, unsigned int *digestlen) {
146
2
  isc_md_t *md;
147
2
  isc_result_t res;
148
149
2
  md = isc_md_new();
150
151
2
  res = isc_md_init(md, md_type);
152
2
  if (res != ISC_R_SUCCESS) {
153
0
    goto end;
154
0
  }
155
156
2
  res = isc_md_update(md, buf, len);
157
2
  if (res != ISC_R_SUCCESS) {
158
0
    goto end;
159
0
  }
160
161
2
  res = isc_md_final(md, digest, digestlen);
162
2
  if (res != ISC_R_SUCCESS) {
163
0
    goto end;
164
0
  }
165
2
end:
166
2
  isc_md_free(md);
167
168
2
  return res;
169
2
}