[patch 5/6] pseudo random bytes - Mailing list pgsql-patches

From Marko Kreen
Subject [patch 5/6] pseudo random bytes
Date
Msg-id 20050319234647.361618000@grue
Whole thread Raw
In response to [patch 0/6] pgcrypto update  (Marko Kreen <marko@l-t.ee>)
List pgsql-patches
Reserve px_get_random_bytes() for strong randomness,
add new function px_get_pseudo_random_bytes() for
weak randomness and use it in gen_salt().

On openssl case, use RAND_pseudo_bytes() for
px_get_pseudo_random_bytes().

Final result is that is user has not configured random
souce but kept the 'silly' one, gen_salt() keeps
working, but pgp_encrypt() will throw error.


Index: pgsql/contrib/pgcrypto/px-crypt.c
===================================================================
*** pgsql.orig/contrib/pgcrypto/px-crypt.c
--- pgsql/contrib/pgcrypto/px-crypt.c
*************** px_gen_salt(const char *salt_type, char
*** 171,177 ****
              return PXE_BAD_SALT_ROUNDS;
      }

!     res = px_get_random_bytes(rbuf, g->input_len);
      if (res < 0)
          return res;

--- 171,177 ----
              return PXE_BAD_SALT_ROUNDS;
      }

!     res = px_get_pseudo_random_bytes(rbuf, g->input_len);
      if (res < 0)
          return res;

Index: pgsql/contrib/pgcrypto/px.h
===================================================================
*** pgsql.orig/contrib/pgcrypto/px.h
--- pgsql/contrib/pgcrypto/px.h
*************** void        px_free(void *p);
*** 83,88 ****
--- 83,89 ----
  #define PXE_UNKNOWN_SALT_ALGO        -14
  #define PXE_BAD_SALT_ROUNDS            -15
  #define PXE_MCRYPT_INTERNAL            -16
+ #define PXE_NO_RANDOM                -17

  typedef struct px_digest PX_MD;
  typedef struct px_alias PX_Alias;
*************** int            px_find_cipher(const char *name, P
*** 168,173 ****
--- 169,175 ----
  int            px_find_combo(const char *name, PX_Combo ** res);

  int            px_get_random_bytes(uint8 *dst, unsigned count);
+ int            px_get_pseudo_random_bytes(uint8 *dst, unsigned count);

  const char *px_strerror(int err);

Index: pgsql/contrib/pgcrypto/random.c
===================================================================
*** pgsql.orig/contrib/pgcrypto/random.c
--- pgsql/contrib/pgcrypto/random.c
*************** px_get_random_bytes(uint8 *dst, unsigned
*** 78,87 ****
      return res;
  }

  #elif defined(RAND_SILLY)

  int
! px_get_random_bytes(uint8 *dst, unsigned count)
  {
      int            i;

--- 78,93 ----
      return res;
  }

+ int
+ px_get_pseudo_random_bytes(uint8 *dst, unsigned count)
+ {
+     return px_get_random_bytes(dst, count);
+ }
+
  #elif defined(RAND_SILLY)

  int
! px_get_pseudo_random_bytes(uint8 *dst, unsigned count)
  {
      int            i;

*************** px_get_random_bytes(uint8 *dst, unsigned
*** 90,95 ****
--- 96,107 ----
      return i;
  }

+ int
+ px_get_random_bytes(uint8 *dst, unsigned count)
+ {
+     return PXE_NO_RANDOM;
+ }
+
  #elif defined(RAND_OPENSSL)

  #include <openssl/evp.h>
*************** px_get_random_bytes(uint8 *dst, unsigned
*** 99,120 ****

  static int    openssl_random_init = 0;

  int
  px_get_random_bytes(uint8 *dst, unsigned count)
  {
      int            res;

      if (!openssl_random_init)
!     {
!         if (RAND_get_rand_method() == NULL)
!             RAND_set_rand_method(RAND_SSLeay());
!         openssl_random_init = 1;
!     }
!
!     /*
!      * OpenSSL random should re-feeded occasionally. From /dev/urandom
!      * preferably.
!      */

      res = RAND_bytes(dst, count);
      if (res == 1)
--- 111,134 ----

  static int    openssl_random_init = 0;

+ /*
+  * OpenSSL random should re-feeded occasionally. From /dev/urandom
+  * preferably.
+  */
+ static void init_openssl()
+ {
+     if (RAND_get_rand_method() == NULL)
+         RAND_set_rand_method(RAND_SSLeay());
+     openssl_random_init = 1;
+ }
+
  int
  px_get_random_bytes(uint8 *dst, unsigned count)
  {
      int            res;

      if (!openssl_random_init)
!         init_openssl();

      res = RAND_bytes(dst, count);
      if (res == 1)
*************** px_get_random_bytes(uint8 *dst, unsigned
*** 123,128 ****
--- 137,157 ----
      return PXE_OSSL_RAND_ERROR;
  }

+ int
+ px_get_pseudo_random_bytes(uint8 *dst, unsigned count)
+ {
+     int            res;
+
+     if (!openssl_random_init)
+         init_openssl();
+
+     res = RAND_pseudo_bytes(dst, count);
+     if (res == 0 || res == 1)
+         return count;
+
+     return PXE_OSSL_RAND_ERROR;
+ }
+
  #else
  #error "Invalid random source"
  #endif
Index: pgsql/contrib/pgcrypto/px.c
===================================================================
*** pgsql.orig/contrib/pgcrypto/px.c
--- pgsql/contrib/pgcrypto/px.c
*************** static const struct error_desc px_err_li
*** 56,61 ****
--- 56,62 ----
      {PXE_UNKNOWN_SALT_ALGO, "Unknown salt algorithm"},
      {PXE_BAD_SALT_ROUNDS, "Incorrect number of rounds"},
      {PXE_MCRYPT_INTERNAL, "mcrypt internal error"},
+     {PXE_NO_RANDOM, "No strong random source"},
      {0, NULL},
  };


--

pgsql-patches by date:

Previous
From: Marko Kreen
Date:
Subject: [patch 0/6] pgcrypto update
Next
From: Marko Kreen
Date:
Subject: [patch 3/6] better error handling