]>
Commit | Line | Data |
---|---|---|
10a89ef0 | 1 | /* Copyright (c) 2008, 2009, 2010, 2011, 2013 Nicira, Inc. |
e251c8d0 BP |
2 | * |
3 | * Licensed under the Apache License, Version 2.0 (the "License"); | |
4 | * you may not use this file except in compliance with the License. | |
5 | * You may obtain a copy of the License at: | |
6 | * | |
7 | * http://www.apache.org/licenses/LICENSE-2.0 | |
8 | * | |
9 | * Unless required by applicable law or agreed to in writing, software | |
10 | * distributed under the License is distributed on an "AS IS" BASIS, | |
11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
12 | * See the License for the specific language governing permissions and | |
13 | * limitations under the License. | |
14 | */ | |
15 | ||
16 | #include <config.h> | |
17 | ||
18 | #include "entropy.h" | |
19 | ||
20 | #include <errno.h> | |
21 | #include <fcntl.h> | |
22 | #include <unistd.h> | |
5d386c06 AS |
23 | #ifdef _WIN32 |
24 | #include <Wincrypt.h> | |
25 | #endif | |
e251c8d0 BP |
26 | |
27 | #include "socket-util.h" | |
28 | #include "vlog.h" | |
29 | ||
d98e6007 | 30 | VLOG_DEFINE_THIS_MODULE(entropy); |
e251c8d0 BP |
31 | |
32 | static const char urandom[] = "/dev/urandom"; | |
33 | ||
34 | /* Initializes 'buffer' with 'n' bytes of high-quality random numbers. Returns | |
35 | * 0 if successful, otherwise a positive errno value or EOF on error. */ | |
36 | int | |
37 | get_entropy(void *buffer, size_t n) | |
38 | { | |
5d386c06 | 39 | #ifndef _WIN32 |
e251c8d0 BP |
40 | size_t bytes_read; |
41 | int error; | |
42 | int fd; | |
43 | ||
44 | fd = open(urandom, O_RDONLY); | |
45 | if (fd < 0) { | |
10a89ef0 | 46 | VLOG_ERR("%s: open failed (%s)", urandom, ovs_strerror(errno)); |
e251c8d0 BP |
47 | return errno ? errno : EINVAL; |
48 | } | |
49 | ||
50 | error = read_fully(fd, buffer, n, &bytes_read); | |
51 | close(fd); | |
52 | ||
53 | if (error) { | |
fe1e967e | 54 | VLOG_ERR("%s: read error (%s)", urandom, ovs_retval_to_string(error)); |
e251c8d0 | 55 | } |
5d386c06 AS |
56 | #else |
57 | int error = 0; | |
58 | HCRYPTPROV crypt_prov = 0; | |
5d386c06 AS |
59 | |
60 | CryptAcquireContext(&crypt_prov, NULL, NULL, | |
61 | PROV_RSA_FULL, CRYPT_VERIFYCONTEXT); | |
62 | if (!CryptGenRandom(crypt_prov, n, buffer)) { | |
06f14c92 | 63 | char *msg_buf = ovs_lasterror_to_string(); |
5d386c06 | 64 | error = EINVAL; |
5d386c06 AS |
65 | VLOG_ERR("CryptGenRandom: read error (%s)", msg_buf); |
66 | LocalFree(msg_buf); | |
67 | } | |
68 | ||
69 | CryptReleaseContext(crypt_prov, 0); | |
70 | #endif | |
e251c8d0 BP |
71 | return error; |
72 | } | |
73 | ||
74 | /* Initializes 'buffer' with 'n' bytes of high-quality random numbers. Exits | |
75 | * if an error occurs. */ | |
76 | void | |
77 | get_entropy_or_die(void *buffer, size_t n) | |
78 | { | |
79 | int error = get_entropy(buffer, n); | |
80 | if (error) { | |
279c9e03 BP |
81 | VLOG_FATAL("%s: read error (%s)", |
82 | urandom, ovs_retval_to_string(error)); | |
e251c8d0 BP |
83 | } |
84 | } |