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 /*!
15  * \file isc/md.h
16  * \brief This is the header file for message digest algorithms.
17  */
18 
19 #pragma once
20 
21 #include <isc/lang.h>
22 #include <isc/platform.h>
23 #include <isc/result.h>
24 #include <isc/types.h>
25 
26 typedef void isc_md_t;
27 
28 /**
29  * isc_md_type_t:
30  * @ISC_MD_MD5: MD5
31  * @ISC_MD_SHA1: SHA-1
32  * @ISC_MD_SHA224: SHA-224
33  * @ISC_MD_SHA256: SHA-256
34  * @ISC_MD_SHA384: SHA-384
35  * @ISC_MD_SHA512: SHA-512
36  *
37  * Enumeration of supported message digest algorithms.
38  */
39 typedef void isc_md_type_t;
40 
41 #define ISC_MD_MD5    isc__md_md5()
42 #define ISC_MD_SHA1   isc__md_sha1()
43 #define ISC_MD_SHA224 isc__md_sha224()
44 #define ISC_MD_SHA256 isc__md_sha256()
45 #define ISC_MD_SHA384 isc__md_sha384()
46 #define ISC_MD_SHA512 isc__md_sha512()
47 
48 const isc_md_type_t *
49 isc__md_md5(void);
50 const isc_md_type_t *
51 isc__md_sha1(void);
52 const isc_md_type_t *
53 isc__md_sha224(void);
54 const isc_md_type_t *
55 isc__md_sha256(void);
56 const isc_md_type_t *
57 isc__md_sha384(void);
58 const isc_md_type_t *
59 isc__md_sha512(void);
60 
61 #define ISC_MD5_DIGESTLENGTH	isc_md_type_get_size(ISC_MD_MD5)
62 #define ISC_MD5_BLOCK_LENGTH	isc_md_type_get_block_size(ISC_MD_MD5)
63 #define ISC_SHA1_DIGESTLENGTH	isc_md_type_get_size(ISC_MD_SHA1)
64 #define ISC_SHA1_BLOCK_LENGTH	isc_md_type_get_block_size(ISC_MD_SHA1)
65 #define ISC_SHA224_DIGESTLENGTH isc_md_type_get_size(ISC_MD_SHA224)
66 #define ISC_SHA224_BLOCK_LENGTH isc_md_type_get_block_size(ISC_MD_SHA224)
67 #define ISC_SHA256_DIGESTLENGTH isc_md_type_get_size(ISC_MD_SHA256)
68 #define ISC_SHA256_BLOCK_LENGTH isc_md_type_get_block_size(ISC_MD_SHA256)
69 #define ISC_SHA384_DIGESTLENGTH isc_md_type_get_size(ISC_MD_SHA384)
70 #define ISC_SHA384_BLOCK_LENGTH isc_md_type_get_block_size(ISC_MD_SHA384)
71 #define ISC_SHA512_DIGESTLENGTH isc_md_type_get_size(ISC_MD_SHA512)
72 #define ISC_SHA512_BLOCK_LENGTH isc_md_type_get_block_size(ISC_MD_SHA512)
73 
74 #define ISC_MAX_MD_SIZE	   64U	/* EVP_MAX_MD_SIZE */
75 #define ISC_MAX_BLOCK_SIZE 128U /* ISC_SHA512_BLOCK_LENGTH */
76 
77 /**
78  * isc_md:
79  * @type: the digest type
80  * @buf: the data to hash
81  * @len: the length of the data to hash
82  * @digest: the output buffer
83  * @digestlen: the length of the data written to @digest
84  *
85  * This function hashes @len bytes of data at @buf and places the result in
86  * @digest.  If the @digestlen parameter is not NULL then the number of bytes of
87  * data written (i.e. the length of the digest) will be written to the integer
88  * at @digestlen, at most ISC_MAX_MD_SIZE bytes will be written.
89  */
90 isc_result_t
91 isc_md(const isc_md_type_t *type, const unsigned char *buf, const size_t len,
92        unsigned char *digest, unsigned int *digestlen);
93 
94 /**
95  * isc_md_new:
96  *
97  * This function allocates, initializes and returns a digest context.
98  */
99 isc_md_t *
100 isc_md_new(void);
101 
102 /**
103  * isc_md_free:
104  * @md: message digest context
105  *
106  * This function cleans up digest context ctx and frees up the space allocated
107  * to it.
108  */
109 void
110 isc_md_free(isc_md_t *);
111 
112 /**
113  * isc_md_init:
114  * @md: message digest context
115  * @type: digest type
116  *
117  * This function sets up digest context @md to use a digest @type. @md must be
118  * initialized before calling this function.
119  */
120 isc_result_t
121 isc_md_init(isc_md_t *, const isc_md_type_t *md_type);
122 
123 /**
124  * isc_md_reset:
125  * @md: message digest context
126  *
127  * This function resets the digest context ctx. This can be used to reuse an
128  * already existing context.
129  */
130 isc_result_t
131 isc_md_reset(isc_md_t *md);
132 
133 /**
134  * isc_md_update:
135  * @md: message digest context
136  * @buf: data to hash
137  * @len: length of the data to hash
138  *
139  * This function hashes @len bytes of data at @buf into the digest context @md.
140  * This function can be called several times on the same @md to hash additional
141  * data.
142  */
143 isc_result_t
144 isc_md_update(isc_md_t *md, const unsigned char *buf, const size_t len);
145 
146 /**
147  * isc_md_final:
148  * @md: message digest context
149  * @digest: the output buffer
150  * @digestlen: the length of the data written to @digest
151  *
152  * This function retrieves the digest value from @md and places it in @digest.
153  * If the @digestlen parameter is not NULL then the number of bytes of data
154  * written (i.e. the length of the digest) will be written to the integer at
155  * @digestlen, at most ISC_MAX_MD_SIZE bytes will be written.  After calling
156  * this function no additional calls to isc_md_update() can be made.
157  */
158 isc_result_t
159 isc_md_final(isc_md_t *md, unsigned char *digest, unsigned int *digestlen);
160 
161 /**
162  * isc_md_get_type:
163  * @md: message digest contezt
164  *
165  * This function return the isc_md_type_t previously set for the supplied
166  * message digest context or NULL if no isc_md_type_t has been set.
167  */
168 const isc_md_type_t *
169 isc_md_get_md_type(isc_md_t *md);
170 
171 /**
172  * isc_md_size:
173  *
174  * This function return the size of the message digest when passed an isc_md_t
175  * structure, i.e. the size of the hash.
176  */
177 size_t
178 isc_md_get_size(isc_md_t *md);
179 
180 /**
181  * isc_md_block_size:
182  *
183  * This function return the block size of the message digest when passed an
184  * isc_md_t structure.
185  */
186 size_t
187 isc_md_get_block_size(isc_md_t *md);
188 
189 /**
190  * isc_md_size:
191  *
192  * This function return the size of the message digest when passed an
193  * isc_md_type_t , i.e. the size of the hash.
194  */
195 size_t
196 isc_md_type_get_size(const isc_md_type_t *md_type);
197 
198 /**
199  * isc_md_block_size:
200  *
201  * This function return the block size of the message digest when passed an
202  * isc_md_type_t.
203  */
204 size_t
205 isc_md_type_get_block_size(const isc_md_type_t *md_type);
206