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