2 * Copyright 2008, Google Inc.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
9 * * Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * * Redistributions in binary form must reproduce the above
12 * copyright notice, this list of conditions and the following disclaimer
13 * in the documentation and/or other materials provided with the
15 * * Neither the name of Google Inc. nor the names of its
16 * contributors may be used to endorse or promote products derived from
17 * this software without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 * NaCl Service Runtime. Secure RNG abstraction.
36 #include "native_client/service_runtime/nacl_global_secure_random.h"
38 #include "native_client/service_runtime/nacl_log.h"
39 #include "native_client/service_runtime/nacl_secure_random.h"
40 #include "native_client/service_runtime/nacl_sync.h"
41 #include "native_client/service_runtime/nacl_sync_checked.h"
44 * Initialization occurs in nacl_globals.c
46 struct NaClMutex nacl_global_rng_mu
;
47 struct NaClSecureRng nacl_global_rng
;
49 void NaClGlobalSecureRngInit(void)
51 NaClMutexCtor(&nacl_global_rng_mu
);
52 if (!NaClSecureRngCtor(&nacl_global_rng
)) {
54 "Could not construct global random number generator.\n");
58 void NaClGlobalSecureRngFini(void)
60 NaClSecureRngDtor(&nacl_global_rng
);
61 NaClMutexDtor(&nacl_global_rng_mu
);
64 int32_t NaClGlobalSecureRngUniform(int32_t range_max
)
68 NaClXMutexLock(&nacl_global_rng_mu
);
69 rv
= NaClSecureRngUniform(&nacl_global_rng
, range_max
);
70 NaClXMutexUnlock(&nacl_global_rng_mu
);
74 void NaClGenerateRandomPath(char *path
, int length
)
77 * This function is used for generating random paths and names, e.g. for
78 * IMC sockets and semaphores.
80 * IMC sockets note: the IMC header file omits some important
81 * details. The alphabet cannot include backslash for Windows. For
82 * Linux, it uses the abstract namespace (see unix(7)), and can
83 * contain arbitrary characters. The limitations for OSX are the
84 * same as for pathname components, since the IMC library uses
85 * unix-domain sockets there.
87 * We uniformly generate from an alphabet of digits and uppercase and
88 * lowercase alphabetic characters on case-sensitive platforms
89 * (non-Windows), and uniformly generate from an alphabet of digits
90 * and lowercase characters on case-insensitive platforms (Windows).
91 * Since IMC allows 28 characters, we can compute the (apparent)
92 * entropy which gives the effort required by an attacker who cannot
93 * enumerate the namespace but must probe blindly. ("Apparent",
94 * since the actual amount of entropy available is the entropy in the
95 * cryptographically secure pseudorandom number generator's seed.)
97 * For case sensitive names (linux, osx), we have an alphabet size of
98 * 62 characters, so assuming that the underlying generator is ideal,
99 * we have a total entropy of the name is
101 * H_{28} = 28 * H_1 = 28 * (-\log_2(1/62))
102 * \approx 166.72 bits
104 * For case insensitive names (windows), we have an alphabet size of
105 * 36 characters, and we have
107 * H_{28} = 28 * H_1 = 28 * -log_2(1/36)
108 * \approx 144.76 bits
110 * If we used the 62-character alphabet in a case insensitive
111 * environment then the case folding means that an attacker will
112 * encounter an entropy of
114 * H_{28} = 28 * H_1 = 28 * (10/62 * -log_2(1/62) + 26*2/62 * -log_2(2/62))
115 * \approx 143.23 bits
117 * which reduces security by 1.52 bits. So, using an equiprobable
118 * alphabet rather than case folding is slightly better in a case
119 * insensitive environment, and using a larger alphabet is much
120 * better than always case folding in a case sensitive environment
123 * TODO: determine if the alphabets can be enlarged, and by how
126 static char const alphabet
[] = ("abcdefghijklmnopqrstuvwxyz"
128 "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
129 #endif /* !NACL_WINDOWS */
131 int const alphabet_size
= sizeof alphabet
- 1; /* NUL termination */
136 for (i
= 0; i
< length
-1; ++i
) {
137 r
= NaClGlobalSecureRngUniform(alphabet_size
);
138 path
[i
] = alphabet
[r
];
140 path
[length
-1] = '\0';