1817466cbSJens Wiklander /** 27901324dSJerome Forissier * \file md.c 3817466cbSJens Wiklander * 4817466cbSJens Wiklander * \brief Generic message digest wrapper for mbed TLS 5817466cbSJens Wiklander * 6817466cbSJens Wiklander * \author Adriaan de Jong <dejong@fox-it.com> 7817466cbSJens Wiklander * 87901324dSJerome Forissier * Copyright The Mbed TLS Contributors 97901324dSJerome Forissier * SPDX-License-Identifier: Apache-2.0 10817466cbSJens Wiklander * 11817466cbSJens Wiklander * Licensed under the Apache License, Version 2.0 (the "License"); you may 12817466cbSJens Wiklander * not use this file except in compliance with the License. 13817466cbSJens Wiklander * You may obtain a copy of the License at 14817466cbSJens Wiklander * 15817466cbSJens Wiklander * http://www.apache.org/licenses/LICENSE-2.0 16817466cbSJens Wiklander * 17817466cbSJens Wiklander * Unless required by applicable law or agreed to in writing, software 18817466cbSJens Wiklander * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 19817466cbSJens Wiklander * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 20817466cbSJens Wiklander * See the License for the specific language governing permissions and 21817466cbSJens Wiklander * limitations under the License. 22817466cbSJens Wiklander */ 23817466cbSJens Wiklander 247901324dSJerome Forissier #include "common.h" 25817466cbSJens Wiklander 26*32b31808SJens Wiklander /* 27*32b31808SJens Wiklander * Availability of functions in this module is controlled by two 28*32b31808SJens Wiklander * feature macros: 29*32b31808SJens Wiklander * - MBEDTLS_MD_C enables the whole module; 30*32b31808SJens Wiklander * - MBEDTLS_MD_LIGHT enables only functions for hashing and accessing 31*32b31808SJens Wiklander * most hash metadata (everything except string names); is it 32*32b31808SJens Wiklander * automatically set whenever MBEDTLS_MD_C is defined. 33*32b31808SJens Wiklander * 34*32b31808SJens Wiklander * In this file, functions from MD_LIGHT are at the top, MD_C at the end. 35*32b31808SJens Wiklander * 36*32b31808SJens Wiklander * In the future we may want to change the contract of some functions 37*32b31808SJens Wiklander * (behaviour with NULL arguments) depending on whether MD_C is defined or 38*32b31808SJens Wiklander * only MD_LIGHT. Also, the exact scope of MD_LIGHT might vary. 39*32b31808SJens Wiklander * 40*32b31808SJens Wiklander * For these reasons, we're keeping MD_LIGHT internal for now. 41*32b31808SJens Wiklander */ 42*32b31808SJens Wiklander #if defined(MBEDTLS_MD_LIGHT) 43817466cbSJens Wiklander 44817466cbSJens Wiklander #include "mbedtls/md.h" 45*32b31808SJens Wiklander #include "md_wrap.h" 463d3b0591SJens Wiklander #include "mbedtls/platform_util.h" 4711fa71b9SJerome Forissier #include "mbedtls/error.h" 4811fa71b9SJerome Forissier 4911fa71b9SJerome Forissier #include "mbedtls/md5.h" 5011fa71b9SJerome Forissier #include "mbedtls/ripemd160.h" 5111fa71b9SJerome Forissier #include "mbedtls/sha1.h" 5211fa71b9SJerome Forissier #include "mbedtls/sha256.h" 5311fa71b9SJerome Forissier #include "mbedtls/sha512.h" 54817466cbSJens Wiklander 55*32b31808SJens Wiklander #if defined(MBEDTLS_MD_SOME_PSA) 56*32b31808SJens Wiklander #include <psa/crypto.h> 57*32b31808SJens Wiklander #include "psa_crypto_core.h" 58817466cbSJens Wiklander #endif 59817466cbSJens Wiklander 60*32b31808SJens Wiklander #include "mbedtls/platform.h" 61*32b31808SJens Wiklander 62817466cbSJens Wiklander #include <string.h> 63817466cbSJens Wiklander 64817466cbSJens Wiklander #if defined(MBEDTLS_FS_IO) 65817466cbSJens Wiklander #include <stdio.h> 66817466cbSJens Wiklander #endif 67817466cbSJens Wiklander 68*32b31808SJens Wiklander #if defined(MBEDTLS_MD_CAN_MD5) 6911fa71b9SJerome Forissier const mbedtls_md_info_t mbedtls_md5_info = { 7011fa71b9SJerome Forissier "MD5", 7111fa71b9SJerome Forissier MBEDTLS_MD_MD5, 7211fa71b9SJerome Forissier 16, 7311fa71b9SJerome Forissier 64, 7411fa71b9SJerome Forissier }; 7511fa71b9SJerome Forissier #endif 7611fa71b9SJerome Forissier 77*32b31808SJens Wiklander #if defined(MBEDTLS_MD_CAN_RIPEMD160) 7811fa71b9SJerome Forissier const mbedtls_md_info_t mbedtls_ripemd160_info = { 7911fa71b9SJerome Forissier "RIPEMD160", 8011fa71b9SJerome Forissier MBEDTLS_MD_RIPEMD160, 8111fa71b9SJerome Forissier 20, 8211fa71b9SJerome Forissier 64, 8311fa71b9SJerome Forissier }; 8411fa71b9SJerome Forissier #endif 8511fa71b9SJerome Forissier 86*32b31808SJens Wiklander #if defined(MBEDTLS_MD_CAN_SHA1) 8711fa71b9SJerome Forissier const mbedtls_md_info_t mbedtls_sha1_info = { 8811fa71b9SJerome Forissier "SHA1", 8911fa71b9SJerome Forissier MBEDTLS_MD_SHA1, 9011fa71b9SJerome Forissier 20, 9111fa71b9SJerome Forissier 64, 9211fa71b9SJerome Forissier }; 9311fa71b9SJerome Forissier #endif 9411fa71b9SJerome Forissier 95*32b31808SJens Wiklander #if defined(MBEDTLS_MD_CAN_SHA224) 9611fa71b9SJerome Forissier const mbedtls_md_info_t mbedtls_sha224_info = { 9711fa71b9SJerome Forissier "SHA224", 9811fa71b9SJerome Forissier MBEDTLS_MD_SHA224, 9911fa71b9SJerome Forissier 28, 10011fa71b9SJerome Forissier 64, 10111fa71b9SJerome Forissier }; 102*32b31808SJens Wiklander #endif 10311fa71b9SJerome Forissier 104*32b31808SJens Wiklander #if defined(MBEDTLS_MD_CAN_SHA256) 10511fa71b9SJerome Forissier const mbedtls_md_info_t mbedtls_sha256_info = { 10611fa71b9SJerome Forissier "SHA256", 10711fa71b9SJerome Forissier MBEDTLS_MD_SHA256, 10811fa71b9SJerome Forissier 32, 10911fa71b9SJerome Forissier 64, 11011fa71b9SJerome Forissier }; 11111fa71b9SJerome Forissier #endif 11211fa71b9SJerome Forissier 113*32b31808SJens Wiklander #if defined(MBEDTLS_MD_CAN_SHA384) 11411fa71b9SJerome Forissier const mbedtls_md_info_t mbedtls_sha384_info = { 11511fa71b9SJerome Forissier "SHA384", 11611fa71b9SJerome Forissier MBEDTLS_MD_SHA384, 11711fa71b9SJerome Forissier 48, 11811fa71b9SJerome Forissier 128, 11911fa71b9SJerome Forissier }; 12011fa71b9SJerome Forissier #endif 12111fa71b9SJerome Forissier 122*32b31808SJens Wiklander #if defined(MBEDTLS_MD_CAN_SHA512) 12311fa71b9SJerome Forissier const mbedtls_md_info_t mbedtls_sha512_info = { 12411fa71b9SJerome Forissier "SHA512", 12511fa71b9SJerome Forissier MBEDTLS_MD_SHA512, 12611fa71b9SJerome Forissier 64, 12711fa71b9SJerome Forissier 128, 12811fa71b9SJerome Forissier }; 12911fa71b9SJerome Forissier #endif 13011fa71b9SJerome Forissier 131817466cbSJens Wiklander const mbedtls_md_info_t *mbedtls_md_info_from_type(mbedtls_md_type_t md_type) 132817466cbSJens Wiklander { 133*32b31808SJens Wiklander switch (md_type) { 134*32b31808SJens Wiklander #if defined(MBEDTLS_MD_CAN_MD5) 135817466cbSJens Wiklander case MBEDTLS_MD_MD5: 136*32b31808SJens Wiklander return &mbedtls_md5_info; 137817466cbSJens Wiklander #endif 138*32b31808SJens Wiklander #if defined(MBEDTLS_MD_CAN_RIPEMD160) 139817466cbSJens Wiklander case MBEDTLS_MD_RIPEMD160: 140*32b31808SJens Wiklander return &mbedtls_ripemd160_info; 141817466cbSJens Wiklander #endif 142*32b31808SJens Wiklander #if defined(MBEDTLS_MD_CAN_SHA1) 143817466cbSJens Wiklander case MBEDTLS_MD_SHA1: 144*32b31808SJens Wiklander return &mbedtls_sha1_info; 145817466cbSJens Wiklander #endif 146*32b31808SJens Wiklander #if defined(MBEDTLS_MD_CAN_SHA224) 147817466cbSJens Wiklander case MBEDTLS_MD_SHA224: 148*32b31808SJens Wiklander return &mbedtls_sha224_info; 149*32b31808SJens Wiklander #endif 150*32b31808SJens Wiklander #if defined(MBEDTLS_MD_CAN_SHA256) 151817466cbSJens Wiklander case MBEDTLS_MD_SHA256: 152*32b31808SJens Wiklander return &mbedtls_sha256_info; 153817466cbSJens Wiklander #endif 154*32b31808SJens Wiklander #if defined(MBEDTLS_MD_CAN_SHA384) 155817466cbSJens Wiklander case MBEDTLS_MD_SHA384: 156*32b31808SJens Wiklander return &mbedtls_sha384_info; 15711fa71b9SJerome Forissier #endif 158*32b31808SJens Wiklander #if defined(MBEDTLS_MD_CAN_SHA512) 159817466cbSJens Wiklander case MBEDTLS_MD_SHA512: 160*32b31808SJens Wiklander return &mbedtls_sha512_info; 161817466cbSJens Wiklander #endif 162817466cbSJens Wiklander default: 163*32b31808SJens Wiklander return NULL; 164817466cbSJens Wiklander } 165817466cbSJens Wiklander } 166817466cbSJens Wiklander 167*32b31808SJens Wiklander #if defined(MBEDTLS_MD_SOME_PSA) 168*32b31808SJens Wiklander static psa_algorithm_t psa_alg_of_md(const mbedtls_md_info_t *info) 169*32b31808SJens Wiklander { 170*32b31808SJens Wiklander switch (info->type) { 171*32b31808SJens Wiklander #if defined(MBEDTLS_MD_MD5_VIA_PSA) 172*32b31808SJens Wiklander case MBEDTLS_MD_MD5: 173*32b31808SJens Wiklander return PSA_ALG_MD5; 174*32b31808SJens Wiklander #endif 175*32b31808SJens Wiklander #if defined(MBEDTLS_MD_RIPEMD160_VIA_PSA) 176*32b31808SJens Wiklander case MBEDTLS_MD_RIPEMD160: 177*32b31808SJens Wiklander return PSA_ALG_RIPEMD160; 178*32b31808SJens Wiklander #endif 179*32b31808SJens Wiklander #if defined(MBEDTLS_MD_SHA1_VIA_PSA) 180*32b31808SJens Wiklander case MBEDTLS_MD_SHA1: 181*32b31808SJens Wiklander return PSA_ALG_SHA_1; 182*32b31808SJens Wiklander #endif 183*32b31808SJens Wiklander #if defined(MBEDTLS_MD_SHA224_VIA_PSA) 184*32b31808SJens Wiklander case MBEDTLS_MD_SHA224: 185*32b31808SJens Wiklander return PSA_ALG_SHA_224; 186*32b31808SJens Wiklander #endif 187*32b31808SJens Wiklander #if defined(MBEDTLS_MD_SHA256_VIA_PSA) 188*32b31808SJens Wiklander case MBEDTLS_MD_SHA256: 189*32b31808SJens Wiklander return PSA_ALG_SHA_256; 190*32b31808SJens Wiklander #endif 191*32b31808SJens Wiklander #if defined(MBEDTLS_MD_SHA384_VIA_PSA) 192*32b31808SJens Wiklander case MBEDTLS_MD_SHA384: 193*32b31808SJens Wiklander return PSA_ALG_SHA_384; 194*32b31808SJens Wiklander #endif 195*32b31808SJens Wiklander #if defined(MBEDTLS_MD_SHA512_VIA_PSA) 196*32b31808SJens Wiklander case MBEDTLS_MD_SHA512: 197*32b31808SJens Wiklander return PSA_ALG_SHA_512; 198*32b31808SJens Wiklander #endif 199*32b31808SJens Wiklander default: 200*32b31808SJens Wiklander return PSA_ALG_NONE; 201*32b31808SJens Wiklander } 202*32b31808SJens Wiklander } 203*32b31808SJens Wiklander 204*32b31808SJens Wiklander static int md_can_use_psa(const mbedtls_md_info_t *info) 205*32b31808SJens Wiklander { 206*32b31808SJens Wiklander psa_algorithm_t alg = psa_alg_of_md(info); 207*32b31808SJens Wiklander if (alg == PSA_ALG_NONE) { 208*32b31808SJens Wiklander return 0; 209*32b31808SJens Wiklander } 210*32b31808SJens Wiklander 211*32b31808SJens Wiklander return psa_can_do_hash(alg); 212*32b31808SJens Wiklander } 213*32b31808SJens Wiklander 214*32b31808SJens Wiklander static int mbedtls_md_error_from_psa(psa_status_t status) 215*32b31808SJens Wiklander { 216*32b31808SJens Wiklander switch (status) { 217*32b31808SJens Wiklander case PSA_SUCCESS: 218*32b31808SJens Wiklander return 0; 219*32b31808SJens Wiklander case PSA_ERROR_NOT_SUPPORTED: 220*32b31808SJens Wiklander return MBEDTLS_ERR_MD_FEATURE_UNAVAILABLE; 221*32b31808SJens Wiklander case PSA_ERROR_INSUFFICIENT_MEMORY: 222*32b31808SJens Wiklander return MBEDTLS_ERR_MD_ALLOC_FAILED; 223*32b31808SJens Wiklander default: 224*32b31808SJens Wiklander return MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED; 225*32b31808SJens Wiklander } 226*32b31808SJens Wiklander } 227*32b31808SJens Wiklander #endif /* MBEDTLS_MD_SOME_PSA */ 228*32b31808SJens Wiklander 229817466cbSJens Wiklander void mbedtls_md_init(mbedtls_md_context_t *ctx) 230817466cbSJens Wiklander { 231*32b31808SJens Wiklander /* Note: this sets engine (if present) to MBEDTLS_MD_ENGINE_LEGACY */ 232817466cbSJens Wiklander memset(ctx, 0, sizeof(mbedtls_md_context_t)); 233817466cbSJens Wiklander } 234817466cbSJens Wiklander 235817466cbSJens Wiklander void mbedtls_md_free(mbedtls_md_context_t *ctx) 236817466cbSJens Wiklander { 237*32b31808SJens Wiklander if (ctx == NULL || ctx->md_info == NULL) { 238817466cbSJens Wiklander return; 239*32b31808SJens Wiklander } 240817466cbSJens Wiklander 241*32b31808SJens Wiklander if (ctx->md_ctx != NULL) { 242*32b31808SJens Wiklander #if defined(MBEDTLS_MD_SOME_PSA) 243*32b31808SJens Wiklander if (ctx->engine == MBEDTLS_MD_ENGINE_PSA) { 244*32b31808SJens Wiklander psa_hash_abort(ctx->md_ctx); 245*32b31808SJens Wiklander } else 24611fa71b9SJerome Forissier #endif 247*32b31808SJens Wiklander switch (ctx->md_info->type) { 24811fa71b9SJerome Forissier #if defined(MBEDTLS_MD5_C) 24911fa71b9SJerome Forissier case MBEDTLS_MD_MD5: 25011fa71b9SJerome Forissier mbedtls_md5_free(ctx->md_ctx); 25111fa71b9SJerome Forissier break; 25211fa71b9SJerome Forissier #endif 25311fa71b9SJerome Forissier #if defined(MBEDTLS_RIPEMD160_C) 25411fa71b9SJerome Forissier case MBEDTLS_MD_RIPEMD160: 25511fa71b9SJerome Forissier mbedtls_ripemd160_free(ctx->md_ctx); 25611fa71b9SJerome Forissier break; 25711fa71b9SJerome Forissier #endif 25811fa71b9SJerome Forissier #if defined(MBEDTLS_SHA1_C) 25911fa71b9SJerome Forissier case MBEDTLS_MD_SHA1: 26011fa71b9SJerome Forissier mbedtls_sha1_free(ctx->md_ctx); 26111fa71b9SJerome Forissier break; 26211fa71b9SJerome Forissier #endif 263*32b31808SJens Wiklander #if defined(MBEDTLS_SHA224_C) 26411fa71b9SJerome Forissier case MBEDTLS_MD_SHA224: 265*32b31808SJens Wiklander mbedtls_sha256_free(ctx->md_ctx); 266*32b31808SJens Wiklander break; 267*32b31808SJens Wiklander #endif 268*32b31808SJens Wiklander #if defined(MBEDTLS_SHA256_C) 26911fa71b9SJerome Forissier case MBEDTLS_MD_SHA256: 27011fa71b9SJerome Forissier mbedtls_sha256_free(ctx->md_ctx); 27111fa71b9SJerome Forissier break; 27211fa71b9SJerome Forissier #endif 273*32b31808SJens Wiklander #if defined(MBEDTLS_SHA384_C) 27411fa71b9SJerome Forissier case MBEDTLS_MD_SHA384: 275*32b31808SJens Wiklander mbedtls_sha512_free(ctx->md_ctx); 276*32b31808SJens Wiklander break; 27711fa71b9SJerome Forissier #endif 278*32b31808SJens Wiklander #if defined(MBEDTLS_SHA512_C) 27911fa71b9SJerome Forissier case MBEDTLS_MD_SHA512: 28011fa71b9SJerome Forissier mbedtls_sha512_free(ctx->md_ctx); 28111fa71b9SJerome Forissier break; 28211fa71b9SJerome Forissier #endif 28311fa71b9SJerome Forissier default: 28411fa71b9SJerome Forissier /* Shouldn't happen */ 28511fa71b9SJerome Forissier break; 28611fa71b9SJerome Forissier } 28711fa71b9SJerome Forissier mbedtls_free(ctx->md_ctx); 28811fa71b9SJerome Forissier } 289817466cbSJens Wiklander 290*32b31808SJens Wiklander #if defined(MBEDTLS_MD_C) 291*32b31808SJens Wiklander if (ctx->hmac_ctx != NULL) { 2923d3b0591SJens Wiklander mbedtls_platform_zeroize(ctx->hmac_ctx, 2933d3b0591SJens Wiklander 2 * ctx->md_info->block_size); 294817466cbSJens Wiklander mbedtls_free(ctx->hmac_ctx); 295817466cbSJens Wiklander } 296*32b31808SJens Wiklander #endif 297817466cbSJens Wiklander 2983d3b0591SJens Wiklander mbedtls_platform_zeroize(ctx, sizeof(mbedtls_md_context_t)); 299817466cbSJens Wiklander } 300817466cbSJens Wiklander 301817466cbSJens Wiklander int mbedtls_md_clone(mbedtls_md_context_t *dst, 302817466cbSJens Wiklander const mbedtls_md_context_t *src) 303817466cbSJens Wiklander { 304817466cbSJens Wiklander if (dst == NULL || dst->md_info == NULL || 305817466cbSJens Wiklander src == NULL || src->md_info == NULL || 306*32b31808SJens Wiklander dst->md_info != src->md_info) { 307*32b31808SJens Wiklander return MBEDTLS_ERR_MD_BAD_INPUT_DATA; 308817466cbSJens Wiklander } 309817466cbSJens Wiklander 310*32b31808SJens Wiklander #if defined(MBEDTLS_MD_SOME_PSA) 311*32b31808SJens Wiklander if (src->engine != dst->engine) { 312*32b31808SJens Wiklander /* This can happen with src set to legacy because PSA wasn't ready 313*32b31808SJens Wiklander * yet, and dst to PSA because it became ready in the meantime. 314*32b31808SJens Wiklander * We currently don't support that case (we'd need to re-allocate 315*32b31808SJens Wiklander * md_ctx to the size of the appropriate MD context). */ 316*32b31808SJens Wiklander return MBEDTLS_ERR_MD_FEATURE_UNAVAILABLE; 317*32b31808SJens Wiklander } 318*32b31808SJens Wiklander 319*32b31808SJens Wiklander if (src->engine == MBEDTLS_MD_ENGINE_PSA) { 320*32b31808SJens Wiklander psa_status_t status = psa_hash_clone(src->md_ctx, dst->md_ctx); 321*32b31808SJens Wiklander return mbedtls_md_error_from_psa(status); 322*32b31808SJens Wiklander } 32311fa71b9SJerome Forissier #endif 324*32b31808SJens Wiklander 325*32b31808SJens Wiklander switch (src->md_info->type) { 32611fa71b9SJerome Forissier #if defined(MBEDTLS_MD5_C) 32711fa71b9SJerome Forissier case MBEDTLS_MD_MD5: 32811fa71b9SJerome Forissier mbedtls_md5_clone(dst->md_ctx, src->md_ctx); 32911fa71b9SJerome Forissier break; 33011fa71b9SJerome Forissier #endif 33111fa71b9SJerome Forissier #if defined(MBEDTLS_RIPEMD160_C) 33211fa71b9SJerome Forissier case MBEDTLS_MD_RIPEMD160: 33311fa71b9SJerome Forissier mbedtls_ripemd160_clone(dst->md_ctx, src->md_ctx); 33411fa71b9SJerome Forissier break; 33511fa71b9SJerome Forissier #endif 33611fa71b9SJerome Forissier #if defined(MBEDTLS_SHA1_C) 33711fa71b9SJerome Forissier case MBEDTLS_MD_SHA1: 33811fa71b9SJerome Forissier mbedtls_sha1_clone(dst->md_ctx, src->md_ctx); 33911fa71b9SJerome Forissier break; 34011fa71b9SJerome Forissier #endif 341*32b31808SJens Wiklander #if defined(MBEDTLS_SHA224_C) 34211fa71b9SJerome Forissier case MBEDTLS_MD_SHA224: 343*32b31808SJens Wiklander mbedtls_sha256_clone(dst->md_ctx, src->md_ctx); 344*32b31808SJens Wiklander break; 345*32b31808SJens Wiklander #endif 346*32b31808SJens Wiklander #if defined(MBEDTLS_SHA256_C) 34711fa71b9SJerome Forissier case MBEDTLS_MD_SHA256: 34811fa71b9SJerome Forissier mbedtls_sha256_clone(dst->md_ctx, src->md_ctx); 34911fa71b9SJerome Forissier break; 35011fa71b9SJerome Forissier #endif 351*32b31808SJens Wiklander #if defined(MBEDTLS_SHA384_C) 35211fa71b9SJerome Forissier case MBEDTLS_MD_SHA384: 353*32b31808SJens Wiklander mbedtls_sha512_clone(dst->md_ctx, src->md_ctx); 354*32b31808SJens Wiklander break; 35511fa71b9SJerome Forissier #endif 356*32b31808SJens Wiklander #if defined(MBEDTLS_SHA512_C) 35711fa71b9SJerome Forissier case MBEDTLS_MD_SHA512: 35811fa71b9SJerome Forissier mbedtls_sha512_clone(dst->md_ctx, src->md_ctx); 35911fa71b9SJerome Forissier break; 36011fa71b9SJerome Forissier #endif 36111fa71b9SJerome Forissier default: 362*32b31808SJens Wiklander return MBEDTLS_ERR_MD_BAD_INPUT_DATA; 36311fa71b9SJerome Forissier } 364817466cbSJens Wiklander 36512484fc7SEdison Ai if (dst->hmac_ctx != NULL && src->hmac_ctx != NULL) 36612484fc7SEdison Ai memcpy(dst->hmac_ctx, src->hmac_ctx, 2 * src->md_info->block_size); 36712484fc7SEdison Ai 368*32b31808SJens Wiklander return 0; 369817466cbSJens Wiklander } 370817466cbSJens Wiklander 37111fa71b9SJerome Forissier #define ALLOC(type) \ 37211fa71b9SJerome Forissier do { \ 37311fa71b9SJerome Forissier ctx->md_ctx = mbedtls_calloc(1, sizeof(mbedtls_##type##_context)); \ 37411fa71b9SJerome Forissier if (ctx->md_ctx == NULL) \ 375*32b31808SJens Wiklander return MBEDTLS_ERR_MD_ALLOC_FAILED; \ 37611fa71b9SJerome Forissier mbedtls_##type##_init(ctx->md_ctx); \ 37711fa71b9SJerome Forissier } \ 37811fa71b9SJerome Forissier while (0) 37911fa71b9SJerome Forissier 380817466cbSJens Wiklander int mbedtls_md_setup(mbedtls_md_context_t *ctx, const mbedtls_md_info_t *md_info, int hmac) 381817466cbSJens Wiklander { 382*32b31808SJens Wiklander if (md_info == NULL || ctx == NULL) { 383*32b31808SJens Wiklander return MBEDTLS_ERR_MD_BAD_INPUT_DATA; 384*32b31808SJens Wiklander } 385817466cbSJens Wiklander 3867901324dSJerome Forissier ctx->md_info = md_info; 3877901324dSJerome Forissier ctx->md_ctx = NULL; 388*32b31808SJens Wiklander #if defined(MBEDTLS_MD_C) 3897901324dSJerome Forissier ctx->hmac_ctx = NULL; 390*32b31808SJens Wiklander #else 391*32b31808SJens Wiklander if (hmac != 0) { 392*32b31808SJens Wiklander return MBEDTLS_ERR_MD_BAD_INPUT_DATA; 393*32b31808SJens Wiklander } 394*32b31808SJens Wiklander #endif 3957901324dSJerome Forissier 396*32b31808SJens Wiklander #if defined(MBEDTLS_MD_SOME_PSA) 397*32b31808SJens Wiklander if (md_can_use_psa(ctx->md_info)) { 398*32b31808SJens Wiklander ctx->md_ctx = mbedtls_calloc(1, sizeof(psa_hash_operation_t)); 399*32b31808SJens Wiklander if (ctx->md_ctx == NULL) { 400*32b31808SJens Wiklander return MBEDTLS_ERR_MD_ALLOC_FAILED; 401*32b31808SJens Wiklander } 402*32b31808SJens Wiklander ctx->engine = MBEDTLS_MD_ENGINE_PSA; 403*32b31808SJens Wiklander } else 40411fa71b9SJerome Forissier #endif 405*32b31808SJens Wiklander switch (md_info->type) { 40611fa71b9SJerome Forissier #if defined(MBEDTLS_MD5_C) 40711fa71b9SJerome Forissier case MBEDTLS_MD_MD5: 40811fa71b9SJerome Forissier ALLOC(md5); 40911fa71b9SJerome Forissier break; 41011fa71b9SJerome Forissier #endif 41111fa71b9SJerome Forissier #if defined(MBEDTLS_RIPEMD160_C) 41211fa71b9SJerome Forissier case MBEDTLS_MD_RIPEMD160: 41311fa71b9SJerome Forissier ALLOC(ripemd160); 41411fa71b9SJerome Forissier break; 41511fa71b9SJerome Forissier #endif 41611fa71b9SJerome Forissier #if defined(MBEDTLS_SHA1_C) 41711fa71b9SJerome Forissier case MBEDTLS_MD_SHA1: 41811fa71b9SJerome Forissier ALLOC(sha1); 41911fa71b9SJerome Forissier break; 42011fa71b9SJerome Forissier #endif 421*32b31808SJens Wiklander #if defined(MBEDTLS_SHA224_C) 42211fa71b9SJerome Forissier case MBEDTLS_MD_SHA224: 423*32b31808SJens Wiklander ALLOC(sha256); 424*32b31808SJens Wiklander break; 425*32b31808SJens Wiklander #endif 426*32b31808SJens Wiklander #if defined(MBEDTLS_SHA256_C) 42711fa71b9SJerome Forissier case MBEDTLS_MD_SHA256: 42811fa71b9SJerome Forissier ALLOC(sha256); 42911fa71b9SJerome Forissier break; 43011fa71b9SJerome Forissier #endif 431*32b31808SJens Wiklander #if defined(MBEDTLS_SHA384_C) 43211fa71b9SJerome Forissier case MBEDTLS_MD_SHA384: 433*32b31808SJens Wiklander ALLOC(sha512); 434*32b31808SJens Wiklander break; 43511fa71b9SJerome Forissier #endif 436*32b31808SJens Wiklander #if defined(MBEDTLS_SHA512_C) 43711fa71b9SJerome Forissier case MBEDTLS_MD_SHA512: 43811fa71b9SJerome Forissier ALLOC(sha512); 43911fa71b9SJerome Forissier break; 44011fa71b9SJerome Forissier #endif 44111fa71b9SJerome Forissier default: 442*32b31808SJens Wiklander return MBEDTLS_ERR_MD_BAD_INPUT_DATA; 44311fa71b9SJerome Forissier } 444817466cbSJens Wiklander 445*32b31808SJens Wiklander #if defined(MBEDTLS_MD_C) 446*32b31808SJens Wiklander if (hmac != 0) { 447817466cbSJens Wiklander ctx->hmac_ctx = mbedtls_calloc(2, md_info->block_size); 448*32b31808SJens Wiklander if (ctx->hmac_ctx == NULL) { 44911fa71b9SJerome Forissier mbedtls_md_free(ctx); 450*32b31808SJens Wiklander return MBEDTLS_ERR_MD_ALLOC_FAILED; 451817466cbSJens Wiklander } 452817466cbSJens Wiklander } 453*32b31808SJens Wiklander #endif 454817466cbSJens Wiklander 455*32b31808SJens Wiklander return 0; 456817466cbSJens Wiklander } 45711fa71b9SJerome Forissier #undef ALLOC 458817466cbSJens Wiklander 459817466cbSJens Wiklander int mbedtls_md_starts(mbedtls_md_context_t *ctx) 460817466cbSJens Wiklander { 461*32b31808SJens Wiklander if (ctx == NULL || ctx->md_info == NULL) { 462*32b31808SJens Wiklander return MBEDTLS_ERR_MD_BAD_INPUT_DATA; 463*32b31808SJens Wiklander } 464817466cbSJens Wiklander 465*32b31808SJens Wiklander #if defined(MBEDTLS_MD_SOME_PSA) 466*32b31808SJens Wiklander if (ctx->engine == MBEDTLS_MD_ENGINE_PSA) { 467*32b31808SJens Wiklander psa_algorithm_t alg = psa_alg_of_md(ctx->md_info); 468*32b31808SJens Wiklander psa_hash_abort(ctx->md_ctx); 469*32b31808SJens Wiklander psa_status_t status = psa_hash_setup(ctx->md_ctx, alg); 470*32b31808SJens Wiklander return mbedtls_md_error_from_psa(status); 471*32b31808SJens Wiklander } 47211fa71b9SJerome Forissier #endif 473*32b31808SJens Wiklander 474*32b31808SJens Wiklander switch (ctx->md_info->type) { 47511fa71b9SJerome Forissier #if defined(MBEDTLS_MD5_C) 47611fa71b9SJerome Forissier case MBEDTLS_MD_MD5: 477*32b31808SJens Wiklander return mbedtls_md5_starts(ctx->md_ctx); 47811fa71b9SJerome Forissier #endif 47911fa71b9SJerome Forissier #if defined(MBEDTLS_RIPEMD160_C) 48011fa71b9SJerome Forissier case MBEDTLS_MD_RIPEMD160: 481*32b31808SJens Wiklander return mbedtls_ripemd160_starts(ctx->md_ctx); 48211fa71b9SJerome Forissier #endif 48311fa71b9SJerome Forissier #if defined(MBEDTLS_SHA1_C) 48411fa71b9SJerome Forissier case MBEDTLS_MD_SHA1: 485*32b31808SJens Wiklander return mbedtls_sha1_starts(ctx->md_ctx); 486*32b31808SJens Wiklander #endif 487*32b31808SJens Wiklander #if defined(MBEDTLS_SHA224_C) 488*32b31808SJens Wiklander case MBEDTLS_MD_SHA224: 489*32b31808SJens Wiklander return mbedtls_sha256_starts(ctx->md_ctx, 1); 49011fa71b9SJerome Forissier #endif 49111fa71b9SJerome Forissier #if defined(MBEDTLS_SHA256_C) 49211fa71b9SJerome Forissier case MBEDTLS_MD_SHA256: 493*32b31808SJens Wiklander return mbedtls_sha256_starts(ctx->md_ctx, 0); 494*32b31808SJens Wiklander #endif 495*32b31808SJens Wiklander #if defined(MBEDTLS_SHA384_C) 496*32b31808SJens Wiklander case MBEDTLS_MD_SHA384: 497*32b31808SJens Wiklander return mbedtls_sha512_starts(ctx->md_ctx, 1); 49811fa71b9SJerome Forissier #endif 49911fa71b9SJerome Forissier #if defined(MBEDTLS_SHA512_C) 50011fa71b9SJerome Forissier case MBEDTLS_MD_SHA512: 501*32b31808SJens Wiklander return mbedtls_sha512_starts(ctx->md_ctx, 0); 50211fa71b9SJerome Forissier #endif 50311fa71b9SJerome Forissier default: 504*32b31808SJens Wiklander return MBEDTLS_ERR_MD_BAD_INPUT_DATA; 50511fa71b9SJerome Forissier } 506817466cbSJens Wiklander } 507817466cbSJens Wiklander 508817466cbSJens Wiklander int mbedtls_md_update(mbedtls_md_context_t *ctx, const unsigned char *input, size_t ilen) 509817466cbSJens Wiklander { 510*32b31808SJens Wiklander if (ctx == NULL || ctx->md_info == NULL) { 511*32b31808SJens Wiklander return MBEDTLS_ERR_MD_BAD_INPUT_DATA; 512*32b31808SJens Wiklander } 513817466cbSJens Wiklander 514*32b31808SJens Wiklander #if defined(MBEDTLS_MD_SOME_PSA) 515*32b31808SJens Wiklander if (ctx->engine == MBEDTLS_MD_ENGINE_PSA) { 516*32b31808SJens Wiklander psa_status_t status = psa_hash_update(ctx->md_ctx, input, ilen); 517*32b31808SJens Wiklander return mbedtls_md_error_from_psa(status); 518*32b31808SJens Wiklander } 51911fa71b9SJerome Forissier #endif 520*32b31808SJens Wiklander 521*32b31808SJens Wiklander switch (ctx->md_info->type) { 52211fa71b9SJerome Forissier #if defined(MBEDTLS_MD5_C) 52311fa71b9SJerome Forissier case MBEDTLS_MD_MD5: 524*32b31808SJens Wiklander return mbedtls_md5_update(ctx->md_ctx, input, ilen); 52511fa71b9SJerome Forissier #endif 52611fa71b9SJerome Forissier #if defined(MBEDTLS_RIPEMD160_C) 52711fa71b9SJerome Forissier case MBEDTLS_MD_RIPEMD160: 528*32b31808SJens Wiklander return mbedtls_ripemd160_update(ctx->md_ctx, input, ilen); 52911fa71b9SJerome Forissier #endif 53011fa71b9SJerome Forissier #if defined(MBEDTLS_SHA1_C) 53111fa71b9SJerome Forissier case MBEDTLS_MD_SHA1: 532*32b31808SJens Wiklander return mbedtls_sha1_update(ctx->md_ctx, input, ilen); 533*32b31808SJens Wiklander #endif 534*32b31808SJens Wiklander #if defined(MBEDTLS_SHA224_C) 535*32b31808SJens Wiklander case MBEDTLS_MD_SHA224: 536*32b31808SJens Wiklander return mbedtls_sha256_update(ctx->md_ctx, input, ilen); 53711fa71b9SJerome Forissier #endif 53811fa71b9SJerome Forissier #if defined(MBEDTLS_SHA256_C) 53911fa71b9SJerome Forissier case MBEDTLS_MD_SHA256: 540*32b31808SJens Wiklander return mbedtls_sha256_update(ctx->md_ctx, input, ilen); 541*32b31808SJens Wiklander #endif 542*32b31808SJens Wiklander #if defined(MBEDTLS_SHA384_C) 543*32b31808SJens Wiklander case MBEDTLS_MD_SHA384: 544*32b31808SJens Wiklander return mbedtls_sha512_update(ctx->md_ctx, input, ilen); 54511fa71b9SJerome Forissier #endif 54611fa71b9SJerome Forissier #if defined(MBEDTLS_SHA512_C) 54711fa71b9SJerome Forissier case MBEDTLS_MD_SHA512: 548*32b31808SJens Wiklander return mbedtls_sha512_update(ctx->md_ctx, input, ilen); 54911fa71b9SJerome Forissier #endif 55011fa71b9SJerome Forissier default: 551*32b31808SJens Wiklander return MBEDTLS_ERR_MD_BAD_INPUT_DATA; 55211fa71b9SJerome Forissier } 553817466cbSJens Wiklander } 554817466cbSJens Wiklander 555817466cbSJens Wiklander int mbedtls_md_finish(mbedtls_md_context_t *ctx, unsigned char *output) 556817466cbSJens Wiklander { 557*32b31808SJens Wiklander if (ctx == NULL || ctx->md_info == NULL) { 558*32b31808SJens Wiklander return MBEDTLS_ERR_MD_BAD_INPUT_DATA; 559*32b31808SJens Wiklander } 560817466cbSJens Wiklander 561*32b31808SJens Wiklander #if defined(MBEDTLS_MD_SOME_PSA) 562*32b31808SJens Wiklander if (ctx->engine == MBEDTLS_MD_ENGINE_PSA) { 563*32b31808SJens Wiklander size_t size = ctx->md_info->size; 564*32b31808SJens Wiklander psa_status_t status = psa_hash_finish(ctx->md_ctx, 565*32b31808SJens Wiklander output, size, &size); 566*32b31808SJens Wiklander return mbedtls_md_error_from_psa(status); 567*32b31808SJens Wiklander } 56811fa71b9SJerome Forissier #endif 569*32b31808SJens Wiklander 570*32b31808SJens Wiklander switch (ctx->md_info->type) { 57111fa71b9SJerome Forissier #if defined(MBEDTLS_MD5_C) 57211fa71b9SJerome Forissier case MBEDTLS_MD_MD5: 573*32b31808SJens Wiklander return mbedtls_md5_finish(ctx->md_ctx, output); 57411fa71b9SJerome Forissier #endif 57511fa71b9SJerome Forissier #if defined(MBEDTLS_RIPEMD160_C) 57611fa71b9SJerome Forissier case MBEDTLS_MD_RIPEMD160: 577*32b31808SJens Wiklander return mbedtls_ripemd160_finish(ctx->md_ctx, output); 57811fa71b9SJerome Forissier #endif 57911fa71b9SJerome Forissier #if defined(MBEDTLS_SHA1_C) 58011fa71b9SJerome Forissier case MBEDTLS_MD_SHA1: 581*32b31808SJens Wiklander return mbedtls_sha1_finish(ctx->md_ctx, output); 582*32b31808SJens Wiklander #endif 583*32b31808SJens Wiklander #if defined(MBEDTLS_SHA224_C) 584*32b31808SJens Wiklander case MBEDTLS_MD_SHA224: 585*32b31808SJens Wiklander return mbedtls_sha256_finish(ctx->md_ctx, output); 58611fa71b9SJerome Forissier #endif 58711fa71b9SJerome Forissier #if defined(MBEDTLS_SHA256_C) 58811fa71b9SJerome Forissier case MBEDTLS_MD_SHA256: 589*32b31808SJens Wiklander return mbedtls_sha256_finish(ctx->md_ctx, output); 590*32b31808SJens Wiklander #endif 591*32b31808SJens Wiklander #if defined(MBEDTLS_SHA384_C) 592*32b31808SJens Wiklander case MBEDTLS_MD_SHA384: 593*32b31808SJens Wiklander return mbedtls_sha512_finish(ctx->md_ctx, output); 59411fa71b9SJerome Forissier #endif 59511fa71b9SJerome Forissier #if defined(MBEDTLS_SHA512_C) 59611fa71b9SJerome Forissier case MBEDTLS_MD_SHA512: 597*32b31808SJens Wiklander return mbedtls_sha512_finish(ctx->md_ctx, output); 59811fa71b9SJerome Forissier #endif 59911fa71b9SJerome Forissier default: 600*32b31808SJens Wiklander return MBEDTLS_ERR_MD_BAD_INPUT_DATA; 60111fa71b9SJerome Forissier } 602817466cbSJens Wiklander } 603817466cbSJens Wiklander 604817466cbSJens Wiklander int mbedtls_md(const mbedtls_md_info_t *md_info, const unsigned char *input, size_t ilen, 605817466cbSJens Wiklander unsigned char *output) 606817466cbSJens Wiklander { 607*32b31808SJens Wiklander if (md_info == NULL) { 608*32b31808SJens Wiklander return MBEDTLS_ERR_MD_BAD_INPUT_DATA; 609*32b31808SJens Wiklander } 610817466cbSJens Wiklander 611*32b31808SJens Wiklander #if defined(MBEDTLS_MD_SOME_PSA) 612*32b31808SJens Wiklander if (md_can_use_psa(md_info)) { 613*32b31808SJens Wiklander size_t size = md_info->size; 614*32b31808SJens Wiklander psa_status_t status = psa_hash_compute(psa_alg_of_md(md_info), 615*32b31808SJens Wiklander input, ilen, 616*32b31808SJens Wiklander output, size, &size); 617*32b31808SJens Wiklander return mbedtls_md_error_from_psa(status); 618*32b31808SJens Wiklander } 61911fa71b9SJerome Forissier #endif 620*32b31808SJens Wiklander 621*32b31808SJens Wiklander switch (md_info->type) { 62211fa71b9SJerome Forissier #if defined(MBEDTLS_MD5_C) 62311fa71b9SJerome Forissier case MBEDTLS_MD_MD5: 624*32b31808SJens Wiklander return mbedtls_md5(input, ilen, output); 62511fa71b9SJerome Forissier #endif 62611fa71b9SJerome Forissier #if defined(MBEDTLS_RIPEMD160_C) 62711fa71b9SJerome Forissier case MBEDTLS_MD_RIPEMD160: 628*32b31808SJens Wiklander return mbedtls_ripemd160(input, ilen, output); 62911fa71b9SJerome Forissier #endif 63011fa71b9SJerome Forissier #if defined(MBEDTLS_SHA1_C) 63111fa71b9SJerome Forissier case MBEDTLS_MD_SHA1: 632*32b31808SJens Wiklander return mbedtls_sha1(input, ilen, output); 633*32b31808SJens Wiklander #endif 634*32b31808SJens Wiklander #if defined(MBEDTLS_SHA224_C) 635*32b31808SJens Wiklander case MBEDTLS_MD_SHA224: 636*32b31808SJens Wiklander return mbedtls_sha256(input, ilen, output, 1); 63711fa71b9SJerome Forissier #endif 63811fa71b9SJerome Forissier #if defined(MBEDTLS_SHA256_C) 63911fa71b9SJerome Forissier case MBEDTLS_MD_SHA256: 640*32b31808SJens Wiklander return mbedtls_sha256(input, ilen, output, 0); 641*32b31808SJens Wiklander #endif 642*32b31808SJens Wiklander #if defined(MBEDTLS_SHA384_C) 643*32b31808SJens Wiklander case MBEDTLS_MD_SHA384: 644*32b31808SJens Wiklander return mbedtls_sha512(input, ilen, output, 1); 64511fa71b9SJerome Forissier #endif 64611fa71b9SJerome Forissier #if defined(MBEDTLS_SHA512_C) 64711fa71b9SJerome Forissier case MBEDTLS_MD_SHA512: 648*32b31808SJens Wiklander return mbedtls_sha512(input, ilen, output, 0); 64911fa71b9SJerome Forissier #endif 65011fa71b9SJerome Forissier default: 651*32b31808SJens Wiklander return MBEDTLS_ERR_MD_BAD_INPUT_DATA; 65211fa71b9SJerome Forissier } 653817466cbSJens Wiklander } 654817466cbSJens Wiklander 655*32b31808SJens Wiklander unsigned char mbedtls_md_get_size(const mbedtls_md_info_t *md_info) 656*32b31808SJens Wiklander { 657*32b31808SJens Wiklander if (md_info == NULL) { 658*32b31808SJens Wiklander return 0; 659*32b31808SJens Wiklander } 660*32b31808SJens Wiklander 661*32b31808SJens Wiklander return md_info->size; 662*32b31808SJens Wiklander } 663*32b31808SJens Wiklander 664*32b31808SJens Wiklander mbedtls_md_type_t mbedtls_md_get_type(const mbedtls_md_info_t *md_info) 665*32b31808SJens Wiklander { 666*32b31808SJens Wiklander if (md_info == NULL) { 667*32b31808SJens Wiklander return MBEDTLS_MD_NONE; 668*32b31808SJens Wiklander } 669*32b31808SJens Wiklander 670*32b31808SJens Wiklander return md_info->type; 671*32b31808SJens Wiklander } 672*32b31808SJens Wiklander 673*32b31808SJens Wiklander /************************************************************************ 674*32b31808SJens Wiklander * Functions above this separator are part of MBEDTLS_MD_LIGHT, * 675*32b31808SJens Wiklander * functions below are only available when MBEDTLS_MD_C is set. * 676*32b31808SJens Wiklander ************************************************************************/ 677*32b31808SJens Wiklander #if defined(MBEDTLS_MD_C) 678*32b31808SJens Wiklander 679*32b31808SJens Wiklander /* 680*32b31808SJens Wiklander * Reminder: update profiles in x509_crt.c when adding a new hash! 681*32b31808SJens Wiklander */ 682*32b31808SJens Wiklander static const int supported_digests[] = { 683*32b31808SJens Wiklander 684*32b31808SJens Wiklander #if defined(MBEDTLS_MD_CAN_SHA512) 685*32b31808SJens Wiklander MBEDTLS_MD_SHA512, 686*32b31808SJens Wiklander #endif 687*32b31808SJens Wiklander 688*32b31808SJens Wiklander #if defined(MBEDTLS_MD_CAN_SHA384) 689*32b31808SJens Wiklander MBEDTLS_MD_SHA384, 690*32b31808SJens Wiklander #endif 691*32b31808SJens Wiklander 692*32b31808SJens Wiklander #if defined(MBEDTLS_MD_CAN_SHA256) 693*32b31808SJens Wiklander MBEDTLS_MD_SHA256, 694*32b31808SJens Wiklander #endif 695*32b31808SJens Wiklander #if defined(MBEDTLS_MD_CAN_SHA224) 696*32b31808SJens Wiklander MBEDTLS_MD_SHA224, 697*32b31808SJens Wiklander #endif 698*32b31808SJens Wiklander 699*32b31808SJens Wiklander #if defined(MBEDTLS_MD_CAN_SHA1) 700*32b31808SJens Wiklander MBEDTLS_MD_SHA1, 701*32b31808SJens Wiklander #endif 702*32b31808SJens Wiklander 703*32b31808SJens Wiklander #if defined(MBEDTLS_MD_CAN_RIPEMD160) 704*32b31808SJens Wiklander MBEDTLS_MD_RIPEMD160, 705*32b31808SJens Wiklander #endif 706*32b31808SJens Wiklander 707*32b31808SJens Wiklander #if defined(MBEDTLS_MD_CAN_MD5) 708*32b31808SJens Wiklander MBEDTLS_MD_MD5, 709*32b31808SJens Wiklander #endif 710*32b31808SJens Wiklander 711*32b31808SJens Wiklander MBEDTLS_MD_NONE 712*32b31808SJens Wiklander }; 713*32b31808SJens Wiklander 714*32b31808SJens Wiklander const int *mbedtls_md_list(void) 715*32b31808SJens Wiklander { 716*32b31808SJens Wiklander return supported_digests; 717*32b31808SJens Wiklander } 718*32b31808SJens Wiklander 719*32b31808SJens Wiklander const mbedtls_md_info_t *mbedtls_md_info_from_string(const char *md_name) 720*32b31808SJens Wiklander { 721*32b31808SJens Wiklander if (NULL == md_name) { 722*32b31808SJens Wiklander return NULL; 723*32b31808SJens Wiklander } 724*32b31808SJens Wiklander 725*32b31808SJens Wiklander /* Get the appropriate digest information */ 726*32b31808SJens Wiklander #if defined(MBEDTLS_MD_CAN_MD5) 727*32b31808SJens Wiklander if (!strcmp("MD5", md_name)) { 728*32b31808SJens Wiklander return mbedtls_md_info_from_type(MBEDTLS_MD_MD5); 729*32b31808SJens Wiklander } 730*32b31808SJens Wiklander #endif 731*32b31808SJens Wiklander #if defined(MBEDTLS_MD_CAN_RIPEMD160) 732*32b31808SJens Wiklander if (!strcmp("RIPEMD160", md_name)) { 733*32b31808SJens Wiklander return mbedtls_md_info_from_type(MBEDTLS_MD_RIPEMD160); 734*32b31808SJens Wiklander } 735*32b31808SJens Wiklander #endif 736*32b31808SJens Wiklander #if defined(MBEDTLS_MD_CAN_SHA1) 737*32b31808SJens Wiklander if (!strcmp("SHA1", md_name) || !strcmp("SHA", md_name)) { 738*32b31808SJens Wiklander return mbedtls_md_info_from_type(MBEDTLS_MD_SHA1); 739*32b31808SJens Wiklander } 740*32b31808SJens Wiklander #endif 741*32b31808SJens Wiklander #if defined(MBEDTLS_MD_CAN_SHA224) 742*32b31808SJens Wiklander if (!strcmp("SHA224", md_name)) { 743*32b31808SJens Wiklander return mbedtls_md_info_from_type(MBEDTLS_MD_SHA224); 744*32b31808SJens Wiklander } 745*32b31808SJens Wiklander #endif 746*32b31808SJens Wiklander #if defined(MBEDTLS_MD_CAN_SHA256) 747*32b31808SJens Wiklander if (!strcmp("SHA256", md_name)) { 748*32b31808SJens Wiklander return mbedtls_md_info_from_type(MBEDTLS_MD_SHA256); 749*32b31808SJens Wiklander } 750*32b31808SJens Wiklander #endif 751*32b31808SJens Wiklander #if defined(MBEDTLS_MD_CAN_SHA384) 752*32b31808SJens Wiklander if (!strcmp("SHA384", md_name)) { 753*32b31808SJens Wiklander return mbedtls_md_info_from_type(MBEDTLS_MD_SHA384); 754*32b31808SJens Wiklander } 755*32b31808SJens Wiklander #endif 756*32b31808SJens Wiklander #if defined(MBEDTLS_MD_CAN_SHA512) 757*32b31808SJens Wiklander if (!strcmp("SHA512", md_name)) { 758*32b31808SJens Wiklander return mbedtls_md_info_from_type(MBEDTLS_MD_SHA512); 759*32b31808SJens Wiklander } 760*32b31808SJens Wiklander #endif 761*32b31808SJens Wiklander return NULL; 762*32b31808SJens Wiklander } 763*32b31808SJens Wiklander 764*32b31808SJens Wiklander const mbedtls_md_info_t *mbedtls_md_info_from_ctx( 765*32b31808SJens Wiklander const mbedtls_md_context_t *ctx) 766*32b31808SJens Wiklander { 767*32b31808SJens Wiklander if (ctx == NULL) { 768*32b31808SJens Wiklander return NULL; 769*32b31808SJens Wiklander } 770*32b31808SJens Wiklander 771*32b31808SJens Wiklander return ctx->MBEDTLS_PRIVATE(md_info); 772*32b31808SJens Wiklander } 773*32b31808SJens Wiklander 774817466cbSJens Wiklander #if defined(MBEDTLS_FS_IO) 775817466cbSJens Wiklander int mbedtls_md_file(const mbedtls_md_info_t *md_info, const char *path, unsigned char *output) 776817466cbSJens Wiklander { 77711fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 778817466cbSJens Wiklander FILE *f; 779817466cbSJens Wiklander size_t n; 780817466cbSJens Wiklander mbedtls_md_context_t ctx; 781817466cbSJens Wiklander unsigned char buf[1024]; 782817466cbSJens Wiklander 783*32b31808SJens Wiklander if (md_info == NULL) { 784*32b31808SJens Wiklander return MBEDTLS_ERR_MD_BAD_INPUT_DATA; 785*32b31808SJens Wiklander } 786817466cbSJens Wiklander 787*32b31808SJens Wiklander if ((f = fopen(path, "rb")) == NULL) { 788*32b31808SJens Wiklander return MBEDTLS_ERR_MD_FILE_IO_ERROR; 789*32b31808SJens Wiklander } 790*32b31808SJens Wiklander 791*32b31808SJens Wiklander /* Ensure no stdio buffering of secrets, as such buffers cannot be wiped. */ 792*32b31808SJens Wiklander mbedtls_setbuf(f, NULL); 793817466cbSJens Wiklander 794817466cbSJens Wiklander mbedtls_md_init(&ctx); 795817466cbSJens Wiklander 796*32b31808SJens Wiklander if ((ret = mbedtls_md_setup(&ctx, md_info, 0)) != 0) { 797817466cbSJens Wiklander goto cleanup; 798*32b31808SJens Wiklander } 799817466cbSJens Wiklander 800*32b31808SJens Wiklander if ((ret = mbedtls_md_starts(&ctx)) != 0) { 8013d3b0591SJens Wiklander goto cleanup; 802*32b31808SJens Wiklander } 803817466cbSJens Wiklander 804*32b31808SJens Wiklander while ((n = fread(buf, 1, sizeof(buf), f)) > 0) { 805*32b31808SJens Wiklander if ((ret = mbedtls_md_update(&ctx, buf, n)) != 0) { 8063d3b0591SJens Wiklander goto cleanup; 807*32b31808SJens Wiklander } 808*32b31808SJens Wiklander } 809817466cbSJens Wiklander 810*32b31808SJens Wiklander if (ferror(f) != 0) { 811817466cbSJens Wiklander ret = MBEDTLS_ERR_MD_FILE_IO_ERROR; 812*32b31808SJens Wiklander } else { 81311fa71b9SJerome Forissier ret = mbedtls_md_finish(&ctx, output); 814*32b31808SJens Wiklander } 815817466cbSJens Wiklander 816817466cbSJens Wiklander cleanup: 8173d3b0591SJens Wiklander mbedtls_platform_zeroize(buf, sizeof(buf)); 818817466cbSJens Wiklander fclose(f); 819817466cbSJens Wiklander mbedtls_md_free(&ctx); 820817466cbSJens Wiklander 821*32b31808SJens Wiklander return ret; 822817466cbSJens Wiklander } 823817466cbSJens Wiklander #endif /* MBEDTLS_FS_IO */ 824817466cbSJens Wiklander 825817466cbSJens Wiklander int mbedtls_md_hmac_starts(mbedtls_md_context_t *ctx, const unsigned char *key, size_t keylen) 826817466cbSJens Wiklander { 82711fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 828817466cbSJens Wiklander unsigned char sum[MBEDTLS_MD_MAX_SIZE]; 829817466cbSJens Wiklander unsigned char *ipad, *opad; 830817466cbSJens Wiklander 831*32b31808SJens Wiklander if (ctx == NULL || ctx->md_info == NULL || ctx->hmac_ctx == NULL) { 832*32b31808SJens Wiklander return MBEDTLS_ERR_MD_BAD_INPUT_DATA; 833*32b31808SJens Wiklander } 834817466cbSJens Wiklander 835*32b31808SJens Wiklander if (keylen > (size_t) ctx->md_info->block_size) { 836*32b31808SJens Wiklander if ((ret = mbedtls_md_starts(ctx)) != 0) { 8373d3b0591SJens Wiklander goto cleanup; 838*32b31808SJens Wiklander } 839*32b31808SJens Wiklander if ((ret = mbedtls_md_update(ctx, key, keylen)) != 0) { 8403d3b0591SJens Wiklander goto cleanup; 841*32b31808SJens Wiklander } 842*32b31808SJens Wiklander if ((ret = mbedtls_md_finish(ctx, sum)) != 0) { 8433d3b0591SJens Wiklander goto cleanup; 844*32b31808SJens Wiklander } 845817466cbSJens Wiklander 846817466cbSJens Wiklander keylen = ctx->md_info->size; 847817466cbSJens Wiklander key = sum; 848817466cbSJens Wiklander } 849817466cbSJens Wiklander 850817466cbSJens Wiklander ipad = (unsigned char *) ctx->hmac_ctx; 851817466cbSJens Wiklander opad = (unsigned char *) ctx->hmac_ctx + ctx->md_info->block_size; 852817466cbSJens Wiklander 853817466cbSJens Wiklander memset(ipad, 0x36, ctx->md_info->block_size); 854817466cbSJens Wiklander memset(opad, 0x5C, ctx->md_info->block_size); 855817466cbSJens Wiklander 856*32b31808SJens Wiklander mbedtls_xor(ipad, ipad, key, keylen); 857*32b31808SJens Wiklander mbedtls_xor(opad, opad, key, keylen); 858817466cbSJens Wiklander 859*32b31808SJens Wiklander if ((ret = mbedtls_md_starts(ctx)) != 0) { 8603d3b0591SJens Wiklander goto cleanup; 861*32b31808SJens Wiklander } 86211fa71b9SJerome Forissier if ((ret = mbedtls_md_update(ctx, ipad, 863*32b31808SJens Wiklander ctx->md_info->block_size)) != 0) { 8643d3b0591SJens Wiklander goto cleanup; 865*32b31808SJens Wiklander } 866817466cbSJens Wiklander 8673d3b0591SJens Wiklander cleanup: 8683d3b0591SJens Wiklander mbedtls_platform_zeroize(sum, sizeof(sum)); 869817466cbSJens Wiklander 870*32b31808SJens Wiklander return ret; 871817466cbSJens Wiklander } 872817466cbSJens Wiklander 873817466cbSJens Wiklander int mbedtls_md_hmac_update(mbedtls_md_context_t *ctx, const unsigned char *input, size_t ilen) 874817466cbSJens Wiklander { 875*32b31808SJens Wiklander if (ctx == NULL || ctx->md_info == NULL || ctx->hmac_ctx == NULL) { 876*32b31808SJens Wiklander return MBEDTLS_ERR_MD_BAD_INPUT_DATA; 877*32b31808SJens Wiklander } 878817466cbSJens Wiklander 879*32b31808SJens Wiklander return mbedtls_md_update(ctx, input, ilen); 880817466cbSJens Wiklander } 881817466cbSJens Wiklander 882817466cbSJens Wiklander int mbedtls_md_hmac_finish(mbedtls_md_context_t *ctx, unsigned char *output) 883817466cbSJens Wiklander { 88411fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 885817466cbSJens Wiklander unsigned char tmp[MBEDTLS_MD_MAX_SIZE]; 886817466cbSJens Wiklander unsigned char *opad; 887817466cbSJens Wiklander 888*32b31808SJens Wiklander if (ctx == NULL || ctx->md_info == NULL || ctx->hmac_ctx == NULL) { 889*32b31808SJens Wiklander return MBEDTLS_ERR_MD_BAD_INPUT_DATA; 890*32b31808SJens Wiklander } 891817466cbSJens Wiklander 892817466cbSJens Wiklander opad = (unsigned char *) ctx->hmac_ctx + ctx->md_info->block_size; 893817466cbSJens Wiklander 894*32b31808SJens Wiklander if ((ret = mbedtls_md_finish(ctx, tmp)) != 0) { 895*32b31808SJens Wiklander return ret; 896*32b31808SJens Wiklander } 897*32b31808SJens Wiklander if ((ret = mbedtls_md_starts(ctx)) != 0) { 898*32b31808SJens Wiklander return ret; 899*32b31808SJens Wiklander } 90011fa71b9SJerome Forissier if ((ret = mbedtls_md_update(ctx, opad, 901*32b31808SJens Wiklander ctx->md_info->block_size)) != 0) { 902*32b31808SJens Wiklander return ret; 903*32b31808SJens Wiklander } 90411fa71b9SJerome Forissier if ((ret = mbedtls_md_update(ctx, tmp, 905*32b31808SJens Wiklander ctx->md_info->size)) != 0) { 906*32b31808SJens Wiklander return ret; 907*32b31808SJens Wiklander } 908*32b31808SJens Wiklander return mbedtls_md_finish(ctx, output); 909817466cbSJens Wiklander } 910817466cbSJens Wiklander 911817466cbSJens Wiklander int mbedtls_md_hmac_reset(mbedtls_md_context_t *ctx) 912817466cbSJens Wiklander { 91311fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 914817466cbSJens Wiklander unsigned char *ipad; 915817466cbSJens Wiklander 916*32b31808SJens Wiklander if (ctx == NULL || ctx->md_info == NULL || ctx->hmac_ctx == NULL) { 917*32b31808SJens Wiklander return MBEDTLS_ERR_MD_BAD_INPUT_DATA; 918*32b31808SJens Wiklander } 919817466cbSJens Wiklander 920817466cbSJens Wiklander ipad = (unsigned char *) ctx->hmac_ctx; 921817466cbSJens Wiklander 922*32b31808SJens Wiklander if ((ret = mbedtls_md_starts(ctx)) != 0) { 923*32b31808SJens Wiklander return ret; 924*32b31808SJens Wiklander } 925*32b31808SJens Wiklander return mbedtls_md_update(ctx, ipad, ctx->md_info->block_size); 926817466cbSJens Wiklander } 927817466cbSJens Wiklander 9283d3b0591SJens Wiklander int mbedtls_md_hmac(const mbedtls_md_info_t *md_info, 9293d3b0591SJens Wiklander const unsigned char *key, size_t keylen, 930817466cbSJens Wiklander const unsigned char *input, size_t ilen, 931817466cbSJens Wiklander unsigned char *output) 932817466cbSJens Wiklander { 933817466cbSJens Wiklander mbedtls_md_context_t ctx; 93411fa71b9SJerome Forissier int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED; 935817466cbSJens Wiklander 936*32b31808SJens Wiklander if (md_info == NULL) { 937*32b31808SJens Wiklander return MBEDTLS_ERR_MD_BAD_INPUT_DATA; 938*32b31808SJens Wiklander } 939817466cbSJens Wiklander 940817466cbSJens Wiklander mbedtls_md_init(&ctx); 941817466cbSJens Wiklander 942*32b31808SJens Wiklander if ((ret = mbedtls_md_setup(&ctx, md_info, 1)) != 0) { 9433d3b0591SJens Wiklander goto cleanup; 944*32b31808SJens Wiklander } 945817466cbSJens Wiklander 946*32b31808SJens Wiklander if ((ret = mbedtls_md_hmac_starts(&ctx, key, keylen)) != 0) { 9473d3b0591SJens Wiklander goto cleanup; 948*32b31808SJens Wiklander } 949*32b31808SJens Wiklander if ((ret = mbedtls_md_hmac_update(&ctx, input, ilen)) != 0) { 9503d3b0591SJens Wiklander goto cleanup; 951*32b31808SJens Wiklander } 952*32b31808SJens Wiklander if ((ret = mbedtls_md_hmac_finish(&ctx, output)) != 0) { 9533d3b0591SJens Wiklander goto cleanup; 954*32b31808SJens Wiklander } 955817466cbSJens Wiklander 9563d3b0591SJens Wiklander cleanup: 957817466cbSJens Wiklander mbedtls_md_free(&ctx); 958817466cbSJens Wiklander 959*32b31808SJens Wiklander return ret; 960817466cbSJens Wiklander } 961817466cbSJens Wiklander 962817466cbSJens Wiklander const char *mbedtls_md_get_name(const mbedtls_md_info_t *md_info) 963817466cbSJens Wiklander { 964*32b31808SJens Wiklander if (md_info == NULL) { 965*32b31808SJens Wiklander return NULL; 966*32b31808SJens Wiklander } 967817466cbSJens Wiklander 968817466cbSJens Wiklander return md_info->name; 969817466cbSJens Wiklander } 970817466cbSJens Wiklander 971817466cbSJens Wiklander #endif /* MBEDTLS_MD_C */ 972*32b31808SJens Wiklander 973*32b31808SJens Wiklander #endif /* MBEDTLS_MD_LIGHT */ 974