From owner-svn-src-all@freebsd.org Wed May 8 00:45:17 2019 Return-Path: Delivered-To: svn-src-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 3A1B815987FD; Wed, 8 May 2019 00:45:17 +0000 (UTC) (envelope-from cem@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) server-signature RSA-PSS (4096 bits) client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id D4BDD83BE9; Wed, 8 May 2019 00:45:16 +0000 (UTC) (envelope-from cem@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id B08F5262AA; Wed, 8 May 2019 00:45:16 +0000 (UTC) (envelope-from cem@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id x480jGQ6032141; Wed, 8 May 2019 00:45:16 GMT (envelope-from cem@FreeBSD.org) Received: (from cem@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id x480jGpo032140; Wed, 8 May 2019 00:45:16 GMT (envelope-from cem@FreeBSD.org) Message-Id: <201905080045.x480jGpo032140@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: cem set sender to cem@FreeBSD.org using -f From: Conrad Meyer Date: Wed, 8 May 2019 00:45:16 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r347239 - head/sys/dev/random X-SVN-Group: head X-SVN-Commit-Author: cem X-SVN-Commit-Paths: head/sys/dev/random X-SVN-Commit-Revision: 347239 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Rspamd-Queue-Id: D4BDD83BE9 X-Spamd-Bar: -- Authentication-Results: mx1.freebsd.org X-Spamd-Result: default: False [-2.97 / 15.00]; local_wl_from(0.00)[FreeBSD.org]; NEURAL_HAM_MEDIUM(-1.00)[-0.999,0]; NEURAL_HAM_SHORT(-0.97)[-0.969,0]; NEURAL_HAM_LONG(-1.00)[-1.000,0]; ASN(0.00)[asn:11403, ipnet:2610:1c1:1::/48, country:US] X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 08 May 2019 00:45:17 -0000 Author: cem Date: Wed May 8 00:45:16 2019 New Revision: 347239 URL: https://svnweb.freebsd.org/changeset/base/347239 Log: random: x86 driver: Prefer RDSEED over RDRAND when available Per https://software.intel.com/en-us/blogs/2012/11/17/the-difference-between-rdrand-and-rdseed , RDRAND is a PRNG seeded from the same source as RDSEED. The source is more suitable as PRNG seed material, so prefer it when the RDSEED intrinsic is available (indicated in CPU feature bits). Reviewed by: delphij, jhb, imp (earlier version) Approved by: secteam(delphij) Security: yes Sponsored by: Dell EMC Isilon Differential Revision: https://reviews.freebsd.org/D20192 Modified: head/sys/dev/random/ivy.c Modified: head/sys/dev/random/ivy.c ============================================================================== --- head/sys/dev/random/ivy.c Wed May 8 00:40:08 2019 (r347238) +++ head/sys/dev/random/ivy.c Wed May 8 00:45:16 2019 (r347239) @@ -44,11 +44,13 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include #define RETRY_COUNT 10 +static bool has_rdrand, has_rdseed; static u_int random_ivy_read(void *, u_int); static struct random_source random_ivy = { @@ -57,10 +59,9 @@ static struct random_source random_ivy = { .rs_read = random_ivy_read }; -static inline int -ivy_rng_store(u_long *buf) +static int +x86_rdrand_store(u_long *buf) { -#ifdef __GNUCLIKE_ASM u_long rndval; int retry; @@ -75,11 +76,40 @@ ivy_rng_store(u_long *buf) : "+r" (retry), "=r" (rndval) : : "cc"); *buf = rndval; return (retry); -#else /* __GNUCLIKE_ASM */ - return (0); -#endif } +static int +x86_rdseed_store(u_long *buf) +{ + u_long rndval; + int retry; + + retry = RETRY_COUNT; + __asm __volatile( + "1:\n\t" + "rdseed %1\n\t" /* read randomness into rndval */ + "jc 2f\n\t" /* CF is set on success, exit retry loop */ + "dec %0\n\t" /* otherwise, retry-- */ + "jne 1b\n\t" /* and loop if retries are not exhausted */ + "2:" + : "+r" (retry), "=r" (rndval) : : "cc"); + *buf = rndval; + return (retry); +} + +DEFINE_IFUNC(static, int, x86_rng_store, (u_long *buf), static) +{ + has_rdrand = (cpu_feature2 & CPUID2_RDRAND); + has_rdseed = (cpu_stdext_feature & CPUID_STDEXT_RDSEED); + + if (has_rdseed) + return (x86_rdseed_store); + else if (has_rdrand) + return (x86_rdrand_store); + else + return (NULL); +} + /* It is required that buf length is a multiple of sizeof(u_long). */ static u_int random_ivy_read(void *buf, u_int c) @@ -90,7 +120,7 @@ random_ivy_read(void *buf, u_int c) KASSERT(c % sizeof(*b) == 0, ("partial read %d", c)); b = buf; for (count = c; count > 0; count -= sizeof(*b)) { - if (ivy_rng_store(&rndval) == 0) + if (x86_rng_store(&rndval) == 0) break; *b++ = rndval; } @@ -104,14 +134,14 @@ rdrand_modevent(module_t mod, int type, void *unused) switch (type) { case MOD_LOAD: - if (cpu_feature2 & CPUID2_RDRAND) { + if (has_rdrand || has_rdseed) { random_source_register(&random_ivy); printf("random: fast provider: \"%s\"\n", random_ivy.rs_ident); } break; case MOD_UNLOAD: - if (cpu_feature2 & CPUID2_RDRAND) + if (has_rdrand || has_rdseed) random_source_deregister(&random_ivy); break;