diff --git a/libexec/rc/rc.conf b/libexec/rc/rc.conf index 00f4b718bfad..d502361eca37 100644 --- a/libexec/rc/rc.conf +++ b/libexec/rc/rc.conf @@ -1,786 +1,786 @@ #!/bin/sh # This is rc.conf - a file full of useful variables that you can set # to change the default startup behavior of your system. You should # not edit this file! Put any overrides into one of the ${rc_conf_files} # instead and you will be able to update these defaults later without # spamming your local configuration information. # # The ${rc_conf_files} files should only contain values which override # values set in this file. This eases the upgrade path when defaults # are changed and new features are added. # # All arguments must be in double or single quotes. # # For a more detailed explanation of all the rc.conf variables, please # refer to the rc.conf(5) manual page. # ############################################################## ### Important initial Boot-time options #################### ############################################################## # Set default value of _localbase if not previously set : ${_localbase:="/usr/local"} # rc_debug can't be set here without interferring with rc.subr's setting it # when the kenv variable rc.debug is set. #rc_debug="NO" # Set to YES to enable debugging output from rc.d rc_info="NO" # Enables display of informational messages at boot. rc_startmsgs="YES" # Show "Starting foo:" messages at boot rcshutdown_timeout="90" # Seconds to wait before terminating rc.shutdown precious_machine="NO" # Set to YES to get some guards against mis-directed # shutdown(8) commands early_late_divider="FILESYSTEMS" # Script that separates early/late # stages of the boot process. Make sure you know # the ramifications if you change this. # See rc.conf(5) for more details. always_force_depends="NO" # Set to check that indicated dependencies are # running during boot (can increase boot time). apm_enable="NO" # Set to YES to enable APM BIOS functions (or NO). apmd_enable="NO" # Run apmd to handle APM event from userland. apmd_flags="" # Flags to apmd (if enabled). ddb_enable="NO" # Set to YES to load ddb scripts at boot. ddb_config="/etc/ddb.conf" # ddb(8) config file. devd_enable="YES" # Run devd, to trigger programs on device tree changes. devd_flags="" # Additional flags for devd(8). devmatch_enable="YES" # Demand load kernel modules based on device ids. devmatch_blocklist="" # List of modules (w/o .ko) to exclude from devmatch. #kld_list="" # Kernel modules to load after local disks are mounted kldxref_enable="YES" # Build linker.hints files with kldxref(8). kldxref_clobber="NO" # Overwrite old linker.hints at boot. kldxref_module_path="" # Override kern.module_path. A ';'-delimited list. powerd_enable="NO" # Run powerd to lower our power usage. powerd_flags="" # Flags to powerd (if enabled). tmpmfs="AUTO" # Set to YES to always create an mfs /tmp, NO to never tmpsize="20m" # Size of mfs /tmp if created tmpmfs_flags="-S" # Extra mdmfs options for the mfs /tmp utx_enable="YES" # Enable user accounting varmfs="AUTO" # Set to YES to always create an mfs /var, NO to never varsize="32m" # Size of mfs /var if created varmfs_flags="-S" # Extra mount options for the mfs /var mfs_type="auto" # "md", "tmpfs", "auto" to prefer tmpfs with md as fallback populate_var="AUTO" # Set to YES to always (re)populate /var, NO to never cleanvar_enable="YES" # Clean the /var directory var_run_enable="YES" # Save/restore /var/run structure at shutdown/reboot var_run_autosave="YES" # Only restore /var/run structure at shutdown/reboot # The user is expected to issue service var_run save to # manually save the /var/run mtree var_run_mtree="/var/db/mtree/BSD.var-run.mtree" # Where to save /var/run mtree local_startup="${_localbase}/etc/rc.d" # startup script dirs. script_name_sep=" " # Change if your startup scripts' names contain spaces rc_conf_files="/etc/rc.conf /etc/rc.conf.local" # ZFS support zfs_enable="NO" # Set to YES to automatically mount ZFS file systems zfskeys_enable="NO" # Set YES to autoload ZFS encryption keys zfs_bootonce_activate="NO" # Set YES to make successful bootonce BE permanent zpool_reguid="" # Set to zpools for which the GUID should be replaced # upon first boot. zpool_upgrade="" # Set to zpools for which the version should be upgraded # upon first boot. # ZFSD support zfsd_enable="NO" # Set to YES to automatically start the ZFS fault # management daemon. gptboot_enable="YES" # GPT boot success/failure reporting. # GELI disk encryption configuration. geli_devices="" # List of devices to automatically attach in addition to # GELI devices listed in /etc/fstab. geli_groups="" # List of groups containing devices to automatically # attach with the same keyfiles and passphrase geli_tries="" # Number of times to attempt attaching geli device. # If empty, kern.geom.eli.tries will be used. geli_default_flags="" # Default flags for geli(8). geli_autodetach="YES" # Automatically detach on last close. # Providers are marked as such when all file systems are # mounted. # Example use. #geli_devices="da1 mirror/home" #geli_da1_flags="-p -k /etc/geli/da1.keys" #geli_da1_autodetach="NO" #geli_mirror_home_flags="-k /etc/geli/home.keys" #geli_groups="storage backup" #geli_storage_flags="-k /etc/geli/storage.keys" #geli_storage_devices="ada0 ada1" #geli_backup_flags="-j /etc/geli/backup.passfile -k /etc/geli/backup.keys" #geli_backup_devices="ada2 ada3" root_rw_mount="YES" # Set to NO to inhibit remounting root read-write. root_hold_delay="30" # Time to wait for root mount hold release. fsck_flags="-p" # May be changed to -f (or -f -y) to force a full fsck fsck_y_enable="NO" # Set to YES to do fsck -y if the initial preen fails. fsck_y_flags="-T ffs:-R -T ufs:-R" # Additional flags for fsck -y background_fsck="YES" # Attempt to run fsck in the background where possible. background_fsck_delay="60" # Time to wait (seconds) before starting the fsck. growfs_enable="NO" # Set to YES to attempt to grow the root filesystem on boot growfs_swap_size="" # Set to 0 to disable growfs swap, "" to default size, # size in bytes to specify swap size. netfs_types="nfs:NFS smbfs:SMB" # Net filesystems. extra_netfs_types="NO" # List of network extra filesystem types for delayed # mount at startup (or NO). ############################################################## ### Network configuration sub-section ###################### ############################################################## ### Basic network and firewall/security options: ### hostname="" # Set this! hostid_enable="YES" # Set host UUID. hostid_file="/etc/hostid" # File with hostuuid. hostid_uuidgen_flags="-r" # Flags to uuidgen. machine_id_file="/etc/machine-id" # File with machine-id. nisdomainname="NO" # Set to NIS domain if using NIS (or NO). dhclient_program="/sbin/dhclient" # Path to dhcp client program. dhclient_flags="" # Extra flags to pass to dhcp client. #dhclient_flags_em0="" # Extra dhclient flags for em0 only background_dhclient="NO" # Start dhcp client in the background. #background_dhclient_em0="YES" # Start dhcp client on em0 in the background. dhclient_arpwait="YES" # Wait for ARP resolution synchronous_dhclient="NO" # Start dhclient directly on configured # interfaces during startup. defaultroute_delay="30" # Time to wait for a default route on a DHCP interface. defaultroute_carrier_delay="5" # Time to wait for carrier while waiting for a default route. netif_enable="YES" # Set to YES to initialize network interfaces netif_ipexpand_max="2048" # Maximum number of IP addrs in a range spec. wpa_supplicant_program="/usr/sbin/wpa_supplicant" wpa_supplicant_flags="-s" # Extra flags to pass to wpa_supplicant wpa_supplicant_conf_file="/etc/wpa_supplicant.conf" # firewall_enable="NO" # Set to YES to enable firewall functionality firewall_script="/etc/rc.firewall" # Which script to run to set up the firewall firewall_type="UNKNOWN" # Firewall type (see /etc/rc.firewall) firewall_quiet="NO" # Set to YES to suppress rule display firewall_logging="NO" # Set to YES to enable events logging firewall_logif="NO" # Set to YES to create logging-pseudo interface firewall_flags="" # Flags passed to ipfw when type is a file firewall_coscripts="" # List of executables/scripts to run after # firewall starts/stops firewall_client_net="192.0.2.0/24" # IPv4 Network address for "client" # firewall. #firewall_client_net_ipv6="2001:db8:2:1::/64" # IPv6 network prefix for # "client" firewall. firewall_simple_iif="em1" # Inside network interface for "simple" # firewall. firewall_simple_inet="192.0.2.16/28" # Inside network address for "simple" # firewall. firewall_simple_oif="em0" # Outside network interface for "simple" # firewall. firewall_simple_onet="192.0.2.0/28" # Outside network address for "simple" # firewall. #firewall_simple_iif_ipv6="em1" # Inside IPv6 network interface for "simple" # firewall. #firewall_simple_inet_ipv6="2001:db8:2:800::/56" # Inside IPv6 network prefix # for "simple" firewall. #firewall_simple_oif_ipv6="em0" # Outside IPv6 network interface for "simple" # firewall. #firewall_simple_onet_ipv6="2001:db8:2:0::/56" # Outside IPv6 network prefix # for "simple" firewall. firewall_myservices="" # List of ports/protocols on which this host # offers services for "workstation" firewall. firewall_allowservices="" # List of IPs which have access to # $firewall_myservices for "workstation" # firewall. firewall_trusted="" # List of IPs which have full access to this # host for "workstation" firewall. firewall_logdeny="NO" # Set to YES to log default denied incoming # packets for "workstation" firewall. firewall_nologports="135-139,445 1026,1027 1433,1434" # List of TCP/UDP ports # for which denied incoming packets are not # logged for "workstation" firewall. firewall_nat_enable="NO" # Enable kernel NAT (if firewall_enable == YES) firewall_nat_interface="" # Public interface or IPaddress to use firewall_nat_flags="" # Additional configuration parameters firewall_nat64_enable="NO" # Enable kernel NAT64 module. firewall_nptv6_enable="NO" # Enable kernel NPTv6 module. firewall_pmod_enable="NO" # Enable kernel protocols modification module. dummynet_enable="NO" # Load the dummynet(4) module ipfw_netflow_enable="NO" # Enable netflow logging via ng_netflow ip_portrange_first="NO" # Set first dynamically allocated port ip_portrange_last="NO" # Set last dynamically allocated port ike_enable="NO" # Enable IKE daemon (usually racoon or isakmpd) ike_program="${_localbase}/sbin/isakmpd" # Path to IKE daemon ike_flags="" # Additional flags for IKE daemon ipsec_enable="NO" # Set to YES to run setkey on ipsec_file ipsec_file="/etc/ipsec.conf" # Name of config file for setkey natd_program="/sbin/natd" # path to natd, if you want a different one. natd_enable="NO" # Enable natd (if firewall_enable == YES). natd_interface="" # Public interface or IPaddress to use. natd_flags="" # Additional flags for natd. ipfilter_enable="NO" # Set to YES to enable ipfilter functionality ipfilter_program="/sbin/ipf" # where the ipfilter program lives ipfilter_rules="/etc/ipf.rules" # rules definition file for ipfilter, see # /usr/src/share/examples/ipfilter for examples ipfilter_flags="" # additional flags for ipfilter ipfilter_optionlist="" # optionlist for ipf(8) -T ippool_enable="NO" # Set to YES to enable ip filter pools ippool_program="/sbin/ippool" # where the ippool program lives ippool_rules="/etc/ippool.tables" # rules definition file for ippool ippool_flags="" # additional flags for ippool ipnat_enable="NO" # Set to YES to enable ipnat functionality ipnat_program="/sbin/ipnat" # where the ipnat program lives ipnat_rules="/etc/ipnat.rules" # rules definition file for ipnat ipnat_flags="" # additional flags for ipnat ipmon_enable="NO" # Set to YES for ipmon; needs ipfilter or ipnat ipmon_program="/sbin/ipmon" # where the ipfilter monitor program lives ipmon_flags="-Ds" # typically "-Ds" or "-D /var/log/ipflog" ipfs_enable="NO" # Set to YES to enable saving and restoring # of state tables at shutdown and boot ipfs_program="/sbin/ipfs" # where the ipfs program lives ipfs_flags="" # additional flags for ipfs pf_enable="NO" # Set to YES to enable packet filter (pf) pf_rules="/etc/pf.conf" # rules definition file for pf (nonexistent # by default) pf_program="/sbin/pfctl" # where the pfctl program lives pf_flags="" # additional flags for pfctl pf_fallback_rules_enable="NO" # fallback if loading ruleset fails pf_fallback_rules="block drop log all" # rules to load on pf ruleset failure #pf_fallback_rules="block drop log all #pass quick on em4" # multi-rule pf_fallback_rules_file="/etc/pf-fallback.conf" # rules file on ruleset failure pflog_enable="NO" # Set to YES to enable packet filter logging pflog_logfile="/var/log/pflog" # where pflogd should store the logfile pflog_program="/sbin/pflogd" # where the pflogd program lives pflog_flags="" # additional flags for pflogd dnctl_enable="NO" dnctl_program="/sbin/dnctl" dnctl_rules="/etc/dnctl.conf" ftpproxy_enable="NO" # Set to YES to enable ftp-proxy(8) for pf ftpproxy_flags="" # additional flags for ftp-proxy(8) pfsync_enable="NO" # Expose pf state to other hosts for syncing pfsync_syncdev="" # Interface for pfsync to work through pfsync_syncpeer="" # IP address of pfsync peer host pfsync_ifconfig="" # Additional options to ifconfig(8) for pfsync tcp_extensions="YES" # Set to NO to turn off RFC1323 extensions. log_in_vain="0" # >=1 to log connects to ports w/o listeners. tcp_keepalive="YES" # Enable stale TCP connection timeout (or NO). tcp_drop_synfin="NO" # Set to YES to drop TCP packets with SYN+FIN # NOTE: this violates the TCP specification icmp_drop_redirect="auto" # Set to YES to ignore ICMP REDIRECT packets icmp_log_redirect="NO" # Set to YES to log ICMP REDIRECT packets network_interfaces="auto" # List of network interfaces (or "auto"). cloned_interfaces="" # List of cloned network interfaces to create. #cloned_interfaces="gif0 gif1 gif2 gif3" # Pre-cloning GENERIC config. #ifconfig_lo0="inet 127.0.0.1/8" # default loopback device configuration. #ifconfig_lo0_alias0="inet 127.0.0.254/32" # Sample alias entry. #ifconfig_em0_ipv6="inet6 2001:db8:1::1 prefixlen 64" # Sample IPv6 addr entry #ifconfig_em0_alias0="inet6 2001:db8:2::1 prefixlen 64" # Sample IPv6 alias #ifconfig_em0_name="net0" # Change interface name from em0 to net0. #vlans_em0="101 vlan0" # vlan(4) interfaces for em0 device #create_args_vlan0="vlan 102" # vlan tag for vlan0 device #wlans_ath0="wlan0" # wlan(4) interfaces for ath0 device #wlandebug_wlan0="scan+auth+assoc" # Set debug flags with wlandebug(8) #ipv4_addrs_em0="192.168.0.1/24 192.168.1.1-5/28" # example IPv4 address entry. # #autobridge_interfaces="bridge0" # List of bridges to check #autobridge_bridge0="tap* vlan0" # Interface glob to automatically add to the bridge # User ppp configuration. ppp_enable="NO" # Start user-ppp (or NO). ppp_program="/usr/sbin/ppp" # Path to user-ppp program. ppp_mode="auto" # Choice of "auto", "ddial", "direct" or "dedicated". # For details see man page for ppp(8). Default is auto. ppp_nat="YES" # Use PPP's internal network address translation or NO. ppp_profile="papchap" # Which profile to use from /etc/ppp/ppp.conf. ppp_user="root" # Which user to run ppp as # Start multiple instances of ppp at boot time #ppp_profile="profile1 profile2 profile3" # Which profiles to use #ppp_profile1_mode="ddial" # Override ppp mode for profile1 #ppp_profile2_nat="NO" # Override nat mode for profile2 # profile3 uses default ppp_mode and ppp_nat ### Network daemon (miscellaneous) ### hostapd_program="/usr/sbin/hostapd" hostapd_enable="NO" # Run hostap daemon. syslogd_enable="YES" # Run syslog daemon (or NO). syslogd_program="/usr/sbin/syslogd" # path to syslogd, if you want a different one. syslogd_flags="-s" # Flags to syslogd (if enabled). syslogd_oomprotect="YES" # Don't kill syslogd when swap space is exhausted. altlog_proglist="" # List of chrooted applicatioins in /var inetd_enable="NO" # Run the network daemon dispatcher (YES/NO). inetd_program="/usr/sbin/inetd" # path to inetd, if you want a different one. inetd_flags="-wW -C 60" # Optional flags to inetd iscsid_enable="NO" # iSCSI initiator daemon. iscsictl_enable="NO" # iSCSI initiator autostart. iscsictl_flags="-Aa" # Optional flags to iscsictl. hastd_enable="NO" # Run the HAST daemon (YES/NO). hastd_program="/sbin/hastd" # path to hastd, if you want a different one. hastd_flags="" # Optional flags to hastd. ggated_enable="NO" # Run the ggate daemon (YES/NO). ggated_config="/etc/gg.exports" # ggated(8) exports file. ggated_flags="" # Extra parameters like which port to bind to. ctld_enable="NO" # CAM Target Layer / iSCSI target daemon. local_unbound_enable="NO" # Local caching DNS resolver local_unbound_oomprotect="YES" # Don't kill local_unbound when swap space is exhausted. local_unbound_tls="NO" # Use DNS over TLS blacklistd_enable="NO" # Run blacklistd daemon (YES/NO). blacklistd_flags="" # Optional flags for blacklistd(8). resolv_enable="YES" # Enable resolv / resolvconf # # kerberos. Do not run the admin daemons on slave servers # kdc_enable="NO" # Run a kerberos 5 KDC (or NO). kdc_program="" # path to kerberos 5 KDC kdc_flags="" # Additional flags to the kerberos 5 KDC kdc_restart="NO" # Auto restart kdc on abnormal termination kdc_restart_delay="" # Auto restart delay seconds kadmind_enable="NO" # Run kadmind (or NO) kadmind_program="/usr/libexec/kadmind" # path to kadmind kpasswdd_enable="NO" # Run kpasswdd (or NO) kpasswdd_program="/usr/libexec/kpasswdd" # path to kpasswdd kfd_enable="NO" # Run kfd (or NO) kfd_program="/usr/libexec/kfd" # path to kerberos 5 kfd daemon kfd_flags="" ipropd_master_enable="NO" # Run Heimdal incremental propagation daemon # (master daemon). ipropd_master_program="/usr/libexec/ipropd-master" ipropd_master_flags="" # Flags to ipropd-master. ipropd_master_keytab="/etc/krb5.keytab" # keytab for ipropd-master. ipropd_master_slaves="" # slave node names used for /var/heimdal/slaves. ipropd_slave_enable="NO" # Run Heimdal incremental propagation daemon # (slave daemon). ipropd_slave_program="/usr/libexec/ipropd-slave" ipropd_slave_flags="" # Flags to ipropd-slave. ipropd_slave_keytab="/etc/krb5.keytab" # keytab for ipropd-slave. ipropd_slave_master="" # master node name. gssd_enable="NO" # Run the gssd daemon (or NO). gssd_program="/usr/sbin/gssd" # Path to gssd. gssd_flags="" # Flags for gssd. rwhod_enable="NO" # Run the rwho daemon (or NO). rwhod_flags="" # Flags for rwhod rarpd_enable="NO" # Run rarpd (or NO). rarpd_flags="-a" # Flags to rarpd. bootparamd_enable="NO" # Run bootparamd (or NO). bootparamd_flags="" # Flags to bootparamd pppoed_enable="NO" # Run the PPP over Ethernet daemon. pppoed_provider="*" # Provider and ppp(8) config file entry. pppoed_flags="-P /var/run/pppoed.pid" # Flags to pppoed (if enabled). pppoed_interface="em0" # The interface that pppoed runs on. sshd_enable="NO" # Enable sshd sshd_oomprotect="YES" # Don't kill sshd when swap space is exhausted. sshd_program="/usr/sbin/sshd" # path to sshd, if you want a different one. sshd_flags="" # Additional flags for sshd. ftpd_enable="NO" # Enable stand-alone ftpd. ftpd_program="/usr/libexec/ftpd" # Path to ftpd, if you want a different one. ftpd_flags="" # Additional flags to stand-alone ftpd. ### Network daemon (NFS): All need rpcbind_enable="YES" ### autofs_enable="NO" # Run autofs daemons. automount_flags="" # Flags to automount(8) (if autofs enabled). automountd_flags="" # Flags to automountd(8) (if autofs enabled). autounmountd_flags="" # Flags to autounmountd(8) (if autofs enabled). nfs_client_enable="NO" # This host is an NFS client (or NO). nfs_access_cache="60" # Client cache timeout in seconds nfs_server_enable="NO" # This host is an NFS server (or NO). nfs_server_flags="-u -t" # Flags to nfsd (if enabled). nfs_server_managegids="NO" # The NFS server maps gids for AUTH_SYS (or NO). nfs_server_maxio="131072" # Maximum I/O size for the nfsd. mountd_enable="NO" # Run mountd (or NO). mountd_flags="-r -S" # Flags to mountd (if NFS server enabled). weak_mountd_authentication="NO" # Allow non-root mount requests to be served. nfs_reserved_port_only="YES" # Provide NFS only on secure port (or NO). nfs_bufpackets="" # bufspace (in packets) for client rpc_lockd_enable="NO" # Run NFS rpc.lockd needed for client/server. rpc_lockd_flags="" # Flags to rpc.lockd (if enabled). rpc_statd_enable="NO" # Run NFS rpc.statd needed for client/server. rpc_statd_flags="" # Flags to rpc.statd (if enabled). rpcbind_enable="NO" # Run the portmapper service (YES/NO). rpcbind_program="/usr/sbin/rpcbind" # path to rpcbind, if you want a different one. rpcbind_flags="" # Flags to rpcbind (if enabled). rpc_ypupdated_enable="NO" # Run if NIS master and SecureRPC (or NO). nfsv4_server_enable="NO" # Enable support for NFSv4 nfsv4_server_only="NO" # Set NFS server to NFSv4 only nfscbd_enable="NO" # NFSv4 client side callback daemon nfscbd_flags="" # Flags for nfscbd nfsuserd_enable="NO" # NFSv4 user/group name mapping daemon nfsuserd_flags="" # Flags for nfsuserd tlsclntd_enable="NO" # Run rpc.tlsclntd needed for NFS-over-TLS mount tlsclntd_flags="" # Flags for rpc.tlsclntd tlsservd_enable="NO" # Run rpc.tlsservd needed for NFS-over-TLS nfsd tlsservd_flags="" # Flags for rpc.tlsservd ### Network Time Services options: ### ntpdate_enable="NO" # Run ntpdate to sync time on boot (or NO). ntpdate_program="/usr/sbin/ntpdate" # path to ntpdate, if you want a different one. ntpdate_flags="-b" # Flags to ntpdate (if enabled). ntpdate_config="/etc/ntp.conf" # ntpdate(8) configuration file ntpdate_hosts="" # Whitespace-separated list of ntpdate(8) servers. ntpd_enable="NO" # Run ntpd Network Time Protocol (or NO). ntpd_program="/usr/sbin/ntpd" # path to ntpd, if you want a different one. ntpd_config="/etc/ntp.conf" # ntpd(8) configuration file ntpd_sync_on_start="NO" # Sync time on ntpd startup, even if offset is high ntpd_flags="" # Additional flags to ntpd ntp_src_leapfile="/etc/ntp/leap-seconds" # Initial source for ntpd leapfile ntp_db_leapfile="/var/db/ntpd.leap-seconds.list" # Canonical place to get the leap seconds from ntp_leapfile_sources="https://hpiers.obspm.fr/iers/bul/bulc/ntp/leap-seconds.list https://data.iana.org/time-zones/tzdb/leap-seconds.list" # Source from which to fetch leapfile ntp_leapfile_fetch_opts="-mq" # Options to use for ntp leapfile fetch, # e.g. --no-verify-peer ntp_leapfile_expiry_days=30 # Check for new leapfile 30 days prior to # expiry. ntp_leapfile_fetch_verbose="NO" # Be verbose during NTP leapfile fetch # Network Information Services (NIS) options: All need rpcbind_enable="YES" ### nis_client_enable="NO" # We're an NIS client (or NO). nis_client_flags="" # Flags to ypbind (if enabled). nis_ypset_enable="NO" # Run ypset at boot time (or NO). nis_ypset_flags="" # Flags to ypset (if enabled). nis_server_enable="NO" # We're an NIS server (or NO). nis_server_flags="" # Flags to ypserv (if enabled). nis_ypxfrd_enable="NO" # Run rpc.ypxfrd at boot time (or NO). nis_ypxfrd_flags="" # Flags to rpc.ypxfrd (if enabled). nis_yppasswdd_enable="NO" # Run rpc.yppasswdd at boot time (or NO). nis_yppasswdd_flags="" # Flags to rpc.yppasswdd (if enabled). nis_ypldap_enable="NO" # Run ypldap at boot time (or NO). nis_ypldap_flags="" # Flags to ypldap (if enabled). ### SNMP daemon ### # Be sure to understand the security implications of running SNMP v1/v2 # in your network. bsnmpd_enable="NO" # Run the SNMP daemon (or NO). bsnmpd_flags="" # Flags for bsnmpd. ### Network routing options: ### defaultrouter="NO" # Set to default gateway (or NO). #defaultrouter_fibN="192.0.2.1" # Use this form to set a gateway for FIB N static_arp_pairs="" # Set to static ARP list (or leave empty). static_ndp_pairs="" # Set to static NDP list (or leave empty). static_routes="" # Set to static route list (or leave empty). gateway_enable="NO" # Set to YES if this host will be a gateway. routed_enable="NO" # Set to YES to enable a routing daemon. routed_program="/sbin/routed" # Name of routing daemon to use if enabled. routed_flags="-q" # Flags for routing daemon. arpproxy_all="NO" # replaces obsolete kernel option ARP_PROXYALL. forward_sourceroute="NO" # do source routing (only if gateway_enable is set to "YES") accept_sourceroute="NO" # accept source routed packets to us ### Bluetooth ### hcsecd_enable="NO" # Enable hcsecd(8) (or NO) hcsecd_config="/etc/bluetooth/hcsecd.conf" # hcsecd(8) configuration file sdpd_enable="NO" # Enable sdpd(8) (or NO) sdpd_control="/var/run/sdp" # sdpd(8) control socket sdpd_groupname="nobody" # set spdp(8) user/group to run as after sdpd_username="nobody" # it initializes bthidd_enable="NO" # Enable bthidd(8) (or NO) bthidd_config="/etc/bluetooth/bthidd.conf" # bthidd(8) configuration file bthidd_hids="/var/db/bthidd.hids" # bthidd(8) known HID devices file bthidd_evdev_support="AUTO" # AUTO depends on EVDEV_SUPPORT kernel option rfcomm_pppd_server_enable="NO" # Enable rfcomm_pppd(8) in server mode (or NO) rfcomm_pppd_server_profile="one two" # Profile to use from /etc/ppp/ppp.conf # #rfcomm_pppd_server_one_bdaddr="" # Override local bdaddr for 'one' rfcomm_pppd_server_one_channel="1" # Override local channel for 'one' #rfcomm_pppd_server_one_register_sp="NO" # Override SP and DUN register #rfcomm_pppd_server_one_register_dun="NO" # for 'one' # #rfcomm_pppd_server_two_bdaddr="" # Override local bdaddr for 'two' rfcomm_pppd_server_two_channel="3" # Override local channel for 'two' #rfcomm_pppd_server_two_register_sp="NO" # Override SP and DUN register #rfcomm_pppd_server_two_register_dun="NO" # for 'two' ubthidhci_enable="NO" # Switch an USB BT controller present on #ubthidhci_busnum="3" # bus 3 and addr 2 from HID mode to HCI mode. #ubthidhci_addr="2" # Check usbconfig list to find the correct # numbers for your system. ### Network link/usability verification options netwait_enable="NO" # Enable rc.d/netwait (or NO) #netwait_ip="" # Wait for ping response from any IP in this list. netwait_timeout="60" # Total number of seconds to perform pings. #netwait_if="" # Wait for active link on each intf in this list. netwait_if_timeout="30" # Total number of seconds to monitor link state. ### Miscellaneous network options: ### icmp_bmcastecho="NO" # respond to broadcast ping packets ### IPv6 options: ### ipv6_network_interfaces="auto" # List of IPv6 network interfaces # (or "auto" or "none"). ipv6_activate_all_interfaces="NO" # If NO, interfaces which have no # corresponding $ifconfig_IF_ipv6 is # marked as IFDISABLED for security # reason. ipv6_defaultrouter="NO" # Set to IPv6 default gateway (or NO). #ipv6_defaultrouter="2002:c058:6301::" # Use this for 6to4 (RFC 3068) #ipv6_defaultrouter_fibN="2001:db8::" # Use this form to set a gateway for FIB N ipv6_static_routes="" # Set to static route list (or leave empty). #ipv6_static_routes="xxx" # An example to set fec0:0000:0000:0006::/64 # route toward loopback interface. #ipv6_route_xxx="fec0:0000:0000:0006:: -prefixlen 64 ::1" ipv6_gateway_enable="NO" # Set to YES if this host will be a gateway. ipv6_cpe_wanif="NO" # Set to the upstream interface name if this # node will work as a router to forward IPv6 # packets not explicitly addressed to itself. ipv6_privacy="NO" # Use privacy address on RA-receiving IFs # (RFC 4941) route6d_enable="NO" # Set to YES to enable an IPv6 routing daemon. route6d_program="/usr/sbin/route6d" # Name of IPv6 routing daemon. route6d_flags="" # Flags to IPv6 routing daemon. #route6d_flags="-l" # Example for route6d with only IPv6 site local # addrs. #route6d_flags="-q" # If you want to run a routing daemon on an end # node, you should stop advertisement. #ipv6_network_interfaces="em0 em1" # Examples for router # or static configuration for end node. # Choose correct prefix value. #ipv6_prefix_em0="fec0:0000:0000:0001 fec0:0000:0000:0002" # Examples for rtr. #ipv6_prefix_em1="fec0:0000:0000:0003 fec0:0000:0000:0004" # Examples for rtr. ipv6_default_interface="NO" # Default output interface for scoped addrs. # This works only with # ipv6_gateway_enable="NO". rtsol_flags="-i" # Flags to IPv6 router solicitation. rtsold_enable="NO" # Set to YES to enable an IPv6 router # solicitation daemon. rtsold_flags="-a -i" # Flags to an IPv6 router solicitation # daemon. rtadvd_enable="NO" # Set to YES to enable an IPv6 router # advertisement daemon. If set to YES, # this router becomes a possible candidate # IPv6 default router for local subnets. rtadvd_flags="" # Flags to the IPv6 router advertisement daemon. rtadvd_interfaces="" # Interfaces rtadvd sends RA packets. stf_interface_ipv4addr="" # Local IPv4 addr for 6to4 IPv6 over IPv4 # tunneling interface. Specify this entry # to enable 6to4 interface. stf_interface_ipv4plen="0" # Prefix length for 6to4 IPv4 addr, # to limit peer addr range. Effective value # is 0-31. stf_interface_ipv6_ifid="0:0:0:1" # IPv6 interface id for stf0. # If you like, you can set "AUTO" for this. stf_interface_ipv6_slaid="0000" # IPv6 Site Level Aggregator for stf0 ipv6_ipv4mapping="NO" # Set to "YES" to enable IPv4 mapped IPv6 addr # communication. (like ::ffff:a.b.c.d) ip6addrctl_enable="YES" # Set to YES to enable default address selection ip6addrctl_verbose="NO" # Set to YES to enable verbose configuration messages ip6addrctl_policy="AUTO" # A pre-defined address selection policy # (ipv4_prefer, ipv6_prefer, or AUTO) ############################################################## ### System console options ################################# ############################################################## keyboard="" # keyboard device to use (default /dev/kbd0). keymap="NO" # keymap in /usr/share/{syscons,vt}/keymaps/* (or NO). keyrate="NO" # keyboard rate to: slow, normal, fast (or NO). keybell="NO" # See kbdcontrol(1) for options. Use "off" to disable. keychange="NO" # function keys default values (or NO). cursor="NO" # cursor type {normal|blink|destructive} (or NO). scrnmap="NO" # screen map in /usr/share/syscons/scrnmaps/* (or NO). font8x16="NO" # font 8x16 from /usr/share/{syscons,vt}/fonts/* (or NO). font8x14="NO" # font 8x14 from /usr/share/{syscons,vt}/fonts/* (or NO). font8x8="NO" # font 8x8 from /usr/share/{syscons,vt}/fonts/* (or NO). blanktime="300" # blank time (in seconds) or "NO" to turn it off. saver="NO" # screen saver: Uses /boot/kernel/${saver}_saver.ko moused_nondefault_enable="YES" # Treat non-default mice as enabled unless # specifically overridden in rc.conf(5). moused_enable="NO" # Run the mouse daemon. moused_type="auto" # See man page for rc.conf(5) for available settings. moused_port="/dev/psm0" # Set to your mouse port. moused_flags="" # Any additional flags to moused. mousechar_start="NO" # if 0xd0-0xd3 default range is occupied in your # language code table, specify alternative range # start like mousechar_start=3, see vidcontrol(1) allscreens_flags="" # Set this vidcontrol mode for all virtual screens allscreens_kbdflags="" # Set this kbdcontrol mode for all virtual screens ############################################################## ### Mail Transfer Agent (MTA) options ###################### ############################################################## # Settings for /etc/rc.d/sendmail: sendmail_enable="NONE" # Run the sendmail inbound daemon (YES/NO/NONE). # If NONE, don't start any sendmail processes. sendmail_pidfile="/var/run/sendmail.pid" # sendmail pid file sendmail_procname="/usr/sbin/sendmail" # sendmail process name sendmail_flags="-L sm-mta -bd -q30m" # Flags to sendmail (as a server) sendmail_cert_create="YES" # Create a server certificate if none (YES/NO) #sendmail_cert_cn="CN" # CN of the generate certificate sendmail_submit_enable="YES" # Start a localhost-only MTA for mail submission sendmail_submit_flags="-L sm-mta -bd -q30m -ODaemonPortOptions=Addr=localhost" # Flags for localhost-only MTA sendmail_outbound_enable="YES" # Dequeue stuck mail (YES/NO). sendmail_outbound_flags="-L sm-queue -q30m" # Flags to sendmail (outbound only) sendmail_msp_queue_enable="YES" # Dequeue stuck clientmqueue mail (YES/NO). sendmail_msp_queue_flags="-L sm-msp-queue -Ac -q30m" # Flags for sendmail_msp_queue daemon. sendmail_rebuild_aliases="NO" # Run newaliases if necessary (YES/NO). ############################################################## ### Miscellaneous administrative options ################### ############################################################## auditd_enable="NO" # Run the audit daemon. auditd_program="/usr/sbin/auditd" # Path to the audit daemon. auditd_flags="" # Which options to pass to the audit daemon. auditdistd_enable="NO" # Run the audit daemon. auditdistd_program="/usr/sbin/auditdistd" # Path to the auditdistd daemon. auditdistd_flags="" # Which options to pass to the auditdistd daemon. cron_enable="YES" # Run the periodic job daemon. cron_program="/usr/sbin/cron" # Which cron executable to run (if enabled). cron_dst="YES" # Handle DST transitions intelligently (YES/NO) cron_flags="" # Which options to pass to the cron daemon. cfumass_enable="NO" # Create default LUN for cfumass(4). cfumass_dir="/var/cfumass" # File to LUN's contents. cfumass_image="/var/tmp/cfumass.img" # LUN's backing file path. lpd_enable="NO" # Run the line printer daemon. lpd_program="/usr/sbin/lpd" # path to lpd, if you want a different one. lpd_flags="" # Flags to lpd (if enabled). nscd_enable="NO" # Run the nsswitch caching daemon. chkprintcap_enable="NO" # Run chkprintcap(8) before running lpd. chkprintcap_flags="-d" # Create missing directories by default. dumpdev="AUTO" # Device to crashdump to (device name, AUTO, or NO); # this should be commented out here # for stable branches to respect kenv. dumpon_flags="" # Options to pass to dumpon(8), followed by dumpdev. dumpdir="/var/crash" # Directory where crash dumps are to be stored savecore_enable="YES" # Extract core from dump devices if any savecore_flags="-m 10" # Used if dumpdev is enabled above, and present. # By default, only the 10 most recent kernel dumps # are saved. service_delete_empty="NO" # Have 'service delete' remove empty rc.conf.d files. crashinfo_enable="YES" # Automatically generate crash dump summary. crashinfo_program="/usr/sbin/crashinfo" # Script to generate crash dump summary. quota_enable="NO" # turn on quotas on startup (or NO). check_quotas="YES" # Check quotas on startup (or NO). quotaon_flags="-a" # Turn quotas on for all file systems (if enabled) quotaoff_flags="-a" # Turn quotas off for all file systems at shutdown quotacheck_flags="-a" # Check all file system quotas (if enabled) accounting_enable="NO" # Turn on process accounting (or NO). firstboot_sentinel="/firstboot" # Scripts with "firstboot" keyword are run if # this file exists. Should be on a R/W filesystem so # the file can be deleted after the boot completes. sysvipc_enable="NO" # Load System V IPC primitives at startup (or NO). linux_enable="NO" # Linux binary compatibility loaded at startup (or NO). linux_mounts_enable="YES" # If linux_enable is set to YES, mount Linux-specific # filesystems at startup. clear_tmp_enable="NO" # Clear /tmp at startup. clear_tmp_X="YES" # Clear and recreate X11-related directories in /tmp ldconfig_insecure="NO" # Set to YES to disable ldconfig security checks ldconfig_paths="/usr/lib/compat ${_localbase}/lib ${_localbase}/lib/compat/pkg" # shared library search paths ldconfig32_paths="/usr/lib32/compat" # 32-bit compatibility shared library search paths ldconfig_local_dirs="${_localbase}/libdata/ldconfig" # Local directories with ldconfig configuration files. ldconfig_local32_dirs="${_localbase}/libdata/ldconfig32" # Local directories with 32-bit compatibility ldconfig # configuration files. kern_securelevel_enable="NO" # kernel security level (see security(7)) kern_securelevel="-1" # range: -1..3 ; `-1' is the most insecure # Note that setting securelevel to 0 will result # in the system booting with securelevel set to 1, as # init(8) will raise the level when rc(8) completes. update_motd="YES" # update version info in /var/run/motd (or NO) entropy_boot_file="/boot/entropy" # Set to NO to disable very early # (used at early boot time) entropy caching through reboots. entropy_file="/entropy" # Set to NO to disable late (used when going multi-user) # entropy through reboots. # /var/db/entropy-file is preferred if / is not avail. entropy_dir="/var/db/entropy" # Set to NO to disable caching entropy via cron. entropy_save_sz="4096" # Size of the entropy cache files. entropy_save_num="8" # Number of entropy cache files to save. -harvest_mask="511" # Entropy device harvests all but the very invasive sources. +harvest_mask="4607" # Entropy device harvests all but the very invasive sources. # (See 'sysctl kern.random.harvest' and random(4)) osrelease_enable="YES" # Update /var/run/os-release on boot (or NO). osrelease_file="/var/run/os-release" # File to update for os-release. osrelease_perms="444" # Default permission for os-release file. dmesg_enable="YES" # Save dmesg(8) to /var/run/dmesg.boot watchdogd_enable="NO" # Start the software watchdog daemon watchdogd_flags="" # Flags to watchdogd (if enabled) watchdogd_timeout="" # watchdogd timeout, overrides -t in watchdogd_flags watchdogd_shutdown_timeout="" # Timeout to use after watchdogd is stopped. # Has effect only for system shutdown. # Overrides -x in watchdogd_flags. devfs_rulesets="/etc/defaults/devfs.rules /etc/devfs.rules" # Files containing # devfs(8) rules. devfs_system_ruleset="" # The name (NOT number) of a ruleset to apply to /dev devfs_set_rulesets="" # A list of /mount/dev=ruleset_name settings to # apply (must be mounted already, i.e. fstab(5)) devfs_load_rulesets="YES" # Enable to always load the default rulesets performance_cx_lowest="NONE" # Online CPU idle state performance_cpu_freq="NONE" # Online CPU frequency economy_cx_lowest="Cmax" # Offline CPU idle state economy_cpu_freq="NONE" # Offline CPU frequency virecover_enable="YES" # Perform housekeeping for the vi(1) editor ugidfw_enable="NO" # Load mac_bsdextended(4) rules on boot bsdextended_script="/etc/rc.bsdextended" # Default mac_bsdextended(4) # ruleset file. newsyslog_enable="YES" # Run newsyslog at startup. newsyslog_flags="-CN" # Newsyslog flags to create marked files mixer_enable="YES" # Run the sound mixer. opensm_enable="NO" # Opensm(8) for infiniband devices defaults to off nuageinit_enable="NO" # Run nuageinit at startup # rctl(8) requires kernel options RACCT and RCTL rctl_enable="YES" # Load rctl(8) rules on boot rctl_rules="/etc/rctl.conf" # rctl(8) ruleset. See rctl.conf(5). iovctl_files="" # Config files for iovctl(8) ############################################################## ### Jail Configuration (see rc.conf(5) manual page) ########## ############################################################## jail_enable="NO" # Set to NO to disable starting of any jails jail_conf="/etc/jail.conf" # Configuration file for jail(8) jail_confwarn="YES" # Prevent warning about obsolete per-jail configuration jail_parallel_start="NO" # Start jails in the background jail_list="" # Space separated list of names of jails jail_reverse_stop="NO" # Stop jails in reverse order ############################################################## ### Define source_rc_confs, the mechanism used by /etc/rc.* ## ### scripts to source rc_conf_files overrides safely. ## ############################################################## if [ -z "${source_rc_confs_defined}" ]; then source_rc_confs_defined=yes source_rc_confs() { local i sourced_files for i in ${rc_conf_files}; do case ${sourced_files} in *:$i:*) ;; *) sourced_files="${sourced_files}:$i:" if [ -r $i ]; then . $i fi ;; esac done # Re-do process to pick up [possibly] redefined $rc_conf_files for i in ${rc_conf_files}; do case ${sourced_files} in *:$i:*) ;; *) sourced_files="${sourced_files}:$i:" if [ -r $i ]; then . $i fi ;; esac done } fi # Allow vendors to override FreeBSD defaults in /etc/default/rc.conf # without the need to carefully manage /etc/rc.conf. if [ -r /etc/defaults/vendor.conf ]; then . /etc/defaults/vendor.conf fi diff --git a/sys/dev/random/random_harvestq.c b/sys/dev/random/random_harvestq.c index 29d4cd4d6857..c7762967c4fb 100644 --- a/sys/dev/random/random_harvestq.c +++ b/sys/dev/random/random_harvestq.c @@ -1,920 +1,921 @@ /*- * Copyright (c) 2017 Oliver Pinter * Copyright (c) 2017 W. Dean Freeman * Copyright (c) 2000-2015 Mark R V Murray * Copyright (c) 2013 Arthur Mesh * Copyright (c) 2004 Robert N. M. Watson * 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. * */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #if defined(RANDOM_ENABLE_ETHER) #define _RANDOM_HARVEST_ETHER_OFF 0 #else #define _RANDOM_HARVEST_ETHER_OFF (1u << RANDOM_NET_ETHER) #endif #if defined(RANDOM_ENABLE_UMA) #define _RANDOM_HARVEST_UMA_OFF 0 #else #define _RANDOM_HARVEST_UMA_OFF (1u << RANDOM_UMA) #endif /* * Note that random_sources_feed() will also use this to try and split up * entropy into a subset of pools per iteration with the goal of feeding * HARVESTSIZE into every pool at least once per second. */ #define RANDOM_KTHREAD_HZ 10 static void random_kthread(void); static void random_sources_feed(void); /* * Random must initialize much earlier than epoch, but we can initialize the * epoch code before SMP starts. Prior to SMP, we can safely bypass * concurrency primitives. */ static __read_mostly bool epoch_inited; static __read_mostly epoch_t rs_epoch; static const char *random_source_descr[ENTROPYSOURCE]; /* * How many events to queue up. We create this many items in * an 'empty' queue, then transfer them to the 'harvest' queue with * supplied junk. When used, they are transferred back to the * 'empty' queue. */ #define RANDOM_RING_MAX 1024 #define RANDOM_ACCUM_MAX 8 /* 1 to let the kernel thread run, 0 to terminate, -1 to mark completion */ volatile int random_kthread_control; /* Allow the sysadmin to select the broad category of * entropy types to harvest. */ __read_frequently u_int hc_source_mask; struct random_sources { CK_LIST_ENTRY(random_sources) rrs_entries; struct random_source *rrs_source; }; static CK_LIST_HEAD(sources_head, random_sources) source_list = CK_LIST_HEAD_INITIALIZER(source_list); SYSCTL_NODE(_kern_random, OID_AUTO, harvest, CTLFLAG_RW | CTLFLAG_MPSAFE, 0, "Entropy Device Parameters"); /* * Put all the harvest queue context stuff in one place. * this make is a bit easier to lock and protect. */ static struct harvest_context { /* The harvest mutex protects all of harvest_context and * the related data. */ struct mtx hc_mtx; /* Round-robin destination cache. */ u_int hc_destination[ENTROPYSOURCE]; /* The context of the kernel thread processing harvested entropy */ struct proc *hc_kthread_proc; /* * A pair of buffers for queued events. New events are added to the * active queue while the kthread processes the other one in parallel. */ struct entropy_buffer { struct harvest_event ring[RANDOM_RING_MAX]; u_int pos; } hc_entropy_buf[2]; u_int hc_active_buf; struct fast_entropy_accumulator { volatile u_int pos; uint32_t buf[RANDOM_ACCUM_MAX]; } hc_entropy_fast_accumulator; } harvest_context; #define RANDOM_HARVEST_INIT_LOCK() mtx_init(&harvest_context.hc_mtx, \ "entropy harvest mutex", NULL, MTX_SPIN) #define RANDOM_HARVEST_LOCK() mtx_lock_spin(&harvest_context.hc_mtx) #define RANDOM_HARVEST_UNLOCK() mtx_unlock_spin(&harvest_context.hc_mtx) static struct kproc_desc random_proc_kp = { "rand_harvestq", random_kthread, &harvest_context.hc_kthread_proc, }; /* Pass the given event straight through to Fortuna/Whatever. */ static __inline void random_harvestq_fast_process_event(struct harvest_event *event) { p_random_alg_context->ra_event_processor(event); explicit_bzero(event, sizeof(*event)); } static void random_kthread(void) { struct harvest_context *hc; hc = &harvest_context; for (random_kthread_control = 1; random_kthread_control;) { struct entropy_buffer *buf; u_int entries; /* Deal with queued events. */ RANDOM_HARVEST_LOCK(); buf = &hc->hc_entropy_buf[hc->hc_active_buf]; entries = buf->pos; buf->pos = 0; hc->hc_active_buf = (hc->hc_active_buf + 1) % nitems(hc->hc_entropy_buf); RANDOM_HARVEST_UNLOCK(); for (u_int i = 0; i < entries; i++) random_harvestq_fast_process_event(&buf->ring[i]); /* Poll sources of noise. */ random_sources_feed(); /* XXX: FIX!! Increase the high-performance data rate? Need some measurements first. */ for (u_int i = 0; i < RANDOM_ACCUM_MAX; i++) { if (hc->hc_entropy_fast_accumulator.buf[i]) { random_harvest_direct(&hc->hc_entropy_fast_accumulator.buf[i], sizeof(hc->hc_entropy_fast_accumulator.buf[0]), RANDOM_UMA); hc->hc_entropy_fast_accumulator.buf[i] = 0; } } /* XXX: FIX!! This is a *great* place to pass hardware/live entropy to random(9) */ tsleep_sbt(&hc->hc_kthread_proc, 0, "-", SBT_1S/RANDOM_KTHREAD_HZ, 0, C_PREL(1)); } random_kthread_control = -1; wakeup(&hc->hc_kthread_proc); kproc_exit(0); /* NOTREACHED */ } SYSINIT(random_device_h_proc, SI_SUB_KICK_SCHEDULER, SI_ORDER_ANY, kproc_start, &random_proc_kp); _Static_assert(SI_SUB_KICK_SCHEDULER > SI_SUB_RANDOM, "random kthread starting before subsystem initialization"); static void rs_epoch_init(void *dummy __unused) { rs_epoch = epoch_alloc("Random Sources", EPOCH_PREEMPT); epoch_inited = true; } SYSINIT(rs_epoch_init, SI_SUB_EPOCH, SI_ORDER_ANY, rs_epoch_init, NULL); /* * Run through all fast sources reading entropy for the given * number of rounds, which should be a multiple of the number * of entropy accumulation pools in use; it is 32 for Fortuna. */ static void random_sources_feed(void) { uint32_t entropy[HARVESTSIZE]; struct epoch_tracker et; struct random_sources *rrs; u_int i, n, npools; bool rse_warm; rse_warm = epoch_inited; /* * Evenly-ish distribute pool population across the second based on how * frequently random_kthread iterates. * * For Fortuna, the math currently works out as such: * * 64 bits * 4 pools = 256 bits per iteration * 256 bits * 10 Hz = 2560 bits per second, 320 B/s * */ npools = howmany(p_random_alg_context->ra_poolcount, RANDOM_KTHREAD_HZ); /*- * If we're not seeded yet, attempt to perform a "full seed", filling * all of the PRNG's pools with entropy; if there is enough entropy * available from "fast" entropy sources this will allow us to finish * seeding and unblock the boot process immediately rather than being * stuck for a few seconds with random_kthread gradually collecting a * small chunk of entropy every 1 / RANDOM_KTHREAD_HZ seconds. * * We collect RANDOM_FORTUNA_DEFPOOLSIZE bytes per pool, i.e. enough * to fill Fortuna's pools in the default configuration. With another * PRNG or smaller pools for Fortuna, we might collect more entropy * than needed to fill the pools, but this is harmless; alternatively, * a different PRNG, larger pools, or fast entropy sources which are * not able to provide as much entropy as we request may result in the * not being fully seeded (and thus remaining blocked) but in that * case we will return here after 1 / RANDOM_KTHREAD_HZ seconds and * try again for a large amount of entropy. */ if (!p_random_alg_context->ra_seeded()) npools = howmany(p_random_alg_context->ra_poolcount * RANDOM_FORTUNA_DEFPOOLSIZE, sizeof(entropy)); /* * Step over all of live entropy sources, and feed their output * to the system-wide RNG. */ if (rse_warm) epoch_enter_preempt(rs_epoch, &et); CK_LIST_FOREACH(rrs, &source_list, rrs_entries) { for (i = 0; i < npools; i++) { n = rrs->rrs_source->rs_read(entropy, sizeof(entropy)); KASSERT((n <= sizeof(entropy)), ("%s: rs_read returned too much data (%u > %zu)", __func__, n, sizeof(entropy))); /* * Sometimes the HW entropy source doesn't have anything * ready for us. This isn't necessarily untrustworthy. * We don't perform any other verification of an entropy * source (i.e., length is allowed to be anywhere from 1 * to sizeof(entropy), quality is unchecked, etc), so * don't balk verbosely at slow random sources either. * There are reports that RDSEED on x86 metal falls * behind the rate at which we query it, for example. * But it's still a better entropy source than RDRAND. */ if (n == 0) continue; random_harvest_direct(entropy, n, rrs->rrs_source->rs_source); } } if (rse_warm) epoch_exit_preempt(rs_epoch, &et); explicit_bzero(entropy, sizeof(entropy)); } /* * State used for conducting NIST SP 800-90B health tests on entropy sources. */ static struct health_test_softc { uint32_t ht_rct_value[HARVESTSIZE + 1]; u_int ht_rct_count; /* number of samples with the same value */ u_int ht_rct_limit; /* constant after init */ uint32_t ht_apt_value[HARVESTSIZE + 1]; u_int ht_apt_count; /* number of samples with the same value */ u_int ht_apt_seq; /* sequence number of the last sample */ u_int ht_apt_cutoff; /* constant after init */ uint64_t ht_total_samples; bool ondemand; /* Set to true to restart the state machine */ enum { INIT = 0, /* initial state */ DISABLED, /* health checking is disabled */ STARTUP, /* doing startup tests, samples are discarded */ STEADY, /* steady-state operation */ FAILED, /* health check failed, discard samples */ } ht_state; } healthtest[ENTROPYSOURCE]; #define RANDOM_SELFTEST_STARTUP_SAMPLES 1024 /* 4.3, requirement 4 */ #define RANDOM_SELFTEST_APT_WINDOW 512 /* 4.4.2 */ static void copy_event(uint32_t dst[static HARVESTSIZE + 1], const struct harvest_event *event) { memset(dst, 0, sizeof(uint32_t) * (HARVESTSIZE + 1)); memcpy(dst, event->he_entropy, event->he_size); dst[HARVESTSIZE] = event->he_somecounter; } static void random_healthtest_rct_init(struct health_test_softc *ht, const struct harvest_event *event) { ht->ht_rct_count = 1; copy_event(ht->ht_rct_value, event); } /* * Apply the repitition count test to a sample. * * Return false if the test failed, i.e., we observed >= C consecutive samples * with the same value, and true otherwise. */ static bool random_healthtest_rct_next(struct health_test_softc *ht, const struct harvest_event *event) { uint32_t val[HARVESTSIZE + 1]; copy_event(val, event); if (memcmp(val, ht->ht_rct_value, sizeof(ht->ht_rct_value)) != 0) { ht->ht_rct_count = 1; memcpy(ht->ht_rct_value, val, sizeof(ht->ht_rct_value)); return (true); } else { ht->ht_rct_count++; return (ht->ht_rct_count < ht->ht_rct_limit); } } static void random_healthtest_apt_init(struct health_test_softc *ht, const struct harvest_event *event) { ht->ht_apt_count = 1; ht->ht_apt_seq = 1; copy_event(ht->ht_apt_value, event); } static bool random_healthtest_apt_next(struct health_test_softc *ht, const struct harvest_event *event) { uint32_t val[HARVESTSIZE + 1]; if (ht->ht_apt_seq == 0) { random_healthtest_apt_init(ht, event); return (true); } copy_event(val, event); if (memcmp(val, ht->ht_apt_value, sizeof(ht->ht_apt_value)) == 0) { ht->ht_apt_count++; if (ht->ht_apt_count >= ht->ht_apt_cutoff) return (false); } ht->ht_apt_seq++; if (ht->ht_apt_seq == RANDOM_SELFTEST_APT_WINDOW) ht->ht_apt_seq = 0; return (true); } /* * Run the health tests for the given event. This is assumed to be called from * a serialized context. */ bool random_harvest_healthtest(const struct harvest_event *event) { struct health_test_softc *ht; ht = &healthtest[event->he_source]; /* * Was on-demand testing requested? Restart the state machine if so, * restarting the startup tests. */ if (atomic_load_bool(&ht->ondemand)) { atomic_store_bool(&ht->ondemand, false); ht->ht_state = INIT; } switch (ht->ht_state) { case __predict_false(INIT): /* Store the first sample and initialize test state. */ random_healthtest_rct_init(ht, event); random_healthtest_apt_init(ht, event); ht->ht_total_samples = 0; ht->ht_state = STARTUP; return (false); case DISABLED: /* No health testing for this source. */ return (true); case STEADY: case STARTUP: ht->ht_total_samples++; if (random_healthtest_rct_next(ht, event) && random_healthtest_apt_next(ht, event)) { if (ht->ht_state == STARTUP && ht->ht_total_samples >= RANDOM_SELFTEST_STARTUP_SAMPLES) { printf( "random: health test passed for source %s\n", random_source_descr[event->he_source]); ht->ht_state = STEADY; } return (ht->ht_state == STEADY); } ht->ht_state = FAILED; printf( "random: health test failed for source %s, discarding samples\n", random_source_descr[event->he_source]); /* FALLTHROUGH */ case FAILED: return (false); } } static bool nist_healthtest_enabled = false; SYSCTL_BOOL(_kern_random, OID_AUTO, nist_healthtest_enabled, CTLFLAG_RDTUN, &nist_healthtest_enabled, 0, "Enable NIST SP 800-90B health tests for noise sources"); static void random_healthtest_init(enum random_entropy_source source) { struct health_test_softc *ht; ht = &healthtest[source]; KASSERT(ht->ht_state == INIT, ("%s: health test state is %d for source %d", __func__, ht->ht_state, source)); /* * If health-testing is enabled, validate all sources except CACHED and * VMGENID: they are deterministic sources used only a small, fixed * number of times, so statistical testing is not applicable. */ if (!nist_healthtest_enabled || source == RANDOM_CACHED || source == RANDOM_PURE_VMGENID) { ht->ht_state = DISABLED; return; } /* * Set cutoff values for the two tests, assuming that each sample has * min-entropy of 1 bit and allowing for an error rate of 1 in 2^{34}. * With a sample rate of RANDOM_KTHREAD_HZ, we expect to see an false * positive once in ~54.5 years. * * The RCT limit comes from the formula in section 4.4.1. * * The APT cutoff is calculated using the formula in section 4.4.2 * footnote 10 with the window size changed from 512 to 511, since the * test as written counts the number of samples equal to the first * sample in the window, and thus tests W-1 samples. */ ht->ht_rct_limit = 35; ht->ht_apt_cutoff = 330; } static int random_healthtest_ondemand(SYSCTL_HANDLER_ARGS) { u_int mask, source; int error; mask = 0; error = sysctl_handle_int(oidp, &mask, 0, req); if (error != 0 || req->newptr == NULL) return (error); while (mask != 0) { source = ffs(mask) - 1; if (source < nitems(healthtest)) atomic_store_bool(&healthtest[source].ondemand, true); mask &= ~(1u << source); } return (0); } SYSCTL_PROC(_kern_random, OID_AUTO, nist_healthtest_ondemand, CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_MPSAFE, NULL, 0, random_healthtest_ondemand, "I", "Re-run NIST SP 800-90B startup health tests for a noise source"); static int random_check_uint_harvestmask(SYSCTL_HANDLER_ARGS) { static const u_int user_immutable_mask = (((1 << ENTROPYSOURCE) - 1) & (-1UL << RANDOM_PURE_START)) | _RANDOM_HARVEST_ETHER_OFF | _RANDOM_HARVEST_UMA_OFF; int error; u_int value, orig_value; orig_value = value = hc_source_mask; error = sysctl_handle_int(oidp, &value, 0, req); if (error != 0 || req->newptr == NULL) return (error); if (flsl(value) > ENTROPYSOURCE) return (EINVAL); /* * Disallow userspace modification of pure entropy sources. */ hc_source_mask = (value & ~user_immutable_mask) | (orig_value & user_immutable_mask); return (0); } SYSCTL_PROC(_kern_random_harvest, OID_AUTO, mask, CTLTYPE_UINT | CTLFLAG_RW | CTLFLAG_NEEDGIANT, NULL, 0, random_check_uint_harvestmask, "IU", "Entropy harvesting mask"); static int random_print_harvestmask(SYSCTL_HANDLER_ARGS) { struct sbuf sbuf; int error, i; error = sysctl_wire_old_buffer(req, 0); if (error == 0) { sbuf_new_for_sysctl(&sbuf, NULL, 128, req); for (i = ENTROPYSOURCE - 1; i >= 0; i--) sbuf_cat(&sbuf, (hc_source_mask & (1 << i)) ? "1" : "0"); error = sbuf_finish(&sbuf); sbuf_delete(&sbuf); } return (error); } SYSCTL_PROC(_kern_random_harvest, OID_AUTO, mask_bin, CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE, NULL, 0, random_print_harvestmask, "A", "Entropy harvesting mask (printable)"); static const char *random_source_descr[ENTROPYSOURCE] = { [RANDOM_CACHED] = "CACHED", [RANDOM_ATTACH] = "ATTACH", [RANDOM_KEYBOARD] = "KEYBOARD", [RANDOM_MOUSE] = "MOUSE", [RANDOM_NET_TUN] = "NET_TUN", [RANDOM_NET_ETHER] = "NET_ETHER", [RANDOM_NET_NG] = "NET_NG", [RANDOM_INTERRUPT] = "INTERRUPT", [RANDOM_SWI] = "SWI", [RANDOM_FS_ATIME] = "FS_ATIME", [RANDOM_UMA] = "UMA", - [RANDOM_CALLOUT] = "CALLOUT", /* ENVIRONMENTAL_END */ + [RANDOM_CALLOUT] = "CALLOUT", + [RANDOM_RANDOMDEV] = "RANDOMDEV", /* ENVIRONMENTAL_END */ [RANDOM_PURE_OCTEON] = "PURE_OCTEON", /* PURE_START */ [RANDOM_PURE_SAFE] = "PURE_SAFE", [RANDOM_PURE_GLXSB] = "PURE_GLXSB", [RANDOM_PURE_HIFN] = "PURE_HIFN", [RANDOM_PURE_RDRAND] = "PURE_RDRAND", [RANDOM_PURE_NEHEMIAH] = "PURE_NEHEMIAH", [RANDOM_PURE_RNDTEST] = "PURE_RNDTEST", [RANDOM_PURE_VIRTIO] = "PURE_VIRTIO", [RANDOM_PURE_BROADCOM] = "PURE_BROADCOM", [RANDOM_PURE_CCP] = "PURE_CCP", [RANDOM_PURE_DARN] = "PURE_DARN", [RANDOM_PURE_TPM] = "PURE_TPM", [RANDOM_PURE_VMGENID] = "PURE_VMGENID", [RANDOM_PURE_QUALCOMM] = "PURE_QUALCOMM", [RANDOM_PURE_ARMV8] = "PURE_ARMV8", [RANDOM_PURE_ARM_TRNG] = "PURE_ARM_TRNG", /* "ENTROPYSOURCE" */ }; static int random_print_harvestmask_symbolic(SYSCTL_HANDLER_ARGS) { struct sbuf sbuf; int error, i; bool first; first = true; error = sysctl_wire_old_buffer(req, 0); if (error == 0) { sbuf_new_for_sysctl(&sbuf, NULL, 128, req); for (i = ENTROPYSOURCE - 1; i >= 0; i--) { if (i >= RANDOM_PURE_START && (hc_source_mask & (1 << i)) == 0) continue; if (!first) sbuf_cat(&sbuf, ","); sbuf_cat(&sbuf, !(hc_source_mask & (1 << i)) ? "[" : ""); sbuf_cat(&sbuf, random_source_descr[i]); sbuf_cat(&sbuf, !(hc_source_mask & (1 << i)) ? "]" : ""); first = false; } error = sbuf_finish(&sbuf); sbuf_delete(&sbuf); } return (error); } SYSCTL_PROC(_kern_random_harvest, OID_AUTO, mask_symbolic, CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE, NULL, 0, random_print_harvestmask_symbolic, "A", "Entropy harvesting mask (symbolic)"); static void random_harvestq_init(void *unused __unused) { static const u_int almost_everything_mask = (((1 << (RANDOM_ENVIRONMENTAL_END + 1)) - 1) & ~_RANDOM_HARVEST_ETHER_OFF & ~_RANDOM_HARVEST_UMA_OFF); hc_source_mask = almost_everything_mask; RANDOM_HARVEST_INIT_LOCK(); harvest_context.hc_active_buf = 0; for (int i = 0; i < ENTROPYSOURCE; i++) random_healthtest_init(i); } SYSINIT(random_device_h_init, SI_SUB_RANDOM, SI_ORDER_THIRD, random_harvestq_init, NULL); /* * Subroutine to slice up a contiguous chunk of 'entropy' and feed it into the * underlying algorithm. Returns number of bytes actually fed into underlying * algorithm. */ static size_t random_early_prime(char *entropy, size_t len) { struct harvest_event event; size_t i; len = rounddown(len, sizeof(event.he_entropy)); if (len == 0) return (0); for (i = 0; i < len; i += sizeof(event.he_entropy)) { event.he_somecounter = random_get_cyclecount(); event.he_size = sizeof(event.he_entropy); event.he_source = RANDOM_CACHED; event.he_destination = harvest_context.hc_destination[RANDOM_CACHED]++; memcpy(event.he_entropy, entropy + i, sizeof(event.he_entropy)); random_harvestq_fast_process_event(&event); } explicit_bzero(entropy, len); return (len); } /* * Subroutine to search for known loader-loaded files in memory and feed them * into the underlying algorithm early in boot. Returns the number of bytes * loaded (zero if none were loaded). */ static size_t random_prime_loader_file(const char *type) { uint8_t *keyfile, *data; size_t size; keyfile = preload_search_by_type(type); if (keyfile == NULL) return (0); data = preload_fetch_addr(keyfile); size = preload_fetch_size(keyfile); if (data == NULL) return (0); return (random_early_prime(data, size)); } /* * This is used to prime the RNG by grabbing any early random stuff * known to the kernel, and inserting it directly into the hashing * module, currently Fortuna. */ static void random_harvestq_prime(void *unused __unused) { size_t size; /* * Get entropy that may have been preloaded by loader(8) * and use it to pre-charge the entropy harvest queue. */ size = random_prime_loader_file(RANDOM_CACHED_BOOT_ENTROPY_MODULE); if (bootverbose) { if (size > 0) printf("random: read %zu bytes from preloaded cache\n", size); else printf("random: no preloaded entropy cache\n"); } size = random_prime_loader_file(RANDOM_PLATFORM_BOOT_ENTROPY_MODULE); if (bootverbose) { if (size > 0) printf("random: read %zu bytes from platform bootloader\n", size); else printf("random: no platform bootloader entropy\n"); } } SYSINIT(random_device_prime, SI_SUB_RANDOM, SI_ORDER_MIDDLE, random_harvestq_prime, NULL); static void random_harvestq_deinit(void *unused __unused) { /* Command the hash/reseed thread to end and wait for it to finish */ random_kthread_control = 0; while (random_kthread_control >= 0) tsleep(&harvest_context.hc_kthread_proc, 0, "harvqterm", hz/5); } SYSUNINIT(random_device_h_init, SI_SUB_RANDOM, SI_ORDER_THIRD, random_harvestq_deinit, NULL); /*- * Entropy harvesting queue routine. * * This is supposed to be fast; do not do anything slow in here! * It is also illegal (and morally reprehensible) to insert any * high-rate data here. "High-rate" is defined as a data source * that is likely to fill up the buffer in much less than 100ms. * This includes the "always-on" sources like the Intel "rdrand" * or the VIA Nehamiah "xstore" sources. */ /* XXXRW: get_cyclecount() is cheap on most modern hardware, where cycle * counters are built in, but on older hardware it will do a real time clock * read which can be quite expensive. */ void random_harvest_queue_(const void *entropy, u_int size, enum random_entropy_source origin) { struct harvest_context *hc; struct entropy_buffer *buf; struct harvest_event *event; KASSERT(origin >= RANDOM_START && origin < ENTROPYSOURCE, ("%s: origin %d invalid", __func__, origin)); hc = &harvest_context; RANDOM_HARVEST_LOCK(); buf = &hc->hc_entropy_buf[hc->hc_active_buf]; if (buf->pos < RANDOM_RING_MAX) { event = &buf->ring[buf->pos++]; event->he_somecounter = random_get_cyclecount(); event->he_source = origin; event->he_destination = hc->hc_destination[origin]++; if (size <= sizeof(event->he_entropy)) { event->he_size = size; memcpy(event->he_entropy, entropy, size); } else { /* Big event, so squash it */ event->he_size = sizeof(event->he_entropy[0]); event->he_entropy[0] = jenkins_hash(entropy, size, (uint32_t)(uintptr_t)event); } } RANDOM_HARVEST_UNLOCK(); } /*- * Entropy harvesting fast routine. * * This is supposed to be very fast; do not do anything slow in here! * This is the right place for high-rate harvested data. */ void random_harvest_fast_(const void *entropy, u_int size) { u_int pos; pos = harvest_context.hc_entropy_fast_accumulator.pos; harvest_context.hc_entropy_fast_accumulator.buf[pos] ^= jenkins_hash(entropy, size, random_get_cyclecount()); harvest_context.hc_entropy_fast_accumulator.pos = (pos + 1)%RANDOM_ACCUM_MAX; } /*- * Entropy harvesting direct routine. * * This is not supposed to be fast, but will only be used during * (e.g.) booting when initial entropy is being gathered. */ void random_harvest_direct_(const void *entropy, u_int size, enum random_entropy_source origin) { struct harvest_event event; KASSERT(origin >= RANDOM_START && origin < ENTROPYSOURCE, ("%s: origin %d invalid\n", __func__, origin)); size = MIN(size, sizeof(event.he_entropy)); event.he_somecounter = random_get_cyclecount(); event.he_size = size; event.he_source = origin; event.he_destination = harvest_context.hc_destination[origin]++; memcpy(event.he_entropy, entropy, size); random_harvestq_fast_process_event(&event); } void random_harvest_register_source(enum random_entropy_source source) { hc_source_mask |= (1 << source); } void random_harvest_deregister_source(enum random_entropy_source source) { hc_source_mask &= ~(1 << source); } void random_source_register(struct random_source *rsource) { struct random_sources *rrs; KASSERT(rsource != NULL, ("invalid input to %s", __func__)); rrs = malloc(sizeof(*rrs), M_ENTROPY, M_WAITOK); rrs->rrs_source = rsource; random_harvest_register_source(rsource->rs_source); printf("random: registering fast source %s\n", rsource->rs_ident); RANDOM_HARVEST_LOCK(); CK_LIST_INSERT_HEAD(&source_list, rrs, rrs_entries); RANDOM_HARVEST_UNLOCK(); } void random_source_deregister(struct random_source *rsource) { struct random_sources *rrs = NULL; KASSERT(rsource != NULL, ("invalid input to %s", __func__)); random_harvest_deregister_source(rsource->rs_source); RANDOM_HARVEST_LOCK(); CK_LIST_FOREACH(rrs, &source_list, rrs_entries) if (rrs->rrs_source == rsource) { CK_LIST_REMOVE(rrs, rrs_entries); break; } RANDOM_HARVEST_UNLOCK(); if (rrs != NULL && epoch_inited) epoch_wait_preempt(rs_epoch); free(rrs, M_ENTROPY); } static int random_source_handler(SYSCTL_HANDLER_ARGS) { struct epoch_tracker et; struct random_sources *rrs; struct sbuf sbuf; int error, count; error = sysctl_wire_old_buffer(req, 0); if (error != 0) return (error); sbuf_new_for_sysctl(&sbuf, NULL, 64, req); count = 0; epoch_enter_preempt(rs_epoch, &et); CK_LIST_FOREACH(rrs, &source_list, rrs_entries) { sbuf_cat(&sbuf, (count++ ? ",'" : "'")); sbuf_cat(&sbuf, rrs->rrs_source->rs_ident); sbuf_cat(&sbuf, "'"); } epoch_exit_preempt(rs_epoch, &et); error = sbuf_finish(&sbuf); sbuf_delete(&sbuf); return (error); } SYSCTL_PROC(_kern_random, OID_AUTO, random_sources, CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE, NULL, 0, random_source_handler, "A", "List of active fast entropy sources."); MODULE_VERSION(random_harvestq, 1); diff --git a/sys/dev/random/randomdev.c b/sys/dev/random/randomdev.c index 9d1c7b1167c8..ced4dd8067d9 100644 --- a/sys/dev/random/randomdev.c +++ b/sys/dev/random/randomdev.c @@ -1,429 +1,429 @@ /*- * Copyright (c) 2017 Oliver Pinter * Copyright (c) 2000-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. * */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define RANDOM_UNIT 0 /* * In loadable random, the core randomdev.c / random(9) routines have static * visibility and an alternative name to avoid conflicting with the function * pointers of the real names in the core kernel. random_alg_context_init * installs pointers to the loadable static names into the core kernel's * function pointers at SI_SUB_RANDOM:SI_ORDER_SECOND. */ #if defined(RANDOM_LOADABLE) static int (read_random_uio)(struct uio *, bool); static void (read_random)(void *, u_int); static bool (is_random_seeded)(void); #endif static d_read_t randomdev_read; static d_write_t randomdev_write; static d_poll_t randomdev_poll; static d_ioctl_t randomdev_ioctl; static struct cdevsw random_cdevsw = { .d_name = "random", .d_version = D_VERSION, .d_read = randomdev_read, .d_write = randomdev_write, .d_poll = randomdev_poll, .d_ioctl = randomdev_ioctl, }; /* For use with make_dev(9)/destroy_dev(9). */ static struct cdev *random_dev; #if defined(RANDOM_LOADABLE) static void random_alg_context_init(void *dummy __unused) { _read_random_uio = (read_random_uio); _read_random = (read_random); _is_random_seeded = (is_random_seeded); } SYSINIT(random_device, SI_SUB_RANDOM, SI_ORDER_SECOND, random_alg_context_init, NULL); #endif static struct selinfo rsel; /* * This is the read uio(9) interface for random(4). */ /* ARGSUSED */ static int randomdev_read(struct cdev *dev __unused, struct uio *uio, int flags) { return ((read_random_uio)(uio, (flags & O_NONBLOCK) != 0)); } /* * If the random device is not seeded, blocks until it is seeded. * * Returns zero when the random device is seeded. * * If the 'interruptible' parameter is true, and the device is unseeded, this * routine may be interrupted. If interrupted, it will return either ERESTART * or EINTR. */ #define SEEDWAIT_INTERRUPTIBLE true #define SEEDWAIT_UNINTERRUPTIBLE false static int randomdev_wait_until_seeded(bool interruptible) { int error, spamcount, slpflags; slpflags = interruptible ? PCATCH : 0; error = 0; spamcount = 0; while (!p_random_alg_context->ra_seeded()) { /* keep tapping away at the pre-read until we seed/unblock. */ p_random_alg_context->ra_pre_read(); /* Only bother the console every 10 seconds or so */ if (spamcount == 0) printf("random: %s unblock wait\n", __func__); spamcount = (spamcount + 1) % 100; error = tsleep(p_random_alg_context, slpflags, "randseed", hz / 10); if (error == ERESTART || error == EINTR) { KASSERT(interruptible, ("unexpected wake of non-interruptible sleep")); break; } /* Squash tsleep timeout condition */ if (error == EWOULDBLOCK) error = 0; KASSERT(error == 0, ("unexpected tsleep error %d", error)); } return (error); } int (read_random_uio)(struct uio *uio, bool nonblock) { /* 16 MiB takes about 0.08 s CPU time on my 2017 AMD Zen CPU */ #define SIGCHK_PERIOD (16 * 1024 * 1024) const size_t sigchk_period = SIGCHK_PERIOD; CTASSERT(SIGCHK_PERIOD % PAGE_SIZE == 0); #undef SIGCHK_PERIOD uint8_t *random_buf; size_t total_read, read_len; ssize_t bufsize; int error; KASSERT(uio->uio_rw == UIO_READ, ("%s: bogus write", __func__)); KASSERT(uio->uio_resid >= 0, ("%s: bogus negative resid", __func__)); p_random_alg_context->ra_pre_read(); error = 0; /* (Un)Blocking logic */ if (!p_random_alg_context->ra_seeded()) { if (nonblock) error = EWOULDBLOCK; else error = randomdev_wait_until_seeded( SEEDWAIT_INTERRUPTIBLE); } if (error != 0) return (error); total_read = 0; /* Easy to deal with the trivial 0 byte case. */ if (__predict_false(uio->uio_resid == 0)) return (0); /* * If memory is plentiful, use maximally sized requests to avoid * per-call algorithm overhead. But fall back to a single page * allocation if the full request isn't immediately available. */ bufsize = MIN(sigchk_period, (size_t)uio->uio_resid); random_buf = malloc(bufsize, M_ENTROPY, M_NOWAIT); if (random_buf == NULL) { bufsize = PAGE_SIZE; random_buf = malloc(bufsize, M_ENTROPY, M_WAITOK); } error = 0; while (uio->uio_resid > 0 && error == 0) { read_len = MIN((size_t)uio->uio_resid, bufsize); p_random_alg_context->ra_read(random_buf, read_len); /* * uiomove() may yield the CPU before each 'read_len' bytes (up * to bufsize) are copied out. */ error = uiomove(random_buf, read_len, uio); total_read += read_len; /* * Poll for signals every few MBs to avoid very long * uninterruptible syscalls. */ if (error == 0 && uio->uio_resid != 0 && total_read % sigchk_period == 0) { error = tsleep_sbt(p_random_alg_context, PCATCH, "randrd", SBT_1NS, 0, C_HARDCLOCK); /* Squash tsleep timeout condition */ if (error == EWOULDBLOCK) error = 0; } } /* * Short reads due to signal interrupt should not indicate error. * Instead, the uio will reflect that the read was shorter than * requested. */ if (error == ERESTART || error == EINTR) error = 0; zfree(random_buf, M_ENTROPY); return (error); } /*- * Kernel API version of read_random(). This is similar to read_random_uio(), * except it doesn't interface with uio(9). It cannot assumed that random_buf * is a multiple of RANDOM_BLOCKSIZE bytes. * * If the tunable 'kern.random.initial_seeding.bypass_before_seeding' is set * non-zero, silently fail to emit random data (matching the pre-r346250 * behavior). If read_random is called prior to seeding and bypassed because * of this tunable, the condition is reported in the read-only sysctl * 'kern.random.initial_seeding.read_random_bypassed_before_seeding'. */ void (read_random)(void *random_buf, u_int len) { KASSERT(random_buf != NULL, ("No suitable random buffer in %s", __func__)); p_random_alg_context->ra_pre_read(); if (len == 0) return; /* (Un)Blocking logic */ if (__predict_false(!p_random_alg_context->ra_seeded())) { if (random_bypass_before_seeding) { if (!read_random_bypassed_before_seeding) { if (!random_bypass_disable_warnings) printf("read_random: WARNING: bypassing" " request for random data because " "the random device is not yet " "seeded and the knob " "'bypass_before_seeding' was " "enabled.\n"); read_random_bypassed_before_seeding = true; } /* Avoid potentially leaking stack garbage */ memset(random_buf, 0, len); return; } (void)randomdev_wait_until_seeded(SEEDWAIT_UNINTERRUPTIBLE); } p_random_alg_context->ra_read(random_buf, len); } bool (is_random_seeded)(void) { return (p_random_alg_context->ra_seeded()); } static __inline void randomdev_accumulate(uint8_t *buf, u_int count) { static u_int destination = 0; static struct harvest_event event; static struct randomdev_hash hash; static uint32_t entropy_data[RANDOM_KEYSIZE_WORDS]; uint32_t timestamp; int i; /* Extra timing here is helpful to scrape scheduler jitter entropy */ randomdev_hash_init(&hash); timestamp = random_get_cyclecount(); randomdev_hash_iterate(&hash, ×tamp, sizeof(timestamp)); randomdev_hash_iterate(&hash, buf, count); timestamp = random_get_cyclecount(); randomdev_hash_iterate(&hash, ×tamp, sizeof(timestamp)); randomdev_hash_finish(&hash, entropy_data); for (i = 0; i < RANDOM_KEYSIZE_WORDS; i += sizeof(event.he_entropy)/sizeof(event.he_entropy[0])) { event.he_somecounter = random_get_cyclecount(); event.he_size = sizeof(event.he_entropy); - event.he_source = RANDOM_CACHED; + event.he_source = RANDOM_RANDOMDEV; event.he_destination = destination++; /* Harmless cheating */ memcpy(event.he_entropy, entropy_data + i, sizeof(event.he_entropy)); p_random_alg_context->ra_event_processor(&event); } explicit_bzero(&event, sizeof(event)); explicit_bzero(entropy_data, sizeof(entropy_data)); } /* ARGSUSED */ static int randomdev_write(struct cdev *dev __unused, struct uio *uio, int flags __unused) { uint8_t *random_buf; int c, error = 0; ssize_t nbytes; random_buf = malloc(PAGE_SIZE, M_ENTROPY, M_WAITOK); nbytes = uio->uio_resid; while (uio->uio_resid > 0 && error == 0) { c = MIN(uio->uio_resid, PAGE_SIZE); error = uiomove(random_buf, c, uio); if (error) break; randomdev_accumulate(random_buf, c); } if (nbytes != uio->uio_resid && (error == ERESTART || error == EINTR)) /* Partial write, not error. */ error = 0; free(random_buf, M_ENTROPY); return (error); } /* ARGSUSED */ static int randomdev_poll(struct cdev *dev __unused, int events, struct thread *td __unused) { if (events & (POLLIN | POLLRDNORM)) { if (p_random_alg_context->ra_seeded()) events &= (POLLIN | POLLRDNORM); else selrecord(td, &rsel); } return (events); } /* This will be called by the entropy processor when it seeds itself and becomes secure */ void randomdev_unblock(void) { selwakeuppri(&rsel, PUSER); wakeup(p_random_alg_context); printf("random: unblocking device.\n"); #ifndef RANDOM_FENESTRASX /* Do random(9) a favour while we are about it. */ (void)atomic_cmpset_int(&arc4rand_iniseed_state, ARC4_ENTR_NONE, ARC4_ENTR_HAVE); #endif } /* ARGSUSED */ static int randomdev_ioctl(struct cdev *dev __unused, u_long cmd, caddr_t addr __unused, int flags __unused, struct thread *td __unused) { int error = 0; switch (cmd) { /* Really handled in upper layer */ case FIOASYNC: case FIONBIO: break; default: error = ENOTTY; } return (error); } /* ARGSUSED */ static int randomdev_modevent(module_t mod __unused, int type, void *data __unused) { int error = 0; switch (type) { case MOD_LOAD: printf("random: entropy device external interface\n"); random_dev = make_dev_credf(MAKEDEV_ETERNAL_KLD, &random_cdevsw, RANDOM_UNIT, NULL, UID_ROOT, GID_WHEEL, 0644, "random"); make_dev_alias(random_dev, "urandom"); /* compatibility */ break; case MOD_UNLOAD: error = EBUSY; break; case MOD_SHUTDOWN: break; default: error = EOPNOTSUPP; break; } return (error); } static moduledata_t randomdev_mod = { "random_device", randomdev_modevent, 0 }; DECLARE_MODULE(random_device, randomdev_mod, SI_SUB_DRIVERS, SI_ORDER_FIRST); MODULE_VERSION(random_device, 1); MODULE_DEPEND(random_device, crypto, 1, 1, 1); MODULE_DEPEND(random_device, random_harvestq, 1, 1, 1); diff --git a/sys/sys/random.h b/sys/sys/random.h index 254ba9451d0a..5abf762cd200 100644 --- a/sys/sys/random.h +++ b/sys/sys/random.h @@ -1,175 +1,176 @@ /*- * SPDX-License-Identifier: BSD-2-Clause * * Copyright (c) 2000-2015, 2017 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. */ #ifndef _SYS_RANDOM_H_ #define _SYS_RANDOM_H_ #include #ifdef _KERNEL struct uio; /* * In the loadable random world, there are set of dangling pointers left in the * core kernel: * * read_random, read_random_uio, is_random_seeded are function pointers, * rather than functions. * * p_random_alg_context is a true pointer in loadable random kernels. * * These are initialized at SI_SUB_RANDOM:SI_ORDER_SECOND during boot. The * read-type pointers are initialized by random_alg_context_init() in * randomdev.c and p_random_alg_context in the algorithm, e.g., fortuna.c's * random_fortuna_init_alg(). The nice thing about function pointers is they * have a similar calling convention to ordinary functions. * * (In !loadable, the read_random, etc, routines are just plain functions; * p_random_alg_context is a macro for the public visibility * &random_alg_context.) */ #if defined(RANDOM_LOADABLE) extern void (*_read_random)(void *, u_int); extern int (*_read_random_uio)(struct uio *, bool); extern bool (*_is_random_seeded)(void); #define read_random(a, b) (*_read_random)(a, b) #define read_random_uio(a, b) (*_read_random_uio)(a, b) #define is_random_seeded() (*_is_random_seeded)() #else void read_random(void *, u_int); int read_random_uio(struct uio *, bool); bool is_random_seeded(void); #endif /* * Note: if you add or remove members of random_entropy_source, remember to * also update the strings in the static array random_source_descr[] in * random_harvestq.c. */ enum random_entropy_source { RANDOM_START = 0, RANDOM_CACHED = 0, /* Environmental sources */ RANDOM_ATTACH, RANDOM_KEYBOARD, RANDOM_MOUSE, RANDOM_NET_TUN, RANDOM_NET_ETHER, RANDOM_NET_NG, RANDOM_INTERRUPT, RANDOM_SWI, RANDOM_FS_ATIME, RANDOM_UMA, /* Special!! UMA/SLAB Allocator */ RANDOM_CALLOUT, - RANDOM_ENVIRONMENTAL_END = RANDOM_CALLOUT, + RANDOM_RANDOMDEV, + RANDOM_ENVIRONMENTAL_END = RANDOM_RANDOMDEV, /* Fast hardware random-number sources from here on. */ RANDOM_PURE_START, RANDOM_PURE_OCTEON = RANDOM_PURE_START, RANDOM_PURE_SAFE, RANDOM_PURE_GLXSB, RANDOM_PURE_HIFN, RANDOM_PURE_RDRAND, RANDOM_PURE_NEHEMIAH, RANDOM_PURE_RNDTEST, RANDOM_PURE_VIRTIO, RANDOM_PURE_BROADCOM, RANDOM_PURE_CCP, RANDOM_PURE_DARN, RANDOM_PURE_TPM, RANDOM_PURE_VMGENID, RANDOM_PURE_QUALCOMM, RANDOM_PURE_ARMV8, RANDOM_PURE_ARM_TRNG, ENTROPYSOURCE }; _Static_assert(ENTROPYSOURCE <= 32, "hardcoded assumption that values fit in a typical word-sized bitset"); #define RANDOM_CACHED_BOOT_ENTROPY_MODULE "boot_entropy_cache" #define RANDOM_PLATFORM_BOOT_ENTROPY_MODULE "boot_entropy_platform" extern u_int hc_source_mask; void random_harvest_queue_(const void *, u_int, enum random_entropy_source); void random_harvest_fast_(const void *, u_int); void random_harvest_direct_(const void *, u_int, enum random_entropy_source); static __inline void random_harvest_queue(const void *entropy, u_int size, enum random_entropy_source origin) { if (hc_source_mask & (1 << origin)) random_harvest_queue_(entropy, size, origin); } static __inline void random_harvest_fast(const void *entropy, u_int size, enum random_entropy_source origin) { if (hc_source_mask & (1 << origin)) random_harvest_fast_(entropy, size); } static __inline void random_harvest_direct(const void *entropy, u_int size, enum random_entropy_source origin) { if (hc_source_mask & (1 << origin)) random_harvest_direct_(entropy, size, origin); } void random_harvest_register_source(enum random_entropy_source); void random_harvest_deregister_source(enum random_entropy_source); #if defined(RANDOM_ENABLE_UMA) #define random_harvest_fast_uma(a, b, c) random_harvest_fast(a, b, c) #else /* !defined(RANDOM_ENABLE_UMA) */ #define random_harvest_fast_uma(a, b, c) do {} while (0) #endif /* defined(RANDOM_ENABLE_UMA) */ #if defined(RANDOM_ENABLE_ETHER) #define random_harvest_queue_ether(a, b) random_harvest_queue(a, b, RANDOM_NET_ETHER) #else /* !defined(RANDOM_ENABLE_ETHER) */ #define random_harvest_queue_ether(a, b) do {} while (0) #endif /* defined(RANDOM_ENABLE_ETHER) */ #else /* !_KERNEL */ #if defined(_FORTIFY_SOURCE) && _FORTIFY_SOURCE > 0 #include #endif #endif /* _KERNEL */ #define GRND_NONBLOCK 0x1 #define GRND_RANDOM 0x2 #define GRND_INSECURE 0x4 __BEGIN_DECLS ssize_t getrandom(void *buf, size_t buflen, unsigned int flags); __END_DECLS #endif /* _SYS_RANDOM_H_ */