OLD | NEW |
1 /* | 1 /* |
2 * Copyright (c) 2011 The Native Client Authors. All rights reserved. | 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 | 3 * Use of this source code is governed by a BSD-style license that can be |
4 * found in the LICENSE file. | 4 * found in the LICENSE file. |
5 */ | 5 */ |
6 | 6 |
7 #include <errno.h> | 7 #include <errno.h> |
8 #include <fcntl.h> | 8 #include <fcntl.h> |
9 | 9 |
10 #include "native_client/src/public/name_service.h" | |
11 #include "native_client/src/untrusted/nacl/nacl_random.h" | 10 #include "native_client/src/untrusted/nacl/nacl_random.h" |
12 #include "native_client/src/untrusted/irt/irt.h" | 11 #include "native_client/src/untrusted/irt/irt.h" |
13 #include "native_client/src/untrusted/irt/irt_private.h" | 12 #include "native_client/src/untrusted/irt/irt_private.h" |
14 #include "native_client/src/untrusted/nacl/syscall_bindings_trampoline.h" | 13 #include "native_client/src/untrusted/nacl/syscall_bindings_trampoline.h" |
15 | 14 |
16 static int secure_random_fd = -1; | |
17 | |
18 static int prepare_secure_random(void) { | |
19 if (secure_random_fd == -1) { | |
20 int fd; | |
21 int status = irt_nameservice_lookup("SecureRandom", O_RDONLY, &fd); | |
22 if (status != NACL_NAME_SERVICE_SUCCESS) { | |
23 return EIO; | |
24 } | |
25 if (!__sync_bool_compare_and_swap(&secure_random_fd, -1, fd)) { | |
26 /* | |
27 * We raced with another thread. It already installed an fd. | |
28 */ | |
29 NACL_SYSCALL(close)(fd); | |
30 } | |
31 } | |
32 return 0; | |
33 } | |
34 | |
35 int nacl_secure_random_init(void) { | 15 int nacl_secure_random_init(void) { |
36 return 0; | 16 return 0; |
37 } | 17 } |
38 | 18 |
39 int nacl_secure_random(void *buf, size_t count, size_t *nread) { | 19 int nacl_secure_random(void *buf, size_t count, size_t *nread) { |
40 int error = prepare_secure_random(); | 20 int rv = NACL_GC_WRAP_SYSCALL(NACL_SYSCALL(get_random_bytes)(buf, count)); |
41 if (error == 0) { | 21 if (rv != 0) |
42 int rv = NACL_GC_WRAP_SYSCALL(NACL_SYSCALL(read)(secure_random_fd, | 22 return -rv; |
43 buf, count)); | 23 *nread = count; |
44 if (rv < 0) | 24 return 0; |
45 error = -rv; | |
46 else | |
47 *nread = rv; | |
48 } | |
49 return error; | |
50 } | 25 } |
51 | 26 |
52 const struct nacl_irt_random nacl_irt_random = { | 27 const struct nacl_irt_random nacl_irt_random = { |
53 nacl_secure_random, | 28 nacl_secure_random, |
54 }; | 29 }; |
OLD | NEW |