void Md5Final(Md5* md5, byte* hash) { __IO uint16_t nbvalidbitsdata = 0; /* finish reading any trailing bytes into FIFO */ if (md5->buffLen > 0) { HASH_DataIn(*(uint32_t*)md5->buffer); md5->loLen += md5->buffLen; } /* calculate number of valid bits in last word of input data */ nbvalidbitsdata = 8 * (md5->loLen % MD5_REG_SIZE); /* configure number of valid bits in last word of the data */ HASH_SetLastWordValidBitsNbr(nbvalidbitsdata); /* start HASH processor */ HASH_StartDigest(); /* wait until Busy flag == RESET */ while (HASH_GetFlagStatus(HASH_FLAG_BUSY) != RESET) {} /* read message digest */ md5->digest[0] = HASH->HR[0]; md5->digest[1] = HASH->HR[1]; md5->digest[2] = HASH->HR[2]; md5->digest[3] = HASH->HR[3]; ByteReverseWords(md5->digest, md5->digest, MD5_DIGEST_SIZE); XMEMCPY(hash, md5->digest, MD5_DIGEST_SIZE); InitMd5(md5); /* reset state */ }
int wc_ShaFinal(Sha* sha, byte* hash) { __IO uint16_t nbvalidbitsdata = 0; /* finish reading any trailing bytes into FIFO */ if (sha->buffLen) { HASH_DataIn(*(uint32_t*)sha->buffer); sha->loLen += sha->buffLen; } /* calculate number of valid bits in last word of input data */ nbvalidbitsdata = 8 * (sha->loLen % SHA_REG_SIZE); /* configure number of valid bits in last word of the data */ HASH_SetLastWordValidBitsNbr(nbvalidbitsdata); /* start HASH processor */ HASH_StartDigest(); /* wait until Busy flag == RESET */ while (HASH_GetFlagStatus(HASH_FLAG_BUSY) != RESET) {} /* read message digest */ sha->digest[0] = HASH->HR[0]; sha->digest[1] = HASH->HR[1]; sha->digest[2] = HASH->HR[2]; sha->digest[3] = HASH->HR[3]; sha->digest[4] = HASH->HR[4]; ByteReverseWords(sha->digest, sha->digest, SHA_DIGEST_SIZE); XMEMCPY(hash, sha->digest, SHA_DIGEST_SIZE); return wc_InitSha(sha); /* reset state */ }
/** * @brief Compute the HASH SHA1 digest. * @param Input: pointer to the Input buffer to be treated. * @param Ilen: length of the Input buffer. * @param Output: the returned digest * @retval An ErrorStatus enumeration value: * - SUCCESS: digest computation done * - ERROR: digest computation failed */ ErrorStatus HASH_SHA1(uint8_t *Input, uint32_t Ilen, uint8_t Output[20]) { HASH_InitTypeDef SHA1_HASH_InitStructure; HASH_MsgDigest SHA1_MessageDigest; __IO uint16_t nbvalidbitsdata = 0; uint32_t i = 0; __IO uint32_t counter = 0; uint32_t busystatus = 0; ErrorStatus status = SUCCESS; uint32_t inputaddr = (uint32_t) Input; uint32_t outputaddr = (uint32_t) Output; /* Number of valid bits in last word of the Input data */ nbvalidbitsdata = 8 * (Ilen % 4); /* HASH peripheral initialization */ HASH_DeInit(); /* HASH Configuration */ SHA1_HASH_InitStructure.HASH_AlgoSelection = HASH_AlgoSelection_SHA1; SHA1_HASH_InitStructure.HASH_AlgoMode = HASH_AlgoMode_HASH; SHA1_HASH_InitStructure.HASH_DataType = HASH_DataType_8b; HASH_Init(&SHA1_HASH_InitStructure); /* Configure the number of valid bits in last word of the data */ HASH_SetLastWordValidBitsNbr(nbvalidbitsdata); /* Write the Input block in the IN FIFO */ for (i = 0; i < Ilen; i += 4) { HASH_DataIn(*(uint32_t*) inputaddr); inputaddr += 4; } /* Start the HASH processor */ HASH_StartDigest(); /* wait until the Busy flag is RESET */ do { busystatus = HASH_GetFlagStatus(HASH_FLAG_BUSY); counter++; } while ((counter != SHA1BUSY_TIMEOUT) && (busystatus != RESET)); if (busystatus != RESET) { status = ERROR; } else { /* Read the message digest */ HASH_GetDigest(&SHA1_MessageDigest); *(uint32_t*) (outputaddr) = __REV(SHA1_MessageDigest.Data[0]); outputaddr += 4; *(uint32_t*) (outputaddr) = __REV(SHA1_MessageDigest.Data[1]); outputaddr += 4; *(uint32_t*) (outputaddr) = __REV(SHA1_MessageDigest.Data[2]); outputaddr += 4; *(uint32_t*) (outputaddr) = __REV(SHA1_MessageDigest.Data[3]); outputaddr += 4; *(uint32_t*) (outputaddr) = __REV(SHA1_MessageDigest.Data[4]); } return status; }
/** * @brief HASH MD5 Digest computation (using DMA for data transfer) * @note DMA2 stream7 channel2 is used to transfer data from memory * (MessageToHash[] array) to HASH Peripheral (the INPUT data register). * @param None * @retval None */ static void HASH_MD5_DMA(void) { HASH_InitTypeDef HASH_InitStructure; DMA_InitTypeDef DMA_InitStructure; /* HASH Configuration */ HASH_InitStructure.HASH_AlgoSelection = HASH_AlgoSelection_MD5; HASH_InitStructure.HASH_AlgoMode = HASH_AlgoMode_HASH; HASH_InitStructure.HASH_DataType = HASH_DataType_8b; HASH_InitStructure.HASH_HMACKeyType = HASH_HMACKeyType_ShortKey; HASH_Init(&HASH_InitStructure); /*DMA Configuration*/ DMA_DeInit(DMA2_Stream7); DMA_InitStructure.DMA_Channel = DMA_Channel_2; DMA_InitStructure.DMA_PeripheralBaseAddr = HASH_DIN_REG_ADDR; DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)MessageToHash; DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral; DMA_InitStructure.DMA_BufferSize = SIZE_MSG_TO_HASH_IN_WORDS; DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word; DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Word; DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; DMA_InitStructure.DMA_Priority = DMA_Priority_High; DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable; DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full; DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single; DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; /* Configure the DMA Stream */ DMA_Init(DMA2_Stream7, &DMA_InitStructure); /* Enable HASH DMA */ HASH_DMACmd(ENABLE); /* Enable DMA2 Transfer */ DMA_Cmd(DMA2_Stream7, ENABLE); /* Note : When the DMA is enabled, it provides the information to the hash processor when it is transferring the last data word. Then the padding and digest computation are performed automatically as if DCAL had been written to 1.*/ /* wait until DMA Transfer completed */ while (DMA_GetFlagStatus(DMA2_Stream7, DMA_FLAG_TCIF7) == RESET); /* wait until the Busy flag is RESET */ while (HASH_GetFlagStatus(HASH_FLAG_BUSY) != RESET); /* Get the MD5 Digest */ HASH_GetDigest(&MsgDigest); }
/** * @brief Compute the HMAC MD5 digest. * @param Key: pointer to the Key used for HMAC. * @param Keylen: length of the Key used for HMAC. * @param Input: pointer to the Input buffer to be treated. * @param Ilen: length of the Input buffer. * @param Output: the returned digest * @retval An ErrorStatus enumeration value: * - SUCCESS: digest computation done * - ERROR: digest computation failed */ ErrorStatus HMAC_MD5(uint8_t *Key, uint32_t Keylen, uint8_t *Input, uint32_t Ilen, uint8_t Output[16]) { HASH_InitTypeDef MD5_HASH_InitStructure; HASH_MsgDigest MD5_MessageDigest; __IO uint16_t nbvalidbitsdata = 0; __IO uint16_t nbvalidbitskey = 0; uint32_t i = 0; __IO uint32_t counter = 0; uint32_t busystatus = 0; ErrorStatus status = SUCCESS; uint32_t keyaddr = (uint32_t)Key; uint32_t inputaddr = (uint32_t)Input; uint32_t outputaddr = (uint32_t)Output; /* Number of valid bits in last word of the Input data */ nbvalidbitsdata = 8 * (Ilen % 4); /* Number of valid bits in last word of the Key */ nbvalidbitskey = 8 * (Keylen % 4); /* HASH peripheral initialization */ HASH_DeInit(); /* HASH Configuration */ MD5_HASH_InitStructure.HASH_AlgoSelection = HASH_AlgoSelection_MD5; MD5_HASH_InitStructure.HASH_AlgoMode = HASH_AlgoMode_HMAC; MD5_HASH_InitStructure.HASH_DataType = HASH_DataType_8b; if(Keylen > 64) { /* HMAC long Key */ MD5_HASH_InitStructure.HASH_HMACKeyType = HASH_HMACKeyType_LongKey; } else { /* HMAC short Key */ MD5_HASH_InitStructure.HASH_HMACKeyType = HASH_HMACKeyType_ShortKey; } HASH_Init(&MD5_HASH_InitStructure); /* Configure the number of valid bits in last word of the Key */ HASH_SetLastWordValidBitsNbr(nbvalidbitskey); /* Write the Key */ for(i=0; i<Keylen; i+=4) { HASH_DataIn(*(uint32_t*)keyaddr); keyaddr+=4; } /* Start the HASH processor */ HASH_StartDigest(); /* wait until the Busy flag is RESET */ do { busystatus = HASH_GetFlagStatus(HASH_FLAG_BUSY); counter++; }while ((counter != MD5BUSY_TIMEOUT) && (busystatus != RESET)); if (busystatus != RESET) { status = ERROR; } else { /* Configure the number of valid bits in last word of the Input data */ HASH_SetLastWordValidBitsNbr(nbvalidbitsdata); /* Write the Input block in the IN FIFO */ for(i=0; i<Ilen; i+=4) { HASH_DataIn(*(uint32_t*)inputaddr); inputaddr+=4; } /* Start the HASH processor */ HASH_StartDigest(); /* wait until the Busy flag is RESET */ counter =0; do { busystatus = HASH_GetFlagStatus(HASH_FLAG_BUSY); counter++; }while ((counter != MD5BUSY_TIMEOUT) && (busystatus != RESET)); if (busystatus != RESET) { status = ERROR; } else { /* Configure the number of valid bits in last word of the Key */ HASH_SetLastWordValidBitsNbr(nbvalidbitskey); /* Write the Key */ keyaddr = (uint32_t)Key; for(i=0; i<Keylen; i+=4) { HASH_DataIn(*(uint32_t*)keyaddr); keyaddr+=4; } /* Start the HASH processor */ HASH_StartDigest(); /* wait until the Busy flag is RESET */ counter =0; do { busystatus = HASH_GetFlagStatus(HASH_FLAG_BUSY); counter++; }while ((counter != MD5BUSY_TIMEOUT) && (busystatus != RESET)); if (busystatus != RESET) { status = ERROR; } else { /* Read the message digest */ HASH_GetDigest(&MD5_MessageDigest); *(uint32_t*)(outputaddr) = __REV(MD5_MessageDigest.Data[0]); outputaddr+=4; *(uint32_t*)(outputaddr) = __REV(MD5_MessageDigest.Data[1]); outputaddr+=4; *(uint32_t*)(outputaddr) = __REV(MD5_MessageDigest.Data[2]); outputaddr+=4; *(uint32_t*)(outputaddr) = __REV(MD5_MessageDigest.Data[3]); } } } return status; }