Compare commits

..

8 Commits

Author SHA1 Message Date
c0f91dcced rr Minor bug (r == -1) 2025-10-11 22:24:00 +02:00
0d05abf282 fs Make fetch subcmd more configurable 2025-10-11 22:23:10 +02:00
7d81e39de5 Add rc to rc.tb 2025-10-11 22:22:53 +02:00
257f494b0c rc Rand/crypto utility 2025-10-11 21:55:04 +02:00
fc97d56eb5 ulib Implement rand() 2025-10-11 21:54:23 +02:00
ee93463c64 Add rand() syscall 2025-10-11 21:54:06 +02:00
d92a652024 Make uniqids truly random 2025-10-11 21:36:50 +02:00
b717387adb Implement random number generation with x86 rdrand 2025-10-11 21:36:33 +02:00
15 changed files with 240 additions and 25 deletions

View File

@ -2,3 +2,4 @@ mkalias pctl base:/bin/pctl
mkalias tb base:/bin/tb mkalias tb base:/bin/tb
mkalias fs base:/bin/fs mkalias fs base:/bin/fs
mkalias dev base:/bin/dev mkalias dev base:/bin/dev
mkalias rc base:/bin/rc

View File

@ -19,6 +19,7 @@ size_t hal_strspn(const char *s, const char *accept);
char *hal_strcpy(char *dest, const char *src); char *hal_strcpy(char *dest, const char *src);
char *hal_strchr(const char *s, int c); char *hal_strchr(const char *s, int c);
void hal_wait(uint32_t ms); void hal_wait(uint32_t ms);
int32_t hal_randnum(void);
#define HAL_PAGE_SIZE 0x1000 #define HAL_PAGE_SIZE 0x1000
#include "x86_64/vmm.h" #include "x86_64/vmm.h"

View File

@ -0,0 +1,13 @@
.global hal_randnum
hal_randnum:
mov $100, %ecx
xor %eax, %eax
.retry:
rdrand %eax
jc .done
loop .retry
.fail:
mov $-1, %eax
.done:
ret

View File

@ -3,6 +3,7 @@
#include "uniqid.h" #include "uniqid.h"
#include "atomic.h" #include "atomic.h"
#include "spinlock/spinlock.h" #include "spinlock/spinlock.h"
#include "hal/hal.h"
static const char *base62 = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; static const char *base62 = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
@ -22,6 +23,22 @@ uint32_t uniqmix32(uint32_t x) {
return x; return x;
} }
void uniqseed(void) {
if (uniqstate != 0u)
return;
uint32_t seed = 0;
int32_t r = hal_randnum();
if (r != -1) {
seed = (uint32_t)r;
} else {
uintptr_t p = (uintptr_t)(void *)&uniqstate;
seed = (uint32_t)(p ^ (p>>32)) ^ 0x9E3779B9u;
}
uniqstate = seed ? seed : 1u;
}
void randcrypto_gen_uniqid(char *out, size_t n) { void randcrypto_gen_uniqid(char *out, size_t n) {
if (!out || n == 0) { if (!out || n == 0) {
return; return;
@ -29,14 +46,10 @@ void randcrypto_gen_uniqid(char *out, size_t n) {
spinlock_acquire(&uniqstate_spinlock); spinlock_acquire(&uniqstate_spinlock);
if (uniqstate == 0u) { uniqseed();
uintptr_t p = (uintptr_t)(void *)&uniqstate;
uint32_t seed = (uint32_t)(p ^ (p >> 16)); int32_t r = hal_randnum();
uniqstate = seed ^ 0x9E3779B9u; uint32_t extra = (r != -1) ? (uint32_t)r : uniqstate * 0x27d4eb2dU;
if (uniqstate == 0u) {
uniqstate = 1u;
}
}
uniqstate += 0x9E3779B1u; uniqstate += 0x9E3779B1u;
uint32_t v = uniqmix32(uniqstate); uint32_t v = uniqmix32(uniqstate);
@ -44,7 +57,7 @@ void randcrypto_gen_uniqid(char *out, size_t n) {
spinlock_release(&uniqstate_spinlock); spinlock_release(&uniqstate_spinlock);
for (size_t i = 0; i < n; i++) { for (size_t i = 0; i < n; i++) {
v = uniqmix32(v + i * 0x27d4eb2dU); v = uniqmix32(v + i * 0x85ebca6bU);
out[i] = base62[v % 62u]; out[i] = base62[v % 62u];
} }
out[n] = '\0'; out[n] = '\0';

View File

@ -0,0 +1,8 @@
#include <stdint.h>
#include <stddef.h>
#include "hal/hal.h"
#include "syscall.h"
int32_t SYSCALL0(sys_rand) {
return hal_randnum();
}

View File

@ -0,0 +1,8 @@
#ifndef SYSCALL_RANDCRYPTO_H_
#define SYSCALL_RANDCRYPTO_H_
#include "syscall.h"
int32_t SYSCALL0(sys_rand);
#endif // SYSCALL_RANDCRYPTO_H_

View File

@ -9,6 +9,7 @@
#include "mman.h" #include "mman.h"
#include "sched.h" #include "sched.h"
#include "devctl.h" #include "devctl.h"
#include "randcrypto.h"
int32_t SYSCALL1(sys_debugprint, string) { int32_t SYSCALL1(sys_debugprint, string) {
char *p = (char *)string; char *p = (char *)string;
@ -25,4 +26,5 @@ SyscallFn SYSCALL_TABLE[SYSCALLS_MAX] = {
[SYS_MMAN_UNMAP] = &sys_mman_unmap, [SYS_MMAN_UNMAP] = &sys_mman_unmap,
[SYS_SCHEDRELEASE] = &sys_schedrelease, [SYS_SCHEDRELEASE] = &sys_schedrelease,
[SYS_DEVCTL] = &sys_devctl, [SYS_DEVCTL] = &sys_devctl,
[SYS_RAND] = &sys_rand,
}; };

View File

@ -9,5 +9,6 @@
#define SYS_MMAN_UNMAP 6 #define SYS_MMAN_UNMAP 6
#define SYS_SCHEDRELEASE 7 #define SYS_SCHEDRELEASE 7
#define SYS_DEVCTL 8 #define SYS_DEVCTL 8
#define SYS_RAND 9
#endif // SHARE_HDRS_SYSCALL_H_ #endif // SHARE_HDRS_SYSCALL_H_

View File

@ -39,3 +39,7 @@ int32_t schedrelease(void) {
int32_t devctl(Dev_t *devh, uint64_t cmd, uint8_t *buffer, size_t len, uint64_t extra) { int32_t devctl(Dev_t *devh, uint64_t cmd, uint8_t *buffer, size_t len, uint64_t extra) {
return syscall(SYS_DEVCTL, (uint64_t)devh, cmd, (uint64_t)buffer, (uint64_t)len, (uint64_t)extra, 0); return syscall(SYS_DEVCTL, (uint64_t)devh, cmd, (uint64_t)buffer, (uint64_t)len, (uint64_t)extra, 0);
} }
int32_t rand(void) {
return syscall(SYS_RAND, 0, 0, 0, 0, 0, 0);
}

View File

@ -13,5 +13,6 @@ int32_t mman_map(uint8_t *addr, size_t size, uint64_t prot, uint64_t flags, uint
int32_t mman_unmap(uint8_t *addr); int32_t mman_unmap(uint8_t *addr);
int32_t schedrelease(void); int32_t schedrelease(void);
int32_t devctl(Dev_t *devh, uint64_t cmd, uint8_t *buffer, size_t len, uint64_t extra); int32_t devctl(Dev_t *devh, uint64_t cmd, uint8_t *buffer, size_t len, uint64_t extra);
int32_t rand(void);
#endif // ULIB_SYSTEM_SYSTEM_H_ #endif // ULIB_SYSTEM_SYSTEM_H_

View File

@ -2,6 +2,29 @@
#include <stdint.h> #include <stdint.h>
#include <ulib.h> #include <ulib.h>
struct {
bool plain;
bool names;
bool sizes;
bool types;
bool humsz;
} FS_FETCH_CONFIG = {
.plain = false,
.names = true,
.sizes = true,
.types = true,
.humsz = true,
};
static Arg ARGS[] = {
ARG("-p", ARG_BOOL, &FS_FETCH_CONFIG.plain),
ARG("-n", ARG_BOOL, &FS_FETCH_CONFIG.names),
ARG("-s", ARG_BOOL, &FS_FETCH_CONFIG.sizes),
ARG("-t", ARG_BOOL, &FS_FETCH_CONFIG.types),
ARG("-h", ARG_BOOL, &FS_FETCH_CONFIG.humsz),
ARG_END(),
};
void fs_fetch(void) { void fs_fetch(void) {
if (argslen() < 2) { if (argslen() < 2) {
uprintf("fs: Not enough arguments\n"); uprintf("fs: Not enough arguments\n");
@ -10,6 +33,17 @@ void fs_fetch(void) {
char *path = *(args()+1); char *path = *(args()+1);
int32_t ret;
if ((ret = parse_args(args()+2, argslen()-2, ARGS)) < 0) {
uprintf("fs: could not parse args: %d\n", ret);
return;
}
if (FS_FETCH_CONFIG.plain) {
FS_FETCH_CONFIG.sizes = false;
FS_FETCH_CONFIG.types = false;
}
IoctlStat statbuf; ZERO(&statbuf); IoctlStat statbuf; ZERO(&statbuf);
if (ioctl(IOCTL_NOHANDLE, IOCTL_STAT, (uint64_t)&statbuf, (uint64_t)path, 0) != E_OK) { if (ioctl(IOCTL_NOHANDLE, IOCTL_STAT, (uint64_t)&statbuf, (uint64_t)path, 0) != E_OK) {
uprintf("fs: could not stat %s\n", path); uprintf("fs: could not stat %s\n", path);
@ -43,23 +77,52 @@ void fs_fetch(void) {
ioctl(IOCTL_NOHANDLE, IOCTL_FETCHDIRENT, (uint64_t)path, (uint64_t)&dirents[i], i); ioctl(IOCTL_NOHANDLE, IOCTL_FETCHDIRENT, (uint64_t)path, (uint64_t)&dirents[i], i);
IoctlDirent *dirent = &dirents[i]; IoctlDirent *dirent = &dirents[i];
if (FS_FETCH_CONFIG.names) {
if (dirent->stat.type == IOCTLSTAT_FILE) { if (FS_FETCH_CONFIG.plain) {
char *membuf = umalloc(20); uprintf("%s ", dirent->name);
uprintf("%-30s %-15s %-1s\n", } else {
dirent->name, uprintf("%-30s ", dirent->name);
human_size(dirent->stat.size, membuf, 20), }
"F"
);
ufree(membuf);
} else if (dirent->stat.type == IOCTLSTAT_DIR) {
uprintf("%-30s %-15s %-1s\n",
dirent->name,
"-",
"D"
);
} }
if (FS_FETCH_CONFIG.sizes) {
if (dirent->stat.type == IOCTLSTAT_FILE) {
if (FS_FETCH_CONFIG.humsz) {
char *membuf = umalloc(20);
if (FS_FETCH_CONFIG.plain) {
uprintf("%s ", human_size(dirent->stat.size, membuf, 20));
} else {
uprintf("%-15s ", human_size(dirent->stat.size, membuf, 20));
}
ufree(membuf);
} else {
if (FS_FETCH_CONFIG.plain) {
uprintf("%zu ", dirent->stat.size);
} else {
uprintf("%-15zu ", dirent->stat.size);
}
}
} else if (dirent->stat.type == IOCTLSTAT_DIR) {
if (FS_FETCH_CONFIG.plain) {
uprintf("- ");
} else {
uprintf("%-15c ", '-');
}
}
}
if (FS_FETCH_CONFIG.types) {
if (dirent->stat.type == IOCTLSTAT_FILE) {
uprintf("%c ", 'F');
} else if (dirent->stat.type == IOCTLSTAT_DIR) {
uprintf("%c ", 'D');
}
}
uprintf("\n");
} }
ufree(dirents); ufree(dirents);

2
user/rc/.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
*.o
rc

24
user/rc/Makefile Normal file
View File

@ -0,0 +1,24 @@
include $(ROOT)/mk/grabsrc.mk
include ../Makefile.inc
.PHONY: all clean
TARGET := rc
LDFLAGS += -L$(ROOT)/ulib -l:libulib.a
SRCFILES := $(call GRABSRC, .)
CFILES := $(call GET_CFILES, $(SRCFILES))
OBJ := $(call GET_OBJ, $(SRCFILES))
%.o: %.c
$(CC) $(CFLAGS) -c $< -o $@
all: $(TARGET)
$(TARGET): $(OBJ)
$(LD) $^ $(LDFLAGS) -o $@
echo $$(realpath $(TARGET)) >> $(FILES)
clean:
rm -f $(OBJ) $(TARGET)

24
user/rc/main.c Normal file
View File

@ -0,0 +1,24 @@
#include <stdint.h>
#include <stddef.h>
#include <ulib.h>
#define CMDS(X) \
X(rr) \
void main(void) {
if (argslen() == 0) {
return;
}
char *cmd = args()[0];
#define X(name) if (string_strcmp(cmd, #name) == 0) { \
extern void rc_ ## name(void); \
rc_ ## name(); \
return; \
}
CMDS(X)
#undef X
uprintf("rc: unknown command %s\n", cmd);
}

50
user/rc/rr.c Normal file
View File

@ -0,0 +1,50 @@
#include <stddef.h>
#include <stdint.h>
#include <ulib.h>
int32_t rr(int32_t min, int32_t max) {
if (max <= min)
return min;
uint32_t range = (uint32_t)(max - min + 1);
uint32_t val;
int32_t rnd;
for (size_t i = 0; i < 10; i++) {
rnd = rand();
if (rnd == -1)
continue;
val = (uint32_t)rnd;
uint32_t limit = (uint32_t)(-range) % range;
if (val >= limit) {
return min + (val % range);
}
}
return -1;
}
void rc_rr(void) {
if (argslen() < 3) {
uprintf("rc: Not enough arguments\n");
return;
}
char *beginstr = *(args()+1);
char *endstr = *(args()+2);
char *endb;
long begin = string_conv_strtol(beginstr, &endb, 10);
char *ende;
long end = string_conv_strtol(endstr, &ende, 10);
int32_t r = rr(begin, end);
if (r == -1) {
uprintf("rc: failed to generate random number in range\n");
return;
}
uprintf("%d\n", r);
}