VirtualBox

source: vbox/trunk/src/VBox/Runtime/r3/posix/rand-posix.cpp

Last change on this file was 98103, checked in by vboxsync, 17 months ago

Copyright year updates by scm.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id Revision
File size: 4.7 KB
RevLine 
[1]1/* $Id: rand-posix.cpp 98103 2023-01-17 14:15:46Z vboxsync $ */
2/** @file
[8245]3 * IPRT - Random Numbers and Byte Streams, POSIX.
[1]4 */
5
6/*
[98103]7 * Copyright (C) 2006-2023 Oracle and/or its affiliates.
[1]8 *
[96407]9 * This file is part of VirtualBox base platform packages, as
10 * available from https://www.virtualbox.org.
[5999]11 *
[96407]12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation, in version 3 of the
15 * License.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, see <https://www.gnu.org/licenses>.
24 *
[5999]25 * The contents of this file may alternatively be used under the terms
26 * of the Common Development and Distribution License Version 1.0
[96407]27 * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included
28 * in the VirtualBox distribution, in which case the provisions of the
[5999]29 * CDDL are applicable instead of those of the GPL.
30 *
31 * You may elect to license modified versions of this file under the
32 * terms and conditions of either the GPL or the CDDL or both.
[96407]33 *
34 * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0
[1]35 */
36
37
[57358]38/*********************************************************************************************************************************
39* Header Files *
40*********************************************************************************************************************************/
[1]41#include <errno.h>
42#include <sys/stat.h>
43#include <sys/types.h>
44#include <sys/ioctl.h>
45#include <fcntl.h>
46#ifdef _MSC_VER
47# include <io.h>
48# include <stdio.h>
49#else
50# include <unistd.h>
51# include <sys/time.h>
52#endif
53
[891]54#include <iprt/rand.h>
[11523]55#include <iprt/mem.h>
[76452]56#include <iprt/errcore.h>
[1]57#include <iprt/assert.h>
[891]58#include "internal/rand.h"
[11523]59#include "internal/magics.h"
[1]60
61
62
[11523]63/** @copydoc RTRANDINT::pfnGetBytes */
64static DECLCALLBACK(void) rtRandAdvPosixGetBytes(PRTRANDINT pThis, uint8_t *pb, size_t cb)
[1]65{
[11523]66 ssize_t cbRead = read(pThis->u.File.hFile, pb, cb);
67 if ((size_t)cbRead != cb)
[1]68 {
[45263]69 /* S10 has been observed returning 1040 bytes at the time from /dev/urandom.
70 Which means we need to do than 256 rounds to reach 668171 bytes if
71 that's what demanded by the caller (like tstRTMemWipe.cpp). */
72 ssize_t cTries = RT_MAX(256, cb / 64);
[11523]73 do
74 {
75 if (cbRead > 0)
76 {
77 cb -= cbRead;
78 pb += cbRead;
79 }
80 cbRead = read(pThis->u.File.hFile, pb, cb);
81 } while ( (size_t)cbRead != cb
82 && cTries-- > 0);
83 AssertReleaseMsg((size_t)cbRead == cb, ("%zu != %zu, cTries=%zd errno=%d\n", cbRead, cb, cTries, errno));
[1]84 }
85}
86
87
[11523]88/** @copydoc RTRANDINT::pfnDestroy */
89static DECLCALLBACK(int) rtRandAdvPosixDestroy(PRTRANDINT pThis)
[1]90{
[11523]91 pThis->u32Magic = ~RTRANDINT_MAGIC;
92 int fd = pThis->u.File.hFile;
[37596]93 pThis->u.File.hFile = -1;
[11523]94 RTMemFree(pThis);
95 close(fd);
96 return VINF_SUCCESS;
97}
[1]98
[11523]99
[57432]100static int rtRandAdvPosixCreateSystem(PRTRAND phRand, const char *pszDev) RT_NO_THROW_DEF
[11523]101{
102 /*
103 * Try open it first and then setup the handle structure.
104 */
105 int fd = open(pszDev, O_RDONLY);
106 if (fd < 0)
107 return RTErrConvertFromErrno(errno);
108 int rc;
109 if (fcntl(fd, F_SETFD, FD_CLOEXEC) != -1)
[1]110 {
[11523]111 PRTRANDINT pThis = (PRTRANDINT)RTMemAlloc(sizeof(*pThis));
112 if (pThis)
[1]113 {
[11523]114 pThis->u32Magic = RTRANDINT_MAGIC;
115 pThis->pfnGetBytes = rtRandAdvPosixGetBytes;
116 pThis->pfnGetU32 = rtRandAdvSynthesizeU32FromBytes;
117 pThis->pfnGetU64 = rtRandAdvSynthesizeU64FromBytes;
118 pThis->pfnSeed = rtRandAdvStubSeed;
119 pThis->pfnSaveState = rtRandAdvStubSaveState;
120 pThis->pfnRestoreState = rtRandAdvStubRestoreState;
121 pThis->pfnDestroy = rtRandAdvPosixDestroy;
122 pThis->u.File.hFile = fd;
123
124 *phRand = pThis;
125 return VINF_SUCCESS;
[1]126 }
[11523]127
128 /* bail out */
129 rc = VERR_NO_MEMORY;
[1]130 }
[11523]131 else
132 rc = RTErrConvertFromErrno(errno);
133 close(fd);
134 return rc;
[1]135}
136
[11523]137
[57432]138RTDECL(int) RTRandAdvCreateSystemFaster(PRTRAND phRand) RT_NO_THROW_DEF
[11523]139{
[11557]140 return rtRandAdvPosixCreateSystem(phRand, "/dev/urandom");
[11523]141}
142
143
[57432]144RTDECL(int) RTRandAdvCreateSystemTruer(PRTRAND phRand) RT_NO_THROW_DEF
[11523]145{
[11557]146 return rtRandAdvPosixCreateSystem(phRand, "/dev/random");
[11523]147}
148
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use