Home | History | Annotate | Line # | Download | only in isc
      1  1.1  christos /*	$NetBSD: md.c,v 1.1 2024/02/18 20:57:49 christos Exp $	*/
      2  1.1  christos 
      3  1.1  christos /*
      4  1.1  christos  * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
      5  1.1  christos  *
      6  1.1  christos  * SPDX-License-Identifier: MPL-2.0
      7  1.1  christos  *
      8  1.1  christos  * This Source Code Form is subject to the terms of the Mozilla Public
      9  1.1  christos  * License, v. 2.0. If a copy of the MPL was not distributed with this
     10  1.1  christos  * file, you can obtain one at https://mozilla.org/MPL/2.0/.
     11  1.1  christos  *
     12  1.1  christos  * See the COPYRIGHT file distributed with this work for additional
     13  1.1  christos  * information regarding copyright ownership.
     14  1.1  christos  */
     15  1.1  christos 
     16  1.1  christos #include <stdio.h>
     17  1.1  christos 
     18  1.1  christos #include <openssl/err.h>
     19  1.1  christos #include <openssl/evp.h>
     20  1.1  christos #include <openssl/opensslv.h>
     21  1.1  christos 
     22  1.1  christos #include <isc/md.h>
     23  1.1  christos #include <isc/util.h>
     24  1.1  christos 
     25  1.1  christos #include "openssl_shim.h"
     26  1.1  christos 
     27  1.1  christos isc_md_t *
     28  1.1  christos isc_md_new(void) {
     29  1.1  christos 	isc_md_t *md = EVP_MD_CTX_new();
     30  1.1  christos 	RUNTIME_CHECK(md != NULL);
     31  1.1  christos 	return (md);
     32  1.1  christos }
     33  1.1  christos 
     34  1.1  christos void
     35  1.1  christos isc_md_free(isc_md_t *md) {
     36  1.1  christos 	if (ISC_UNLIKELY(md == NULL)) {
     37  1.1  christos 		return;
     38  1.1  christos 	}
     39  1.1  christos 
     40  1.1  christos 	EVP_MD_CTX_free(md);
     41  1.1  christos }
     42  1.1  christos 
     43  1.1  christos isc_result_t
     44  1.1  christos isc_md_init(isc_md_t *md, const isc_md_type_t *md_type) {
     45  1.1  christos 	REQUIRE(md != NULL);
     46  1.1  christos 
     47  1.1  christos 	if (md_type == NULL) {
     48  1.1  christos 		return (ISC_R_NOTIMPLEMENTED);
     49  1.1  christos 	}
     50  1.1  christos 
     51  1.1  christos 	if (EVP_DigestInit_ex(md, md_type, NULL) != 1) {
     52  1.1  christos 		return (ISC_R_CRYPTOFAILURE);
     53  1.1  christos 	}
     54  1.1  christos 
     55  1.1  christos 	return (ISC_R_SUCCESS);
     56  1.1  christos }
     57  1.1  christos 
     58  1.1  christos isc_result_t
     59  1.1  christos isc_md_reset(isc_md_t *md) {
     60  1.1  christos 	REQUIRE(md != NULL);
     61  1.1  christos 
     62  1.1  christos 	if (EVP_MD_CTX_reset(md) != 1) {
     63  1.1  christos 		return (ISC_R_CRYPTOFAILURE);
     64  1.1  christos 	}
     65  1.1  christos 
     66  1.1  christos 	return (ISC_R_SUCCESS);
     67  1.1  christos }
     68  1.1  christos 
     69  1.1  christos isc_result_t
     70  1.1  christos isc_md_update(isc_md_t *md, const unsigned char *buf, const size_t len) {
     71  1.1  christos 	REQUIRE(md != NULL);
     72  1.1  christos 
     73  1.1  christos 	if (ISC_UNLIKELY(buf == NULL || len == 0)) {
     74  1.1  christos 		return (ISC_R_SUCCESS);
     75  1.1  christos 	}
     76  1.1  christos 
     77  1.1  christos 	if (EVP_DigestUpdate(md, buf, len) != 1) {
     78  1.1  christos 		return (ISC_R_CRYPTOFAILURE);
     79  1.1  christos 	}
     80  1.1  christos 
     81  1.1  christos 	return (ISC_R_SUCCESS);
     82  1.1  christos }
     83  1.1  christos 
     84  1.1  christos isc_result_t
     85  1.1  christos isc_md_final(isc_md_t *md, unsigned char *digest, unsigned int *digestlen) {
     86  1.1  christos 	REQUIRE(md != NULL);
     87  1.1  christos 	REQUIRE(digest != NULL);
     88  1.1  christos 
     89  1.1  christos 	if (EVP_DigestFinal_ex(md, digest, digestlen) != 1) {
     90  1.1  christos 		return (ISC_R_CRYPTOFAILURE);
     91  1.1  christos 	}
     92  1.1  christos 
     93  1.1  christos 	return (ISC_R_SUCCESS);
     94  1.1  christos }
     95  1.1  christos 
     96  1.1  christos const isc_md_type_t *
     97  1.1  christos isc_md_get_md_type(isc_md_t *md) {
     98  1.1  christos 	REQUIRE(md != NULL);
     99  1.1  christos 
    100  1.1  christos 	return (EVP_MD_CTX_md(md));
    101  1.1  christos }
    102  1.1  christos 
    103  1.1  christos size_t
    104  1.1  christos isc_md_get_size(isc_md_t *md) {
    105  1.1  christos 	REQUIRE(md != NULL);
    106  1.1  christos 
    107  1.1  christos 	return (EVP_MD_CTX_size(md));
    108  1.1  christos }
    109  1.1  christos 
    110  1.1  christos size_t
    111  1.1  christos isc_md_get_block_size(isc_md_t *md) {
    112  1.1  christos 	REQUIRE(md != NULL);
    113  1.1  christos 
    114  1.1  christos 	return (EVP_MD_CTX_block_size(md));
    115  1.1  christos }
    116  1.1  christos 
    117  1.1  christos size_t
    118  1.1  christos isc_md_type_get_size(const isc_md_type_t *md_type) {
    119  1.1  christos 	STATIC_ASSERT(ISC_MAX_MD_SIZE >= EVP_MAX_MD_SIZE,
    120  1.1  christos 		      "Change ISC_MAX_MD_SIZE to be greater than or equal to "
    121  1.1  christos 		      "EVP_MAX_MD_SIZE");
    122  1.1  christos 	if (md_type != NULL) {
    123  1.1  christos 		return ((size_t)EVP_MD_size(md_type));
    124  1.1  christos 	}
    125  1.1  christos 
    126  1.1  christos 	return (ISC_MAX_MD_SIZE);
    127  1.1  christos }
    128  1.1  christos 
    129  1.1  christos size_t
    130  1.1  christos isc_md_type_get_block_size(const isc_md_type_t *md_type) {
    131  1.1  christos 	STATIC_ASSERT(ISC_MAX_MD_SIZE >= EVP_MAX_MD_SIZE,
    132  1.1  christos 		      "Change ISC_MAX_MD_SIZE to be greater than or equal to "
    133  1.1  christos 		      "EVP_MAX_MD_SIZE");
    134  1.1  christos 	if (md_type != NULL) {
    135  1.1  christos 		return ((size_t)EVP_MD_block_size(md_type));
    136  1.1  christos 	}
    137  1.1  christos 
    138  1.1  christos 	return (ISC_MAX_MD_SIZE);
    139  1.1  christos }
    140  1.1  christos 
    141  1.1  christos isc_result_t
    142  1.1  christos isc_md(const isc_md_type_t *md_type, const unsigned char *buf, const size_t len,
    143  1.1  christos        unsigned char *digest, unsigned int *digestlen) {
    144  1.1  christos 	isc_md_t *md;
    145  1.1  christos 	isc_result_t res;
    146  1.1  christos 
    147  1.1  christos 	md = isc_md_new();
    148  1.1  christos 
    149  1.1  christos 	res = isc_md_init(md, md_type);
    150  1.1  christos 	if (res != ISC_R_SUCCESS) {
    151  1.1  christos 		goto end;
    152  1.1  christos 	}
    153  1.1  christos 
    154  1.1  christos 	res = isc_md_update(md, buf, len);
    155  1.1  christos 	if (res != ISC_R_SUCCESS) {
    156  1.1  christos 		goto end;
    157  1.1  christos 	}
    158  1.1  christos 
    159  1.1  christos 	res = isc_md_final(md, digest, digestlen);
    160  1.1  christos 	if (res != ISC_R_SUCCESS) {
    161  1.1  christos 		goto end;
    162  1.1  christos 	}
    163  1.1  christos end:
    164  1.1  christos 	isc_md_free(md);
    165  1.1  christos 
    166  1.1  christos 	return (res);
    167  1.1  christos }
    168  1.1  christos 
    169  1.1  christos #define md_register_algorithm(alg) \
    170  1.1  christos 	const isc_md_type_t *isc__md_##alg(void) { return (EVP_##alg()); }
    171  1.1  christos 
    172  1.1  christos md_register_algorithm(md5);
    173  1.1  christos md_register_algorithm(sha1);
    174  1.1  christos md_register_algorithm(sha224);
    175  1.1  christos md_register_algorithm(sha256);
    176  1.1  christos md_register_algorithm(sha384);
    177  1.1  christos md_register_algorithm(sha512);
    178