DF-0220 / rand_probe.c
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 | /* * DF-0220 RNG predictability probe. * * Reads bytes from every kernel RNG interface that the finding claims is * vulnerable, plus records the uptime at read time so we can correlate * "before first reseed" vs "after". * * - /dev/urandom (read_random unlimited, CSPRNG_UNLIMITED) * - /dev/random (blocking variant) * - getrandom(2) (sys_getrandom -> read_random unlimited) * - kern.random (sysctl -> read_random unlimited) * * All outputs are printed as lowercase hex so they can be compared byte for * byte across independent boots. * * Build: cc -O2 -o rand_probe rand_probe.c * Run: ./rand_probe */ #include <sys/types.h> #include <sys/sysctl.h> #include <sys/time.h> #include <sys/random.h> #include <fcntl.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <time.h> #define N 64 static void hexdump(const char *label, const unsigned char *buf, int len) { int i; printf("%s (%d bytes):", label, len); for (i = 0; i < len; i++) { if (i % 16 == 0) printf("\n %04x:", i); printf(" %02x", buf[i]); } printf("\n"); } static double uptime_sec(void) { struct timespec ts; if (clock_gettime(CLOCK_UPTIME, &ts) == 0) return ts.tv_sec + ts.tv_nsec / 1e9; struct timeval bt; size_t sz = sizeof(bt); if (sysctlbyname("kern.boottime", &bt, &sz, NULL, 0) == 0) { struct timeval now; gettimeofday(&now, NULL); return (now.tv_sec - bt.tv_sec) + (now.tv_usec - bt.tv_usec) / 1e6; } return -1.0; } int main(void) { unsigned char buf[N]; ssize_t r; int fd; printf("uptime_at_read = %.6f sec\n", uptime_sec()); /* /dev/urandom */ fd = open("/dev/urandom", O_RDONLY); if (fd < 0) { perror("open /dev/urandom"); } else { r = read(fd, buf, N); if (r < 0) perror("read urandom"); else hexdump("/dev/urandom", buf, (int)r); close(fd); } /* /dev/random */ fd = open("/dev/random", O_RDONLY); if (fd < 0) { perror("open /dev/random"); } else { r = read(fd, buf, N); if (r < 0) perror("read random"); else hexdump("/dev/random", buf, (int)r); close(fd); } /* getrandom(2) syscall via libc */ memset(buf, 0xaa, N); r = getrandom(buf, N, 0); if (r < 0) perror("getrandom"); else hexdump("getrandom(2)", buf, (int)r); /* kern.random sysctl */ { size_t sz = N; memset(buf, 0x55, N); if (sysctlbyname("kern.random", buf, &sz, NULL, 0) < 0) perror("sysctl kern.random"); else hexdump("kern.random sysctl", buf, (int)sz); } return 0; } |