1.\" $NetBSD: rnd.9,v 1.30 2022/03/19 11:54:53 riastradh Exp $ 2.\" 3.\" Copyright (c) 1997 The NetBSD Foundation, Inc. 4.\" All rights reserved. 5.\" 6.\" This documentation is derived from text contributed to The NetBSD 7.\" Foundation by S.P.Zeidler (aka stargazer). 8.\" 9.\" Redistribution and use in source and binary forms, with or without 10.\" modification, are permitted provided that the following conditions 11.\" are met: 12.\" 1. Redistributions of source code must retain the above copyright 13.\" notice, this list of conditions and the following disclaimer. 14.\" 2. Redistributions in binary form must reproduce the above copyright 15.\" notice, this list of conditions and the following disclaimer in the 16.\" documentation and/or other materials provided with the distribution. 17.\" 18.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 19.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 20.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 21.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 22.\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28.\" POSSIBILITY OF SUCH DAMAGE. 29.\" 30.Dd April 25, 2020 31.Dt RND 9 32.Os 33.Sh NAME 34.Nm RND , 35.Nm rnd_attach_source , 36.Nm rnd_detach_source , 37.Nm rnd_add_data , 38.Nm rnd_add_data_sync , 39.Nm rnd_add_uint32 40.Nd functions to make a device available for entropy collection 41.Sh SYNOPSIS 42.In sys/rndsource.h 43.Vt typedef struct krndsource krndsource_t; 44.Ft void 45.Fn rndsource_setcb "krndsource_t *rnd_source" "void (*callback)(size_t, void *)" "void *cookie" 46.Ft void 47.Fn rnd_attach_source "krndsource_t *rnd_source" "char *devname" "uint32_t source_type" "uint32_t flags" 48.Ft void 49.Fn rnd_detach_source "krndsource_t *rnd_source" 50.Ft void 51.Fn rnd_add_data "krndsource_t *rnd_source" "void *data" "uint32_t len" "uint32_t entropy" 52.Ft void 53.Fn rnd_add_data_sync "krndsource_t *rnd_source" "void *data" "uint32_t len" "uint32_t entropy" 54.Ft void 55.Fn rnd_add_uint32 "krndsource_t *rnd_source" "uint32_t datum" 56.Sh DESCRIPTION 57The 58.Nm 59functions enable drivers to collect samples of physical observations, 60such as network packet timings or hardware random number generator 61outputs, into a kernel entropy pool to derive key material for 62.Xr cprng 9 63and 64.Xr rnd 4 65.Pq Pa /dev/random , Pa /dev/urandom . 66.Pp 67Usage model: 68.Bl -enum -compact 69.It 70Allocate and zero a 71.Vt struct krndsource 72object before using the 73.Nm 74functions. 75.It 76Optionally, set a callback with 77.Fn rndsource_setcb 78if appropriate, e.g. for an on-demand hardware random number 79generator. 80.It 81Attach the random source with 82.Fn rnd_attach_source . 83.It 84Enter data with 85.Fn rnd_add_data 86or 87.Fn rnd_add_uint32 , 88or, if in the callback, 89.Fn rnd_add_data_sync . 90.It 91When the driver is done, detach it with 92.Fn rnd_detach_source . 93.El 94.Pp 95The following types of random sources are defined: 96.Bl -tag -width "Dv RND_TYPE_UNKNOWN" -compact 97.It Dv RND_TYPE_DISK 98Disk devices, typically sampling seek timings. 99.It Dv RND_TYPE_ENV 100Environmental sensors. 101.It Dv RND_TYPE_POWER 102Power sensors and timing of power-related events. 103.It Dv RND_TYPE_NET 104Network interfaces, typically sampling packet timings. 105By default, sample from network interfaces are ignored, for hysterical 106raisins. 107.It Dv RND_TYPE_RNG 108Hardware random number generators. 109.It Dv RND_TYPE_SKEW 110Skew between clocks. 111.It Dv RND_TYPE_TAPE 112Tape devices, typically sampling I/O timings. 113.It Dv RND_TYPE_TTY 114Tty devices, typically sampling interrupt timings. 115.It Dv RND_TYPE_VM 116Virtual memory fault timings. 117.It Dv RND_TYPE_UNKNOWN 118Unknown sources, or sources not otherwise classified. 119.El 120.Sh FUNCTIONS 121.Bl -tag -width abcd 122.It Fn rndsource_setcb "rnd_source" "callback" "cookie" 123Sets a callback to be invoked when the entropy pool is hungry 124to draw data from this source on demand. 125Optional; if used, must be used 126.Em before 127.Fn rnd_attach_source , 128and the caller must pass 129.Dv RND_FLAG_HASCB 130to 131.Fn rnd_attach_source . 132.Pp 133The callback is invoked as 134.Fo callback 135.Fa nbytes 136.Fa cookie 137.Fc , 138where 139.Fa nbytes 140is the number of bytes requested for the entropy pool, and 141.Fa cookie 142is the cookie that was passed to 143.Fn rndsource_setcb . 144The callback normally does one of two things: 145.Bl -dash 146.It 147Sends a request to a hardware device for entropy and returns. 148The hardware will later return data asynchronously by an interrupt, and 149the callback will use 150.Fn rnd_add_data 151or 152.Fn rnd_add_uint32 153to add the data to the pool. 154.It 155Synchronously gathers entropy from hardware \(em for example, by a CPU 156instruction like Intel RDSEED. 157In this case, in order to add data to the pool 158.Em before 159returning, the callback 160.Em must 161use 162.Fn rnd_add_data_sync , 163not 164.Fn rnd_add_data 165or 166.Fn rnd_add_uint32 . 167.El 168.Pp 169.Nm 170issues calls to each source's 171.Fa callback 172in serial \(em it never issues two calls to the same source's callback 173at the same time in two differen threads or on two different CPUs. 174.It Fn rnd_attach_source "rnd_source" "devname" "type" "flags" 175Makes 176.Fa rnd_source 177available for entropy collection. 178Must be called 179.Em before 180the source struct pointed to by 181.Fa rnd_source 182is used in any of the following functions. 183If a callback was specified with 184.Fn rndsource_setcb , 185the kernel may invoke it at any time after 186.Fn rnd_attach_source 187until 188.Fn rnd_detach_source , 189so the callback must be ready to be invoked 190.Em before 191calling 192.Fn rnd_attach_source . 193.Pp 194The 195.Fa devname 196is exposed via 197.Xr rnd 4 198and 199.Xr rndctl 8 . 200The 201.Fa type 202must be one of the 203.Dv RND_TYPE_* 204constants above. 205The 206.Fa flags 207are the bitwise-or of any of the following constants: 208.Bl -tag -width abcd 209.It Dv RND_FLAG_HASCB 210The random source has a callback, which must have been set with 211.Fn rndsource_setcb . 212.It Dv RND_FLAG_COLLECT_TIME 213Enter the timing of each 214.Fn rnd_add_* 215call into the entropy pool. 216If not set, at most only the data arguments to 217.Fn rnd_add_* 218will be entered. 219.It Dv RND_FLAG_COLLECT_VALUE 220Enter the data arguments passed to the 221.Fn rnd_add_* 222functions into the pool. 223If not set, the data will be ignored; at most the timing of the sample 224will be entered. 225.It Dv RND_FLAG_DEFAULT 226Equivalent to 227.Dv RND_FLAG_COLLECT_TIME | RND_FLAG_COLLECT_VALUE . 228.It Dv RND_FLAG_ESTIMATE_TIME , RND_FLAG_ESTIMATE_VALUE 229Legacy options no longer used. 230.El 231.It Fn rnd_detach_source "rnd_source" 232Disconnects 233.Fa rnd_source 234from entropy collection. 235The kernel will cease to invoke the callback, if any, and the caller 236must not use 237.Fa rnd_source 238with any of the 239.Fn rnd_add_* 240functions after 241.Fn rnd_detach_source . 242The caller may release the memory for 243.Fa rnd_source 244afterward. 245.It Fn rnd_add_data "rnd_source" "data" "len" "entropy" 246Enters 247.Fa len 248bytes at 249.Fa data 250into the entropy pool, if 251.Dv RND_FLAG_COLLECT_VALUE 252was specified for 253.Fa rnd_source , 254and a timestamp, if 255.Dv RND_FLAG_COLLECT_TIME 256was specified. 257.Pp 258The argument 259.Fa entropy 260provides a conservative estimate for the number of bits of entropy in 261the 262.Em physical process 263that generated the data, given all the past samples. 264Drivers for devices for which this is not known should pass zero; 265typically only drivers for hardware random number generators pass 266nonzero values. 267Hardware random number generator drivers should perform on-line 268self-tests before advertising nonzero entropy for samples. 269.Pp 270.Fn rnd_add_data 271.Em must not 272be used during a callback as set with 273.Fn rndsource_setcb ; 274use 275.Fn rnd_add_data_sync 276instead. 277.It Fn rnd_add_data_sync "rnd_source" "data" "len" "entropy" 278Like 279.Fn rnd_add_data , 280but may be used in a callback as set with 281.Fn rndsource_setcb . 282.It Fn rnd_add_uint32 "rnd_source" "datum" 283Equivalent to 284.Li rnd_add_data Ns ( Ns Fa rnd_source , Li & Ns Fa datum , Li 4 , 0 ) . 285.Pp 286.Fn rnd_add_uint32 287.Em must not 288be used during a callback as set with 289.Fn rndsource_setcb ; 290use 291.Fn rnd_add_data_sync 292instead. 293.El 294.Sh FILES 295These functions are declared in src/sys/sys/rndsource.h and defined in 296src/sys/kern/kern_entropy.c. 297.Sh EXAMPLES 298.Bd -literal 299struct xyz_softc { 300 ... 301 struct krndsource sc_rndsource; 302}; 303 304static void 305xyz_attach(device_t parent, device_t self, void *aux) 306{ 307 struct xyz_softc *sc = device_private(self); 308 ... 309 rndsource_setcb(&sc->sc_rndsource, xyz_get, sc); 310 rnd_attach_source(&sc->sc_rndsource, device_xname(self), 311 RND_TYPE_RNG, RND_FLAG_DEFAULT); 312} 313 314static int 315xyz_detach(device_t self, int flags) 316{ 317 ... 318 rnd_detach_source(&sc->sc_rndsource); 319 ... 320 return 0; 321} 322 323static void 324xyz_get(size_t nbytes, void *cookie) 325{ 326 struct xyz_softc *sc = cookie; 327 uint32_t v; 328 unsigned timo = 10; 329 330 while (nbytes) { 331 while (bus_space_read_4(sc->sc_bst, sc->sc_bsh, 332 XYZ_RNGREADY) == 0) { 333 if (--timo == 0) 334 return; 335 DELAY(10); 336 } 337 v = bus_space_read_4(sc->sc_bst, sc->sc_bsh, 338 XYZ_RNGDATUM); 339 /* data sheet sez 18 bits entropy in 32-bit sample */ 340 rnd_add_data_sync(&sc->sc_rndsource, &v, sizeof v, 18); 341 nbytes -= 18/NBBY; 342 } 343} 344 345static void 346xyz_intr(void *cookie) 347{ 348 struct xyz_softc *sc = cookie; 349 uint32_t isr; 350 351 isr = bus_space_read_4(sc->sc_bst, sc->sc_bsh, XYZ_ISR); 352 bus_space_write_4(sc->sc_bst, sc->sc_bsh, XYZ_ISR, isr); 353 rnd_add_uint32(&sc->sc_rndsource, isr); 354 ... 355} 356.Ed 357.Sh SEE ALSO 358.Xr rnd 4 , 359.Xr rndctl 8 , 360.Xr cprng 9 361.Sh HISTORY 362The random device was introduced in 363.Nx 1.3 . 364It was substantially rewritten in 365.Nx 6.0 , 366and again in 367.Nx 10.0 . 368.Sh AUTHORS 369This implementation was written by 370.An Taylor R Campbell Aq Mt riastradh@NetBSD.org . 371