11cb0ef41Sopenharmony_ci/* Copyright libuv contributors. All rights reserved. 21cb0ef41Sopenharmony_ci * 31cb0ef41Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a copy 41cb0ef41Sopenharmony_ci * of this software and associated documentation files (the "Software"), to 51cb0ef41Sopenharmony_ci * deal in the Software without restriction, including without limitation the 61cb0ef41Sopenharmony_ci * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 71cb0ef41Sopenharmony_ci * sell copies of the Software, and to permit persons to whom the Software is 81cb0ef41Sopenharmony_ci * furnished to do so, subject to the following conditions: 91cb0ef41Sopenharmony_ci * 101cb0ef41Sopenharmony_ci * The above copyright notice and this permission notice shall be included in 111cb0ef41Sopenharmony_ci * all copies or substantial portions of the Software. 121cb0ef41Sopenharmony_ci * 131cb0ef41Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 141cb0ef41Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 151cb0ef41Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 161cb0ef41Sopenharmony_ci * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 171cb0ef41Sopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 181cb0ef41Sopenharmony_ci * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 191cb0ef41Sopenharmony_ci * IN THE SOFTWARE. 201cb0ef41Sopenharmony_ci */ 211cb0ef41Sopenharmony_ci 221cb0ef41Sopenharmony_ci#include "uv.h" 231cb0ef41Sopenharmony_ci#include "uv-common.h" 241cb0ef41Sopenharmony_ci 251cb0ef41Sopenharmony_ci#ifdef _WIN32 261cb0ef41Sopenharmony_ci# include "win/internal.h" 271cb0ef41Sopenharmony_ci#else 281cb0ef41Sopenharmony_ci# include "unix/internal.h" 291cb0ef41Sopenharmony_ci#endif 301cb0ef41Sopenharmony_ci 311cb0ef41Sopenharmony_cistatic int uv__random(void* buf, size_t buflen) { 321cb0ef41Sopenharmony_ci int rc; 331cb0ef41Sopenharmony_ci 341cb0ef41Sopenharmony_ci#if defined(__PASE__) 351cb0ef41Sopenharmony_ci rc = uv__random_readpath("/dev/urandom", buf, buflen); 361cb0ef41Sopenharmony_ci#elif defined(_AIX) || defined(__QNX__) 371cb0ef41Sopenharmony_ci rc = uv__random_readpath("/dev/random", buf, buflen); 381cb0ef41Sopenharmony_ci#elif defined(__APPLE__) || defined(__OpenBSD__) || \ 391cb0ef41Sopenharmony_ci (defined(__ANDROID_API__) && __ANDROID_API__ >= 28) 401cb0ef41Sopenharmony_ci rc = uv__random_getentropy(buf, buflen); 411cb0ef41Sopenharmony_ci if (rc == UV_ENOSYS) 421cb0ef41Sopenharmony_ci rc = uv__random_devurandom(buf, buflen); 431cb0ef41Sopenharmony_ci#elif defined(__NetBSD__) 441cb0ef41Sopenharmony_ci rc = uv__random_sysctl(buf, buflen); 451cb0ef41Sopenharmony_ci#elif defined(__FreeBSD__) || defined(__linux__) 461cb0ef41Sopenharmony_ci rc = uv__random_getrandom(buf, buflen); 471cb0ef41Sopenharmony_ci if (rc == UV_ENOSYS) 481cb0ef41Sopenharmony_ci rc = uv__random_devurandom(buf, buflen); 491cb0ef41Sopenharmony_ci# if defined(__linux__) 501cb0ef41Sopenharmony_ci switch (rc) { 511cb0ef41Sopenharmony_ci case UV_EACCES: 521cb0ef41Sopenharmony_ci case UV_EIO: 531cb0ef41Sopenharmony_ci case UV_ELOOP: 541cb0ef41Sopenharmony_ci case UV_EMFILE: 551cb0ef41Sopenharmony_ci case UV_ENFILE: 561cb0ef41Sopenharmony_ci case UV_ENOENT: 571cb0ef41Sopenharmony_ci case UV_EPERM: 581cb0ef41Sopenharmony_ci rc = uv__random_sysctl(buf, buflen); 591cb0ef41Sopenharmony_ci break; 601cb0ef41Sopenharmony_ci } 611cb0ef41Sopenharmony_ci# endif 621cb0ef41Sopenharmony_ci#elif defined(_WIN32) 631cb0ef41Sopenharmony_ci uv__once_init(); 641cb0ef41Sopenharmony_ci rc = uv__random_rtlgenrandom(buf, buflen); 651cb0ef41Sopenharmony_ci#else 661cb0ef41Sopenharmony_ci rc = uv__random_devurandom(buf, buflen); 671cb0ef41Sopenharmony_ci#endif 681cb0ef41Sopenharmony_ci 691cb0ef41Sopenharmony_ci return rc; 701cb0ef41Sopenharmony_ci} 711cb0ef41Sopenharmony_ci 721cb0ef41Sopenharmony_ci 731cb0ef41Sopenharmony_cistatic void uv__random_work(struct uv__work* w) { 741cb0ef41Sopenharmony_ci uv_random_t* req; 751cb0ef41Sopenharmony_ci 761cb0ef41Sopenharmony_ci req = container_of(w, uv_random_t, work_req); 771cb0ef41Sopenharmony_ci req->status = uv__random(req->buf, req->buflen); 781cb0ef41Sopenharmony_ci} 791cb0ef41Sopenharmony_ci 801cb0ef41Sopenharmony_ci 811cb0ef41Sopenharmony_cistatic void uv__random_done(struct uv__work* w, int status) { 821cb0ef41Sopenharmony_ci uv_random_t* req; 831cb0ef41Sopenharmony_ci 841cb0ef41Sopenharmony_ci req = container_of(w, uv_random_t, work_req); 851cb0ef41Sopenharmony_ci uv__req_unregister(req->loop, req); 861cb0ef41Sopenharmony_ci 871cb0ef41Sopenharmony_ci if (status == 0) 881cb0ef41Sopenharmony_ci status = req->status; 891cb0ef41Sopenharmony_ci 901cb0ef41Sopenharmony_ci req->cb(req, status, req->buf, req->buflen); 911cb0ef41Sopenharmony_ci} 921cb0ef41Sopenharmony_ci 931cb0ef41Sopenharmony_ci 941cb0ef41Sopenharmony_ciint uv_random(uv_loop_t* loop, 951cb0ef41Sopenharmony_ci uv_random_t* req, 961cb0ef41Sopenharmony_ci void *buf, 971cb0ef41Sopenharmony_ci size_t buflen, 981cb0ef41Sopenharmony_ci unsigned flags, 991cb0ef41Sopenharmony_ci uv_random_cb cb) { 1001cb0ef41Sopenharmony_ci if (buflen > 0x7FFFFFFFu) 1011cb0ef41Sopenharmony_ci return UV_E2BIG; 1021cb0ef41Sopenharmony_ci 1031cb0ef41Sopenharmony_ci if (flags != 0) 1041cb0ef41Sopenharmony_ci return UV_EINVAL; 1051cb0ef41Sopenharmony_ci 1061cb0ef41Sopenharmony_ci if (cb == NULL) 1071cb0ef41Sopenharmony_ci return uv__random(buf, buflen); 1081cb0ef41Sopenharmony_ci 1091cb0ef41Sopenharmony_ci uv__req_init(loop, req, UV_RANDOM); 1101cb0ef41Sopenharmony_ci req->loop = loop; 1111cb0ef41Sopenharmony_ci req->status = 0; 1121cb0ef41Sopenharmony_ci req->cb = cb; 1131cb0ef41Sopenharmony_ci req->buf = buf; 1141cb0ef41Sopenharmony_ci req->buflen = buflen; 1151cb0ef41Sopenharmony_ci 1161cb0ef41Sopenharmony_ci uv__work_submit(loop, 1171cb0ef41Sopenharmony_ci &req->work_req, 1181cb0ef41Sopenharmony_ci UV__WORK_CPU, 1191cb0ef41Sopenharmony_ci uv__random_work, 1201cb0ef41Sopenharmony_ci uv__random_done); 1211cb0ef41Sopenharmony_ci 1221cb0ef41Sopenharmony_ci return 0; 1231cb0ef41Sopenharmony_ci} 124