Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 22 Jul 2015 11:42:13 -1000 (HST)
From:      Jeff Roberson <jroberson@jroberson.net>
To:        Mark Murray <markm@FreeBSD.org>
Cc:        src-committers@freebsd.org, svn-src-all@freebsd.org,  svn-src-head@freebsd.org
Subject:   Re: svn commit: r284959 - in head: . share/man/man4 share/man/man9 sys/conf sys/dev/glxsb sys/dev/hifn sys/dev/random sys/dev/rndtest sys/dev/safe sys/dev/syscons sys/dev/ubsec sys/dev/virtio/random sy...
Message-ID:  <alpine.BSF.2.20.1507221138360.1071@desktop>
In-Reply-To: <201506301700.t5UH0jPq001498@svn.freebsd.org>
References:  <201506301700.t5UH0jPq001498@svn.freebsd.org>

next in thread | previous in thread | raw e-mail | index | archive | help
On Tue, 30 Jun 2015, Mark Murray wrote:

> Author: markm
> Date: Tue Jun 30 17:00:45 2015
> New Revision: 284959
> URL: https://svnweb.freebsd.org/changeset/base/284959
>
> Log:
>  Huge cleanup of random(4) code.
>
>  * GENERAL
>  - Update copyright.
>  - Make kernel options for RANDOM_YARROW and RANDOM_DUMMY. Set
>    neither to ON, which means we want Fortuna
>  - If there is no 'device random' in the kernel, there will be NO
>    random(4) device in the kernel, and the KERN_ARND sysctl will
>    return nothing. With RANDOM_DUMMY there will be a random(4) that
>    always blocks.
>  - Repair kern.arandom (KERN_ARND sysctl). The old version went
>    through arc4random(9) and was a bit weird.
>  - Adjust arc4random stirring a bit - the existing code looks a little
>    suspect.
>  - Fix the nasty pre- and post-read overloading by providing explictit
>    functions to do these tasks.
>  - Redo read_random(9) so as to duplicate random(4)'s read internals.
>    This makes it a first-class citizen rather than a hack.
>  - Move stuff out of locked regions when it does not need to be
>    there.
>  - Trim RANDOM_DEBUG printfs. Some are excess to requirement, some
>    behind boot verbose.
>  - Use SYSINIT to sequence the startup.
>  - Fix init/deinit sysctl stuff.
>  - Make relevant sysctls also tunables.
>  - Add different harvesting "styles" to allow for different requirements
>    (direct, queue, fast).
>  - Add harvesting of FFS atime events. This needs to be checked for
>    weighing down the FS code.
>  - Add harvesting of slab allocator events. This needs to be checked for
>    weighing down the allocator code.

Neither filesystem operations nor allocations are random events.  They are 
trivially influenced by user code.  A malicious attacker could create 
repeated patterns of allocations or filesystem activity through the 
syscall path to degrade your random sample source.

Perhaps more importantly to me, this is an unacceptable performance 
burden for the allocator.  At a minimum it should compile out by 
default.  Great care has been taken to reduce the fast path of the 
allocator to the minimum number of cycles and even cache misses.

Thanks,
Jeff

>  - Fix the random(9) manpage.
>  - Loadable modules are not present for now. These will be re-engineered
>    when the dust settles.
>  - Use macros for locks.
>  - Fix comments.
>
>  * src/share/man/...
>  - Update the man pages.
>
>  * src/etc/...
>  - The startup/shutdown work is done in D2924.
>
>  * src/UPDATING
>  - Add UPDATING announcement.
>
>  * src/sys/dev/random/build.sh
>  - Add copyright.
>  - Add libz for unit tests.
>
>  * src/sys/dev/random/dummy.c
>  - Remove; no longer needed. Functionality incorporated into randomdev.*.
>
>  * live_entropy_sources.c live_entropy_sources.h
>  - Remove; content moved.
>  - move content to randomdev.[ch] and optimise.
>
>  * src/sys/dev/random/random_adaptors.c src/sys/dev/random/random_adaptors.h
>  - Remove; plugability is no longer used. Compile-time algorithm
>    selection is the way to go.
>
>  * src/sys/dev/random/random_harvestq.c src/sys/dev/random/random_harvestq.h
>  - Add early (re)boot-time randomness caching.
>
>  * src/sys/dev/random/randomdev_soft.c src/sys/dev/random/randomdev_soft.h
>  - Remove; no longer needed.
>
>  * src/sys/dev/random/uint128.h
>  - Provide a fake uint128_t; if a real one ever arrived, we can use
>    that instead. All that is needed here is N=0, N++, N==0, and some
>    localised trickery is used to manufacture a 128-bit 0ULLL.
>
>  * src/sys/dev/random/unit_test.c src/sys/dev/random/unit_test.h
>  - Improve unit tests; previously the testing human needed clairvoyance;
>    now the test will do a basic check of compressibility. Clairvoyant
>    talent is still a good idea.
>  - This is still a long way off a proper unit test.
>
>  * src/sys/dev/random/fortuna.c src/sys/dev/random/fortuna.h
>  - Improve messy union to just uint128_t.
>  - Remove unneeded 'static struct fortuna_start_cache'.
>  - Tighten up up arithmetic.
>  - Provide a method to allow eternal junk to be introduced; harden
>    it against blatant by compress/hashing.
>  - Assert that locks are held correctly.
>  - Fix the nasty pre- and post-read overloading by providing explictit
>    functions to do these tasks.
>  - Turn into self-sufficient module (no longer requires randomdev_soft.[ch])
>
>  * src/sys/dev/random/yarrow.c src/sys/dev/random/yarrow.h
>  - Improve messy union to just uint128_t.
>  - Remove unneeded 'staic struct start_cache'.
>  - Tighten up up arithmetic.
>  - Provide a method to allow eternal junk to be introduced; harden
>    it against blatant by compress/hashing.
>  - Assert that locks are held correctly.
>  - Fix the nasty pre- and post-read overloading by providing explictit
>    functions to do these tasks.
>  - Turn into self-sufficient module (no longer requires randomdev_soft.[ch])
>  - Fix some magic numbers elsewhere used as FAST and SLOW.
>
>  Differential Revision: https://reviews.freebsd.org/D2025
>  Reviewed by: vsevolod,delphij,rwatson,trasz,jmg
>  Approved by: so (delphij)
>
> Added:
>  head/sys/dev/random/randomdev_none.c   (contents, props changed)
>     - copied, changed from r284956, head/sys/dev/random/randomdev_soft.h
> Deleted:
>  head/sys/dev/random/dummy_rng.c
>  head/sys/dev/random/live_entropy_sources.c
>  head/sys/dev/random/live_entropy_sources.h
>  head/sys/dev/random/random_adaptors.c
>  head/sys/dev/random/random_adaptors.h
>  head/sys/dev/random/randomdev_soft.c
>  head/sys/dev/random/randomdev_soft.h
>  head/sys/modules/random/Makefile
> Modified:
>  head/UPDATING
>  head/share/man/man4/random.4
>  head/share/man/man9/random.9
>  head/share/man/man9/random_harvest.9
>  head/sys/conf/files
>  head/sys/conf/options
>  head/sys/dev/glxsb/glxsb.c
>  head/sys/dev/hifn/hifn7751.c
>  head/sys/dev/random/build.sh
>  head/sys/dev/random/fortuna.c
>  head/sys/dev/random/fortuna.h
>  head/sys/dev/random/hash.c
>  head/sys/dev/random/hash.h
>  head/sys/dev/random/ivy.c
>  head/sys/dev/random/nehemiah.c
>  head/sys/dev/random/random_harvestq.c
>  head/sys/dev/random/random_harvestq.h
>  head/sys/dev/random/randomdev.c
>  head/sys/dev/random/randomdev.h
>  head/sys/dev/random/uint128.h
>  head/sys/dev/random/unit_test.c
>  head/sys/dev/random/unit_test.h
>  head/sys/dev/random/yarrow.c
>  head/sys/dev/random/yarrow.h
>  head/sys/dev/rndtest/rndtest.c
>  head/sys/dev/safe/safe.c
>  head/sys/dev/syscons/scmouse.c
>  head/sys/dev/syscons/syscons.c
>  head/sys/dev/ubsec/ubsec.c
>  head/sys/dev/virtio/random/virtio_random.c
>  head/sys/dev/vt/vt_core.c
>  head/sys/dev/vt/vt_sysmouse.c
>  head/sys/fs/tmpfs/tmpfs_subr.c
>  head/sys/kern/kern_intr.c
>  head/sys/kern/kern_mib.c
>  head/sys/kern/subr_bus.c
>  head/sys/libkern/arc4random.c
>  head/sys/libkern/random.c
>  head/sys/mips/cavium/octeon_rnd.c
>  head/sys/mips/conf/AR71XX_BASE
>  head/sys/mips/conf/AR724X_BASE
>  head/sys/mips/conf/AR91XX_BASE
>  head/sys/mips/conf/AR933X_BASE
>  head/sys/mips/conf/AR934X_BASE
>  head/sys/mips/conf/PB92
>  head/sys/mips/conf/QCA955X_BASE
>  head/sys/mips/conf/RT305X
>  head/sys/modules/Makefile
>  head/sys/modules/crypto/Makefile
>  head/sys/net/if_ethersubr.c
>  head/sys/net/if_tun.c
>  head/sys/netgraph/ng_iface.c
>  head/sys/sys/kernel.h
>  head/sys/sys/random.h
>  head/sys/ufs/ffs/ffs_inode.c
>  head/sys/vm/uma_core.c
>
> Modified: head/UPDATING
> ==============================================================================
> --- head/UPDATING	Tue Jun 30 16:26:13 2015	(r284958)
> +++ head/UPDATING	Tue Jun 30 17:00:45 2015	(r284959)
> @@ -31,6 +31,41 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 11
> 	disable the most expensive debugging functionality run
> 	"ln -s 'abort:false,junk:false' /etc/malloc.conf".)
>
> +20150630:
> +	The default kernel entropy-processing algorithm is now
> +	Fortuna, replacing Yarrow.
> +
> +	Assuming you have 'device random' in your kernel config
> +	file, the configurations allow a kernel option to override
> +	this default. You may choose *ONE* of:
> +
> +	options	RANDOM_YARROW	# Legacy /dev/random algorithm.
> +	options	RANDOM_DUMMY	# Blocking-only driver.
> +
> +	If you have neither, you get Fortuna.  For most people,
> +	read no further, Fortuna will give a /dev/random that works
> +	like it always used to, and the difference will be irrelevant.
> +
> +	If you remove 'device random', you get *NO* kernel-processed
> +	entopy at all. This may be acceptable to folks building
> +	embedded systems, but has complications. Carry on reading,
> +	and it is assumed you know what you need.
> +
> +	*PLEASE* read random(4) and random(9) if you are in the
> +	habit of tweeking kernel configs, and/or if you are a member
> +	of the embedded community, wanting specific and not-usual
> +	behaviour from your security subsystems.
> +
> +	NOTE!! If you use RANDOM_DUMMY and/or have no 'device
> +	random', you will NOT have a functioning /dev/random, and
> +	many cryptographic features will not work, including SSH.
> +	You may also find strange behaviour from the random(3) set
> +	of library functions, in particular sranddev(3), srandomdev(3)
> +	and arc4random(3). The reason for this is that the KERN_ARND
> +	sysctl only returns entropy if it thinks it has some to
> +	share, and with RANDOM_DUMMY or no 'device random' this
> +	will never happen.
> +
> 20150623:
> 	An additional fix for the issue described in the 20150614 sendmail
> 	entry below has been been committed in revision 284717.
>
> Modified: head/share/man/man4/random.4
> ==============================================================================
> --- head/share/man/man4/random.4	Tue Jun 30 16:26:13 2015	(r284958)
> +++ head/share/man/man4/random.4	Tue Jun 30 17:00:45 2015	(r284959)
> @@ -1,4 +1,4 @@
> -.\" Copyright (c) 2001-2013	Mark R V Murray.  All rights reserved.
> +.\" Copyright (c) 2001-2015	Mark R V Murray.  All rights reserved.
> .\"
> .\" Redistribution and use in source and binary forms, with or without
> .\" modification, are permitted provided that the following conditions
> @@ -23,7 +23,7 @@
> .\"
> .\" $FreeBSD$
> .\"
> -.Dd October 12, 2013
> +.Dd June 30, 2015
> .Dt RANDOM 4
> .Os
> .Sh NAME
> @@ -37,31 +37,32 @@ The
> device
> returns an endless supply of random bytes when read.
> It also accepts and reads data
> -as any ordinary (and willing) file,
> -but discards data written to it.
> -The device will probe for
> -certain hardware entropy sources,
> -and use these in preference to the fallback,
> -which is a generator implemented in software.
> +as any ordinary file.
> .Pp
> -The software generator will start in an
> +The generator will start in an
> .Em unseeded
> state, and will block reads until
> -it is (re)seeded.
> +it is seeded for the first time.
> This may cause trouble at system boot
> when keys and the like
> are generated from
> -/dev/random
> +.Xr random 4
> so steps should be taken to ensure a
> -reseed as soon as possible.
> -The
> -.Xr sysctl 8
> -controlling the
> -.Em seeded
> -status (see below) may be used
> -if security is not an issue
> -or for convenience
> -during setup or development.
> +seeding as soon as possible.
> +.Pp
> +It is also possible
> +to read random bytes
> +by using the KERN_ARND sysctl.
> +On the command line
> +this could be done by
> +.Pp
> +.Dl "sysctl -x -B 16 kern.arandom"
> +.Pp
> +This sysctl will not return
> +random bytes unless
> +the
> +.Xr random 4
> +is seeded.
> .Pp
> This initial seeding
> of random number generators
> @@ -90,101 +91,57 @@ To see the current settings of the softw
> .Nm
> device, use the command line:
> .Pp
> -.Dl sysctl kern.random
> +.Dl "sysctl kern.random"
> .Pp
> which results in something like:
> .Bd -literal -offset indent
> -kern.random.adaptors: yarrow,dummy
> -kern.random.active_adaptor: yarrow
> -kern.random.yarrow.gengateinterval: 10
> -kern.random.yarrow.bins: 10
> -kern.random.yarrow.fastthresh: 96
> -kern.random.yarrow.slowthresh: 128
> -kern.random.yarrow.slowoverthresh: 2
> -kern.random.sys.seeded: 1
> -kern.random.sys.harvest.ethernet: 1
> -kern.random.sys.harvest.point_to_point: 1
> -kern.random.sys.harvest.interrupt: 1
> -kern.random.sys.harvest.swi: 1
> +kern.random.fortuna.minpoolsize: 64
> +kern.random.harvest.mask_symbolic: [HIGH_PERFORMANCE], ... ,CACHED
> +kern.random.harvest.mask_bin: 00111111111
> +kern.random.harvest.mask: 511
> +kern.random.random_sources: 'Intel Secure Key RNG'
> .Ed
> .Pp
> Other than
> -.Dl kern.random.adaptors
> -all settings are read/write.
> -.Pp
> -The
> -.Va kern.random.sys.seeded
> -variable indicates whether or not the
> -.Nm
> -device is in an acceptably secure state
> -as a result of reseeding.
> -If set to 0,
> -the device will block (on read)
> -until the next reseed
> -as a result of entropy harvesting.
> -A reseed will set the value to 1 (non-blocking).
> -.Pp
> -The
> -.Va kern.random.sys.harvest.ethernet
> -variable is used to select LAN traffic as an entropy source.
> -A 0 (zero) value means that LAN traffic
> -is not considered as an entropy source.
> -Set the variable to 1 (one)
> -if you wish to use LAN traffic for entropy harvesting.
> +.Dl kern.random.fortuna.minpoolsize
> +and
> +.Dl kern.random.harvest.mask
> +all settings are read-only.
> .Pp
> The
> -.Va kern.random.sys.harvest.point_to_point
> -variable is used to select serial line traffic as an entropy source.
> -(Serial line traffic includes PPP, SLIP and all tun0 traffic.)
> -A 0 (zero) value means such traffic
> -is not considered as an entropy source.
> -Set the variable to 1 (one)
> -if you wish to use it for entropy harvesting.
> +.Pa kern.random.fortuna.minpoolsize
> +sysctl is used
> +to set the seed threshhold.
> +A smaller number gives a faster seed,
> +but a less secure one.
> +In practice,
> +values between 64 and 256
> +are acceptable.
> .Pp
> The
> -.Va kern.random.sys.harvest.interrupt
> -variable is used to select hardware interrupts
> +.Va kern.random.harvest.mask
> +bitmask is used to select
> +the possible entropy sources.
> +A 0 (zero) value means
> +the corresponding source
> +is not considered
> as an entropy source.
> -A 0 (zero) value means hardware interrupts
> -are not considered as an entropy source.
> -Set the variable to 1 (one)
> -if you wish to use them for entropy harvesting.
> -All hardware interrupt harvesting is set up by the
> -individual device drivers.
> -.Pp
> +Set the bit to 1 (one)
> +if you wish to use
> +that source.
> The
> -.Va kern.random.sys.harvest.swi
> -variable is used to select software interrupts
> -as an entropy source.
> -A 0 (zero) value means software interrupts
> -are not considered as an entropy source.
> -Set the variable to 1 (one)
> -if you wish to use them for entropy harvesting.
> -.Pp
> -The other variables are explained in the paper describing the
> -.Em Yarrow
> -algorithm at
> -.Pa http://www.schneier.com/yarrow.html .
> -.Pp
> -These variables are all limited
> -in terms of the values they may contain:
> -.Bl -tag -width "kern.random.yarrow.gengateinterval" -compact -offset indent
> -.It Va kern.random.yarrow.gengateinterval
> -.Bq 4..64
> -.It Va kern.random.yarrow.bins
> -.Bq 2..16
> -.It Va kern.random.yarrow.fastthresh
> -.Bq 64..256
> -.It Va kern.random.yarrow.slowthresh
> -.Bq 64..256
> -.It Va kern.random.yarrow.slowoverthresh
> -.Bq 1..5
> -.El
> -.Pp
> -Internal
> -.Xr sysctl 3
> -handlers force the above variables
> -into the stated ranges.
> +.Va kern.random.harvest.mask_bin
> +and
> +.Va kern.random.harvest.mask_symbolic
> +sysctl
> +can be used confirm
> +that your choices are correct.
> +Note that disabled items
> +in the latter item
> +are listed in square brackets.
> +See
> +.Xr random_harvest 9
> +for more on the harvesting of entropy.
> .Sh RANDOMNESS
> The use of randomness in the field of computing
> is a rather subtle issue because randomness means
> @@ -308,23 +265,36 @@ so its use is discouraged.
> .Xr RAND_add 3 ,
> .Xr RAND_bytes 3 ,
> .Xr random 3 ,
> -.Xr sysctl 8
> +.Xr sysctl 8 ,
> +.Xr random 9
> +.Rs
> +.%A Ferguson
> +.%A Schneier
> +.%A Kohno
> +.%B Cryptography Engineering
> +.%I Wiley
> +.%O ISBN 978-0-470-47424-2
> +.Re
> .Sh HISTORY
> A
> .Nm
> device appeared in
> .Fx 2.2 .
> -The early version was taken from Theodore Ts'o's entropy driver for Linux.
> The current software implementation,
> introduced in
> -.Fx 5.0 ,
> -is a complete rewrite by
> +.Fx 10.0 ,
> +is by
> .An Mark R V Murray ,
> and is an implementation of the
> -.Em Yarrow
> -algorithm by Bruce Schneier,
> +.Em Fortuna
> +algorithm by Ferguson
> .Em et al .
> -Significant infrastructure work was done by Arthur Mesh.
> -.Pp
> -The author gratefully acknowledges
> -significant assistance from VIA Technologies, Inc.
> +It replaces the previous
> +.Em Yarrow
> +implementation,
> +introduced in
> +.Fx 5.0 .
> +The older
> +.Em Yarrow
> +algorithm remains available
> +as a compile-time fallback.
>
> Modified: head/share/man/man9/random.9
> ==============================================================================
> --- head/share/man/man9/random.9	Tue Jun 30 16:26:13 2015	(r284958)
> +++ head/share/man/man9/random.9	Tue Jun 30 17:00:45 2015	(r284959)
> @@ -1,4 +1,6 @@
> .\"
> +.\" Copyright (c) 2015
> +.\"	Mark R V Murray
> .\" Copyright (c) 2000
> .\"	The Regents of the University of California.  All rights reserved.
> .\"
> @@ -26,7 +28,7 @@
> .\"
> .\" $FreeBSD$
> .\" "
> -.Dd September 25, 2000
> +.Dd June 30, 2015
> .Dt RANDOM 9
> .Os
> .Sh NAME
> @@ -53,11 +55,12 @@
> .Sh DESCRIPTION
> The
> .Fn random
> -function will by default produce a sequence of numbers that can be duplicated
> +function will by default produce
> +a sequence of numbers
> +that can be duplicated
> by calling
> .Fn srandom
> -with
> -.Ql 1
> +with some constant
> as the
> .Fa seed .
> The
> @@ -67,19 +70,28 @@ function may be called with any arbitrar
> value to get slightly more unpredictable numbers.
> It is important to remember that the
> .Fn random
> -function is entirely predictable, and is therefore not of use where
> -knowledge of the sequence of numbers may be of benefit to an attacker.
> +function is entirely predictable,
> +and is therefore not of use where
> +knowledge of the sequence of numbers
> +may be of benefit to an attacker.
> .Pp
> The
> .Fn arc4rand
> -function will return very good quality random numbers, slightly better
> -suited for security-related purposes.
> +function will return very good quality random numbers,
> +better suited
> +for security-related purposes.
> The random numbers from
> .Fn arc4rand
> -are seeded from the entropy device if it is available.
> -Automatic reseeds happen after a certain timeinterval and after a
> -certain number of bytes have been delivered.
> -A forced reseed can be forced by passing a non-zero value in the
> +are seeded from the entropy device
> +if it is available.
> +Automatic reseeds happen
> +after a certain timeinterval
> +and after a certain number of bytes
> +have been delivered.
> +A forced reseed
> +can be forced
> +by passing a non-zero
> +value in the
> .Fa reseed
> argument.
> .Pp
> @@ -90,19 +102,24 @@ if it has been loaded.
> If the entropy device is not loaded, then
> the
> .Fa buffer
> -is filled with output generated by
> -.Fn random .
> +is ignored
> +and zero is returned.
> The
> .Fa buffer
> is filled with no more than
> .Fa count
> bytes.
> -It is advised that
> +It is strongly advised that
> .Fn read_random
> -is not used; instead use
> +is not used;
> +instead use
> .Fn arc4rand
> +unless it is
> +necessary to know
> +that no entropy
> +has been returned.
> .Pp
> -All the bits generated by
> +All the bits returned by
> .Fn random ,
> .Fn arc4rand
> and
> @@ -120,32 +137,38 @@ to return a 32 bit pseudo-random integer
> .Sh RETURN VALUES
> The
> .Fn random
> -function
> -uses a non-linear additive feedback random number generator employing a
> -default table of size 31 long integers to return successive pseudo-random
> +function uses
> +a non-linear additive feedback random number generator
> +employing a default table
> +of size 31
> +containing long integers
> +to return successive pseudo-random
> numbers in the range from 0 to
> .if t 2\u\s731\s10\d\(mi1.
> .if n (2**31)\(mi1.
> -The period of this random number generator is very large, approximately
> +The period of this random number generator
> +is very large,
> +approximately
> .if t 16\(mu(2\u\s731\s10\d\(mi1).
> .if n 16*((2**31)\(mi1).
> .Pp
> The
> .Fn arc4rand
> -function uses the RC4 algorithm to generate successive pseudo-random
> -bytes.
> +function uses the RC4 algorithm
> +to generate successive pseudo-random bytes.
> The
> .Fn arc4random
> -function
> -uses
> +function uses
> .Fn arc4rand
> -to generate pseudo-random numbers in the range from 0 to
> +to generate pseudo-random numbers
> +in the range from 0 to
> .if t 2\u\s732\s10\d\(mi1.
> .if n (2**32)\(mi1.
> .Pp
> The
> .Fn read_random
> -function returns the number of bytes placed in
> +function returns
> +the number of bytes placed in
> .Fa buffer .
> .Sh AUTHORS
> .An Dan Moschuk
>
> Modified: head/share/man/man9/random_harvest.9
> ==============================================================================
> --- head/share/man/man9/random_harvest.9	Tue Jun 30 16:26:13 2015	(r284958)
> +++ head/share/man/man9/random_harvest.9	Tue Jun 30 17:00:45 2015	(r284959)
> @@ -1,5 +1,5 @@
> .\"
> -.\" Copyright (c) 2002 Mark R V Murray
> +.\" Copyright (c) 2002-2015 Mark R V Murray
> .\" All rights reserved.
> .\"
> .\" Redistribution and use in source and binary forms, with or without
> @@ -25,7 +25,7 @@
> .\"
> .\" $FreeBSD$
> .\"
> -.Dd February 6, 2002
> +.Dd June 30, 2015
> .Dt RANDOM_HARVEST 9
> .Os
> .Sh NAME
> @@ -35,59 +35,93 @@
> .In sys/types.h
> .In sys/random.h
> .Ft void
> -.Fo random_harvest
> +.Fo random_harvest_direct
> +.Fa "void *entropy"
> +.Fa "u_int size"
> +.Fa "u_int bits"
> +.Fa "enum esource source"
> +.Fc
> +.Ft void
> +.Fo random_harvest_fast
> +.Fa "void *entropy"
> +.Fa "u_int size"
> +.Fa "u_int bits"
> +.Fa "enum esource source"
> +.Fc
> +.Ft void
> +.Fo random_harvest_queue
> .Fa "void *entropy"
> .Fa "u_int size"
> .Fa "u_int bits"
> -.Fa "u_int frac"
> .Fa "enum esource source"
> .Fc
> .Sh DESCRIPTION
> The
> -.Fn random_harvest
> -function is used by device drivers
> +.Fn random_harvest_*
> +functions are used by device drivers
> and other kernel processes to pass data
> that is considered (at least partially) stochastic
> to the entropy device.
> .Pp
> -The caller should pass a pointer (to no more than 16 bytes) of
> -the
> +The caller should pass
> +a pointer pointing to the
> .Dq random
> data in
> .Fa entropy .
> The argument
> .Fa size
> contains the number of bytes pointed to.
> -The caller should
> +The
> +.Fa source
> +is chosen from one of
> +the values enumerated in
> +.Pa sys/dev/random.h .
> +and is used to indicate the source of the entropy.
> +.Pp
> +The
> +.Fo random_harvest_direct
> +.Fc
> +variant is used
> +for early harvesting
> +before any multitasking
> +is enabled.
> +.Pp
> +The
> +.Fn random_harvest_fast
> +variant is used
> +by sources that
> +should not take
> +a performance hit
> +from harvesting,
> +as they are high-rate
> +sources.
> +Some entropy is sacrificed,
> +but the hig rate of supply
> +will compensate for this.
> +.Pp
> +The
> +.Fn random_harvest_queue
> +variant is used
> +for general harvesting
> +and is the default
> +choice for most entropy sources
> +such as interrupts
> +or console events.
> +.Pp
> +The
> +.Fa bits
> +argument is only used
> +by the deprecated Yarrow algorithm.
> +For compatibility,
> +the caller should
> .Em "very conservatively"
> estimate the number of random bits
> in the sample,
> and pass this in
> -.Fa bits
> -or
> -.Fa frac .
> -If the estimated number of bits per sample is an integer, then
> -.Fa bits
> -is used, and
> -.Fa frac
> -is 0.
> -Otherwise,
> -for low-entropy samples,
> -.Dq fractional
> -entropy can be supplied in
> -.Fa frac .
> -(This is considered to be
> -.Fa frac /
> -1024 bits of entropy.)
> -The
> -.Fa source
> -is chosen from
> -.Dv RANDOM_WRITE , RANDOM_KEYBOARD , RANDOM_MOUSE , RANDOM_NET
> -and
> -.Dv RANDOM_INTERRUPT ,
> -and is used to indicate the source of the entropy.
> +.Fa bits .
> .Pp
> -Interrupt harvesting has been simplified
> +Interrupt harvesting has been
> +in part simplified simplified
> for the kernel programmer.
> If a device driver registers an interrupt handler
> with
> @@ -101,6 +135,7 @@ bit in the
> .Fa flags
> argument to have that interrupt source
> be used for entropy harvesting.
> +This should be done wherever practicable.
> .Sh SEE ALSO
> .Xr random 4 ,
> .Xr BUS_SETUP_INTR 9
>
> Modified: head/sys/conf/files
> ==============================================================================
> --- head/sys/conf/files	Tue Jun 30 16:26:13 2015	(r284958)
> +++ head/sys/conf/files	Tue Jun 30 17:00:45 2015	(r284959)
> @@ -528,14 +528,14 @@ crypto/des/des_ecb.c		optional crypto |
> crypto/des/des_setkey.c		optional crypto | ipsec | netsmb
> crypto/rc4/rc4.c		optional netgraph_mppc_encryption | kgssapi
> crypto/rijndael/rijndael-alg-fst.c optional crypto | geom_bde | \
> -					 ipsec | random | wlan_ccmp
> -crypto/rijndael/rijndael-api-fst.c optional geom_bde | random
> +					 ipsec | random random_yarrow | random !random_yarrow !random_dummy | wlan_ccmp
> +crypto/rijndael/rijndael-api-fst.c optional geom_bde | random random_yarrow | random !random_yarrow !random_dummy
> crypto/rijndael/rijndael-api.c	optional crypto | ipsec | wlan_ccmp
> crypto/sha1.c			optional carp | crypto | ipsec | \
> 					 netgraph_mppc_encryption | sctp
> -crypto/sha2/sha2.c		optional crypto | geom_bde | ipsec | random | \
> +crypto/sha2/sha2.c		optional crypto | geom_bde | ipsec | random random_yarrow | random !random_yarrow !random_dummy | \
> 					 sctp | zfs
> -crypto/sha2/sha256c.c		optional crypto | geom_bde | ipsec | random | \
> +crypto/sha2/sha256c.c		optional crypto | geom_bde | ipsec | random random_yarrow | random !random_yarrow !random_dummy | \
> 					 sctp | zfs
> crypto/siphash/siphash.c	optional inet | inet6
> crypto/siphash/siphash_test.c	optional inet | inet6
> @@ -2139,15 +2139,12 @@ rt2860.fw			optional rt2860fw | ralfw		\
> 	compile-with	"${NORMAL_FW}"					\
> 	no-obj no-implicit-rule						\
> 	clean		"rt2860.fw"
> -dev/random/randomdev.c		standard
> -dev/random/random_adaptors.c	standard
> -dev/random/dummy_rng.c		standard
> -dev/random/live_entropy_sources.c	standard
> -dev/random/random_harvestq.c	standard
> -dev/random/randomdev_soft.c	optional random
> -dev/random/yarrow.c		optional random
> -dev/random/fortuna.c		optional random
> -dev/random/hash.c		optional random
> +dev/random/randomdev_none.c	optional !random
> +dev/random/randomdev.c		optional random
> +dev/random/random_harvestq.c	optional random random_yarrow | random !random_dummy
> +dev/random/yarrow.c		optional random random_yarrow
> +dev/random/fortuna.c		optional random !random_yarrow !random_dummy
> +dev/random/hash.c		optional random random_yarrow | random !random_dummy
> dev/rc/rc.c			optional rc
> dev/re/if_re.c			optional re
> dev/rl/if_rl.c			optional rl pci
>
> Modified: head/sys/conf/options
> ==============================================================================
> --- head/sys/conf/options	Tue Jun 30 16:26:13 2015	(r284958)
> +++ head/sys/conf/options	Tue Jun 30 17:00:45 2015	(r284959)
> @@ -939,9 +939,16 @@ RACCT_DEFAULT_TO_DISABLED	opt_global.h
> RCTL		opt_global.h
>
> # Random number generator(s)
> +# The DEBUG option is in global.h as the random harvesting
> +# puts probes all over the place, and it makes little sense
> +# to pollute these headers with an extra include.
> +# the DUMMY option is in global.h because it is used to
> +# turn off harvesting all over the kernel.
> +RANDOM_DEBUG	opt_global.h
> +# Which CSPRNG hashes we get.
> +# These are mutually exclusive. With neither, Fortuna is selected.
> +RANDOM_DUMMY	opt_global.h
> RANDOM_YARROW	opt_random.h
> -RANDOM_FORTUNA	opt_random.h
> -RANDOM_DEBUG	opt_random.h
>
> # Intel em(4) driver
> EM_MULTIQUEUE	opt_em.h
>
> Modified: head/sys/dev/glxsb/glxsb.c
> ==============================================================================
> --- head/sys/dev/glxsb/glxsb.c	Tue Jun 30 16:26:13 2015	(r284958)
> +++ head/sys/dev/glxsb/glxsb.c	Tue Jun 30 17:00:45 2015	(r284959)
> @@ -476,7 +476,8 @@ glxsb_rnd(void *v)
> 	if (status & SB_RNS_TRNG_VALID) {
> 		value = bus_read_4(sc->sc_sr, SB_RANDOM_NUM);
> 		/* feed with one uint32 */
> -		random_harvest(&value, sizeof(value), 32/2, RANDOM_PURE_GLXSB);
> +		/* MarkM: FIX!! Check that this does not swamp the harvester! */
> +		random_harvest_queue(&value, sizeof(value), 32/2, RANDOM_PURE_GLXSB);
> 	}
>
> 	callout_reset(&sc->sc_rngco, sc->sc_rnghz, glxsb_rnd, sc);
>
> Modified: head/sys/dev/hifn/hifn7751.c
> ==============================================================================
> --- head/sys/dev/hifn/hifn7751.c	Tue Jun 30 16:26:13 2015	(r284958)
> +++ head/sys/dev/hifn/hifn7751.c	Tue Jun 30 17:00:45 2015	(r284959)
> @@ -258,7 +258,8 @@ hifn_partname(struct hifn_softc *sc)
> static void
> default_harvest(struct rndtest_state *rsp, void *buf, u_int count)
> {
> -	random_harvest(buf, count, count*NBBY/2, RANDOM_PURE_HIFN);
> +	/* MarkM: FIX!! Check that this does not swamp the harvester! */
> +	random_harvest_queue(buf, count, count*NBBY/2, RANDOM_PURE_HIFN);
> }
>
> static u_int
>
> Modified: head/sys/dev/random/build.sh
> ==============================================================================
> --- head/sys/dev/random/build.sh	Tue Jun 30 16:26:13 2015	(r284958)
> +++ head/sys/dev/random/build.sh	Tue Jun 30 17:00:45 2015	(r284959)
> @@ -1,3 +1,29 @@
> +#!/bin/sh
> +#-
> +# Copyright (c) 2013-2015 Mark R V Murray
> +# All rights reserved.
> +#
> +# Redistribution and use in source and binary forms, with or without
> +# modification, are permitted provided that the following conditions
> +# are met:
> +# 1. Redistributions of source code must retain the above copyright
> +#    notice, this list of conditions and the following disclaimer
> +#    in this position and unchanged.
> +# 2. Redistributions in binary form must reproduce the above copyright
> +#    notice, this list of conditions and the following disclaimer in the
> +#    documentation and/or other materials provided with the distribution.
> +#
> +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
> +# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
> +# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
> +# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
> +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
> +# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
> +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
> +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
> +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
> +# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
> +#
> # $FreeBSD$
> #
> # Basic script to build crude unit tests.
> @@ -11,6 +37,7 @@ cc -g -O0 -pthread -DRANDOM_DEBUG -DRAND
> 	../../crypto/rijndael/rijndael-alg-fst.c \
> 	../../crypto/sha2/sha2.c \
> 	../../crypto/sha2/sha256c.c \
> +	-lz \
> 	-o yunit_test
> cc -g -O0 -pthread -DRANDOM_DEBUG -DRANDOM_FORTUNA \
> 	-I../.. -lstdthreads -Wall \
> @@ -21,4 +48,5 @@ cc -g -O0 -pthread -DRANDOM_DEBUG -DRAND
> 	../../crypto/rijndael/rijndael-alg-fst.c \
> 	../../crypto/sha2/sha2.c \
> 	../../crypto/sha2/sha256c.c \
> +	-lz \
> 	-o funit_test
>
> Modified: head/sys/dev/random/fortuna.c
> ==============================================================================
> --- head/sys/dev/random/fortuna.c	Tue Jun 30 16:26:13 2015	(r284958)
> +++ head/sys/dev/random/fortuna.c	Tue Jun 30 17:00:45 2015	(r284959)
> @@ -1,5 +1,5 @@
> /*-
> - * Copyright (c) 2013-2014 Mark R V Murray
> + * Copyright (c) 2013-2015 Mark R V Murray
>  * All rights reserved.
>  *
>  * Redistribution and use in source and binary forms, with or without
> @@ -25,25 +25,24 @@
>  *
>  */
>
> -/* This implementation of Fortuna is based on the descriptions found in
> - * ISBN 0-471-22357-3 "Practical Cryptography" by Ferguson and Schneier
> - * ("F&S").
> - *
> - * The above book is superseded by ISBN 978-0-470-47424-2 "Cryptography
> - * Engineering" by Ferguson, Schneier and Kohno ("FS&K").  The code has
> - * not yet fully caught up with FS&K.
> +/*
> + * This implementation of Fortuna is based on the descriptions found in
> + * ISBN 978-0-470-47424-2 "Cryptography Engineering" by Ferguson, Schneier
> + * and Kohno ("FS&K").
>  */
>
> #include <sys/cdefs.h>
> __FBSDID("$FreeBSD$");
>
> -#ifdef _KERNEL
> -#include "opt_random.h"
> +#include <sys/limits.h>
>
> +#ifdef _KERNEL
> #include <sys/param.h>
> #include <sys/kernel.h>
> +#include <sys/conf.h>
> #include <sys/lock.h>
> #include <sys/malloc.h>
> +#include <sys/module.h>
> #include <sys/mutex.h>
> #include <sys/random.h>
> #include <sys/sysctl.h>
> @@ -56,13 +55,10 @@ __FBSDID("$FreeBSD$");
>
> #include <dev/random/hash.h>
> #include <dev/random/randomdev.h>
> -#include <dev/random/random_adaptors.h>
> #include <dev/random/random_harvestq.h>
> #include <dev/random/uint128.h>
> #include <dev/random/fortuna.h>
> #else /* !_KERNEL */
> -#include <sys/param.h>
> -#include <sys/types.h>
> #include <inttypes.h>
> #include <stdio.h>
> #include <stdlib.h>
> @@ -79,351 +75,405 @@ __FBSDID("$FreeBSD$");
> #include <dev/random/fortuna.h>
> #endif /* _KERNEL */
>
> -#if !defined(RANDOM_YARROW) && !defined(RANDOM_FORTUNA)
> -#define RANDOM_YARROW
> -#elif defined(RANDOM_YARROW) && defined(RANDOM_FORTUNA)
> -#error "Must define either RANDOM_YARROW or RANDOM_FORTUNA"
> -#endif
> -
> -#if defined(RANDOM_FORTUNA)
> -
> -#define NPOOLS 32
> -#define MINPOOLSIZE 64
> -#define DEFPOOLSIZE 256
> -#define MAXPOOLSIZE 65536
> -
> -/* This algorithm (and code) presumes that KEYSIZE is twice as large as BLOCKSIZE */
> -CTASSERT(BLOCKSIZE == sizeof(uint128_t));
> -CTASSERT(KEYSIZE == 2*BLOCKSIZE);
> -
> -/* This is the beastie that needs protecting. It contains all of the
> - * state that we are excited about.
> - * Exactly one is instantiated.
> +/* Defined in FS&K */
> +#define	RANDOM_FORTUNA_NPOOLS 32		/* The number of accumulation pools */
> +#define	RANDOM_FORTUNA_DEFPOOLSIZE 64		/* The default pool size/length for a (re)seed */
> +#define	RANDOM_FORTUNA_MAX_READ (1 << 20)	/* Max bytes in a single read */
> +
> +/*
> + * The allowable range of RANDOM_FORTUNA_DEFPOOLSIZE. The default value is above.
> + * Making RANDOM_FORTUNA_DEFPOOLSIZE too large will mean a long time between reseeds,
> + * and too small may compromise initial security but get faster reseeds.
> + */
> +#define	RANDOM_FORTUNA_MINPOOLSIZE 16
> +#define	RANDOM_FORTUNA_MAXPOOLSIZE UINT_MAX
> +CTASSERT(RANDOM_FORTUNA_MINPOOLSIZE <= RANDOM_FORTUNA_DEFPOOLSIZE);
> +CTASSERT(RANDOM_FORTUNA_DEFPOOLSIZE <= RANDOM_FORTUNA_MAXPOOLSIZE);
> +
> +/* This algorithm (and code) presumes that RANDOM_KEYSIZE is twice as large as RANDOM_BLOCKSIZE */
> +CTASSERT(RANDOM_BLOCKSIZE == sizeof(uint128_t));
> +CTASSERT(RANDOM_KEYSIZE == 2*RANDOM_BLOCKSIZE);
> +
> +/*
> + * This is the beastie that needs protecting. It contains all of the
> + * state that we are excited about. Exactly one is instantiated.
>  */
> static struct fortuna_state {
> -	/* P_i */
> -	struct pool {
> -		u_int length;
> -		struct randomdev_hash hash;
> -	} pool[NPOOLS];
> -
> -	/* ReseedCnt */
> -	u_int reseedcount;
> -
> -	/* C - 128 bits */
> -	union {
> -		uint8_t byte[BLOCKSIZE];
> -		uint128_t whole;
> -	} counter;
> -
> -	/* K */
> -	struct randomdev_key key;
> -
> -	/* Extras */
> -	u_int minpoolsize;
> -
> +	struct fs_pool {		/* P_i */
> +		u_int fsp_length;	/* Only the first one is used by Fortuna */
> +		struct randomdev_hash fsp_hash;
> +	} fs_pool[RANDOM_FORTUNA_NPOOLS];
> +	u_int fs_reseedcount;		/* ReseedCnt */
> +	uint128_t fs_counter;		/* C */
> +	struct randomdev_key fs_key;	/* K */
> +	u_int fs_minpoolsize;		/* Extras */
> 	/* Extras for the OS */
> -
> #ifdef _KERNEL
> 	/* For use when 'pacing' the reseeds */
> -	sbintime_t lasttime;
> +	sbintime_t fs_lasttime;
> #endif
> +	/* Reseed lock */
> +	mtx_t fs_mtx;
> } fortuna_state;
>
> -/* The random_reseed_mtx mutex protects seeding and polling/blocking.  */
> -static mtx_t random_reseed_mtx;
> +#ifdef _KERNEL
> +static struct sysctl_ctx_list random_clist;
> +RANDOM_CHECK_UINT(fs_minpoolsize, RANDOM_FORTUNA_MINPOOLSIZE, RANDOM_FORTUNA_MAXPOOLSIZE);
> +#else
> +static uint8_t zero_region[RANDOM_ZERO_BLOCKSIZE];
> +#endif
>
> -static struct fortuna_start_cache {
> -	uint8_t junk[PAGE_SIZE];
> -	size_t length;
> -	struct randomdev_hash hash;
> -} fortuna_start_cache;
> +static void random_fortuna_pre_read(void);
> +static void random_fortuna_read(uint8_t *, u_int);
> +static void random_fortuna_post_read(void);
> +static void random_fortuna_write(uint8_t *, u_int);
> +static void random_fortuna_reseed(void);
> +static int random_fortuna_seeded(void);
> +static void random_fortuna_process_event(struct harvest_event *);
>
> #ifdef _KERNEL
> -static struct sysctl_ctx_list random_clist;
> -RANDOM_CHECK_UINT(minpoolsize, MINPOOLSIZE, MAXPOOLSIZE);
> +/* Interface to Adaptors system */
> +struct random_algorithm random_alg_context = {
> +	.ra_ident = "Fortuna",
> +	.ra_pre_read = random_fortuna_pre_read,
> +	.ra_read = random_fortuna_read,
> +	.ra_post_read = random_fortuna_post_read,
> +	.ra_write = random_fortuna_write,
> +	.ra_reseed = random_fortuna_reseed,
> +	.ra_seeded = random_fortuna_seeded,
> +	.ra_event_processor = random_fortuna_process_event,
> +	.ra_poolcount = RANDOM_FORTUNA_NPOOLS,
> +};
> #endif
>
> -void
> -random_fortuna_init_alg(void)
> +/* ARGSUSED */
> +static void
> +random_fortuna_init_alg(void *unused __unused)
> {
> 	int i;
> #ifdef _KERNEL
> 	struct sysctl_oid *random_fortuna_o;
> #endif
>
> -	memset(fortuna_start_cache.junk, 0, sizeof(fortuna_start_cache.junk));
> -	fortuna_start_cache.length = 0U;
> -	randomdev_hash_init(&fortuna_start_cache.hash);
> -
> -	/* Set up a lock for the reseed process */
> -#ifdef _KERNEL
> -	mtx_init(&random_reseed_mtx, "reseed mutex", NULL, MTX_DEF);
> -#else /* !_KERNEL */
> -	mtx_init(&random_reseed_mtx, mtx_plain);
> -#endif /* _KERNEL */
> -
> -#ifdef _KERNEL
> -	/* Fortuna parameters. Do not adjust these unless you have
> +	RANDOM_RESEED_INIT_LOCK();
> +	/*
> +	 * Fortuna parameters. Do not adjust these unless you have
> 	 * have a very good clue about what they do!
> 	 */
> +	fortuna_state.fs_minpoolsize = RANDOM_FORTUNA_DEFPOOLSIZE;
> +#ifdef _KERNEL
> +	fortuna_state.fs_lasttime = 0;
> 	random_fortuna_o = SYSCTL_ADD_NODE(&random_clist,
> 		SYSCTL_STATIC_CHILDREN(_kern_random),
> 		OID_AUTO, "fortuna", CTLFLAG_RW, 0,
> 		"Fortuna Parameters");
> -
> 	SYSCTL_ADD_PROC(&random_clist,
> 		SYSCTL_CHILDREN(random_fortuna_o), OID_AUTO,
> -		"minpoolsize", CTLTYPE_UINT|CTLFLAG_RW,
> -		&fortuna_state.minpoolsize, DEFPOOLSIZE,
> -		random_check_uint_minpoolsize, "IU",
> -		"Minimum pool size necessary to cause a reseed automatically");
> -
> -	fortuna_state.lasttime = 0U;
> +		"minpoolsize", CTLTYPE_UINT | CTLFLAG_RWTUN,
> +		&fortuna_state.fs_minpoolsize, RANDOM_FORTUNA_DEFPOOLSIZE,
> +		random_check_uint_fs_minpoolsize, "IU",
> +		"Minimum pool size necessary to cause a reseed");
> +	KASSERT(fortuna_state.fs_minpoolsize > 0, ("random: Fortuna threshold must be > 0 at startup"));
> #endif
>
> -	fortuna_state.minpoolsize = DEFPOOLSIZE;
> -
> -	/* F&S - InitializePRNG() */
> -
> -	/* F&S - P_i = \epsilon */
> -	for (i = 0; i < NPOOLS; i++) {
> -		randomdev_hash_init(&fortuna_state.pool[i].hash);
> -		fortuna_state.pool[i].length = 0U;
> +	/*-
> +	 * FS&K - InitializePRNG()
> +	 *      - P_i = \epsilon
> +	 *      - ReseedCNT = 0
> +	 */
> +	for (i = 0; i < RANDOM_FORTUNA_NPOOLS; i++) {
> +		randomdev_hash_init(&fortuna_state.fs_pool[i].fsp_hash);
> +		fortuna_state.fs_pool[i].fsp_length = 0;
> 	}
> -
> -	/* F&S - ReseedCNT = 0 */
> -	fortuna_state.reseedcount = 0U;
> -
> -	/* F&S - InitializeGenerator() */
> -
> -	/* F&S - C = 0 */
> -	uint128_clear(&fortuna_state.counter.whole);
> -
> -	/* F&S - K = 0 */
> -	memset(&fortuna_state.key, 0, sizeof(fortuna_state.key));
> +	fortuna_state.fs_reseedcount = 0;
>
> *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
>



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?alpine.BSF.2.20.1507221138360.1071>