mirror of https://github.com/microsoft/WSL
272 lines
6.4 KiB
C
272 lines
6.4 KiB
C
/*++
|
|
|
|
Copyright (c) Microsoft. All rights reserved.
|
|
|
|
Module Name:
|
|
|
|
random.c
|
|
|
|
Abstract:
|
|
|
|
This file is a test for the getrandom system call and the /dev/random and
|
|
/dev/urandom devices.
|
|
|
|
--*/
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <unistd.h>
|
|
#include <sys/types.h>
|
|
#include <sys/stat.h>
|
|
#include <fcntl.h>
|
|
#include <sys/socket.h>
|
|
#include <sys/un.h>
|
|
#include <netinet/in.h>
|
|
#include <netdb.h>
|
|
#include <time.h>
|
|
#include <linux/random.h>
|
|
#include "lxtcommon.h"
|
|
#include "unittests.h"
|
|
|
|
#define DEV_RANDOM "/dev/random"
|
|
#define DEV_RANDOM_MAX_BYTES (512)
|
|
|
|
#define DEV_URANDOM "/dev/urandom"
|
|
#define DEV_URANDOM_MAX_BYTES (0x1FFFFFF)
|
|
|
|
#define PROC_SYS_KERNEL_RANDOM "/proc/sys/kernel/random"
|
|
#define PROC_SYS_KERNEL_RANDOM_BOOTID PROC_SYS_KERNEL_RANDOM "/boot_id"
|
|
#define PROC_SYS_KERNEL_RANDOM_ENTROPY_AVAIL PROC_SYS_KERNEL_RANDOM "/entropy_avail"
|
|
#define PROC_SYS_KERNEL_RANDOM_POOLSIZE PROC_SYS_KERNEL_RANDOM "/poolsize"
|
|
#define PROC_SYS_KERNEL_RANDOM_UUID PROC_SYS_KERNEL_RANDOM "/uuid"
|
|
#define PROC_SYS_KERNEL_RANDOM_BYTES 37
|
|
|
|
#define LXT_NAME "random"
|
|
|
|
int GetrandomSyscall(PLXT_ARGS Args);
|
|
|
|
int DevRandomDevice(PLXT_ARGS Args);
|
|
|
|
int DevUrandomDevice(PLXT_ARGS Args);
|
|
|
|
int ProcfsRandom(PLXT_ARGS Args);
|
|
|
|
static const LXT_VARIATION g_LxtVariations[] = {
|
|
{"getrandom syscall", GetrandomSyscall},
|
|
{"/dev/random device", DevRandomDevice},
|
|
{"/dev/urandom device", DevUrandomDevice},
|
|
{"/proc/sys/kernel/random", ProcfsRandom}};
|
|
|
|
int RandomTestEntry(int Argc, char* Argv[])
|
|
{
|
|
|
|
LXT_ARGS Args;
|
|
int Result;
|
|
|
|
LxtCheckResult(LxtInitialize(Argc, Argv, &Args, LXT_NAME));
|
|
LxtCheckResult(LxtRunVariations(&Args, g_LxtVariations, LXT_COUNT_OF(g_LxtVariations)));
|
|
|
|
ErrorExit:
|
|
LxtUninitialize();
|
|
return 0;
|
|
}
|
|
|
|
int GetrandomSyscall(PLXT_ARGS Args)
|
|
|
|
{
|
|
|
|
char* Buffer;
|
|
size_t BufferSize;
|
|
size_t Result;
|
|
|
|
BufferSize = DEV_URANDOM_MAX_BYTES + 1;
|
|
Buffer = malloc(BufferSize);
|
|
if (Buffer == NULL)
|
|
{
|
|
Result = LXT_RESULT_FAILURE;
|
|
LxtLogError("malloc failed");
|
|
goto ErrorExit;
|
|
}
|
|
|
|
//
|
|
// Valid parameter variations.
|
|
//
|
|
|
|
LxtCheckResult(LxtGetrandom(NULL, 0, 0));
|
|
LxtCheckEqual(Result, 0, "%Iu");
|
|
LxtCheckResult(LxtGetrandom(NULL, 0, GRND_RANDOM));
|
|
LxtCheckResult(LxtGetrandom(NULL, 0, GRND_NONBLOCK));
|
|
LxtCheckResult(LxtGetrandom(NULL, 0, (GRND_RANDOM | GRND_NONBLOCK)));
|
|
LxtCheckResult(LxtGetrandom(Buffer, BufferSize, 0));
|
|
if (Result > DEV_URANDOM_MAX_BYTES)
|
|
{
|
|
Result = LXT_RESULT_FAILURE;
|
|
LxtLogError("BytesRead %Iu greater than expected %Iu", Result, DEV_URANDOM_MAX_BYTES);
|
|
|
|
goto ErrorExit;
|
|
}
|
|
|
|
LxtCheckResult(LxtGetrandom(Buffer, BufferSize, GRND_RANDOM));
|
|
if (Result > DEV_RANDOM_MAX_BYTES)
|
|
{
|
|
Result = LXT_RESULT_FAILURE;
|
|
LxtLogError("BytesRead %Iu greater than expected %Iu", Result, DEV_RANDOM_MAX_BYTES);
|
|
|
|
goto ErrorExit;
|
|
}
|
|
|
|
//
|
|
// Invalid parameter variations.
|
|
//
|
|
|
|
LxtCheckErrnoFailure(LxtGetrandom(NULL, 0, ((GRND_RANDOM | GRND_NONBLOCK) + 1)), EINVAL);
|
|
LxtCheckErrnoFailure(LxtGetrandom(NULL, 0, -1), EINVAL);
|
|
LxtCheckErrnoFailure(LxtGetrandom(NULL, 1, 0), EFAULT);
|
|
LxtCheckErrnoFailure(LxtGetrandom(-1, 1, 0), EFAULT);
|
|
|
|
ErrorExit:
|
|
if (Buffer != NULL)
|
|
{
|
|
free(Buffer);
|
|
}
|
|
|
|
return Result;
|
|
}
|
|
|
|
int DevRandomDevice(PLXT_ARGS Args)
|
|
{
|
|
|
|
char Buffer[DEV_RANDOM_MAX_BYTES + 1];
|
|
int BytesRead;
|
|
int Fd;
|
|
int Result;
|
|
|
|
Fd = -1;
|
|
|
|
LxtCheckResult(Fd = open(DEV_RANDOM, O_RDONLY));
|
|
LxtCheckResult(BytesRead = read(Fd, Buffer, LXT_COUNT_OF(Buffer)));
|
|
|
|
if (BytesRead > DEV_RANDOM_MAX_BYTES)
|
|
{
|
|
Result = LXT_RESULT_FAILURE;
|
|
LxtLogError("BytesRead %d greater than expected %d", BytesRead, DEV_RANDOM_MAX_BYTES);
|
|
|
|
goto ErrorExit;
|
|
}
|
|
|
|
Result = LXT_RESULT_SUCCESS;
|
|
|
|
ErrorExit:
|
|
if (Fd != -1)
|
|
{
|
|
LxtClose(Fd);
|
|
}
|
|
|
|
return Result;
|
|
}
|
|
|
|
int DevUrandomDevice(PLXT_ARGS Args)
|
|
{
|
|
|
|
char* Buffer;
|
|
size_t BufferSize;
|
|
int BytesRead;
|
|
int Fd;
|
|
int Result;
|
|
|
|
BufferSize = DEV_URANDOM_MAX_BYTES + 1;
|
|
Fd = -1;
|
|
Buffer = malloc(BufferSize);
|
|
if (Buffer == NULL)
|
|
{
|
|
Result = LXT_RESULT_FAILURE;
|
|
LxtLogError("malloc failed");
|
|
goto ErrorExit;
|
|
}
|
|
|
|
LxtCheckResult(Fd = open(DEV_URANDOM, O_RDONLY));
|
|
LxtCheckResult(BytesRead = read(Fd, Buffer, BufferSize));
|
|
if (BytesRead > DEV_URANDOM_MAX_BYTES)
|
|
{
|
|
Result = LXT_RESULT_FAILURE;
|
|
LxtLogError("BytesRead %d greater than expected %d", BytesRead, DEV_URANDOM_MAX_BYTES);
|
|
|
|
goto ErrorExit;
|
|
}
|
|
|
|
Result = LXT_RESULT_SUCCESS;
|
|
|
|
ErrorExit:
|
|
if (Buffer != NULL)
|
|
{
|
|
free(Buffer);
|
|
}
|
|
|
|
if (Fd != -1)
|
|
{
|
|
LxtClose(Fd);
|
|
}
|
|
|
|
return Result;
|
|
}
|
|
|
|
int ProcfsRandom(PLXT_ARGS Args)
|
|
|
|
{
|
|
char Buffer[PROC_SYS_KERNEL_RANDOM_BYTES];
|
|
int BytesRead;
|
|
int Fd;
|
|
int Result;
|
|
|
|
//
|
|
// Test /proc/sys/kernel/random/uuid.
|
|
//
|
|
|
|
LxtCheckResult(Fd = open(PROC_SYS_KERNEL_RANDOM_UUID, O_RDONLY));
|
|
LxtCheckResult(BytesRead = read(Fd, Buffer, sizeof(Buffer)));
|
|
LxtCheckEqual(PROC_SYS_KERNEL_RANDOM_BYTES, BytesRead, "%d");
|
|
LxtClose(Fd);
|
|
Fd = -1;
|
|
|
|
//
|
|
// Test /proc/sys/kernel/random/boot_id.
|
|
//
|
|
|
|
LxtCheckResult(Fd = open(PROC_SYS_KERNEL_RANDOM_BOOTID, O_RDONLY));
|
|
LxtCheckResult(BytesRead = read(Fd, Buffer, sizeof(Buffer)));
|
|
LxtCheckEqual(PROC_SYS_KERNEL_RANDOM_BYTES, BytesRead, "%d");
|
|
LxtClose(Fd);
|
|
Fd = -1;
|
|
|
|
//
|
|
// Test /proc/sys/kernel/random/entropy_avail.
|
|
//
|
|
|
|
LxtCheckResult(Fd = open(PROC_SYS_KERNEL_RANDOM_ENTROPY_AVAIL, O_RDONLY));
|
|
LxtCheckResult(BytesRead = read(Fd, Buffer, (sizeof(Buffer) - 1)));
|
|
LxtCheckEqual(5, BytesRead, "%d");
|
|
LxtClose(Fd);
|
|
Fd = -1;
|
|
|
|
//
|
|
// Test /proc/sys/kernel/random/poolsize.
|
|
//
|
|
|
|
LxtCheckResult(Fd = open(PROC_SYS_KERNEL_RANDOM_POOLSIZE, O_RDONLY));
|
|
LxtCheckResult(BytesRead = read(Fd, Buffer, (sizeof(Buffer) - 1)));
|
|
LxtCheckEqual(5, BytesRead, "%d");
|
|
Buffer[BytesRead] = '\0';
|
|
LxtCheckStringEqual(Buffer, "4096\n");
|
|
LxtClose(Fd);
|
|
Fd = -1;
|
|
|
|
ErrorExit:
|
|
if (Fd != -1)
|
|
{
|
|
LxtClose(Fd);
|
|
}
|
|
|
|
return Result;
|
|
}
|