LCOV - code coverage report
Current view: directory - src/shared/platform - nacl_global_secure_random.c (source / functions) Found Hit Coverage
Test: coverage.lcov Lines: 34 11 32.4 %
Date: 2014-06-18 Functions: 0 0 -

       1                 : /*
       2                 :  * Copyright (c) 2011 The Native Client Authors. All rights reserved.
       3                 :  * Use of this source code is governed by a BSD-style license that can be
       4                 :  * found in the LICENSE file.
       5                 :  */
       6                 : 
       7                 : /*
       8                 :  * NaCl Service Runtime.  Secure RNG abstraction.
       9                 :  */
      10                 : 
      11                 : #include "native_client/src/shared/platform/nacl_global_secure_random.h"
      12                 : #include "native_client/src/shared/platform/nacl_log.h"
      13                 : #include "native_client/src/shared/platform/nacl_secure_random.h"
      14                 : #include "native_client/src/shared/platform/nacl_sync.h"
      15                 : #include "native_client/src/shared/platform/nacl_sync_checked.h"
      16                 : 
      17                 : static struct NaClMutex          nacl_global_rng_mu;
      18                 : static struct NaClSecureRng      nacl_global_rng;
      19                 : 
      20                 : static struct NaClSecureRng      *nacl_grngp = &nacl_global_rng;
      21                 : 
      22                 : void NaClGlobalSecureRngInit(void) {
      23             330 :   NaClXMutexCtor(&nacl_global_rng_mu);
      24             330 :   if (!NaClSecureRngCtor(nacl_grngp)) {
      25               0 :     NaClLog(LOG_FATAL,
      26                 :             "Could not construct global random number generator.\n");
      27               0 :   }
      28             330 : }
      29                 : 
      30                 : void NaClGlobalSecureRngFini(void) {
      31              53 :   (*nacl_grngp->base.vtbl->Dtor)(&nacl_grngp->base);
      32              53 :   NaClMutexDtor(&nacl_global_rng_mu);
      33              53 : }
      34                 : 
      35               0 : void NaClGlobalSecureRngSwitchRngForTesting(struct NaClSecureRng  *rng) {
      36               0 :   NaClXMutexLock(&nacl_global_rng_mu);
      37               0 :   nacl_grngp = rng;
      38               0 :   NaClXMutexUnlock(&nacl_global_rng_mu);
      39               0 : }
      40                 : 
      41               0 : int32_t NaClGlobalSecureRngUniform(int32_t range_max) {
      42               0 :   int32_t  rv;
      43                 : 
      44               0 :   NaClXMutexLock(&nacl_global_rng_mu);
      45               0 :   rv = (*nacl_grngp->base.vtbl->Uniform)(&nacl_grngp->base, range_max);
      46               0 :   NaClXMutexUnlock(&nacl_global_rng_mu);
      47               0 :   return rv;
      48                 : }
      49                 : 
      50                 : uint32_t NaClGlobalSecureRngUint32(void) {
      51            1024 :   uint32_t rv;
      52            1024 :   NaClXMutexLock(&nacl_global_rng_mu);
      53            1024 :   rv = (*nacl_grngp->base.vtbl->GenUint32)(&nacl_grngp->base);
      54            1024 :   NaClXMutexUnlock(&nacl_global_rng_mu);
      55            1024 :   return rv;
      56                 : }
      57                 : 
      58               0 : void NaClGenerateRandomPath(char *path, int length) {
      59                 :   /*
      60                 :    * This function is used for generating random paths and names,
      61                 :    * e.g. for IMC sockets and semaphores.
      62                 :    *
      63                 :    * IMC sockets note: the IMC header file omits some important
      64                 :    * details.  The alphabet cannot include backslash for Windows.  For
      65                 :    * Linux, it uses the abstract namespace (see unix(7)), and can
      66                 :    * contain arbitrary characters.  The limitations for OSX are the
      67                 :    * same as for pathname components, since the IMC library uses
      68                 :    * unix-domain sockets there.
      69                 :    *
      70                 :    * We uniformly generate from an alphabet of digits and uppercase
      71                 :    * and lowercase alphabetic characters on case-sensitive platforms
      72                 :    * (non-Windows), and uniformly generate from an alphabet of digits
      73                 :    * and lowercase characters on case-insensitive platforms (Windows).
      74                 :    * Since IMC allows 27 characters (plus a '\0' terminator), we can
      75                 :    * compute the (apparent) entropy which gives the effort required by
      76                 :    * an attacker who cannot enumerate the namespace but must probe
      77                 :    * blindly.  ("Apparent", since the actual amount of entropy
      78                 :    * available is the entropy in the cryptographically secure
      79                 :    * pseudorandom number generator's seed.)
      80                 :    *
      81                 :    * For case sensitive names (linux, osx), we have an alphabet size
      82                 :    * of 62 characters, so assuming that the underlying generator is
      83                 :    * ideal, we have a total entropy of the name is
      84                 :    *
      85                 :    *  H_{27} = 27 * H_1 = 27 * -\log_2(1/62)
      86                 :    *         \approx 160.76 bits
      87                 :    *
      88                 :    * For case insensitive names (windows), we have an alphabet size of
      89                 :    * 36 characters, and we have
      90                 :    *
      91                 :    *  H_{27} = 27 * H_1 = 27 * -log_2(1/36)
      92                 :    *         \approx 137.59 bits
      93                 :    *
      94                 :    * If we used the 62-character alphabet in a case insensitive
      95                 :    * environment then the case folding means that an attacker will
      96                 :    * encounter an entropy of
      97                 :    *
      98                 :    *  H_{27} = 27 * H_1 = 27 * (10/62 * -log_2(1/62) + 26*2/62 * -log_2(2/62))
      99                 :    *         \approx 138.12 bits
     100                 :    *
     101                 :    * which reduces security by 1.47 bits.  So, using an equiprobable
     102                 :    * alphabet rather than case folding is slightly better in a case
     103                 :    * insensitive environment, and using a larger alphabet is much
     104                 :    * better than always case folding in a case sensitive environment
     105                 :    * (23.48 bits).
     106                 :    *
     107                 :    * TODO(bsy): determine if the alphabets can be enlarged, and by how
     108                 :    * much.
     109                 :    */
     110                 :   static char const alphabet[] =
     111                 :       "abcdefghijklmnopqrstuvwxyz"
     112                 : #if !NACL_WINDOWS
     113                 :       "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
     114                 : #endif  /* !NACL_WINDOWS */
     115                 :       "0123456789";
     116               0 :   int const         alphabet_size = sizeof alphabet - 1;  /* NUL termination */
     117                 : 
     118               0 :   int               i;
     119               0 :   int               r;
     120                 : 
     121               0 :   for (i = 0; i < length-1; ++i) {
     122               0 :     r = NaClGlobalSecureRngUniform(alphabet_size);
     123               0 :     path[i] = alphabet[r];
     124               0 :   }
     125               0 :   path[length-1] = '\0';
     126               0 : }

Generated by: LCOV version 1.7