1// SPDX-License-Identifier: GPL-2.0-or-later 2/* 3 * Copyright (C) 2015 Cedric Hnyda <ced.hnyda@gmail.com> 4 * 5 * Calls getrandom(2), checks that the buffer is filled with random bytes 6 * and expects success. 7 */ 8 9#include "tst_test.h" 10#include "lapi/getrandom.h" 11#include "lapi/syscalls.h" 12 13#define PROC_ENTROPY_AVAIL "/proc/sys/kernel/random/entropy_avail" 14 15static int modes[] = { 0, GRND_RANDOM, GRND_NONBLOCK, 16 GRND_RANDOM | GRND_NONBLOCK }; 17 18static int check_content(unsigned char *buf, int nb) 19{ 20 int table[256]; 21 int i, index, max; 22 23 memset(table, 0, sizeof(table)); 24 25 max = 6 + nb * 0.2; 26 27 for (i = 0; i < nb; i++) { 28 index = buf[i]; 29 table[index]++; 30 } 31 32 for (i = 0; i < nb; i++) { 33 if (max > 0 && table[i] > max) 34 return 0; 35 } 36 return 1; 37} 38 39static void verify_getrandom(unsigned int n) 40{ 41 unsigned char buf[256]; 42 int bufsize = 64, entropy_avail; 43 44 if (access(PROC_ENTROPY_AVAIL, F_OK) == 0) { 45 SAFE_FILE_SCANF(PROC_ENTROPY_AVAIL, "%d", &entropy_avail); 46 if (entropy_avail > 256) 47 bufsize = sizeof(buf); 48 } 49 50 memset(buf, 0, sizeof(buf)); 51 do { 52 TEST(tst_syscall(__NR_getrandom, buf, bufsize, modes[n])); 53 } while ((modes[n] & GRND_NONBLOCK) && TST_RET == -1 54 && TST_ERR == EAGAIN); 55 56 if (!check_content(buf, TST_RET)) 57 tst_res(TFAIL | TTERRNO, "getrandom failed"); 58 else 59 tst_res(TPASS, "getrandom returned %ld", TST_RET); 60} 61 62static struct tst_test test = { 63 .tcnt = ARRAY_SIZE(modes), 64 .test = verify_getrandom, 65}; 66