1 /*! 2 * @file apm32f4xx_hash.c 3 * 4 * @brief This file provides all the HASH firmware functions 5 * 6 * @version V1.0.2 7 * 8 * @date 2022-06-23 9 * 10 * @attention 11 * 12 * Copyright (C) 2021-2022 Geehy Semiconductor 13 * 14 * You may not use this file except in compliance with the 15 * GEEHY COPYRIGHT NOTICE (GEEHY SOFTWARE PACKAGE LICENSE). 16 * 17 * The program is only for reference, which is distributed in the hope 18 * that it will be usefull and instructional for customers to develop 19 * their software. Unless required by applicable law or agreed to in 20 * writing, the program is distributed on an "AS IS" BASIS, WITHOUT 21 * ANY WARRANTY OR CONDITIONS OF ANY KIND, either express or implied. 22 * See the GEEHY SOFTWARE PACKAGE LICENSE for the governing permissions 23 * and limitations under the License. 24 */ 25 26 #include "apm32f4xx_hash.h" 27 #include "apm32f4xx_rcm.h" 28 29 /** @addtogroup APM32F4xx_StdPeriphDriver 30 @{ 31 */ 32 33 /** @defgroup HASH_Driver 34 * @brief HASH driver modules 35 @{ 36 */ 37 38 /** @defgroup HASH_Functions 39 @{ 40 */ 41 42 /*! 43 * @brief Reset the HASH peripheral register. 44 * 45 * @param None 46 * 47 * @retval None 48 */ HASH_Reset(void)49void HASH_Reset(void) 50 { 51 RCM_EnableAHB2PeriphReset(RCM_AHB2_PERIPH_HASH); 52 RCM_DisableAHB2PeriphReset(RCM_AHB2_PERIPH_HASH); 53 } 54 55 /*! 56 * @brief Config the HASH peripheral according to the specified parameters in the hashConfig. 57 * 58 * @param hashConfig: pointer to a HASH_Config_T structure. 59 * 60 * @retval None 61 */ HASH_Config(HASH_Config_T * hashConfig)62void HASH_Config(HASH_Config_T *hashConfig) 63 { 64 /* Configure the Algorithm used, algorithm mode and the datatype */ 65 HASH->CTRL_B.ALGSEL = RESET; 66 HASH->CTRL_B.DTYPE = RESET; 67 HASH->CTRL_B.MODESEL = RESET; 68 69 HASH->CTRL_B.ALGSEL = hashConfig->algoSelect; 70 HASH->CTRL_B.DTYPE = hashConfig->dataType; 71 HASH->CTRL_B.MODESEL = hashConfig->algoMode; 72 73 /* if algorithm mode is HMAC, set the Key */ 74 if (hashConfig->algoMode == HASH_ALGO_MODE_HMAC) 75 { 76 HASH->CTRL_B.LKEYSEL = RESET; 77 HASH->CTRL_B.LKEYSEL = hashConfig->hmacKeyType; 78 } 79 80 /* Reset the HASH processor core, so that the HASH will be ready to compute 81 the message digest of a new message */ 82 HASH->CTRL_B.INITCAL = SET; 83 } 84 85 /*! 86 * @brief Fills each HASH_Config_T member with its default value. 87 * 88 * @param hashConfig: pointer to an HASH_Config_T structure. 89 * 90 * @retval None 91 */ HASH_ConfigStructInit(HASH_Config_T * hashConfig)92void HASH_ConfigStructInit(HASH_Config_T *hashConfig) 93 { 94 hashConfig->algoSelect = HASH_ALGO_SELECTION_SHA1; 95 hashConfig->algoMode = HASH_ALGO_MODE_HASH; 96 hashConfig->dataType = HASH_DATA_TYPE_32B; 97 hashConfig->hmacKeyType = HASH_HMAC_KEY_TYPE_SHORTKEY; 98 } 99 100 /*! 101 * @brief Resets the HASH processor core. 102 * 103 * @param None 104 * 105 * @retval None 106 */ HASH_ResetProceCore(void)107void HASH_ResetProceCore(void) 108 { 109 HASH->CTRL_B.INITCAL = SET; 110 } 111 112 /*! 113 * @brief Configure the Number of valid bits in last word of the message. 114 * 115 * @param ValidNumber: Number of valid bits in last word of the message. 116 * 117 * @retval None 118 */ HASH_ConfigLastWordValidBitsNbr(uint16_t validNumber)119void HASH_ConfigLastWordValidBitsNbr(uint16_t validNumber) 120 { 121 HASH->START_B.LWNUM = RESET; 122 HASH->START_B.LWNUM = validNumber; 123 } 124 125 /*! 126 * @brief Writes data in the Input Data FIFO. 127 * 128 * @param data: new data of the message to be processed. 129 * 130 * @retval None 131 */ HASH_WritesInputData(uint32_t data)132void HASH_WritesInputData(uint32_t data) 133 { 134 HASH->INDATA_B.INDATA = data; 135 } 136 137 /*! 138 * @brief Read the number of words already pushed into the IN FIFO. 139 * 140 * @param None 141 * 142 * @retval None 143 */ HASH_ReadInFIFOWordsNbr(void)144uint8_t HASH_ReadInFIFOWordsNbr(void) 145 { 146 return (HASH->CTRL_B.WNUM); 147 } 148 149 /*! 150 * @brief Read the provides message digest. 151 * 152 * @param messageDigest: pointer to a HASH_Config_T structure. 153 * 154 * @retval None 155 */ HASH_ReadDigest(HASH_MessageDigest_T * messageDigest)156void HASH_ReadDigest(HASH_MessageDigest_T *messageDigest) 157 { 158 /* Read the data field */ 159 messageDigest->Data[0] = HASH->DIG[0]; 160 messageDigest->Data[1] = HASH->DIG[1]; 161 messageDigest->Data[2] = HASH->DIG[2]; 162 messageDigest->Data[3] = HASH->DIG[3]; 163 messageDigest->Data[4] = HASH->DIG[4]; 164 } 165 166 /*! 167 * @brief Start the Digest calculation. 168 * 169 * @param None 170 * 171 * @retval None 172 */ HASH_StartDigest(void)173void HASH_StartDigest(void) 174 { 175 HASH->START_B.DIGCAL = SET; 176 } 177 178 /*! 179 * @brief Read the Hash peripheral Context. 180 * 181 * @param contextRead: pointer to a HASH_Context_T structure that contains 182 * the repository for current context. 183 * 184 * @retval None 185 */ HASH_ReadContext(HASH_Context_T * contextRead)186void HASH_ReadContext(HASH_Context_T *contextRead) 187 { 188 uint8_t i = 0; 189 190 contextRead->HASH_INT = HASH->INT; 191 contextRead->HASH_START = HASH->START; 192 contextRead->HASH_CTRL = HASH->CTRL; 193 194 for (i = 0; i <= 50; i++) 195 { 196 contextRead->HASH_CTSWAP[i] = HASH->CTSWAP[i]; 197 } 198 } 199 200 /*! 201 * @brief Write the Hash peripheral Context. 202 * 203 * @param contextWrite: pointer to a HASH_Context_T structure that contains 204 * the repository for current context. 205 * 206 * @retval None 207 */ HASH_WriteContext(HASH_Context_T * contextWrite)208void HASH_WriteContext(HASH_Context_T *contextWrite) 209 { 210 uint8_t i = 0; 211 212 HASH->INT = contextWrite->HASH_INT; 213 HASH->START = contextWrite->HASH_START; 214 HASH->CTRL = contextWrite->HASH_CTRL; 215 216 HASH->CTRL_B.INITCAL = SET; 217 218 for (i = 0; i <= 50; i++) 219 { 220 HASH->CTSWAP[i] = contextWrite->HASH_CTSWAP[i]; 221 } 222 } 223 224 /*! 225 * @brief Enables the HASH DMA interface. 226 * 227 * @param None 228 * 229 * @retval None 230 */ HASH_EnableDMA(void)231void HASH_EnableDMA(void) 232 { 233 HASH->CTRL_B.DMAEN = SET; 234 } 235 236 /*! 237 * @brief Disabled the HASH DMA interface. 238 * 239 * @param None 240 * 241 * @retval None 242 */ HASH_DisableDMA(void)243void HASH_DisableDMA(void) 244 { 245 HASH->CTRL_B.DMAEN = RESET; 246 } 247 248 /*! 249 * @brief Enables the specified HASH interrupts. 250 * 251 * @param interrupt: Select the ADC interrupt sources 252 * This parameter can be any combination of the following values: 253 * @arg HASH_INT_INDATAINT: Input Data interrupt mask 254 * @arg HASH_INT_DCALCINT: Digest calculation completion Data interrupt mask 255 * 256 * @retval None 257 */ HASH_EnableInterrupt(uint32_t interrupt)258void HASH_EnableInterrupt(uint32_t interrupt) 259 { 260 HASH->INT |= interrupt; 261 } 262 263 /*! 264 * @brief Disables the specified HASH interrupts. 265 * 266 * @param interrupt: Select the ADC interrupt sources 267 * This parameter can be any combination of the following values: 268 * @arg HASH_INT_INDATAINT: Input Data interrupt mask 269 * @arg HASH_INT_DCALCINT: Digest calculation completion Data interrupt mask 270 * 271 * @retval None 272 */ HASH_DisableInterrupt(uint32_t interrupt)273void HASH_DisableInterrupt(uint32_t interrupt) 274 { 275 HASH->INT &= (uint32_t)~interrupt; 276 } 277 278 /*! 279 * @brief Reads the pending HASH flag 280 * 281 * @param flag: Select the flag to check 282 * This parameter can be one of the following values: 283 * @arg HASH_FLAG_INDATAINT: Data input interrupt status flag 284 * @arg HASH_FLAG_DCALCINT: Digest calculation completion interrupt status flag 285 * @arg HASH_FLAG_DMA: DMAS Status flag 286 * @arg HASH_FLAG_BUSY: Busy flag 287 * @arg HASH_FLAG_DINNEMPT: Data Input register (DIN) not empty status flag 288 * 289 * @retval SET or RESET 290 */ HASH_ReadFlagStatus(HASH_FLAG_T flag)291uint8_t HASH_ReadFlagStatus(HASH_FLAG_T flag) 292 { 293 uint32_t reg = 0; 294 295 if (flag == HASH_FLAG_DINNEMPT) 296 { 297 reg = HASH->CTRL; 298 } 299 else 300 { 301 reg = HASH->STS; 302 } 303 304 return (reg & flag) ? SET : RESET; 305 } 306 307 /*! 308 * @brief Clears the pending HASH flag 309 * 310 * @param flag: Select the flag to check 311 * This parameter can be one of the following values: 312 * @arg HASH_FLAG_INDATAINT: Data input interrupt status flag 313 * @arg HASH_FLAG_DCALCINT: Digest calculation completion interrupt status flag 314 * 315 * @retval None 316 */ HASH_ClearStatusFlag(HASH_FLAG_T flag)317void HASH_ClearStatusFlag(HASH_FLAG_T flag) 318 { 319 if (flag == HASH_FLAG_INDATAINT) 320 { 321 HASH->STS_B.INDATAINT = BIT_RESET; 322 } 323 else if (flag == HASH_FLAG_DCALCINT) 324 { 325 HASH->STS_B.DCALCINT = BIT_RESET; 326 } 327 } 328 329 /*! 330 * @brief Reads the specified HASH Interrupt flag. 331 * 332 * @param flag: Select the ADC interrupt source. 333 * This parameter can be one of the following values: 334 * @arg HASH_INT_FLAG_INDATA: Input Data interrupt 335 * @arg HASH_INT_FLAG_DCALC: Digest Calculation Completion Interrupt 336 * 337 * @retval SET or RESET 338 */ HASH_ReadIntFlag(HASH_INT_FLAG_T flag)339uint8_t HASH_ReadIntFlag(HASH_INT_FLAG_T flag) 340 { 341 uint32_t intStatus = 0, reg = 0; 342 343 intStatus = HASH->INT; 344 reg = HASH->STS; 345 346 return (intStatus & (reg & flag)) ? SET : RESET; 347 } 348 349 /*! 350 * @brief Clears the pending HASH flag 351 * 352 * @param flag: Select the flag to check 353 * This parameter can be one of the following values: 354 * @arg HASH_INT_FLAG_INDATA: Input Data interrupt 355 * @arg HASH_INT_FLAG_DCALC: Digest Calculation Completion Interrupt 356 * 357 * @retval None 358 */ HASH_ClearIntFlag(HASH_INT_FLAG_T flag)359void HASH_ClearIntFlag(HASH_INT_FLAG_T flag) 360 { 361 if (flag == HASH_INT_FLAG_INDATA) 362 { 363 HASH->STS_B.INDATAINT = BIT_RESET; 364 } 365 else if (flag == HASH_INT_FLAG_DCALC) 366 { 367 HASH->STS_B.DCALCINT = BIT_RESET; 368 } 369 } 370 371 /*! 372 * @brief Waits for Compute data 373 * 374 * @param timeOut: Waits for Compute time 375 * 376 * @retval 0: No block is currently being compute 377 * 1: The hash core is compute a block of data 378 * 379 */ HASH_WaitForCompute(uint32_t timeOut)380uint8_t HASH_WaitForCompute(uint32_t timeOut) 381 { 382 __IO uint8_t flag = SET; 383 uint32_t time = timeOut; 384 385 while ((flag == SET) && (time > 0)) 386 { 387 flag = HASH_ReadFlagStatus(HASH_FLAG_BUSY); 388 time --; 389 } 390 391 if ((flag == RESET) && (time > 0)) 392 { 393 return 0; 394 } 395 396 return 1; 397 } 398 399 /**@} end of group HASH_Functions */ 400 /**@} end of group HASH_Driver */ 401 /**@} end of group APM32F4xx_StdPeriphDriver */ 402