libmicrohttpd2

HTTP server C library (MHD 2.x, alpha)
Log | Files | Refs | README | LICENSE

sha512_256_mbedtls.c (5514B)


      1 /* SPDX-License-Identifier: LGPL-2.1-or-later OR (GPL-2.0-or-later WITH eCos-exception-2.0) */
      2 /*
      3   This file is part of GNU libmicrohttpd.
      4   Copyright (C) 2026 Evgeny Grin (Karlson2k)
      5   Copyright (C) 2025 Christian Grothoff
      6 
      7   GNU libmicrohttpd is free software; you can redistribute it and/or
      8   modify it under the terms of the GNU Lesser General Public
      9   License as published by the Free Software Foundation; either
     10   version 2.1 of the License, or (at your option) any later version.
     11 
     12   GNU libmicrohttpd is distributed in the hope that it will be useful,
     13   but WITHOUT ANY WARRANTY; without even the implied warranty of
     14   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     15   Lesser General Public License for more details.
     16 
     17   Alternatively, you can redistribute GNU libmicrohttpd and/or
     18   modify it under the terms of the GNU General Public License as
     19   published by the Free Software Foundation; either version 2 of
     20   the License, or (at your option) any later version, together
     21   with the eCos exception, as follows:
     22 
     23     As a special exception, if other files instantiate templates or
     24     use macros or inline functions from this file, or you compile this
     25     file and link it with other works to produce a work based on this
     26     file, this file does not by itself cause the resulting work to be
     27     covered by the GNU General Public License. However the source code
     28     for this file must still be made available in accordance with
     29     section (3) of the GNU General Public License v2.
     30 
     31     This exception does not invalidate any other reasons why a work
     32     based on this file might be covered by the GNU General Public
     33     License.
     34 
     35   You should have received copies of the GNU Lesser General Public
     36   License and the GNU General Public License along with this library;
     37   if not, see <https://www.gnu.org/licenses/>.
     38 */
     39 
     40 /**
     41  * @file src/mhd2/sha512_256_mbedtls.c
     42  * @brief  Wrapper for SHA-512/256 calculation performed by mbedTLS library
     43  * @author Karlson2k (Evgeny Grin)
     44  * @author Christian Grothoff
     45  */
     46 
     47 #include "mhd_sys_options.h"
     48 
     49 /* mbedTLS does not natively support SHA-512/256: the backend initialises
     50    SHA-512 and overrides the internal hash state with the SHA-512/256 initial
     51    values, which requires access to private context members. The definition
     52    must precede the mbedTLS header so that the private members are visible. */
     53 #ifndef MBEDTLS_ALLOW_PRIVATE_ACCESS
     54 #  define MBEDTLS_ALLOW_PRIVATE_ACCESS 1
     55 #endif
     56 
     57 #include <string.h>
     58 #include "mhd_assert.h"
     59 
     60 #include "sha512_256_mbedtls.h"
     61 
     62 
     63 /**
     64  * Start SHA-512 calculation and override the internal state with the
     65  * SHA-512/256 initial hash values, see FIPS PUB 180-4 clause 5.3.6.2.
     66  *
     67  * mbedTLS does not natively support SHA-512/256, so the SHA-512 machinery is
     68  * reused with a different initial state.
     69  *
     70  * @param ctx the calculation context, must be already initialised
     71  */
     72 static MHD_FN_PAR_NONNULL_ALL_ void
     73 mtls_set_sha512_256_iv (struct mhd_Sha512_256CtxMtls *ctx)
     74 {
     75   static const uint64_t iv_sha512_256[8] = {
     76     UINT64_C (0x22312194FC2BF72C), UINT64_C (0x9F555FA3C84C64C2),
     77     UINT64_C (0x2393B86B6F53B151), UINT64_C (0x963877195940EABD),
     78     UINT64_C (0x96283EE2A88EFFE3), UINT64_C (0xBE5E1E2553863992),
     79     UINT64_C (0x2B0199FC2C85B8AA), UINT64_C (0x0EB72DDC81C52CA2)
     80   };
     81 
     82   /* The second argument must be zero to start SHA-512 (not SHA-384) */
     83   ctx->ext_error = (0 != mbedtls_sha512_starts (&(ctx->mbed_ctx),
     84                                                 0));
     85   if (ctx->ext_error)
     86     return;
     87 
     88   mhd_assert (sizeof(ctx->mbed_ctx.state) == sizeof(iv_sha512_256));
     89   memcpy (ctx->mbed_ctx.state,
     90           iv_sha512_256,
     91           sizeof(iv_sha512_256));
     92 }
     93 
     94 
     95 MHD_INTERNAL MHD_FN_PAR_NONNULL_ALL_ MHD_FN_PAR_OUT_ (1) void
     96 mhd_SHA512_256_mtls_init (struct mhd_Sha512_256CtxMtls *ctx)
     97 {
     98   mbedtls_sha512_init (&(ctx->mbed_ctx));
     99   mtls_set_sha512_256_iv (ctx);
    100 }
    101 
    102 
    103 MHD_INTERNAL MHD_FN_PAR_NONNULL_ALL_ MHD_FN_PAR_INOUT_ (1) void
    104 mhd_SHA512_256_mtls_reset (struct mhd_Sha512_256CtxMtls *ctx)
    105 {
    106   if (ctx->ext_error)
    107     return;
    108 
    109   mtls_set_sha512_256_iv (ctx);
    110 }
    111 
    112 
    113 MHD_INTERNAL MHD_FN_PAR_NONNULL_ALL_ MHD_FN_PAR_INOUT_ (1)
    114 MHD_FN_PAR_IN_SIZE_ (3, 2) void
    115 mhd_SHA512_256_mtls_update (struct mhd_Sha512_256CtxMtls *restrict ctx,
    116                             size_t size,
    117                             const void *restrict data)
    118 {
    119 #ifndef MHD_UNIT_TESTING
    120   mhd_assert (0 != size);
    121 #endif
    122 
    123   if (ctx->ext_error)
    124     return;
    125 
    126   ctx->ext_error = (0 != mbedtls_sha512_update (&(ctx->mbed_ctx),
    127                                                 (const unsigned char *)data,
    128                                                 size));
    129 }
    130 
    131 
    132 MHD_INTERNAL MHD_FN_PAR_NONNULL_ALL_ MHD_FN_PAR_INOUT_ (1)
    133 MHD_FN_PAR_OUT_ (2) void
    134 mhd_SHA512_256_mtls_finish (
    135   struct mhd_Sha512_256CtxMtls *restrict ctx,
    136   uint8_t digest[MHD_FN_PAR_FIX_ARR_SIZE_ (mhd_SHA512_256_DIGEST_SIZE)])
    137 {
    138   uint8_t full_digest[64]; /* SHA-512 produces 64 bytes */
    139 
    140   if (ctx->ext_error)
    141     return;
    142 
    143   ctx->ext_error = (0 != mbedtls_sha512_finish (&(ctx->mbed_ctx),
    144                                                 (unsigned char *)full_digest));
    145   if (ctx->ext_error)
    146     return;
    147 
    148   /* SHA-512/256 is the leftmost 256 bits of SHA-512 computed with the
    149      SHA-512/256 initial values. */
    150   memcpy (digest,
    151           full_digest,
    152           mhd_SHA512_256_DIGEST_SIZE);
    153 }
    154 
    155 
    156 MHD_INTERNAL MHD_FN_PAR_NONNULL_ALL_ MHD_FN_PAR_INOUT_ (1) void
    157 mhd_SHA512_256_mtls_deinit (struct mhd_Sha512_256CtxMtls *ctx)
    158 {
    159   mbedtls_sha512_free (&(ctx->mbed_ctx));
    160 }