So I'm trying to implement a RNG on Windows and as part of creating the seed I'm checking for installed and currently active WSL distros to get some random bits from /dev/random.
Afaik there is no API in C that directly connects to the WSL Distro, so I'm running the wslconfig /l /running
command from my C script, storing and parsing the output to check for running WSL distros, and if one is detected then fetch the bits from /dev/random.
Here's my code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <wchar.h>
int WSLGetEntropy(unsigned char* randBuf, size_t randBufSize) {
wchar_t buffer[128];
FILE* pipe = _wpopen(L"wslconfig /l /running", L"rb");
if (!pipe) return 0;
size_t bytesRead = fread(buffer, sizeof(wchar_t), sizeof(buffer) / sizeof(wchar_t), pipe);
if (bytesRead == 0) {
printf("No data received\n");
_pclose(pipe);
return 0;
}
/* Convert the wide character buffer to a regular C string */
char* bufferStr = (char*) malloc(bytesRead + 1);
if (bufferStr == NULL) {
perror("malloc");
return 0;
}
wcstombs(bufferStr, buffer, bytesRead);
bufferStr[bytesRead] = '\0';
/* parse the command output to get the name of any active wsl distro */
char* start = strstr(bufferStr, "Windows Subsystem for Linux Distributions:\r\r\n");
if (start == NULL) {
free(bufferStr);
_pclose(pipe);
return 0;
}
start += 45;
char* end = strstr(start, " (Default)");
if (end == NULL) {
free(bufferStr);
_pclose(pipe);
return 0;
}
size_t length = end - start;
char* wslDistroName = (char*) malloc(length + 1);
if (wslDistroName == NULL) {
perror("malloc");
free(bufferStr);
return 1;
}
strncpy(wslDistroName, start, length);
wslDistroName[length] = '\0';
/* Get randBufSize bytes from /dev/random if a running WSL2 distro is detected */
char *loc = malloc(12 + 17 + length + 1);
strcpy(loc, "\\\\wsl.localhost\\");
strcat(loc, wslDistroName);
strcat(loc, "\\dev\\random");
FILE *file = fopen(loc, "rb");
if (file == NULL) {
perror("Error opening random");
return 0;
}
bytesRead = fread(randBuf, 1, randBufSize, file);
if (bytesRead != randBufSize) {
perror("Error reading from random");
fclose(file);
return 0;
}
fclose(file);
free(wslDistroName);
free(bufferStr);
_pclose(pipe);
return 1;
}
int main() {
unsigned char buf[64];
if (WSLGetEntropy(buf, 64)){
for (int i = 0; i < 64; i++) printf("%02x ", buf[i]);
printf("\n");
}
return 0;
}
However the string parsing and indirectly running the command like this makes this very inefficient. Is there a better and faster method to achieve this? Speed and memory are very important factors for my use case.
Aucun commentaire:
Enregistrer un commentaire