1 /* 2 * This file is part of the openHiTLS project. 3 * 4 * openHiTLS is licensed under the Mulan PSL v2. 5 * You can use this software according to the terms and conditions of the Mulan PSL v2. 6 * You may obtain a copy of Mulan PSL v2 at: 7 * 8 * http://license.coscl.org.cn/MulanPSL2 9 * 10 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, 11 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, 12 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. 13 * See the Mulan PSL v2 for more details. 14 */ 15 16 #ifndef CRYPT_DRBG_H 17 #define CRYPT_DRBG_H 18 19 #include "hitls_build.h" 20 #ifdef HITLS_CRYPTO_DRBG 21 22 #include <stdint.h> 23 #include <stdbool.h> 24 #include "crypt_types.h" 25 #include "crypt_local_types.h" 26 27 #ifdef __cplusplus 28 extern "C" { 29 #endif 30 31 // hlcheck : health testing 32 // pr : prediction_resistance 33 34 typedef struct DrbgCtx DRBG_Ctx; 35 36 #define DRBG_MAX_LEN (0x7ffffff0) 37 #define DRBG_MAX_REQUEST (1 << 16) 38 39 #ifndef DRBG_MAX_RESEED_INTERVAL 40 #define DRBG_MAX_RESEED_INTERVAL (10000) 41 #endif 42 43 /* Default reseed intervals */ 44 # define DRBG_RESEED_INTERVAL (1 << 8) 45 # define DRBG_TIME_INTERVAL (60 * 60) /* 1 hour */ 46 47 #ifndef DRBG_MAX_REQUEST_SM3 48 #define DRBG_MAX_REQUEST_SM3 (1 << 5) 49 #endif 50 51 #ifndef DRBG_MAX_REQUEST_SM4 52 #define DRBG_MAX_REQUEST_SM4 (1 << 4) 53 #endif 54 55 #ifndef DRBG_RESEED_INTERVAL_GM1 56 #define DRBG_RESEED_INTERVAL_GM1 (1 << 20) 57 #endif 58 59 #ifndef DRBG_RESEED_TIME_GM1 60 #define DRBG_RESEED_TIME_GM1 (600) 61 #endif 62 63 #ifndef DRBG_RESEED_INTERVAL_GM2 64 #define DRBG_RESEED_INTERVAL_GM2 (1 << 10) 65 #endif 66 67 #ifndef DRBG_RESEED_TIME_GM2 68 #define DRBG_RESEED_TIME_GM2 (60) 69 #endif 70 71 #ifndef HITLS_CRYPTO_DRBG_GM_LEVEL 72 #define HITLS_CRYPTO_DRBG_GM_LEVEL 2 73 #endif 74 75 #ifndef HITLS_CRYPTO_RESEED_INTERVAL_GM 76 #if HITLS_CRYPTO_DRBG_GM_LEVEL == 1 77 #define HITLS_CRYPTO_RESEED_INTERVAL_GM DRBG_RESEED_INTERVAL_GM1 78 #else 79 #define HITLS_CRYPTO_RESEED_INTERVAL_GM DRBG_RESEED_INTERVAL_GM2 80 #endif 81 #endif 82 83 #ifdef HITLS_CRYPTO_ENTROPY 84 #ifndef HITLS_SEED_DRBG_INIT_RAND_ALG 85 #ifdef HITLS_CRYPTO_AES 86 #define HITLS_SEED_DRBG_INIT_RAND_ALG CRYPT_RAND_AES256_CTR 87 #else 88 #error "HITLS_SEED_DRBG_INIT_RAND_ALG configuration error." 89 #endif 90 #endif 91 #endif 92 93 #ifndef HITLS_CRYPTO_DRBG_RESEED_TIME_GM 94 #if HITLS_CRYPTO_DRBG_GM_LEVEL == 1 95 #define HITLS_CRYPTO_DRBG_RESEED_TIME_GM DRBG_RESEED_TIME_GM1 96 #else 97 #define HITLS_CRYPTO_DRBG_RESEED_TIME_GM DRBG_RESEED_TIME_GM2 98 #endif 99 #endif 100 101 #define DRBG_HASH_MAX_MDSIZE (64) 102 103 #define RAND_TYPE_MD 1 104 #define RAND_TYPE_MAC 2 105 #define RAND_TYPE_AES 3 106 #define RAND_TYPE_AES_DF 4 107 #define RAND_TYPE_SM4_DF 5 108 109 typedef struct { 110 CRYPT_RAND_AlgId drbgId; 111 int32_t depId; 112 uint32_t type; 113 } DrbgIdMap; 114 115 /** 116 * @ingroup drbg 117 * @brief Apply for a context for the DRBG. 118 * @brief This API does not support multiple threads. 119 * 120 * @param algId Algorithm ID for the DRBG 121 * @param param DRBG parameters 122 * 123 * @retval DRBG_Ctx* Success 124 * @retval NULL Failure 125 */ 126 DRBG_Ctx *DRBG_New(int32_t algId, BSL_Param *param); 127 128 /** 129 * @ingroup drbg 130 * @brief Release the DRBG context. 131 * @brief This API does not support multiple threads. 132 * 133 * @param ctx DRBG context 134 * 135 * @retval None 136 */ 137 void DRBG_Free(DRBG_Ctx *ctx); 138 139 /** 140 * @ingroup drbg 141 * @brief Instantiating a DRBG based on personalization string. 142 * @brief This API does not support multiple threads. 143 * 144 * @param ctx DRBG context 145 * @param person Personalization string. The personalization string can be NULL. 146 * @param persLen Personalization string length, 147 * @param param DRBG parameters,Not in use yet 148 * 149 * @retval CRYPT_SUCCESS Instantiation succeeded. 150 * @retval CRYPT_NULL_INPUT Invalid null pointer 151 * @retval CRYPT_DRBG_ERR_STATE The DRBG status is incorrect. 152 * @retval CRYPT_DRBG_FAIL_GET_ENTROPY Failed to obtain the entropy. 153 * @retval CRYPT_DRBG_FAIL_GET_NONCE Failed to obtain the nonce. 154 * @retval Hash function error code: Failed to invoke the hash function. 155 */ 156 int32_t DRBG_Instantiate(DRBG_Ctx *ctx, const uint8_t *person, uint32_t persLen, BSL_Param *param); 157 158 /** 159 * @ingroup drbg 160 * @brief Reseeding the DRBG. 161 * @brief The additional input can be NULL. This API does not support multiple threads. 162 * 163 * @param ctx DRBG context 164 * @param adin Additional input. The data can be empty. 165 * @param adinLen Additional input length 166 * @param param DRBG parameters,Not in use yet 167 * 168 * @retval CRYPT_SUCCESS Instantiation succeeded. 169 * @retval CRYPT_NULL_INPUT Invalid null pointer 170 * @retval CRYPT_DRBG_ERR_STATE The DRBG status is incorrect. 171 * @retval CRYPT_DRBG_FAIL_GET_ENTROPY Failed to obtain the entropy. 172 * @retval Hash function error code: Failed to invoke the hash function. 173 */ 174 int32_t DRBG_Reseed(DRBG_Ctx *ctx, const uint8_t *adin, uint32_t adinLen, BSL_Param *param); 175 176 /** 177 * @ingroup drbg 178 * @brief Generating pseudorandom bits using a DRBG. 179 * @brief The additional input can be null. The user specifies the additional obfuscation data. 180 * This API does not support multiple threads. 181 * @brief External invoking must have a recovery mechanism after the status is abnormal. 182 * 183 * @param ctx DRBG context 184 * @param out Output BUF 185 * @param outLen Output length 186 * @param adin Additional input. The data can be empty. 187 * @param adinLen Additional input length 188 * @param param DRBG parameters,involve: 189 * pr Predicted resistance. If this parameter is set to true, reseed is executed each time. 190 * 191 * @retval CRYPT_SUCCESS Instantiation succeeded. 192 * @retval CRYPT_NULL_INPUT Invalid null pointer 193 * @retval CRYPT_DRBG_ERR_STATE The DRBG status is incorrect. 194 * @retval Hash function error code: Failed to invoke the hash function. 195 */ 196 int32_t DRBG_GenerateBytes(DRBG_Ctx *ctx, uint8_t *out, uint32_t outLen, 197 const uint8_t *adin, uint32_t adinLen, BSL_Param *param); 198 199 /** 200 * @ingroup drbg 201 * @brief Remove the DRBG instantiation 202 * @brief This API does not support multiple threads. 203 * 204 * @param ctx DRBG context 205 * 206 * @retval CRYPT_SUCCESS Removed successfully. 207 * @retval CRYPT_NULL_INPUT Invalid null pointer 208 */ 209 int32_t DRBG_Uninstantiate(DRBG_Ctx *ctx); 210 211 /** 212 * @ingroup drbg 213 * @brief get or set drbg param 214 * 215 * @param ctx [IN] drbg context 216 * @param cmd [IN] Option information 217 * @param val [IN/OUT] Data to be set/obtained 218 * @param valLen [IN] Length of the data marked as "val" 219 * 220 * @retval #CRYPT_SUCCESS. 221 * For other error codes, see crypt_errno.h. 222 */ 223 int32_t DRBG_Ctrl(DRBG_Ctx *ctx, int32_t cmd, void *val, uint32_t valLen); 224 225 /** 226 * @ingroup drbg 227 * @brief Get the map corresponding to the algid. 228 * 229 * @param id enum of CRYPT_RAND_AlgId 230 * 231 * @retval DrbgIdMap 232 * @retval NULL Invalid arguments 233 */ 234 const DrbgIdMap *DRBG_GetIdMap(CRYPT_RAND_AlgId id); 235 236 #ifdef __cplusplus 237 } 238 #endif 239 240 #endif // HITLS_CRYPTO_DRBG 241 242 #endif // CRYPT_DRBG_H 243