Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sudo-project
GitHub Repository: sudo-project/sudo
Path: blob/main/lib/util/digest_openssl.c
1532 views
1
/*
2
* SPDX-License-Identifier: ISC
3
*
4
* Copyright (c) 2013-2021 Todd C. Miller <[email protected]>
5
*
6
* Permission to use, copy, modify, and distribute this software for any
7
* purpose with or without fee is hereby granted, provided that the above
8
* copyright notice and this permission notice appear in all copies.
9
*
10
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17
*/
18
19
#include <config.h>
20
21
#include <stdlib.h>
22
#include <errno.h>
23
24
#if defined(HAVE_WOLFSSL)
25
# include <wolfssl/options.h>
26
#endif
27
#include <openssl/evp.h>
28
29
#include <sudo_compat.h>
30
#include <sudo_debug.h>
31
#include <sudo_digest.h>
32
33
struct sudo_digest {
34
EVP_MD_CTX *ctx;
35
const EVP_MD *md;
36
};
37
38
static const EVP_MD *
39
sudo_digest_type_to_md(unsigned int digest_type)
40
{
41
const EVP_MD *md = NULL;
42
debug_decl(sudo_digest_type_to_md, SUDO_DEBUG_UTIL);
43
44
switch (digest_type) {
45
case SUDO_DIGEST_SHA224:
46
md = EVP_sha224();
47
break;
48
case SUDO_DIGEST_SHA256:
49
md = EVP_sha256();
50
break;
51
case SUDO_DIGEST_SHA384:
52
md = EVP_sha384();
53
break;
54
case SUDO_DIGEST_SHA512:
55
md = EVP_sha512();
56
break;
57
default:
58
errno = EINVAL;
59
break;
60
}
61
debug_return_const_ptr(md);
62
}
63
64
struct sudo_digest *
65
sudo_digest_alloc_v1(unsigned int digest_type)
66
{
67
struct sudo_digest *dig;
68
EVP_MD_CTX *mdctx = NULL;
69
const EVP_MD *md;
70
debug_decl(sudo_digest_alloc, SUDO_DEBUG_UTIL);
71
72
md = sudo_digest_type_to_md(digest_type);
73
if (md == NULL)
74
goto bad;
75
76
mdctx = EVP_MD_CTX_new();
77
if (mdctx == NULL || !EVP_DigestInit_ex(mdctx, md, NULL))
78
goto bad;
79
80
if ((dig = malloc(sizeof(*dig))) == NULL)
81
goto bad;
82
dig->md = md;
83
dig->ctx = mdctx;
84
85
debug_return_ptr(dig);
86
bad:
87
EVP_MD_CTX_free(mdctx);
88
debug_return_ptr(NULL);
89
}
90
91
void
92
sudo_digest_free_v1(struct sudo_digest *dig)
93
{
94
debug_decl(sudo_digest_free, SUDO_DEBUG_UTIL);
95
96
if (dig != NULL) {
97
EVP_MD_CTX_free(dig->ctx);
98
free(dig);
99
}
100
101
debug_return;
102
}
103
104
void
105
sudo_digest_reset_v1(struct sudo_digest *dig)
106
{
107
debug_decl(sudo_digest_reset, SUDO_DEBUG_UTIL);
108
109
/* These cannot fail. */
110
EVP_MD_CTX_reset(dig->ctx);
111
EVP_DigestInit_ex(dig->ctx, dig->md, NULL);
112
113
debug_return;
114
}
115
116
size_t
117
sudo_digest_getlen_v2(unsigned int digest_type)
118
{
119
const EVP_MD *md;
120
debug_decl(sudo_digest_getlen, SUDO_DEBUG_UTIL);
121
122
md = sudo_digest_type_to_md(digest_type);
123
if (md == NULL)
124
debug_return_size_t(0);
125
126
debug_return_size_t((size_t)EVP_MD_size(md));
127
}
128
129
int
130
sudo_digest_getlen_v1(unsigned int digest_type)
131
{
132
size_t len = sudo_digest_getlen_v2(digest_type);
133
return len ? (int)len : -1;
134
}
135
136
void
137
sudo_digest_update_v1(struct sudo_digest *dig, const void *data, size_t len)
138
{
139
debug_decl(sudo_digest_update, SUDO_DEBUG_UTIL);
140
141
EVP_DigestUpdate(dig->ctx, data, len);
142
143
debug_return;
144
}
145
146
void
147
sudo_digest_final_v1(struct sudo_digest *dig, unsigned char *md)
148
{
149
debug_decl(sudo_digest_final, SUDO_DEBUG_UTIL);
150
151
EVP_DigestFinal_ex(dig->ctx, md, NULL);
152
153
debug_return;
154
}
155
156