libmicrohttpd2

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

sha512_256_mbedtls.c (5631B)


      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 #include "mhd_static_assert.h"
     60 
     61 #include "sha512_256_mbedtls.h"
     62 
     63 
     64 /**
     65  * Start SHA-512 calculation and override the internal state with the
     66  * SHA-512/256 initial hash values, see FIPS PUB 180-4 clause 5.3.6.2.
     67  *
     68  * mbedTLS does not natively support SHA-512/256, so the SHA-512 machinery is
     69  * reused with a different initial state.
     70  *
     71  * @param ctx the calculation context, must be already initialised
     72  */
     73 static MHD_FN_PAR_NONNULL_ALL_ void
     74 mtls_set_sha512_256_iv (struct mhd_Sha512_256CtxMtls *ctx)
     75 {
     76   static const uint64_t iv_sha512_256[8] = {
     77     UINT64_C (0x22312194FC2BF72C), UINT64_C (0x9F555FA3C84C64C2),
     78     UINT64_C (0x2393B86B6F53B151), UINT64_C (0x963877195940EABD),
     79     UINT64_C (0x96283EE2A88EFFE3), UINT64_C (0xBE5E1E2553863992),
     80     UINT64_C (0x2B0199FC2C85B8AA), UINT64_C (0x0EB72DDC81C52CA2)
     81   };
     82 
     83   /* The second argument must be zero to start SHA-512 (not SHA-384) */
     84   ctx->ext_error = (0 != mbedtls_sha512_starts (&(ctx->mbed_ctx),
     85                                                 0));
     86   if (ctx->ext_error)
     87     return;
     88 
     89   mhd_STATIC_ASSERT_STMT (
     90     sizeof(ctx->mbed_ctx.state) == sizeof(iv_sha512_256),
     91     "The mbedTLS SHA-512 state and SHA-512/256 IV sizes must match");
     92   memcpy (ctx->mbed_ctx.state,
     93           iv_sha512_256,
     94           sizeof(iv_sha512_256));
     95 }
     96 
     97 
     98 MHD_INTERNAL MHD_FN_PAR_NONNULL_ALL_ MHD_FN_PAR_OUT_ (1) void
     99 mhd_SHA512_256_mtls_init (struct mhd_Sha512_256CtxMtls *ctx)
    100 {
    101   mbedtls_sha512_init (&(ctx->mbed_ctx));
    102   mtls_set_sha512_256_iv (ctx);
    103 }
    104 
    105 
    106 MHD_INTERNAL MHD_FN_PAR_NONNULL_ALL_ MHD_FN_PAR_INOUT_ (1) void
    107 mhd_SHA512_256_mtls_reset (struct mhd_Sha512_256CtxMtls *ctx)
    108 {
    109   if (ctx->ext_error)
    110     return;
    111 
    112   mtls_set_sha512_256_iv (ctx);
    113 }
    114 
    115 
    116 MHD_INTERNAL MHD_FN_PAR_NONNULL_ALL_ MHD_FN_PAR_INOUT_ (1)
    117 MHD_FN_PAR_IN_SIZE_ (3, 2) void
    118 mhd_SHA512_256_mtls_update (struct mhd_Sha512_256CtxMtls *restrict ctx,
    119                             size_t size,
    120                             const void *restrict data)
    121 {
    122 #ifndef MHD_UNIT_TESTING
    123   mhd_assert (0 != size);
    124 #endif
    125 
    126   if (ctx->ext_error)
    127     return;
    128 
    129   ctx->ext_error = (0 != mbedtls_sha512_update (&(ctx->mbed_ctx),
    130                                                 (const unsigned char *)data,
    131                                                 size));
    132 }
    133 
    134 
    135 MHD_INTERNAL MHD_FN_PAR_NONNULL_ALL_ MHD_FN_PAR_INOUT_ (1)
    136 MHD_FN_PAR_OUT_ (2) void
    137 mhd_SHA512_256_mtls_finish (
    138   struct mhd_Sha512_256CtxMtls *restrict ctx,
    139   uint8_t digest[MHD_FN_PAR_FIX_ARR_SIZE_ (mhd_SHA512_256_DIGEST_SIZE)])
    140 {
    141   uint8_t full_digest[64]; /* SHA-512 produces 64 bytes */
    142 
    143   if (ctx->ext_error)
    144     return;
    145 
    146   ctx->ext_error = (0 != mbedtls_sha512_finish (&(ctx->mbed_ctx),
    147                                                 (unsigned char *)full_digest));
    148   if (ctx->ext_error)
    149     return;
    150 
    151   /* SHA-512/256 is the leftmost 256 bits of SHA-512 computed with the
    152      SHA-512/256 initial values. */
    153   memcpy (digest,
    154           full_digest,
    155           mhd_SHA512_256_DIGEST_SIZE);
    156 }
    157 
    158 
    159 MHD_INTERNAL MHD_FN_PAR_NONNULL_ALL_ MHD_FN_PAR_INOUT_ (1) void
    160 mhd_SHA512_256_mtls_deinit (struct mhd_Sha512_256CtxMtls *ctx)
    161 {
    162   mbedtls_sha512_free (&(ctx->mbed_ctx));
    163 }