Skip to content

Commit

Permalink
Improve the randomization of the password(s) generated
Browse files Browse the repository at this point in the history
- 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)
  • Loading branch information
LouisErigHerve committed Aug 13, 2023
1 parent e846784 commit 87d5827
Show file tree
Hide file tree
Showing 3 changed files with 123 additions and 97 deletions.
97 changes: 76 additions & 21 deletions main.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 ---------------------------------------------------------*/

Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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);
Expand All @@ -554,6 +607,8 @@ int main(int argc, char *argv[])
/* ----------------------------------------------------------------------- */
/* ----------------------------------------------------------------------- */

/* Free memory */
if(BufferCharactersListExtended) free(BufferCharactersListExtended);

/* Get the current time */
time(&rawtime);
Expand Down
121 changes: 47 additions & 74 deletions password_lib.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
2 changes: 0 additions & 2 deletions password_lib.h
Original file line number Diff line number Diff line change
Expand Up @@ -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_ */
Expand Down

0 comments on commit 87d5827

Please sign in to comment.