From 87d5827a050332fc30daac38f61604d951ab0c1a Mon Sep 17 00:00:00 2001 From: Louis-Erig HERVE <6905505+LouisErigHerve@users.noreply.github.com> Date: Sun, 13 Aug 2023 14:30:34 +0200 Subject: [PATCH] Improve the randomization of the password(s) generated - Change some functions to be sure to generate a better random password - Avoid repetition on password (a random letter/number must me different from the 4 previous letters/numbers of the password) --- main.c | 97 ++++++++++++++++++++++++++++++--------- password_lib.c | 121 +++++++++++++++++++------------------------------ password_lib.h | 2 - 3 files changed, 123 insertions(+), 97 deletions(-) diff --git a/main.c b/main.c index f1e0480..47dec4a 100644 --- a/main.c +++ b/main.c @@ -30,6 +30,8 @@ #define DEFAULT_USE_SPECIAL_CHARACTERS 0 #define DEFAULT_USE_CUSTOM_LIST 0 +#define EXTENDED_BUFFER_SIZE 0x100000 /* 1 MByte buffer */ + /* Global variables ---------------------------------------------------------*/ @@ -63,26 +65,29 @@ const uint8_t ExcludeSimilarCharacterList[] = */ int main(int argc, char *argv[]) { - uint32_t i = 0; - time_t rawtime; - struct tm * timeinfo = NULL; - uint32_t PasswordOptionsSet = 0; - uint32_t PasswordLengthOptionsSet = 0; - uint32_t PasswordNumberOptionsSet = 0; - uint32_t UseDecNumbers = 0; - uint32_t UseHexNumbers = 0; - uint32_t UseLettersUpperCase = 0; - uint32_t UseLettersLowerCase = 0; - uint32_t UseSpecialCharacters = 0; - uint32_t UseCustomList = 0; - uint32_t ExcludeSimilarCharacters = 0; - uint32_t PasswordLength = 0; - uint32_t NbOfPasswordToGenerate = 0; - uint8_t BufferCharactersList[512] = {0}; /* 512 bytes should be enough to store the entire character list, increase if necessary */ - uint32_t BufferCharactersLen = 0; - uint8_t GeneratedPassword[MAX_PASSWORD_LEN + 1] = {0}; - uint8_t CustomListBuffer[256 + 1] = {0}; - uint32_t CustomListLen = 0; + uint32_t i = 0; + time_t rawtime; + struct tm * timeinfo = NULL; + uint32_t PasswordOptionsSet = 0; + uint32_t PasswordLengthOptionsSet = 0; + uint32_t PasswordNumberOptionsSet = 0; + uint32_t UseDecNumbers = 0; + uint32_t UseHexNumbers = 0; + uint32_t UseLettersUpperCase = 0; + uint32_t UseLettersLowerCase = 0; + uint32_t UseSpecialCharacters = 0; + uint32_t UseCustomList = 0; + uint32_t ExcludeSimilarCharacters = 0; + uint32_t PasswordLength = 0; + uint32_t NbOfPasswordToGenerate = 0; + uint8_t BufferCharactersList[512] = {0}; /* 512 bytes should be enough to store the entire character list, increase if necessary */ + uint32_t BufferCharactersLen = 0; + uint8_t GeneratedPassword[MAX_PASSWORD_LEN + 1] = {0}; + uint8_t CustomListBuffer[256 + 1] = {0}; + uint32_t CustomListLen = 0; + uint8_t * BufferCharactersListExtended = NULL; /* The pointer where EXTENDED_BUFFER_SIZE byte will be allocated */ + uint32_t RandomIndex = 0; + uint8_t TempByte = 0; int Temp = 0; int c; @@ -530,11 +535,59 @@ int main(int argc, char *argv[]) /* ----------------------------------------------------------------------- */ /* ----------------------------------------------------------------------- */ + + /* Allocate a new buffer with higher place */ + BufferCharactersListExtended = malloc(EXTENDED_BUFFER_SIZE * sizeof(uint8_t)); + + /* Check the memory allocation result */ + if(BufferCharactersListExtended == NULL) + { + /* Get the current time */ + time(&rawtime); + timeinfo = localtime(&rawtime); + + /* Print the current time */ + printf("[%04d-%02d-%02d %02d:%02d:%02d] ", timeinfo->tm_year + 1900, timeinfo->tm_mon + 1, + timeinfo->tm_mday, timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec); + + printf("Error when allocating memory, exits the program\n"); + fflush(stdout); + exit(0); + } + + /* Fill the extended buffer */ + for(i = 0; i < EXTENDED_BUFFER_SIZE; i++) + { + BufferCharactersListExtended[i] = BufferCharactersList[i % BufferCharactersLen]; + } + + /* Init the pseudo random generator */ + srand(time(NULL)); + + /* Make some permutations on the extended buffer */ + for(i = 0; i < EXTENDED_BUFFER_SIZE; i++) + { + /* Generate a random index */ + RandomIndex = rand() % EXTENDED_BUFFER_SIZE; + + /* Permute values */ + TempByte = BufferCharactersListExtended[RandomIndex]; + BufferCharactersListExtended[RandomIndex] = BufferCharactersListExtended[i]; + BufferCharactersListExtended[i] = TempByte; + } + + + /* ----------------------------------------------------------------------- */ + /* ----------------------------------------------------------------------- */ + /* ----------------------------------------------------------------------- */ + /* ----------------------------------------------------------------------- */ + + /* Generate all passwords */ for(i = 0; i < NbOfPasswordToGenerate; i++) { /* Generates a password */ - GeneratePassword(PasswordLength, BufferCharactersList, BufferCharactersLen, GeneratedPassword); + GeneratePassword(PasswordLength, BufferCharactersListExtended, EXTENDED_BUFFER_SIZE, GeneratedPassword); /* Get the current time */ time(&rawtime); @@ -554,6 +607,8 @@ int main(int argc, char *argv[]) /* ----------------------------------------------------------------------- */ /* ----------------------------------------------------------------------- */ + /* Free memory */ + if(BufferCharactersListExtended) free(BufferCharactersListExtended); /* Get the current time */ time(&rawtime); diff --git a/password_lib.c b/password_lib.c index 5154873..b855c49 100644 --- a/password_lib.c +++ b/password_lib.c @@ -83,107 +83,80 @@ void GeneratePassword(uint32_t PasswordLen, { uint64_t i = 0; uint64_t NbLoop = 0; - uint64_t RandomXor = 0; time_t rawtime; struct tm * timeinfo = NULL; struct timeval tv; uint32_t RandomIndex; + uint8_t OldByte1 = 0; + uint8_t OldByte2 = 0; + uint8_t OldByte3 = 0; + uint8_t OldByte4 = 0; + uint32_t RepeatLoop = 0; - /* Step 1 : Get the current time */ + /* Step 1 : Init the pseudo random generator */ + srand(time(NULL)); + + /* Step 2 : Get the current time */ time(&rawtime); timeinfo = localtime(&rawtime); gettimeofday (&tv, NULL); - /* Step 2 : Compute the number of loop to process */ + /* Step 3 : Compute the number of loop to process */ NbLoop = (uint32_t)(timeinfo->tm_yday * 24 * 3600); NbLoop += (uint32_t)(timeinfo->tm_hour * 3600); NbLoop += (uint32_t)(timeinfo->tm_min * 60); NbLoop += (uint32_t)(timeinfo->tm_sec); NbLoop += (uint32_t)(tv.tv_usec); - /* Step 3 : Generate random numbers */ + /* Step 3 : Generate several random numbers */ for(i = 0; i < NbLoop; i++) { rand(); } - /* Step 4 : Generate a 64 bits random number based on the current time */ - RandomXor = Generate64BitsRandomNumber(); - - /* Step 5 : Generates a random password */ + /* Step 4 : Generates a random password */ for(i = 0; i < PasswordLen; i++) { - RandomIndex = (uint32_t)((rand() ^ RandomXor) % CharacterListSize); + RandomIndex = (uint32_t)(rand() % CharacterListSize); + + /* Check that the current random byte selected is different from the previous */ + if(((OldByte1 & 0xFF) == (CharacterList[RandomIndex] & 0xFF)) || + ((OldByte2 & 0xFF) == (CharacterList[RandomIndex] & 0xFF)) || + ((OldByte3 & 0xFF) == (CharacterList[RandomIndex] & 0xFF)) || + ((OldByte4 & 0xFF) == (CharacterList[RandomIndex] & 0xFF))) + { + RepeatLoop = 0; + + /* Force exit after up to 1000 loop */ + while(RepeatLoop < 1000) + { + /* Generate a new random index */ + RandomIndex = (uint32_t)(rand() % CharacterListSize); + RepeatLoop++; + + /* Exit the "while" loop only when a new byte different from the + * 4 previous one has been found */ + if(((OldByte1 & 0xFF) != (CharacterList[RandomIndex] & 0xFF)) && + ((OldByte2 & 0xFF) != (CharacterList[RandomIndex] & 0xFF)) && + ((OldByte3 & 0xFF) != (CharacterList[RandomIndex] & 0xFF)) && + ((OldByte4 & 0xFF) != (CharacterList[RandomIndex] & 0xFF))) + { + break; + } + } + } + + /* Store the random byte as a character of the password */ OutputPassword[i] = CharacterList[RandomIndex]; - /* Re-generate the 64 bits random number */ - RandomXor = Generate64BitsRandomNumber(); + /* Shift all previous bytes */ + OldByte4 = OldByte3; + OldByte3 = OldByte2; + OldByte2 = OldByte1; + OldByte1 = CharacterList[RandomIndex]; } } /* End GeneratePassword() */ -/* - * @brief : This function generate a random 64 bits number - * based on the current microsecond time machine - * value. - * - * @param None - * - * @return A 64 bits random number - * - */ -uint64_t Generate64BitsRandomNumber(void) -{ - uint64_t Random64bitsNum = 0; - uint32_t i; - struct timeval tv; - - /* For a 64 bits number there are 16 loop */ - for(i = 0; i < (sizeof(Random64bitsNum) / 4); i++) - { - /* Get the current time */ - gettimeofday (&tv, NULL); - - /* Get 4 MSBits of the microsecond time value as a part - * of the 64 bits random number */ - Random64bitsNum = (Random64bitsNum << 4) | (uint64_t)(tv.tv_usec & 0x0F); - - /* Wait for a random delay (this ensure the - * microsecond counter value will change randomly on - * next call of the current function) */ - Password_delay((tv.tv_usec & 0xF) + 10); - - /* Call rand() to be sure to change - * the random system value */ - rand(); - } - - return Random64bitsNum; -} - - -/* - * @brief : This function generate a delay, it replace the "usleep" function not - * available on Windows machines. - * This function is not precise and must not be used for real - * time applications. - * - * @param None - * - * @return None - * - */ -void Password_delay(uint64_t Delay) -{ - volatile uint64_t i = 0; - for(i = 0; i < (Delay * 100); i++) - { - /* Call rand() to be sure to change - * the random system value */ - rand(); - } -} /* End Password_delay() */ - - /* End of file */ diff --git a/password_lib.h b/password_lib.h index dae1642..77f0fb3 100644 --- a/password_lib.h +++ b/password_lib.h @@ -39,8 +39,6 @@ void GeneratePassword(uint32_t PassowrdLen, uint8_t * CharacterList, uint32_t CharacterListSize, uint8_t * OutputPassword); -uint64_t Generate64BitsRandomNumber(void); -void Password_delay(uint64_t); #endif /* PASSWORD_LIB_H_ */