1*62c56f98SSadaf Ebrahimi /** 2*62c56f98SSadaf Ebrahimi * \file entropy.h 3*62c56f98SSadaf Ebrahimi * 4*62c56f98SSadaf Ebrahimi * \brief Entropy accumulator implementation 5*62c56f98SSadaf Ebrahimi */ 6*62c56f98SSadaf Ebrahimi /* 7*62c56f98SSadaf Ebrahimi * Copyright The Mbed TLS Contributors 8*62c56f98SSadaf Ebrahimi * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later 9*62c56f98SSadaf Ebrahimi */ 10*62c56f98SSadaf Ebrahimi #ifndef MBEDTLS_ENTROPY_H 11*62c56f98SSadaf Ebrahimi #define MBEDTLS_ENTROPY_H 12*62c56f98SSadaf Ebrahimi #include "mbedtls/private_access.h" 13*62c56f98SSadaf Ebrahimi 14*62c56f98SSadaf Ebrahimi #include "mbedtls/build_info.h" 15*62c56f98SSadaf Ebrahimi 16*62c56f98SSadaf Ebrahimi #include <stddef.h> 17*62c56f98SSadaf Ebrahimi 18*62c56f98SSadaf Ebrahimi #include "md.h" 19*62c56f98SSadaf Ebrahimi 20*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_MD_CAN_SHA512) && !defined(MBEDTLS_ENTROPY_FORCE_SHA256) 21*62c56f98SSadaf Ebrahimi #define MBEDTLS_ENTROPY_SHA512_ACCUMULATOR 22*62c56f98SSadaf Ebrahimi #define MBEDTLS_ENTROPY_MD MBEDTLS_MD_SHA512 23*62c56f98SSadaf Ebrahimi #define MBEDTLS_ENTROPY_BLOCK_SIZE 64 /**< Block size of entropy accumulator (SHA-512) */ 24*62c56f98SSadaf Ebrahimi #else 25*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_MD_CAN_SHA256) 26*62c56f98SSadaf Ebrahimi #define MBEDTLS_ENTROPY_SHA256_ACCUMULATOR 27*62c56f98SSadaf Ebrahimi #define MBEDTLS_ENTROPY_MD MBEDTLS_MD_SHA256 28*62c56f98SSadaf Ebrahimi #define MBEDTLS_ENTROPY_BLOCK_SIZE 32 /**< Block size of entropy accumulator (SHA-256) */ 29*62c56f98SSadaf Ebrahimi #endif 30*62c56f98SSadaf Ebrahimi #endif 31*62c56f98SSadaf Ebrahimi 32*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_THREADING_C) 33*62c56f98SSadaf Ebrahimi #include "mbedtls/threading.h" 34*62c56f98SSadaf Ebrahimi #endif 35*62c56f98SSadaf Ebrahimi 36*62c56f98SSadaf Ebrahimi 37*62c56f98SSadaf Ebrahimi /** Critical entropy source failure. */ 38*62c56f98SSadaf Ebrahimi #define MBEDTLS_ERR_ENTROPY_SOURCE_FAILED -0x003C 39*62c56f98SSadaf Ebrahimi /** No more sources can be added. */ 40*62c56f98SSadaf Ebrahimi #define MBEDTLS_ERR_ENTROPY_MAX_SOURCES -0x003E 41*62c56f98SSadaf Ebrahimi /** No sources have been added to poll. */ 42*62c56f98SSadaf Ebrahimi #define MBEDTLS_ERR_ENTROPY_NO_SOURCES_DEFINED -0x0040 43*62c56f98SSadaf Ebrahimi /** No strong sources have been added to poll. */ 44*62c56f98SSadaf Ebrahimi #define MBEDTLS_ERR_ENTROPY_NO_STRONG_SOURCE -0x003D 45*62c56f98SSadaf Ebrahimi /** Read/write error in file. */ 46*62c56f98SSadaf Ebrahimi #define MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR -0x003F 47*62c56f98SSadaf Ebrahimi 48*62c56f98SSadaf Ebrahimi /** 49*62c56f98SSadaf Ebrahimi * \name SECTION: Module settings 50*62c56f98SSadaf Ebrahimi * 51*62c56f98SSadaf Ebrahimi * The configuration options you can set for this module are in this section. 52*62c56f98SSadaf Ebrahimi * Either change them in mbedtls_config.h or define them on the compiler command line. 53*62c56f98SSadaf Ebrahimi * \{ 54*62c56f98SSadaf Ebrahimi */ 55*62c56f98SSadaf Ebrahimi 56*62c56f98SSadaf Ebrahimi #if !defined(MBEDTLS_ENTROPY_MAX_SOURCES) 57*62c56f98SSadaf Ebrahimi #define MBEDTLS_ENTROPY_MAX_SOURCES 20 /**< Maximum number of sources supported */ 58*62c56f98SSadaf Ebrahimi #endif 59*62c56f98SSadaf Ebrahimi 60*62c56f98SSadaf Ebrahimi #if !defined(MBEDTLS_ENTROPY_MAX_GATHER) 61*62c56f98SSadaf Ebrahimi #define MBEDTLS_ENTROPY_MAX_GATHER 128 /**< Maximum amount requested from entropy sources */ 62*62c56f98SSadaf Ebrahimi #endif 63*62c56f98SSadaf Ebrahimi 64*62c56f98SSadaf Ebrahimi /** \} name SECTION: Module settings */ 65*62c56f98SSadaf Ebrahimi 66*62c56f98SSadaf Ebrahimi #define MBEDTLS_ENTROPY_MAX_SEED_SIZE 1024 /**< Maximum size of seed we read from seed file */ 67*62c56f98SSadaf Ebrahimi #define MBEDTLS_ENTROPY_SOURCE_MANUAL MBEDTLS_ENTROPY_MAX_SOURCES 68*62c56f98SSadaf Ebrahimi 69*62c56f98SSadaf Ebrahimi #define MBEDTLS_ENTROPY_SOURCE_STRONG 1 /**< Entropy source is strong */ 70*62c56f98SSadaf Ebrahimi #define MBEDTLS_ENTROPY_SOURCE_WEAK 0 /**< Entropy source is weak */ 71*62c56f98SSadaf Ebrahimi 72*62c56f98SSadaf Ebrahimi #ifdef __cplusplus 73*62c56f98SSadaf Ebrahimi extern "C" { 74*62c56f98SSadaf Ebrahimi #endif 75*62c56f98SSadaf Ebrahimi 76*62c56f98SSadaf Ebrahimi /** 77*62c56f98SSadaf Ebrahimi * \brief Entropy poll callback pointer 78*62c56f98SSadaf Ebrahimi * 79*62c56f98SSadaf Ebrahimi * \param data Callback-specific data pointer 80*62c56f98SSadaf Ebrahimi * \param output Data to fill 81*62c56f98SSadaf Ebrahimi * \param len Maximum size to provide 82*62c56f98SSadaf Ebrahimi * \param olen The actual amount of bytes put into the buffer (Can be 0) 83*62c56f98SSadaf Ebrahimi * 84*62c56f98SSadaf Ebrahimi * \return 0 if no critical failures occurred, 85*62c56f98SSadaf Ebrahimi * MBEDTLS_ERR_ENTROPY_SOURCE_FAILED otherwise 86*62c56f98SSadaf Ebrahimi */ 87*62c56f98SSadaf Ebrahimi typedef int (*mbedtls_entropy_f_source_ptr)(void *data, unsigned char *output, size_t len, 88*62c56f98SSadaf Ebrahimi size_t *olen); 89*62c56f98SSadaf Ebrahimi 90*62c56f98SSadaf Ebrahimi /** 91*62c56f98SSadaf Ebrahimi * \brief Entropy source state 92*62c56f98SSadaf Ebrahimi */ 93*62c56f98SSadaf Ebrahimi typedef struct mbedtls_entropy_source_state { 94*62c56f98SSadaf Ebrahimi mbedtls_entropy_f_source_ptr MBEDTLS_PRIVATE(f_source); /**< The entropy source callback */ 95*62c56f98SSadaf Ebrahimi void *MBEDTLS_PRIVATE(p_source); /**< The callback data pointer */ 96*62c56f98SSadaf Ebrahimi size_t MBEDTLS_PRIVATE(size); /**< Amount received in bytes */ 97*62c56f98SSadaf Ebrahimi size_t MBEDTLS_PRIVATE(threshold); /**< Minimum bytes required before release */ 98*62c56f98SSadaf Ebrahimi int MBEDTLS_PRIVATE(strong); /**< Is the source strong? */ 99*62c56f98SSadaf Ebrahimi } 100*62c56f98SSadaf Ebrahimi mbedtls_entropy_source_state; 101*62c56f98SSadaf Ebrahimi 102*62c56f98SSadaf Ebrahimi /** 103*62c56f98SSadaf Ebrahimi * \brief Entropy context structure 104*62c56f98SSadaf Ebrahimi */ 105*62c56f98SSadaf Ebrahimi typedef struct mbedtls_entropy_context { 106*62c56f98SSadaf Ebrahimi mbedtls_md_context_t MBEDTLS_PRIVATE(accumulator); 107*62c56f98SSadaf Ebrahimi int MBEDTLS_PRIVATE(accumulator_started); /* 0 after init. 108*62c56f98SSadaf Ebrahimi * 1 after the first update. 109*62c56f98SSadaf Ebrahimi * -1 after free. */ 110*62c56f98SSadaf Ebrahimi int MBEDTLS_PRIVATE(source_count); /* Number of entries used in source. */ 111*62c56f98SSadaf Ebrahimi mbedtls_entropy_source_state MBEDTLS_PRIVATE(source)[MBEDTLS_ENTROPY_MAX_SOURCES]; 112*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_THREADING_C) 113*62c56f98SSadaf Ebrahimi mbedtls_threading_mutex_t MBEDTLS_PRIVATE(mutex); /*!< mutex */ 114*62c56f98SSadaf Ebrahimi #endif 115*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_ENTROPY_NV_SEED) 116*62c56f98SSadaf Ebrahimi int MBEDTLS_PRIVATE(initial_entropy_run); 117*62c56f98SSadaf Ebrahimi #endif 118*62c56f98SSadaf Ebrahimi } 119*62c56f98SSadaf Ebrahimi mbedtls_entropy_context; 120*62c56f98SSadaf Ebrahimi 121*62c56f98SSadaf Ebrahimi #if !defined(MBEDTLS_NO_PLATFORM_ENTROPY) 122*62c56f98SSadaf Ebrahimi /** 123*62c56f98SSadaf Ebrahimi * \brief Platform-specific entropy poll callback 124*62c56f98SSadaf Ebrahimi */ 125*62c56f98SSadaf Ebrahimi int mbedtls_platform_entropy_poll(void *data, 126*62c56f98SSadaf Ebrahimi unsigned char *output, size_t len, size_t *olen); 127*62c56f98SSadaf Ebrahimi #endif 128*62c56f98SSadaf Ebrahimi 129*62c56f98SSadaf Ebrahimi /** 130*62c56f98SSadaf Ebrahimi * \brief Initialize the context 131*62c56f98SSadaf Ebrahimi * 132*62c56f98SSadaf Ebrahimi * \param ctx Entropy context to initialize 133*62c56f98SSadaf Ebrahimi */ 134*62c56f98SSadaf Ebrahimi void mbedtls_entropy_init(mbedtls_entropy_context *ctx); 135*62c56f98SSadaf Ebrahimi 136*62c56f98SSadaf Ebrahimi /** 137*62c56f98SSadaf Ebrahimi * \brief Free the data in the context 138*62c56f98SSadaf Ebrahimi * 139*62c56f98SSadaf Ebrahimi * \param ctx Entropy context to free 140*62c56f98SSadaf Ebrahimi */ 141*62c56f98SSadaf Ebrahimi void mbedtls_entropy_free(mbedtls_entropy_context *ctx); 142*62c56f98SSadaf Ebrahimi 143*62c56f98SSadaf Ebrahimi /** 144*62c56f98SSadaf Ebrahimi * \brief Adds an entropy source to poll 145*62c56f98SSadaf Ebrahimi * (Thread-safe if MBEDTLS_THREADING_C is enabled) 146*62c56f98SSadaf Ebrahimi * 147*62c56f98SSadaf Ebrahimi * \param ctx Entropy context 148*62c56f98SSadaf Ebrahimi * \param f_source Entropy function 149*62c56f98SSadaf Ebrahimi * \param p_source Function data 150*62c56f98SSadaf Ebrahimi * \param threshold Minimum required from source before entropy is released 151*62c56f98SSadaf Ebrahimi * ( with mbedtls_entropy_func() ) (in bytes) 152*62c56f98SSadaf Ebrahimi * \param strong MBEDTLS_ENTROPY_SOURCE_STRONG or 153*62c56f98SSadaf Ebrahimi * MBEDTLS_ENTROPY_SOURCE_WEAK. 154*62c56f98SSadaf Ebrahimi * At least one strong source needs to be added. 155*62c56f98SSadaf Ebrahimi * Weaker sources (such as the cycle counter) can be used as 156*62c56f98SSadaf Ebrahimi * a complement. 157*62c56f98SSadaf Ebrahimi * 158*62c56f98SSadaf Ebrahimi * \return 0 if successful or MBEDTLS_ERR_ENTROPY_MAX_SOURCES 159*62c56f98SSadaf Ebrahimi */ 160*62c56f98SSadaf Ebrahimi int mbedtls_entropy_add_source(mbedtls_entropy_context *ctx, 161*62c56f98SSadaf Ebrahimi mbedtls_entropy_f_source_ptr f_source, void *p_source, 162*62c56f98SSadaf Ebrahimi size_t threshold, int strong); 163*62c56f98SSadaf Ebrahimi 164*62c56f98SSadaf Ebrahimi /** 165*62c56f98SSadaf Ebrahimi * \brief Trigger an extra gather poll for the accumulator 166*62c56f98SSadaf Ebrahimi * (Thread-safe if MBEDTLS_THREADING_C is enabled) 167*62c56f98SSadaf Ebrahimi * 168*62c56f98SSadaf Ebrahimi * \param ctx Entropy context 169*62c56f98SSadaf Ebrahimi * 170*62c56f98SSadaf Ebrahimi * \return 0 if successful, or MBEDTLS_ERR_ENTROPY_SOURCE_FAILED 171*62c56f98SSadaf Ebrahimi */ 172*62c56f98SSadaf Ebrahimi int mbedtls_entropy_gather(mbedtls_entropy_context *ctx); 173*62c56f98SSadaf Ebrahimi 174*62c56f98SSadaf Ebrahimi /** 175*62c56f98SSadaf Ebrahimi * \brief Retrieve entropy from the accumulator 176*62c56f98SSadaf Ebrahimi * (Maximum length: MBEDTLS_ENTROPY_BLOCK_SIZE) 177*62c56f98SSadaf Ebrahimi * (Thread-safe if MBEDTLS_THREADING_C is enabled) 178*62c56f98SSadaf Ebrahimi * 179*62c56f98SSadaf Ebrahimi * \param data Entropy context 180*62c56f98SSadaf Ebrahimi * \param output Buffer to fill 181*62c56f98SSadaf Ebrahimi * \param len Number of bytes desired, must be at most MBEDTLS_ENTROPY_BLOCK_SIZE 182*62c56f98SSadaf Ebrahimi * 183*62c56f98SSadaf Ebrahimi * \return 0 if successful, or MBEDTLS_ERR_ENTROPY_SOURCE_FAILED 184*62c56f98SSadaf Ebrahimi */ 185*62c56f98SSadaf Ebrahimi int mbedtls_entropy_func(void *data, unsigned char *output, size_t len); 186*62c56f98SSadaf Ebrahimi 187*62c56f98SSadaf Ebrahimi /** 188*62c56f98SSadaf Ebrahimi * \brief Add data to the accumulator manually 189*62c56f98SSadaf Ebrahimi * (Thread-safe if MBEDTLS_THREADING_C is enabled) 190*62c56f98SSadaf Ebrahimi * 191*62c56f98SSadaf Ebrahimi * \param ctx Entropy context 192*62c56f98SSadaf Ebrahimi * \param data Data to add 193*62c56f98SSadaf Ebrahimi * \param len Length of data 194*62c56f98SSadaf Ebrahimi * 195*62c56f98SSadaf Ebrahimi * \return 0 if successful 196*62c56f98SSadaf Ebrahimi */ 197*62c56f98SSadaf Ebrahimi int mbedtls_entropy_update_manual(mbedtls_entropy_context *ctx, 198*62c56f98SSadaf Ebrahimi const unsigned char *data, size_t len); 199*62c56f98SSadaf Ebrahimi 200*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_ENTROPY_NV_SEED) 201*62c56f98SSadaf Ebrahimi /** 202*62c56f98SSadaf Ebrahimi * \brief Trigger an update of the seed file in NV by using the 203*62c56f98SSadaf Ebrahimi * current entropy pool. 204*62c56f98SSadaf Ebrahimi * 205*62c56f98SSadaf Ebrahimi * \param ctx Entropy context 206*62c56f98SSadaf Ebrahimi * 207*62c56f98SSadaf Ebrahimi * \return 0 if successful 208*62c56f98SSadaf Ebrahimi */ 209*62c56f98SSadaf Ebrahimi int mbedtls_entropy_update_nv_seed(mbedtls_entropy_context *ctx); 210*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_ENTROPY_NV_SEED */ 211*62c56f98SSadaf Ebrahimi 212*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_FS_IO) 213*62c56f98SSadaf Ebrahimi /** 214*62c56f98SSadaf Ebrahimi * \brief Write a seed file 215*62c56f98SSadaf Ebrahimi * 216*62c56f98SSadaf Ebrahimi * \param ctx Entropy context 217*62c56f98SSadaf Ebrahimi * \param path Name of the file 218*62c56f98SSadaf Ebrahimi * 219*62c56f98SSadaf Ebrahimi * \return 0 if successful, 220*62c56f98SSadaf Ebrahimi * MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR on file error, or 221*62c56f98SSadaf Ebrahimi * MBEDTLS_ERR_ENTROPY_SOURCE_FAILED 222*62c56f98SSadaf Ebrahimi */ 223*62c56f98SSadaf Ebrahimi int mbedtls_entropy_write_seed_file(mbedtls_entropy_context *ctx, const char *path); 224*62c56f98SSadaf Ebrahimi 225*62c56f98SSadaf Ebrahimi /** 226*62c56f98SSadaf Ebrahimi * \brief Read and update a seed file. Seed is added to this 227*62c56f98SSadaf Ebrahimi * instance. No more than MBEDTLS_ENTROPY_MAX_SEED_SIZE bytes are 228*62c56f98SSadaf Ebrahimi * read from the seed file. The rest is ignored. 229*62c56f98SSadaf Ebrahimi * 230*62c56f98SSadaf Ebrahimi * \param ctx Entropy context 231*62c56f98SSadaf Ebrahimi * \param path Name of the file 232*62c56f98SSadaf Ebrahimi * 233*62c56f98SSadaf Ebrahimi * \return 0 if successful, 234*62c56f98SSadaf Ebrahimi * MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR on file error, 235*62c56f98SSadaf Ebrahimi * MBEDTLS_ERR_ENTROPY_SOURCE_FAILED 236*62c56f98SSadaf Ebrahimi */ 237*62c56f98SSadaf Ebrahimi int mbedtls_entropy_update_seed_file(mbedtls_entropy_context *ctx, const char *path); 238*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_FS_IO */ 239*62c56f98SSadaf Ebrahimi 240*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_SELF_TEST) 241*62c56f98SSadaf Ebrahimi /** 242*62c56f98SSadaf Ebrahimi * \brief Checkup routine 243*62c56f98SSadaf Ebrahimi * 244*62c56f98SSadaf Ebrahimi * This module self-test also calls the entropy self-test, 245*62c56f98SSadaf Ebrahimi * mbedtls_entropy_source_self_test(); 246*62c56f98SSadaf Ebrahimi * 247*62c56f98SSadaf Ebrahimi * \return 0 if successful, or 1 if a test failed 248*62c56f98SSadaf Ebrahimi */ 249*62c56f98SSadaf Ebrahimi int mbedtls_entropy_self_test(int verbose); 250*62c56f98SSadaf Ebrahimi 251*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_ENTROPY_HARDWARE_ALT) 252*62c56f98SSadaf Ebrahimi /** 253*62c56f98SSadaf Ebrahimi * \brief Checkup routine 254*62c56f98SSadaf Ebrahimi * 255*62c56f98SSadaf Ebrahimi * Verifies the integrity of the hardware entropy source 256*62c56f98SSadaf Ebrahimi * provided by the function 'mbedtls_hardware_poll()'. 257*62c56f98SSadaf Ebrahimi * 258*62c56f98SSadaf Ebrahimi * Note this is the only hardware entropy source that is known 259*62c56f98SSadaf Ebrahimi * at link time, and other entropy sources configured 260*62c56f98SSadaf Ebrahimi * dynamically at runtime by the function 261*62c56f98SSadaf Ebrahimi * mbedtls_entropy_add_source() will not be tested. 262*62c56f98SSadaf Ebrahimi * 263*62c56f98SSadaf Ebrahimi * \return 0 if successful, or 1 if a test failed 264*62c56f98SSadaf Ebrahimi */ 265*62c56f98SSadaf Ebrahimi int mbedtls_entropy_source_self_test(int verbose); 266*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_ENTROPY_HARDWARE_ALT */ 267*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_SELF_TEST */ 268*62c56f98SSadaf Ebrahimi 269*62c56f98SSadaf Ebrahimi #ifdef __cplusplus 270*62c56f98SSadaf Ebrahimi } 271*62c56f98SSadaf Ebrahimi #endif 272*62c56f98SSadaf Ebrahimi 273*62c56f98SSadaf Ebrahimi #endif /* entropy.h */ 274