summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon Josefsson <simon@josefsson.org>2004-08-16 19:10:30 +0000
committerSimon Josefsson <simon@josefsson.org>2004-08-16 19:10:30 +0000
commitf960d38c20612907b89b6f8c52c35f1c81d5e9f7 (patch)
tree33de0f18c42cf65bd6a6bbcf420103ccdb58acbb
parent8898bf167f4a15717536ebf00e86e2747bc486bc (diff)
downloadgnutls-f960d38c20612907b89b6f8c52c35f1c81d5e9f7.tar.gz
Move randomness calls to generic crypto API.
Implement randomness for libgcrypt and nettle wrappers.
-rw-r--r--configure.in69
-rw-r--r--crypto/gc-libgcrypt.c33
-rw-r--r--crypto/gc-nettle.c81
-rw-r--r--crypto/gc.h5
-rw-r--r--lib/gnutls_errors.c2
-rw-r--r--lib/gnutls_errors_int.h2
-rw-r--r--lib/gnutls_random.c30
-rw-r--r--lib/gnutls_random.h6
8 files changed, 217 insertions, 11 deletions
diff --git a/configure.in b/configure.in
index 81042ca7f7..262e162567 100644
--- a/configure.in
+++ b/configure.in
@@ -311,6 +311,75 @@ if test "$nettle" != "no" ; then
NETTLE_CFLAGS="-I\$(top_srcdir)/nettle"
NETTLE_LIBS="\$(top_builddir)/nettle/libnettle.la"
AX_CREATE_STDINT_H([nettle/nettle-types.h], [sys/types.h])
+
+ # Devices with randomness.
+ # FIXME: Are these the best defaults?
+ case "${target}" in
+ *-openbsd*)
+ NAME_OF_RANDOM_DEVICE="/dev/srandom"
+ NAME_OF_PSEUDO_RANDOM_DEVICE="/dev/prandom"
+ NAME_OF_NONCE_DEVICE="/dev/urandom"
+ ;;
+
+ *-netbsd*)
+ NAME_OF_RANDOM_DEVICE="/dev/srandom"
+ NAME_OF_PSEUDO_RANDOM_DEVICE="/dev/urandom"
+ NAME_OF_NONCE_DEVICE="/dev/urandom"
+ ;;
+
+ *-solaris* | *-irix* | *-dec-osf* )
+ NAME_OF_RANDOM_DEVICE="/dev/random"
+ NAME_OF_PSEUDO_RANDOM_DEVICE="/dev/random"
+ NAME_OF_NONCE_DEVICE="/dev/random"
+ ;;
+
+ *)
+ NAME_OF_RANDOM_DEVICE="/dev/random"
+ NAME_OF_PSEUDO_RANDOM_DEVICE="/dev/urandom"
+ NAME_OF_NONCE_DEVICE="/dev/urandom"
+ ;;
+ esac
+
+ AC_MSG_CHECKING([device with (strong) random data...])
+ AC_ARG_ENABLE(random-device,
+ AC_HELP_STRING([--enable-random-device],
+ [device with (strong) randomness (for Nettle)]),
+ NAME_OF_RANDOM_DEVICE=$enableval)
+ AC_MSG_RESULT($NAME_OF_RANDOM_DEVICE)
+
+ AC_MSG_CHECKING([device with pseudo random data...])
+ AC_ARG_ENABLE(pseudo-random-device,
+ AC_HELP_STRING([--enable-pseudo-random-device],
+ [device with pseudo randomness (for Nettle)]),
+ NAME_OF_PSEUDO_RANDOM_DEVICE=$enableval)
+ AC_MSG_RESULT($NAME_OF_PSEUDO_RANDOM_DEVICE)
+
+ AC_MSG_CHECKING([device with unpredictable data for nonces...])
+ AC_ARG_ENABLE(nonce-device,
+ AC_HELP_STRING([--enable-nonce-device],
+ [device with unpredictable nonces (for Nettle)]),
+ NAME_OF_NONCE_DEVICE=$enableval)
+ AC_MSG_RESULT($NAME_OF_NONCE_DEVICE)
+
+ AC_CHECK_FILE($NAME_OF_RANDOM_DEVICE,, AC_MSG_ERROR([[
+*** Device for (strong) random data $NAME_OF_RANDOM_DEVICE does not exist
+]]))
+ AC_CHECK_FILE($NAME_OF_PSEUDO_RANDOM_DEVICE,, AC_MSG_ERROR([[
+*** Device for pseudo-random data $NAME_OF_PSEUDO_RANDOM_DEVICE does not exist
+]]))
+ AC_CHECK_FILE($NAME_OF_NONCE_DEVICE,, AC_MSG_ERROR([[
+*** Device for unpredictable nonces $NAME_OF_NONCE_DEVICE does not exist
+]]))
+
+ # FIXME: Open+read 42 bytes+close twice and compare data. Should differ.
+
+ AC_DEFINE_UNQUOTED(NAME_OF_RANDOM_DEVICE, "$NAME_OF_RANDOM_DEVICE",
+ [defined to the name of the (strong) random device])
+ AC_DEFINE_UNQUOTED(NAME_OF_PSEUDO_RANDOM_DEVICE,
+ "$NAME_OF_PSEUDO_RANDOM_DEVICE",
+ [defined to the name of the pseudo random device])
+ AC_DEFINE_UNQUOTED(NAME_OF_NONCE_DEVICE, "$NAME_OF_NONCE_DEVICE",
+ [defined to the name of the unpredictable nonce device])
else
AC_MSG_RESULT(no)
fi
diff --git a/crypto/gc-libgcrypt.c b/crypto/gc-libgcrypt.c
index bd776eaca9..84c4ee7f5f 100644
--- a/crypto/gc-libgcrypt.c
+++ b/crypto/gc-libgcrypt.c
@@ -22,12 +22,18 @@
/* Note: This file is only built if GC uses Libgcrypt. */
+#if HAVE_CONFIG_H
+# include <config.h>
+#endif
+
/* Get prototype. */
#include <gc.h>
/* Get libgcrypt API. */
#include <gcrypt.h>
+/* Initialization. */
+
int
gc_init (void)
{
@@ -53,6 +59,31 @@ gc_done (void)
return;
}
+/* Randomness. */
+
+int
+gc_nonce (char *data, size_t datalen)
+{
+ gcry_create_nonce ((unsigned char *) data, datalen);
+ return GC_OK;
+}
+
+int
+gc_pseudo_random (char *data, size_t datalen)
+{
+ gcry_randomize ((unsigned char *) data, datalen, GCRY_STRONG_RANDOM);
+ return GC_OK;
+}
+
+int
+gc_random (char *data, size_t datalen)
+{
+ gcry_randomize ((unsigned char *) data, datalen, GCRY_VERY_STRONG_RANDOM);
+ return GC_OK;
+}
+
+/* Memory allocation. */
+
void
gc_set_allocators (gc_malloc_t func_malloc,
gc_malloc_t secure_malloc,
@@ -63,6 +94,8 @@ gc_set_allocators (gc_malloc_t func_malloc,
func_realloc, func_free);
}
+/* Ciphers. */
+
int
gc_cipher_open (int alg, int mode, gc_cipher * outhandle)
{
diff --git a/crypto/gc-nettle.c b/crypto/gc-nettle.c
index fdaf521cf6..68d05775fa 100644
--- a/crypto/gc-nettle.c
+++ b/crypto/gc-nettle.c
@@ -22,11 +22,21 @@
/* Note: This file is only built if GC uses Nettle. */
+#if HAVE_CONFIG_H
+# include <config.h>
+#endif
+
#include <stdlib.h>
/* Get prototype. */
#include <gc.h>
+/* For randomize. */
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
/* XXX GnuTLS still need Libgcrypt. */
#include <gcrypt.h>
@@ -57,6 +67,75 @@ gc_done (void)
return;
}
+/* Randomness. */
+
+static int
+randomize (int level, char *data, size_t datalen)
+{
+ int fd;
+ char *device;
+ size_t len = 0;
+ int rc;
+
+ switch (level)
+ {
+ case 0:
+ device = NAME_OF_NONCE_DEVICE;
+ break;
+
+ case 1:
+ device = NAME_OF_PSEUDO_RANDOM_DEVICE;
+ break;
+
+ default:
+ device = NAME_OF_RANDOM_DEVICE;
+ break;
+ }
+
+ fd = open (device, O_RDONLY);
+ if (fd < 0)
+ return GC_RANDOM_ERROR;
+
+ do
+ {
+ ssize_t tmp;
+
+ tmp = read (fd, data, datalen);
+
+ if (tmp < 0)
+ return GC_RANDOM_ERROR;
+
+ len += tmp;
+ }
+ while (len < datalen);
+
+ rc = close (fd);
+ if (rc < 0)
+ return GC_RANDOM_ERROR;
+
+ return GC_OK;
+}
+
+int
+gc_nonce (char *data, size_t datalen)
+{
+ return randomize (0, data, datalen);
+}
+
+int
+gc_pseudo_random (char *data, size_t datalen)
+{
+ return randomize (1, data, datalen);
+}
+
+int
+gc_random (char *data, size_t datalen)
+{
+ return randomize (2, data, datalen);
+}
+
+/* Memory allocation. */
+
void
gc_set_allocators (gc_malloc_t func_malloc,
gc_malloc_t secure_malloc,
@@ -68,6 +147,8 @@ gc_set_allocators (gc_malloc_t func_malloc,
func_realloc, func_free);
}
+/* Ciphers. */
+
#include "nettle-meta.h"
#include "aes.h"
diff --git a/crypto/gc.h b/crypto/gc.h
index 3f912bfc26..ae3469c8f8 100644
--- a/crypto/gc.h
+++ b/crypto/gc.h
@@ -31,6 +31,7 @@ enum Gc_rc
GC_OK = 0,
GC_MALLOC_ERROR,
GC_INIT_ERROR,
+ GC_RANDOM_ERROR,
GC_INVALID_CIPHER
};
typedef enum Gc_rc Gc_rc;
@@ -60,6 +61,10 @@ typedef void *gc_cipher;
extern int gc_init (void);
extern void gc_done (void);
+extern int gc_nonce (char *data, size_t datalen);
+extern int gc_pseudo_random (char *data, size_t datalen);
+extern int gc_random (char *data, size_t datalen);
+
/* Memory allocation (avoid). */
typedef void *(*gc_malloc_t) (size_t n);
typedef int (*gc_secure_check_t) (const void *);
diff --git a/lib/gnutls_errors.c b/lib/gnutls_errors.c
index 66da4496f4..6edc98eba6 100644
--- a/lib/gnutls_errors.c
+++ b/lib/gnutls_errors.c
@@ -1,4 +1,5 @@
/*
+ * Copyright (C) 2004 Simon Josefsson
* Copyright (C) 2000,2001,2002,2003 Nikos Mavroyanopoulos
* Copyright (C) 2004 Free Software Foundation
*
@@ -228,6 +229,7 @@ static gnutls_error_entry error_algorithms[] = {
ERROR_ENTRY("The Message Authentication Code verification failed.",
GNUTLS_E_MAC_VERIFY_FAILED, 1),
ERROR_ENTRY("Some constraint limits were reached.", GNUTLS_E_CONSTRAINT_ERROR, 1),
+ ERROR_ENTRY("Failed to acquire random data.", GNUTLS_E_RANDOM_FAILED, 1),
{NULL, NULL, 0, 0}
};
diff --git a/lib/gnutls_errors_int.h b/lib/gnutls_errors_int.h
index 97f242ae00..c3e1543c8b 100644
--- a/lib/gnutls_errors_int.h
+++ b/lib/gnutls_errors_int.h
@@ -125,6 +125,8 @@
#define GNUTLS_E_OPENPGP_KEYRING_ERROR -204
#define GNUTLS_E_X509_UNSUPPORTED_OID -205
+#define GNUTLS_E_RANDOM_FAILED -206
+
#define GNUTLS_E_UNIMPLEMENTED_FEATURE -1250
/* _INT_ internal errors. Not exported */
diff --git a/lib/gnutls_random.c b/lib/gnutls_random.c
index d8360e8e66..e53a593fd1 100644
--- a/lib/gnutls_random.c
+++ b/lib/gnutls_random.c
@@ -1,16 +1,17 @@
/*
+ * Copyright (C) 2004 Simon Josefsson
* Copyright (C) 2001,2003 Nikos Mavroyanopoulos
* Copyright (C) 2004 Free Software Foundation
*
* 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
+ * 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
+ * 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.
*
@@ -32,12 +33,25 @@
*/
int _gnutls_get_random(opaque * res, int bytes, int level)
{
- if (level == GNUTLS_WEAK_RANDOM) {
- gcry_create_nonce(res, bytes);
- return 0;
+ int err;
+
+ switch (level)
+ {
+ case GNUTLS_WEAK_RANDOM:
+ err = gc_nonce ((char*) res, (size_t) bytes);
+ break;
+
+ case GNUTLS_STRONG_RANDOM:
+ err = gc_pseudo_random ((char*) res, (size_t) bytes);
+ break;
+
+ default: /* GNUTLS_VERY_STRONG_RANDOM */
+ err = gc_random ((char*) res, (size_t) bytes);
+ break;
}
- gcry_randomize(res, bytes, level);
+ if (err != GC_OK)
+ return GNUTLS_E_RANDOM_FAILED;
- return 0;
+ return GNUTLS_E_SUCCESS;
}
diff --git a/lib/gnutls_random.h b/lib/gnutls_random.h
index 2cbde3cbf6..3b304b4930 100644
--- a/lib/gnutls_random.h
+++ b/lib/gnutls_random.h
@@ -1,7 +1,7 @@
#include "defines.h"
-#define GNUTLS_WEAK_RANDOM GCRY_WEAK_RANDOM
-#define GNUTLS_STRONG_RANDOM GCRY_STRONG_RANDOM
-#define GNUTLS_VERY_STRONG_RANDOM GCRY_VERY_STRONG_RANDOM
+#define GNUTLS_WEAK_RANDOM 0
+#define GNUTLS_STRONG_RANDOM 1
+#define GNUTLS_VERY_STRONG_RANDOM 2
int _gnutls_get_random(opaque * res, int bytes, int);