URL: https://github.com/SSSD/sssd/pull/838
Author: alexey-tikhonov
 Title: #838: FIPS140 compliant usage of PRNG
Action: opened

PR body:
"""
Resolves https://pagure.io/SSSD/sssd/issue/4024
"""

To pull the PR as Git branch:
git remote add ghsssd https://github.com/SSSD/sssd
git fetch ghsssd pull/838/head:pr838
git checkout pr838
From 8a0e1d79653eeed48178d7893bbfc6b7fb492649 Mon Sep 17 00:00:00 2001
From: Alexey Tikhonov <[email protected]>
Date: Fri, 14 Jun 2019 12:47:41 +0200
Subject: [PATCH 1/6] util/crypto: removed erroneous declaration

---
 src/util/crypto/sss_crypto.h | 2 --
 1 file changed, 2 deletions(-)

diff --git a/src/util/crypto/sss_crypto.h b/src/util/crypto/sss_crypto.h
index f8778cdbbd..cd1b4aef25 100644
--- a/src/util/crypto/sss_crypto.h
+++ b/src/util/crypto/sss_crypto.h
@@ -33,8 +33,6 @@ enum obfmethod {
     NUM_OBFMETHODS
 };
 
-int test2(void);
-
 char *sss_base64_encode(TALLOC_CTX *mem_ctx,
                         const unsigned char *in,
                         size_t insize);

From 1a3ea8457900b319d64788f72b6639072f00c23f Mon Sep 17 00:00:00 2001
From: Alexey Tikhonov <[email protected]>
Date: Fri, 14 Jun 2019 14:13:56 +0200
Subject: [PATCH 2/6] util/crypto/sss_crypto.c: cleanup of includes

Removed unneeded include of config.h and added includes for open()
and error codes according to the man page.
---
 src/util/crypto/sss_crypto.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/src/util/crypto/sss_crypto.c b/src/util/crypto/sss_crypto.c
index 5958155d41..582f2caab1 100644
--- a/src/util/crypto/sss_crypto.c
+++ b/src/util/crypto/sss_crypto.c
@@ -18,14 +18,16 @@
     along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
-#include "config.h"
 
+#include <errno.h>
+#include <sys/types.h>
 #include <sys/stat.h>
 #include <fcntl.h>
 
 #include "util/util.h"
 #include "util/crypto/sss_crypto.h"
 
+
 int generate_csprng_buffer(uint8_t *buf, size_t size)
 {
     ssize_t rsize;

From 3e563fc1b42cb4a32f905bbd701f4461050c7ee6 Mon Sep 17 00:00:00 2001
From: Alexey Tikhonov <[email protected]>
Date: Fri, 14 Jun 2019 19:04:08 +0200
Subject: [PATCH 3/6] util/crypto: generate_csprng_buffer() changed

1) generate_csprng_buffer() is renamed to sss_generate_csprng_buffer()
to make util/crypto API more consistent
2) its implementation became dependant on crypto backend being used
3) in case of libcrypto backend RAND_bytes() is used instead of
direct access to "/dev/urandom"

Relates: https://pagure.io/SSSD/sssd/issue/4024
---
 Makefile.am                                   | 12 +++---
 src/util/crypto/libcrypto/crypto_prng.c       | 37 +++++++++++++++++++
 src/util/crypto/nss/nss_nite.c                |  2 +-
 .../crypto/{sss_crypto.c => nss/nss_prng.c}   | 10 ++++-
 src/util/crypto/sss_crypto.h                  |  2 +-
 src/util/secrets/secrets.c                    |  2 +-
 6 files changed, 54 insertions(+), 11 deletions(-)
 create mode 100644 src/util/crypto/libcrypto/crypto_prng.c
 rename src/util/crypto/{sss_crypto.c => nss/nss_prng.c} (88%)

diff --git a/Makefile.am b/Makefile.am
index 043a7ebb44..256e099b7f 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -939,9 +939,9 @@ if HAVE_NSS
                         src/util/crypto/nss/nss_obfuscate.c \
                         src/util/crypto/nss/nss_nite.c \
                         src/util/crypto/nss/nss_util.c \
-			src/util/crypto/sss_crypto.c \
-			src/util/atomic_io.c \
-			$(NULL)
+                        src/util/crypto/nss/nss_prng.c \
+                        src/util/atomic_io.c \
+                        $(NULL)
     SSS_CRYPT_CFLAGS = $(NSS_CFLAGS)
     SSS_CRYPT_LIBS = $(NSS_LIBS)
 
@@ -962,9 +962,9 @@ else
                         src/util/crypto/libcrypto/crypto_sha512crypt.c \
                         src/util/crypto/libcrypto/crypto_obfuscate.c \
                         src/util/crypto/libcrypto/crypto_nite.c \
-			src/util/crypto/sss_crypto.c \
-			src/util/atomic_io.c \
-			$(NULL)
+                        src/util/crypto/libcrypto/crypto_prng.c \
+                        src/util/atomic_io.c \
+                        $(NULL)
     SSS_CRYPT_CFLAGS = $(CRYPTO_CFLAGS)
     SSS_CRYPT_LIBS = $(CRYPTO_LIBS)
 
diff --git a/src/util/crypto/libcrypto/crypto_prng.c b/src/util/crypto/libcrypto/crypto_prng.c
new file mode 100644
index 0000000000..211553fe91
--- /dev/null
+++ b/src/util/crypto/libcrypto/crypto_prng.c
@@ -0,0 +1,37 @@
+/*
+    Copyright (C) Red Hat 2019
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 3 of the License, or
+    (at your option) any later version.
+
+    This program 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 General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+
+#include <errno.h>
+#include <limits.h>
+#include <openssl/rand.h>
+
+#include "util/util_errors.h"
+#include "util/crypto/sss_crypto.h"
+
+int sss_generate_csprng_buffer(uint8_t *buf, size_t size)
+{
+    if ((buf == NULL) || (size > INT_MAX)) {
+        return EINVAL;
+    }
+
+    if (RAND_bytes((unsigned char *)buf, (int)size) == 1) {
+        return EOK;
+    }
+
+    return EAGAIN;
+}
diff --git a/src/util/crypto/nss/nss_nite.c b/src/util/crypto/nss/nss_nite.c
index 2ae28fd1a0..30ccce262e 100644
--- a/src/util/crypto/nss/nss_nite.c
+++ b/src/util/crypto/nss/nss_nite.c
@@ -89,7 +89,7 @@ int sss_encrypt(TALLOC_CTX *mem_ctx, enum encmethod enctype,
     /* First Encrypt */
 
     if (ivlen != 0) {
-        ret = generate_csprng_buffer(out, ivlen);
+        ret = sss_generate_csprng_buffer(out, ivlen);
         if (ret) return ret;
     }
 
diff --git a/src/util/crypto/sss_crypto.c b/src/util/crypto/nss/nss_prng.c
similarity index 88%
rename from src/util/crypto/sss_crypto.c
rename to src/util/crypto/nss/nss_prng.c
index 582f2caab1..9924bff6b9 100644
--- a/src/util/crypto/sss_crypto.c
+++ b/src/util/crypto/nss/nss_prng.c
@@ -28,14 +28,20 @@
 #include "util/crypto/sss_crypto.h"
 
 
-int generate_csprng_buffer(uint8_t *buf, size_t size)
+int sss_generate_csprng_buffer(uint8_t *buf, size_t size)
 {
     ssize_t rsize;
     int ret;
     int fd;
 
+    if (buf == NULL) {
+        return EINVAL;
+    }
+
     fd = open("/dev/urandom", O_RDONLY);
-    if (fd == -1) return errno;
+    if (fd == -1) {
+        return errno;
+    }
 
     rsize = sss_atomic_read_s(fd, buf, size);
     if (rsize == -1) {
diff --git a/src/util/crypto/sss_crypto.h b/src/util/crypto/sss_crypto.h
index cd1b4aef25..d4697b11c3 100644
--- a/src/util/crypto/sss_crypto.h
+++ b/src/util/crypto/sss_crypto.h
@@ -21,7 +21,7 @@
 #include <talloc.h>
 #include <stdint.h>
 
-int generate_csprng_buffer(uint8_t *buf, size_t size);
+int sss_generate_csprng_buffer(uint8_t *buf, size_t size);
 
 int s3crypt_sha512(TALLOC_CTX *mmectx,
                    const char *key, const char *salt, char **_hash);
diff --git a/src/util/secrets/secrets.c b/src/util/secrets/secrets.c
index 6a317a0673..f5c978a725 100644
--- a/src/util/secrets/secrets.c
+++ b/src/util/secrets/secrets.c
@@ -537,7 +537,7 @@ static int generate_master_key(const char *filename, size_t size)
     int ret;
     int fd;
 
-    ret = generate_csprng_buffer(buf, size);
+    ret = sss_generate_csprng_buffer(buf, size);
     if (ret) {
         DEBUG(SSSDBG_OP_FAILURE,
               "generate_csprng_buffer failed [%d]: %s\n",

From 023a1c951d37c83a30896cbd26cfaf2ef83216d8 Mon Sep 17 00:00:00 2001
From: Alexey Tikhonov <[email protected]>
Date: Fri, 21 Jun 2019 18:45:52 +0200
Subject: [PATCH 4/6] util/crypto: added sss_rand()

Introduced `sss_rand()` wrapper to be used in project sources in every
applicable case where "raw" rand()/etc are used now.

Relates: https://pagure.io/SSSD/sssd/issue/4024
---
 src/util/crypto/libcrypto/crypto_prng.c | 26 +++++++++++++++++++++++++
 src/util/crypto/nss/nss_prng.c          | 14 +++++++++++++
 src/util/crypto/sss_crypto.h            |  2 ++
 3 files changed, 42 insertions(+)

diff --git a/src/util/crypto/libcrypto/crypto_prng.c b/src/util/crypto/libcrypto/crypto_prng.c
index 211553fe91..57b8c48e1d 100644
--- a/src/util/crypto/libcrypto/crypto_prng.c
+++ b/src/util/crypto/libcrypto/crypto_prng.c
@@ -18,11 +18,37 @@
 
 #include <errno.h>
 #include <limits.h>
+#include <stdlib.h>
+#include <stdbool.h>
+#include <time.h>
+#include <sys/types.h>
+#include <unistd.h>
 #include <openssl/rand.h>
 
 #include "util/util_errors.h"
 #include "util/crypto/sss_crypto.h"
 
+
+int sss_rand(void)
+{
+    static bool srand_done = false;
+    int result;
+
+    if (RAND_bytes((unsigned char*)&result, (int)sizeof(int)) == 1)
+    {
+        return result;
+    }
+
+    /* Fallback to libc `rand()` */
+    if (!srand_done)
+    {
+        srand(time(NULL) * getpid());
+        srand_done = true;
+    }
+    return rand();
+}
+
+
 int sss_generate_csprng_buffer(uint8_t *buf, size_t size)
 {
     if ((buf == NULL) || (size > INT_MAX)) {
diff --git a/src/util/crypto/nss/nss_prng.c b/src/util/crypto/nss/nss_prng.c
index 9924bff6b9..33a5ec5bd4 100644
--- a/src/util/crypto/nss/nss_prng.c
+++ b/src/util/crypto/nss/nss_prng.c
@@ -28,6 +28,20 @@
 #include "util/crypto/sss_crypto.h"
 
 
+int sss_rand(void)
+{
+    static bool srand_done = false;
+
+    if (!srand_done)
+    {
+        srand(time(NULL) * getpid());
+        srand_done = true;
+    }
+
+    return rand();
+}
+
+
 int sss_generate_csprng_buffer(uint8_t *buf, size_t size)
 {
     ssize_t rsize;
diff --git a/src/util/crypto/sss_crypto.h b/src/util/crypto/sss_crypto.h
index d4697b11c3..7b8cceedf7 100644
--- a/src/util/crypto/sss_crypto.h
+++ b/src/util/crypto/sss_crypto.h
@@ -21,6 +21,8 @@
 #include <talloc.h>
 #include <stdint.h>
 
+int sss_rand(void);
+
 int sss_generate_csprng_buffer(uint8_t *buf, size_t size);
 
 int s3crypt_sha512(TALLOC_CTX *mmectx,

From 9eaf2014f9253864deba645e64199758b17a796f Mon Sep 17 00:00:00 2001
From: Alexey Tikhonov <[email protected]>
Date: Mon, 24 Jun 2019 17:51:58 +0200
Subject: [PATCH 5/6] crypto/libcrypto/crypto_nite.c: memory leak fixed

Fixed leaking of memory in case of failure in `sss_encrypt()` function.
---
 src/util/crypto/libcrypto/crypto_nite.c | 14 ++++++++++++--
 1 file changed, 12 insertions(+), 2 deletions(-)

diff --git a/src/util/crypto/libcrypto/crypto_nite.c b/src/util/crypto/libcrypto/crypto_nite.c
index 61b236ac1a..c3867d73ee 100644
--- a/src/util/crypto/libcrypto/crypto_nite.c
+++ b/src/util/crypto/libcrypto/crypto_nite.c
@@ -50,7 +50,7 @@ int sss_encrypt(TALLOC_CTX *mem_ctx, enum encmethod enctype,
     const EVP_CIPHER *cipher;
     const EVP_MD *digest;
     EVP_PKEY *hmackey = NULL;
-    EVP_CIPHER_CTX *ctx;
+    EVP_CIPHER_CTX *ctx = NULL;
     EVP_MD_CTX *mdctx = NULL;
     uint8_t *out = NULL;
     int evpkeylen;
@@ -81,6 +81,10 @@ int sss_encrypt(TALLOC_CTX *mem_ctx, enum encmethod enctype,
     outlen = plainlen + (2 * EVP_CIPHER_block_size(cipher))
                 + evpivlen + hmaclen;
     out = talloc_zero_size(mem_ctx, outlen);
+    if (out == NULL) {
+        ret = ENOMEM;
+        goto done;
+    }
 
     /* First Encrypt */
 
@@ -154,12 +158,18 @@ int sss_encrypt(TALLOC_CTX *mem_ctx, enum encmethod enctype,
     outlen += hmaclen;
 
     *ciphertext = out;
+    out = NULL;
     *cipherlen = outlen;
     ret = EOK;
 
 done:
+    if (out) {
+        talloc_free(out);
+    }
     EVP_MD_CTX_free(mdctx);
-    EVP_CIPHER_CTX_free(ctx);
+    if (ctx) {
+        EVP_CIPHER_CTX_free(ctx);
+    }
     EVP_PKEY_free(hmackey);
     return ret;
 }

From ce159f9e92bac46e918bfee2baf65fef7c88921e Mon Sep 17 00:00:00 2001
From: Alexey Tikhonov <[email protected]>
Date: Mon, 24 Jun 2019 18:39:56 +0200
Subject: [PATCH 6/6] FIPS140 compliant usage of PRNG

Calls to `rand()`, "/dev/urandom", etc are replaced with
appropriate wrappers from `util/crypto`.

Resolves: https://pagure.io/SSSD/sssd/issue/4024
---
 src/p11_child/p11_child_openssl.c              |  7 ++++---
 src/providers/be_ptask.c                       |  4 ++--
 src/providers/be_ptask_private.h               |  1 -
 src/providers/krb5/krb5_auth.c                 |  6 ++----
 src/providers/krb5/krb5_init.c                 |  3 ---
 src/resolv/async_resolv.c                      |  4 ++++
 src/responder/kcm/kcmsrv_ccache_secdb.c        |  2 +-
 src/responder/kcm/kcmsrv_ccache_secrets.c      |  6 +-----
 src/responder/nss/nsssrv_mmap_cache.c          |  5 ++---
 src/responder/ssh/ssh_known_hosts.c            | 10 +++++++---
 src/sss_client/common.c                        |  5 +++++
 src/util/crypto/libcrypto/crypto_nite.c        |  5 ++++-
 src/util/crypto/libcrypto/crypto_obfuscate.c   | 10 ++++++++--
 src/util/crypto/libcrypto/crypto_prng.c        |  6 +++++-
 src/util/crypto/libcrypto/crypto_sha512crypt.c |  7 ++++---
 src/util/crypto/nss/nss_prng.c                 |  3 +++
 16 files changed, 52 insertions(+), 32 deletions(-)

diff --git a/src/p11_child/p11_child_openssl.c b/src/p11_child/p11_child_openssl.c
index 75e4bef8e1..007f58c52e 100644
--- a/src/p11_child/p11_child_openssl.c
+++ b/src/p11_child/p11_child_openssl.c
@@ -1184,9 +1184,10 @@ static int sign_data(CK_FUNCTION_LIST *module, CK_SESSION_HANDLE session,
         return EIO;
     }
 
-    ret = RAND_bytes(random_value, sizeof(random_value));
-    if (ret != 1) {
-        DEBUG(SSSDBG_OP_FAILURE, "RAND_bytes failed.\n");
+    ret = sss_generate_csprng_buffer((uint8_t *)random_value,
+                                     sizeof(random_value));
+    if (ret != EOK) {
+        DEBUG(SSSDBG_OP_FAILURE, "sss_generate_csprng_buffer failed.\n");
         return EINVAL;
     }
 
diff --git a/src/providers/be_ptask.c b/src/providers/be_ptask.c
index c433517553..c953c43807 100644
--- a/src/providers/be_ptask.c
+++ b/src/providers/be_ptask.c
@@ -24,6 +24,7 @@
 #include <string.h>
 
 #include "util/util.h"
+#include "util/crypto/sss_crypto.h"
 #include "providers/backend.h"
 #include "providers/be_ptask_private.h"
 #include "providers/be_ptask.h"
@@ -224,7 +225,7 @@ static void be_ptask_schedule(struct be_ptask *task,
 
     /* add random offset */
     if (task->random_offset != 0) {
-        delay = delay + (rand_r(&task->ro_seed) % task->random_offset);
+        delay = delay + (sss_rand() % task->random_offset);
     }
 
     switch (from) {
@@ -296,7 +297,6 @@ errno_t be_ptask_create(TALLOC_CTX *mem_ctx,
     task->first_delay = first_delay;
     task->enabled_delay = enabled_delay;
     task->random_offset = random_offset;
-    task->ro_seed = time(NULL) * getpid();
     task->max_backoff = max_backoff;
     task->timeout = timeout;
     task->offline = offline;
diff --git a/src/providers/be_ptask_private.h b/src/providers/be_ptask_private.h
index 4144a39385..2169854bb5 100644
--- a/src/providers/be_ptask_private.h
+++ b/src/providers/be_ptask_private.h
@@ -28,7 +28,6 @@ struct be_ptask {
     time_t first_delay;
     time_t enabled_delay;
     time_t random_offset;
-    unsigned int ro_seed;
     time_t timeout;
     time_t max_backoff;
     enum be_ptask_offline offline;
diff --git a/src/providers/krb5/krb5_auth.c b/src/providers/krb5/krb5_auth.c
index 9a92504349..84771e74ca 100644
--- a/src/providers/krb5/krb5_auth.c
+++ b/src/providers/krb5/krb5_auth.c
@@ -33,6 +33,7 @@
 #include <security/pam_modules.h>
 
 #include "util/util.h"
+#include "util/crypto/sss_crypto.h"
 #include "util/find_uid.h"
 #include "util/auth_utils.h"
 #include "db/sysdb.h"
@@ -314,12 +315,9 @@ static errno_t krb5_auth_prepare_ccache_name(struct krb5child_req *kr,
     case DOM_TYPE_APPLICATION:
         DEBUG(SSSDBG_TRACE_FUNC,
                "Domain type application, will use in-memory ccache\n");
-        /* We don't care about using cryptographic randomness, just
-         * a non-predictable ccname, so using rand() here is fine
-         */
         kr->ccname = talloc_asprintf(kr,
                                      NON_POSIX_CCNAME_FMT,
-                                     rand() % UINT_MAX);
+                                     sss_rand() % UINT_MAX);
         if (kr->ccname == NULL) {
             DEBUG(SSSDBG_CRIT_FAILURE, "talloc_asprintf failed.\n");
             return ENOMEM;
diff --git a/src/providers/krb5/krb5_init.c b/src/providers/krb5/krb5_init.c
index 3f4c1b3619..dafcc2a137 100644
--- a/src/providers/krb5/krb5_init.c
+++ b/src/providers/krb5/krb5_init.c
@@ -151,9 +151,6 @@ errno_t sssm_krb5_init(TALLOC_CTX *mem_ctx,
         return ENOMEM;
     }
 
-    /* Only needed to generate random ccache names for non-POSIX domains */
-    srand(time(NULL) * getpid());
-
     ret = sss_krb5_get_options(ctx, be_ctx->cdb, be_ctx->conf_path, &ctx->opts);
     if (ret != EOK) {
         DEBUG(SSSDBG_CRIT_FAILURE, "Unable to get krb5 options [%d]: %s\n",
diff --git a/src/resolv/async_resolv.c b/src/resolv/async_resolv.c
index bb27011548..01d835ec9a 100644
--- a/src/resolv/async_resolv.c
+++ b/src/resolv/async_resolv.c
@@ -2176,6 +2176,10 @@ static int reply_weight_rearrange(int len,
         return ENOMEM;
     }
 
+    /* This is not security relevant functionality and
+     * it is undesirable to pull unnecessary dependency (util/crypto)
+     * so plain srand() & rand() are used here.
+     */
     srand(time(NULL) * getpid());
 
     /* promote all servers with weight==0 to the top */
diff --git a/src/responder/kcm/kcmsrv_ccache_secdb.c b/src/responder/kcm/kcmsrv_ccache_secdb.c
index a61d7b15be..c68f53f970 100644
--- a/src/responder/kcm/kcmsrv_ccache_secdb.c
+++ b/src/responder/kcm/kcmsrv_ccache_secdb.c
@@ -606,7 +606,7 @@ static struct tevent_req *ccdb_secdb_nextid_send(TALLOC_CTX *mem_ctx,
     }
 
     for (numtry = 0; numtry  < maxtries; numtry++) {
-        state->nextid = rand() % MAX_CC_NUM;
+        state->nextid = sss_rand() % MAX_CC_NUM;
         nextid_name = talloc_asprintf(state, "%"SPRIuid":%u",
                                       cli_creds_get_uid(client),
                                       state->nextid);
diff --git a/src/responder/kcm/kcmsrv_ccache_secrets.c b/src/responder/kcm/kcmsrv_ccache_secrets.c
index 4c52497d45..93be4fafac 100644
--- a/src/responder/kcm/kcmsrv_ccache_secrets.c
+++ b/src/responder/kcm/kcmsrv_ccache_secrets.c
@@ -675,10 +675,6 @@ static errno_t ccdb_sec_init(struct kcm_ccdb *db)
         return ENOMEM;
    }
 
-    /* We just need the random numbers to generate pseudo-random ccache names
-     * and avoid conflicts */
-    srand(time(NULL));
-
     db->db_handle = secdb;
     return EOK;
 }
@@ -887,7 +883,7 @@ static errno_t ccdb_sec_nextid_generate(struct tevent_req *req)
         return EBUSY;
     }
 
-    state->nextid = rand() % MAX_CC_NUM;
+    state->nextid = sss_rand() % MAX_CC_NUM;
     state->nextid_name = talloc_asprintf(state, "%"SPRIuid":%u",
                                          cli_creds_get_uid(state->client),
                                          state->nextid);
diff --git a/src/responder/nss/nsssrv_mmap_cache.c b/src/responder/nss/nsssrv_mmap_cache.c
index d5181d771c..6efb24b34c 100644
--- a/src/responder/nss/nsssrv_mmap_cache.c
+++ b/src/responder/nss/nsssrv_mmap_cache.c
@@ -20,6 +20,7 @@
 */
 
 #include "util/util.h"
+#include "util/crypto/sss_crypto.h"
 #include "confdb/confdb.h"
 #include <sys/mman.h>
 #include <fcntl.h>
@@ -1254,7 +1255,6 @@ errno_t sss_mmap_cache_init(TALLOC_CTX *mem_ctx, const char *name,
                             time_t timeout, struct sss_mc_ctx **mcc)
 {
     struct sss_mc_ctx *mc_ctx = NULL;
-    unsigned int rseed;
     int payload;
     int ret, dret;
 
@@ -1353,8 +1353,7 @@ errno_t sss_mmap_cache_init(TALLOC_CTX *mem_ctx, const char *name,
 
     /* generate a pseudo-random seed.
      * Needed to fend off dictionary based collision attacks */
-    rseed = time(NULL) * getpid();
-    mc_ctx->seed = rand_r(&rseed);
+    mc_ctx->seed = sss_rand();
 
     sss_mc_header_update(mc_ctx, SSS_MC_HEADER_ALIVE);
 
diff --git a/src/responder/ssh/ssh_known_hosts.c b/src/responder/ssh/ssh_known_hosts.c
index ca0872264f..2be240b8e0 100644
--- a/src/responder/ssh/ssh_known_hosts.c
+++ b/src/responder/ssh/ssh_known_hosts.c
@@ -92,7 +92,7 @@ ssh_host_pubkeys_format_known_host_hashed(TALLOC_CTX *mem_ctx,
     errno_t ret;
     char *name, *pubkey, *saltstr, *hashstr, *result;
     unsigned char salt[SSS_SHA1_LENGTH], hash[SSS_SHA1_LENGTH];
-    size_t i, j, k;
+    size_t i, j;
 
     tmp_ctx = talloc_new(NULL);
     if (!tmp_ctx) {
@@ -114,8 +114,12 @@ ssh_host_pubkeys_format_known_host_hashed(TALLOC_CTX *mem_ctx,
         for (j = 0; j <= ent->num_aliases; j++) {
             name = (j == 0 ? ent->name : ent->aliases[j-1]);
 
-            for (k = 0; k < SSS_SHA1_LENGTH; k++) {
-                salt[k] = rand();
+            ret = sss_generate_csprng_buffer((uint8_t *)salt, SSS_SHA1_LENGTH);
+            if (ret != EOK) {
+                DEBUG(SSSDBG_OP_FAILURE,
+                      "sss_generate_csprng_buffer() failed (%d)\n", ret);
+                result = NULL;
+                goto done;
             }
 
             ret = sss_hmac_sha1(salt, SSS_SHA1_LENGTH,
diff --git a/src/sss_client/common.c b/src/sss_client/common.c
index e2d8405401..930efe4a18 100644
--- a/src/sss_client/common.c
+++ b/src/sss_client/common.c
@@ -566,6 +566,11 @@ static int sss_cli_open_socket(int *errnop, const char *socket_name, int timeout
     /* this piece is adapted from winbind client code */
     wait_time = 0;
     sleep_time = 0;
+    /* This is not security relevant functionality and
+     * it is undesirable to pull unnecessary dependency (util/crypto)
+     * so plain srand() & rand() are used here.
+     */
+    srand(time(NULL) * getpid());
     while (inprogress) {
         int connect_errno = 0;
         socklen_t errnosize;
diff --git a/src/util/crypto/libcrypto/crypto_nite.c b/src/util/crypto/libcrypto/crypto_nite.c
index c3867d73ee..e71f6ce086 100644
--- a/src/util/crypto/libcrypto/crypto_nite.c
+++ b/src/util/crypto/libcrypto/crypto_nite.c
@@ -89,7 +89,10 @@ int sss_encrypt(TALLOC_CTX *mem_ctx, enum encmethod enctype,
     /* First Encrypt */
 
     if (evpivlen != 0) {
-        RAND_bytes(out, evpivlen);
+        ret = sss_generate_csprng_buffer(out, evpivlen);
+        if (ret != EOK) {
+            goto done;
+        }
     }
 
     ctx = EVP_CIPHER_CTX_new();
diff --git a/src/util/crypto/libcrypto/crypto_obfuscate.c b/src/util/crypto/libcrypto/crypto_obfuscate.c
index 69b622e1d4..5bb6bc6183 100644
--- a/src/util/crypto/libcrypto/crypto_obfuscate.c
+++ b/src/util/crypto/libcrypto/crypto_obfuscate.c
@@ -114,8 +114,14 @@ int sss_password_encrypt(TALLOC_CTX *mem_ctx, const char *password, int plen,
         goto done;
     }
 
-    RAND_bytes(keybuf, mech_props->keylen);
-    RAND_bytes(ivbuf, mech_props->bsize);
+    ret = sss_generate_csprng_buffer((uint8_t *)keybuf, mech_props->keylen);
+    if (ret != EOK) {
+        goto done;
+    }
+    ret = sss_generate_csprng_buffer((uint8_t *)ivbuf, mech_props->bsize);
+    if (ret != EOK) {
+        goto done;
+    }
 
     /* cryptotext buffer must be at least len(plaintext)+blocksize */
     ct_maxsize = plen + (mech_props->bsize);
diff --git a/src/util/crypto/libcrypto/crypto_prng.c b/src/util/crypto/libcrypto/crypto_prng.c
index 57b8c48e1d..02dbfe3a66 100644
--- a/src/util/crypto/libcrypto/crypto_prng.c
+++ b/src/util/crypto/libcrypto/crypto_prng.c
@@ -39,7 +39,11 @@ int sss_rand(void)
         return result;
     }
 
-    /* Fallback to libc `rand()` */
+    /* Fallback to libc `rand()`
+     * Coverity might complain here: "DC.WEAK_CRYPTO (CWE-327)"
+     * But if `RAND_bytes()` failed then there is no entropy available
+     * so it doesn't make any sense to try reading "/dev/[u]random"
+     */
     if (!srand_done)
     {
         srand(time(NULL) * getpid());
diff --git a/src/util/crypto/libcrypto/crypto_sha512crypt.c b/src/util/crypto/libcrypto/crypto_sha512crypt.c
index 2275ccd962..cba1111f54 100644
--- a/src/util/crypto/libcrypto/crypto_sha512crypt.c
+++ b/src/util/crypto/libcrypto/crypto_sha512crypt.c
@@ -24,6 +24,7 @@
 
 #include "util/util.h"
 #include "util/sss_endian.h"
+#include "util/crypto/sss_crypto.h"
 
 #include <openssl/evp.h>
 #include <openssl/rand.h>
@@ -374,9 +375,9 @@ int s3crypt_gen_salt(TALLOC_CTX *memctx, char **_salt)
         return ENOMEM;
     }
 
-    ret = RAND_bytes(rb, SALT_RAND_LEN);
-    if (ret == 0) {
-        return EIO;
+    ret = sss_generate_csprng_buffer(rb, SALT_RAND_LEN);
+    if (ret != EOK) {
+        return ret;
     }
 
     slen = SALT_LEN_MAX;
diff --git a/src/util/crypto/nss/nss_prng.c b/src/util/crypto/nss/nss_prng.c
index 33a5ec5bd4..fca6f03811 100644
--- a/src/util/crypto/nss/nss_prng.c
+++ b/src/util/crypto/nss/nss_prng.c
@@ -38,6 +38,9 @@ int sss_rand(void)
         srand_done = true;
     }
 
+    /* Coverity will complain here: "DC.WEAK_CRYPTO (CWE-327)"
+     * We do not care as libnss is being deprecated as crypto backend.
+     */
     return rand();
 }
 
_______________________________________________
sssd-devel mailing list -- [email protected]
To unsubscribe send an email to [email protected]
Fedora Code of Conduct: 
https://docs.fedoraproject.org/en-US/project/code-of-conduct/
List Guidelines: https://fedoraproject.org/wiki/Mailing_list_guidelines
List Archives: 
https://lists.fedorahosted.org/archives/list/[email protected]

Reply via email to