]> git.ipfire.org Git - thirdparty/gnutls.git/commitdiff
nettle: Support sysctl(KERN_ARND) for RNG on NetBSD.
authornia <nia@NetBSD.org>
Sat, 26 Oct 2019 19:58:49 +0000 (20:58 +0100)
committernia <nia@NetBSD.org>
Sat, 26 Oct 2019 19:58:49 +0000 (20:58 +0100)
This system call will never block and does not require a file
descriptor to be opened. It provides an endless stream of random
numbers from the kernel's ChaCha20-based random number generator.

Signed-off-by: Nia Alarie <nia@NetBSD.org>
configure.ac
lib/nettle/Makefile.am
lib/nettle/sysrng-netbsd.c [new file with mode: 0644]

index 146fe039cf7f4e6b3cd2150e076aca57798f9f6c..4e7a8ece556c6742315fc6fdd045e8bea464ca43 100644 (file)
@@ -261,6 +261,23 @@ AC_LINK_IFELSE([AC_LANG_PROGRAM([
                   rnd_variant=getrandom],
                  [AC_MSG_RESULT(no)])
 
+AC_MSG_CHECKING([for KERN_ARND])
+AC_LINK_IFELSE([AC_LANG_PROGRAM([
+          #include <sys/sysctl.h>
+           #ifdef __linux__
+           #error 1
+           #endif
+           static int name[] = {CTL_KERN, KERN_ARND};
+          ],[
+                  sysctl(0, 0, 0, 0, 0, 0);
+                 ])],
+                 [AC_MSG_RESULT(yes)
+                  AC_DEFINE([HAVE_KERN_ARND], 1, [Enable the BSD sysctl(KERN_ARND) function])
+                  rnd_variant=kern_arnd],
+                 [AC_MSG_RESULT(no)])
+
+AM_CONDITIONAL(HAVE_KERN_ARND, test "$rnd_variant" = "kern_arnd")
+
 AC_MSG_CHECKING([for getentropy])
 AC_LINK_IFELSE([AC_LANG_PROGRAM([
           #include <unistd.h>
index bd9dd753a6d2930d1c02abcc2e94a3b93b9aaca1..035102f127445012fe5569562540d54efe5a5a47 100644 (file)
@@ -56,9 +56,13 @@ else
 if HAVE_GETENTROPY
 libcrypto_la_SOURCES += sysrng-getentropy.c
 else
+if HAVE_KERN_ARND
+libcrypto_la_SOURCES += sysrng-netbsd.c
+else
 libcrypto_la_SOURCES += sysrng-linux.c
 endif
 endif
+endif
 
 libcrypto_la_SOURCES += rnd-fuzzer.c
 
diff --git a/lib/nettle/sysrng-netbsd.c b/lib/nettle/sysrng-netbsd.c
new file mode 100644 (file)
index 0000000..7fb3d8d
--- /dev/null
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2010-2016 Free Software Foundation, Inc.
+ * Copyright (C) 2015-2016 Red Hat, Inc.
+ *
+ * Author: Nia Alarie
+ *
+ * This file is part of GNUTLS.
+ *
+ * The GNUTLS library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program.  If not, see <https://www.gnu.org/licenses/>
+ *
+ */
+
+/*
+ * The *BSD sysctl-based system random generator.
+ * Used on NetBSD.
+ */
+
+#include "gnutls_int.h"
+#include "errors.h"
+#include <locks.h>
+#include <num.h>
+#include <errno.h>
+#include <rnd-common.h>
+
+#include <sys/sysctl.h>
+
+#define        ARRAY_SIZE(A)   (sizeof(A)/sizeof((A)[0]))
+
+get_entropy_func _rnd_get_system_entropy = NULL;
+
+static int _rnd_get_system_entropy_sysctl(void* _rnd, size_t size)
+{
+       static int name[] = {CTL_KERN, KERN_ARND};
+       size_t count, req;
+       unsigned char* p;
+
+       p = _rnd;
+       while (size) {
+               req = size < 32 ? size : 32;
+               count = req;
+
+               if (sysctl(name, ARRAY_SIZE(name), p, &count, NULL, 0) == -1) {
+                       return GNUTLS_E_RANDOM_DEVICE_ERROR;
+               }
+
+               if (count != req) {
+                       return GNUTLS_E_RANDOM_DEVICE_ERROR; /* Can't happen. */
+               }
+
+               p += count;
+               size -= count;
+       }
+
+       return 0;
+}
+
+int _rnd_system_entropy_init(void)
+{
+       _rnd_get_system_entropy = _rnd_get_system_entropy_sysctl;
+       return 0;
+}
+
+int _rnd_system_entropy_check(void)
+{
+       return 0;
+}
+
+void _rnd_system_entropy_deinit(void)
+{
+       return;
+}
+