/src/sudo/lib/util/digest_openssl.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * SPDX-License-Identifier: ISC |
3 | | * |
4 | | * Copyright (c) 2013-2021 Todd C. Miller <Todd.Miller@sudo.ws> |
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 | | /* |
20 | | * This is an open source non-commercial project. Dear PVS-Studio, please check it. |
21 | | * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com |
22 | | */ |
23 | | |
24 | | #include <config.h> |
25 | | |
26 | | #include <stdlib.h> |
27 | | #include <errno.h> |
28 | | |
29 | | #if defined(HAVE_WOLFSSL) |
30 | | # include <wolfssl/options.h> |
31 | | #endif |
32 | | #include <openssl/evp.h> |
33 | | |
34 | | #include "sudo_compat.h" |
35 | | #include "sudo_debug.h" |
36 | | #include "sudo_digest.h" |
37 | | |
38 | | struct sudo_digest { |
39 | | EVP_MD_CTX *ctx; |
40 | | const EVP_MD *md; |
41 | | }; |
42 | | |
43 | | static const EVP_MD * |
44 | | sudo_digest_type_to_md(int digest_type) |
45 | 1 | { |
46 | 1 | const EVP_MD *md = NULL; |
47 | 1 | debug_decl(sudo_digest_type_to_md, SUDO_DEBUG_UTIL); |
48 | | |
49 | 1 | switch (digest_type) { |
50 | 0 | case SUDO_DIGEST_SHA224: |
51 | 0 | md = EVP_sha224(); |
52 | 0 | break; |
53 | 1 | case SUDO_DIGEST_SHA256: |
54 | 1 | md = EVP_sha256(); |
55 | 1 | break; |
56 | 0 | case SUDO_DIGEST_SHA384: |
57 | 0 | md = EVP_sha384(); |
58 | 0 | break; |
59 | 0 | case SUDO_DIGEST_SHA512: |
60 | 0 | md = EVP_sha512(); |
61 | 0 | break; |
62 | 0 | default: |
63 | 0 | errno = EINVAL; |
64 | 0 | break; |
65 | 1 | } |
66 | 1 | debug_return_const_ptr(md); |
67 | 1 | } |
68 | | |
69 | | struct sudo_digest * |
70 | | sudo_digest_alloc_v1(int digest_type) |
71 | 0 | { |
72 | 0 | struct sudo_digest *dig; |
73 | 0 | EVP_MD_CTX *mdctx = NULL; |
74 | 0 | const EVP_MD *md; |
75 | 0 | debug_decl(sudo_digest_alloc, SUDO_DEBUG_UTIL); |
76 | |
|
77 | 0 | md = sudo_digest_type_to_md(digest_type); |
78 | 0 | if (md == NULL) |
79 | 0 | goto bad; |
80 | | |
81 | 0 | mdctx = EVP_MD_CTX_new(); |
82 | 0 | if (mdctx == NULL || !EVP_DigestInit_ex(mdctx, md, NULL)) |
83 | 0 | goto bad; |
84 | | |
85 | 0 | if ((dig = malloc(sizeof(*dig))) == NULL) |
86 | 0 | goto bad; |
87 | 0 | dig->md = md; |
88 | 0 | dig->ctx = mdctx; |
89 | |
|
90 | 0 | debug_return_ptr(dig); |
91 | 0 | bad: |
92 | 0 | EVP_MD_CTX_free(mdctx); |
93 | 0 | debug_return_ptr(NULL); |
94 | 0 | } |
95 | | |
96 | | void |
97 | | sudo_digest_free_v1(struct sudo_digest *dig) |
98 | 0 | { |
99 | 0 | debug_decl(sudo_digest_free, SUDO_DEBUG_UTIL); |
100 | |
|
101 | 0 | if (dig != NULL) { |
102 | 0 | EVP_MD_CTX_free(dig->ctx); |
103 | 0 | free(dig); |
104 | 0 | } |
105 | |
|
106 | 0 | debug_return; |
107 | 0 | } |
108 | | |
109 | | void |
110 | | sudo_digest_reset_v1(struct sudo_digest *dig) |
111 | 0 | { |
112 | 0 | debug_decl(sudo_digest_reset, SUDO_DEBUG_UTIL); |
113 | | |
114 | | /* These cannot fail. */ |
115 | 0 | EVP_MD_CTX_reset(dig->ctx); |
116 | 0 | EVP_DigestInit_ex(dig->ctx, dig->md, NULL); |
117 | |
|
118 | 0 | debug_return; |
119 | 0 | } |
120 | | |
121 | | int |
122 | | sudo_digest_getlen_v1(int digest_type) |
123 | 1 | { |
124 | 1 | const EVP_MD *md; |
125 | 1 | debug_decl(sudo_digest_getlen, SUDO_DEBUG_UTIL); |
126 | | |
127 | 1 | md = sudo_digest_type_to_md(digest_type); |
128 | 1 | if (md == NULL) |
129 | 0 | debug_return_int(-1); |
130 | | |
131 | 1 | debug_return_int(EVP_MD_size(md)); |
132 | 1 | } |
133 | | |
134 | | void |
135 | | sudo_digest_update_v1(struct sudo_digest *dig, const void *data, size_t len) |
136 | 0 | { |
137 | 0 | debug_decl(sudo_digest_update, SUDO_DEBUG_UTIL); |
138 | |
|
139 | 0 | EVP_DigestUpdate(dig->ctx, data, len); |
140 | |
|
141 | 0 | debug_return; |
142 | 0 | } |
143 | | |
144 | | void |
145 | | sudo_digest_final_v1(struct sudo_digest *dig, unsigned char *md) |
146 | 0 | { |
147 | 0 | debug_decl(sudo_digest_final, SUDO_DEBUG_UTIL); |
148 | |
|
149 | 0 | EVP_DigestFinal_ex(dig->ctx, md, NULL); |
150 | |
|
151 | 0 | debug_return; |
152 | 0 | } |