Skip to content

Commit

Permalink
Change random number generator
Browse files Browse the repository at this point in the history
Four fixes are applied in this patch:

  1) The `SYS_RandomInt()` function is renamed to `SYS_RandomLong()`,
  and its return type is now `long`. It no longer takes a range as
  parameters for its random number generation; it always uses the full
  range.
  2) The `getrandom()` syscall is added to configure.ac as a requested
  function.
  3) The generator for `SYS_RandomLong()` is changed. The previous
  generator was from the `rand()` function, but now it uses
  `getrandom()` when available and otherwise `lrand48()`, from the POSIX
  API.
  4) The seeding of the generator is via `SYS_InitRandom()`. It is
  modified accordingly to seed the new generator.

Addresses Ref #9
"Improve SYS_RandomInt()"
https://salsa.debian.org/rousseau/PCSC/-/issues/9
  • Loading branch information
createyourpersonalaccount authored and LudovicRousseau committed May 22, 2022
1 parent 615160f commit 2c3d3bf
Show file tree
Hide file tree
Showing 5 changed files with 37 additions and 19 deletions.
2 changes: 1 addition & 1 deletion configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ AC_STRUCT_DIRENT_D_TYPE
AC_FUNC_ERROR_AT_LINE
AC_FUNC_STAT
AC_FUNC_VPRINTF
AC_CHECK_FUNCS(getopt_long nanosleep strerror vsnprintf)
AC_CHECK_FUNCS(getopt_long nanosleep strerror vsnprintf getrandom)
AC_FUNC_ALLOCA

# C Compiler features
Expand Down
4 changes: 2 additions & 2 deletions src/readerfactory.c
Original file line number Diff line number Diff line change
Expand Up @@ -1181,12 +1181,12 @@ SCARDHANDLE RFCreateReaderHandle(READER_CONTEXT * rContext)
{
READER_CONTEXT *dummy_reader;

/* Create a random handle with 32 bits check to see if it already is
/* Create a random handle with 64 bits check to see if it already is
* used. */
/* FIXME: THIS IS NOT STRONG ENOUGH: A 128-bit token should be
* generated. The client and server would associate token and hCard
* for authentication. */
randHandle = SYS_RandomInt(0, -1);
randHandle = SYS_RandomLong();

/* do we already use this hCard somewhere? */
ret = RFReaderInfoById(randHandle, &dummy_reader);
Expand Down
2 changes: 1 addition & 1 deletion src/sys_generic.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

int SYS_USleep(int);

int SYS_RandomInt(int, int);
long SYS_RandomLong(void);

void SYS_InitRandom(void);

Expand Down
46 changes: 32 additions & 14 deletions src/sys_unix.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,12 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#include "config.h"
#include <sys/time.h>
#include <limits.h>
#include <stdlib.h>
#include <time.h>
#ifdef HAVE_GETRANDOM
#include <sys/random.h>
#endif /* HAVE_GETRANDOM */

#include "misc.h"
#include "sys_generic.h"
Expand Down Expand Up @@ -87,29 +91,42 @@ INTERNAL int SYS_USleep(int iTimeVal)
/**
* Generate a pseudo random number
*
* @param[in] fStart minimal value
* @param[in] fEnd maximal value or -1 for a full range
* @return a non-negative random number
*
* @return a random number between fStart and fEnd
* @remark the range is at least up to `2^31`.
* @remark this is a CSPRNG when `getrandom()` is available, LCG otherwise.
* @warning SYS_InitRandom() should be called (once) before using this function.
* @warning not thread safe when system lacks `getrandom()` syscall.
* @warning not cryptographically secure when system lacks `getrandom()` syscall.
* @warning if interrupted by a signal, this function may return 0.
*/
INTERNAL int SYS_RandomInt(int fStart, int fEnd)
INTERNAL long SYS_RandomLong(void)
{
int iRandNum = 0;

if (-1 == fEnd)
/* full int range */
iRandNum = rand();
else
iRandNum = ((rand()+0.0)/RAND_MAX * (fEnd - fStart)) + fStart;

return iRandNum;
#ifdef HAVE_GETRANDOM
unsigned long ul = 0;
unsigned char c[sizeof ul] = {0};
size_t i;

(void)getrandom(c, sizeof c, 0);
// this loop avoids trap representations that may occur in the naive solution
for(i = 0; i < sizeof ul; i++) {
ul <<= CHAR_BIT;
ul |= c[i];
}
// the casts are for the sake of clarity
return (long)(ul & (unsigned long)LONG_MAX);
#else
long r = lrand48(); // this is not thread-safe
return r;
#endif /* HAVE_GETRANDOM */
}

/**
* Initialize the random generator
*/
INTERNAL void SYS_InitRandom(void)
{
#ifndef HAVE_GETRANDOM
struct timeval tv;
struct timezone tz;
long myseed = 0;
Expand All @@ -124,6 +141,7 @@ INTERNAL void SYS_InitRandom(void)
myseed = (long) time(NULL);
}

srand(myseed);
srand48(myseed);
#endif /* HAVE_GETRANDOM */
}

2 changes: 1 addition & 1 deletion src/winscard.c
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@ LONG SCardEstablishContext(DWORD dwScope, /*@unused@*/ LPCVOID pvReserved1,
* identified by clients and distinguished from others
*/

*phContext = SYS_RandomInt(0, -1);
*phContext = SYS_RandomLong();

Log2(PCSC_LOG_DEBUG, "Establishing Context: 0x%lX", *phContext);

Expand Down

0 comments on commit 2c3d3bf

Please sign in to comment.