VirtualBox

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

Last change on this file was 98103, checked in by vboxsync, 16 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
Line 
1/* $Id: rand-posix.cpp 98103 2023-01-17 14:15:46Z vboxsync $ */
2/** @file
3 * IPRT - Random Numbers and Byte Streams, POSIX.
4 */
5
6/*
7 * Copyright (C) 2006-2023 Oracle and/or its affiliates.
8 *
9 * This file is part of VirtualBox base platform packages, as
10 * available from https://www.virtualbox.org.
11 *
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 *
25 * The contents of this file may alternatively be used under the terms
26 * of the Common Development and Distribution License Version 1.0
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
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.
33 *
34 * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0
35 */
36
37
38/*********************************************************************************************************************************
39* Header Files *
40*********************************************************************************************************************************/
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
54#include <iprt/rand.h>
55#include <iprt/mem.h>
56#include <iprt/errcore.h>
57#include <iprt/assert.h>
58#include "internal/rand.h"
59#include "internal/magics.h"
60
61
62
63/** @copydoc RTRANDINT::pfnGetBytes */
64static DECLCALLBACK(void) rtRandAdvPosixGetBytes(PRTRANDINT pThis, uint8_t *pb, size_t cb)
65{
66 ssize_t cbRead = read(pThis->u.File.hFile, pb, cb);
67 if ((size_t)cbRead != cb)
68 {
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);
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));
84 }
85}
86
87
88/** @copydoc RTRANDINT::pfnDestroy */
89static DECLCALLBACK(int) rtRandAdvPosixDestroy(PRTRANDINT pThis)
90{
91 pThis->u32Magic = ~RTRANDINT_MAGIC;
92 int fd = pThis->u.File.hFile;
93 pThis->u.File.hFile = -1;
94 RTMemFree(pThis);
95 close(fd);
96 return VINF_SUCCESS;
97}
98
99
100static int rtRandAdvPosixCreateSystem(PRTRAND phRand, const char *pszDev) RT_NO_THROW_DEF
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)
110 {
111 PRTRANDINT pThis = (PRTRANDINT)RTMemAlloc(sizeof(*pThis));
112 if (pThis)
113 {
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;
126 }
127
128 /* bail out */
129 rc = VERR_NO_MEMORY;
130 }
131 else
132 rc = RTErrConvertFromErrno(errno);
133 close(fd);
134 return rc;
135}
136
137
138RTDECL(int) RTRandAdvCreateSystemFaster(PRTRAND phRand) RT_NO_THROW_DEF
139{
140 return rtRandAdvPosixCreateSystem(phRand, "/dev/urandom");
141}
142
143
144RTDECL(int) RTRandAdvCreateSystemTruer(PRTRAND phRand) RT_NO_THROW_DEF
145{
146 return rtRandAdvPosixCreateSystem(phRand, "/dev/random");
147}
148
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use