Packages
hackney
3.0.1
4.7.2
4.7.1
4.7.0
4.6.1
4.6.0
4.5.2
4.5.1
4.5.0
4.4.5
4.4.3
4.4.2
4.4.1
4.4.0
4.3.0
4.2.3
4.2.2
4.2.1
4.2.0
4.1.0
4.0.3
4.0.2
4.0.1
4.0.0
3.2.1
3.2.0
3.1.2
3.1.1
3.1.0
3.0.3
3.0.2
3.0.1
3.0.0
retired
2.0.1
2.0.0
2.0.0-beta.1
1.25.0
1.24.1
1.24.0
1.23.0
1.22.0
1.21.0
1.20.1
1.20.0
1.19.1
1.19.0
1.18.2
1.18.1
1.18.0
1.17.4
1.17.3
1.17.2
1.17.1
1.17.0
1.16.0
1.15.2
1.15.1
1.15.0
1.14.3
1.14.2
1.14.0
1.13.0
1.12.1
1.12.0
1.11.0
1.10.1
1.10.0
1.9.0
1.8.6
1.8.5
1.8.4
1.8.3
1.8.2
1.8.0
1.7.1
1.7.0
1.6.6
retired
1.6.5
1.6.4
retired
1.6.3
1.6.2
1.6.1
1.6.0
1.5.7
1.5.6
1.5.5
1.5.4
1.5.3
1.5.2
1.5.1
1.5.0
1.4.10
1.4.8
1.4.7
1.4.6
1.4.5
1.4.4
1.4.3
1.4.2
1.4.1
1.4.0
1.3.2
1.3.1
1.3.0
1.2.0
1.1.0
1.0.6
1.0.5
1.0.2
1.0.1
0.15.2
0.15.0
0.14.3
0.14.2
0.14.1
0.14.0
0.13.1
Simple HTTP client with HTTP/1.1, HTTP/2, and HTTP/3 support
Security advisory:
This version has known vulnerabilities.
View advisories
Current section
Files
Jump to
Current section
Files
c_src/boringssl/crypto/rand/passive.cc
// Copyright 2020 The BoringSSL Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <openssl/ctrdrbg.h>
#include "../bcm_support.h"
#include "../fipsmodule/bcm_interface.h"
#include "../internal.h"
#if defined(BORINGSSL_FIPS)
#include <atomic>
// passive_get_seed_entropy writes |out_entropy_len| bytes of entropy, suitable
// for seeding a DRBG, to |out_entropy|. It sets |*out_used_cpu| to one if the
// entropy came directly from the CPU and zero if it came from the OS. It
// actively obtains entropy from the CPU/OS
static void passive_get_seed_entropy(uint8_t *out_entropy,
size_t out_entropy_len,
int *out_want_additional_input) {
*out_want_additional_input = 0;
if (bcm_success(BCM_rand_bytes_hwrng(out_entropy, out_entropy_len))) {
*out_want_additional_input = 1;
} else {
CRYPTO_sysrand(out_entropy, out_entropy_len);
}
}
#define ENTROPY_READ_LEN \
(/* last_block size */ 16 + CTR_DRBG_SEED_LEN * BORINGSSL_FIPS_OVERREAD)
#if defined(OPENSSL_ANDROID)
#include <errno.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/un.h>
#include <unistd.h>
// socket_history_t enumerates whether the entropy daemon should be contacted
// for a given entropy request. Values other than socket_not_yet_attempted are
// sticky so if the first attempt to read from the daemon fails it's assumed
// that the daemon is not present and no more attempts will be made. If the
// first attempt is successful then attempts will be made forever more.
enum class socket_history_t {
// initial value, no connections to the entropy daemon have been made yet.
socket_not_yet_attempted = 0,
// reading from the entropy daemon was successful
socket_success,
// reading from the entropy daemon failed.
socket_failed,
};
static std::atomic<socket_history_t> g_socket_history{
socket_history_t::socket_not_yet_attempted};
// DAEMON_RESPONSE_LEN is the number of bytes that the entropy daemon replies
// with.
#define DAEMON_RESPONSE_LEN 496
static_assert(ENTROPY_READ_LEN == DAEMON_RESPONSE_LEN,
"entropy daemon response length mismatch");
static int get_seed_from_daemon(uint8_t *out_entropy, size_t out_entropy_len) {
// |RAND_need_entropy| should never call this function for more than
// |DAEMON_RESPONSE_LEN| bytes.
if (out_entropy_len > DAEMON_RESPONSE_LEN) {
abort();
}
const socket_history_t socket_history =
g_socket_history.load(std::memory_order_acquire);
if (socket_history == socket_history_t::socket_failed) {
return 0;
}
int ret = 0;
static const char kSocketPath[] = "/dev/socket/prng_seeder";
struct sockaddr_un sun;
uint8_t buffer[DAEMON_RESPONSE_LEN];
size_t done = 0;
const int sock = socket(AF_UNIX, SOCK_STREAM, 0);
if (sock < 0) {
goto out;
}
memset(&sun, 0, sizeof(sun));
sun.sun_family = AF_UNIX;
static_assert(sizeof(kSocketPath) <= UNIX_PATH_MAX, "kSocketPath too long");
OPENSSL_memcpy(sun.sun_path, kSocketPath, sizeof(kSocketPath));
if (connect(sock, (struct sockaddr *)&sun, sizeof(sun))) {
goto out;
}
while (done < sizeof(buffer)) {
ssize_t n;
do {
n = read(sock, buffer + done, sizeof(buffer) - done);
} while (n == -1 && errno == EINTR);
if (n < 1) {
goto out;
}
done += n;
}
if (done != DAEMON_RESPONSE_LEN) {
// The daemon should always write |DAEMON_RESPONSE_LEN| bytes on every
// connection.
goto out;
}
assert(out_entropy_len <= DAEMON_RESPONSE_LEN);
OPENSSL_memcpy(out_entropy, buffer, out_entropy_len);
ret = 1;
out:
if (socket_history == socket_history_t::socket_not_yet_attempted) {
socket_history_t expected = socket_history_t::socket_not_yet_attempted;
// If another thread has already updated |g_socket_history| then we defer
// to their value.
g_socket_history.compare_exchange_strong(
expected,
(ret == 0) ? socket_history_t::socket_failed
: socket_history_t::socket_success,
std::memory_order_release, std::memory_order_relaxed);
}
close(sock);
return ret;
}
#else
static int get_seed_from_daemon(uint8_t *out_entropy, size_t out_entropy_len) {
return 0;
}
#endif // OPENSSL_ANDROID
// RAND_need_entropy is called by the FIPS module when it has blocked because of
// a lack of entropy. This signal is used as an indication to feed it more.
void RAND_need_entropy(size_t bytes_needed) {
uint8_t buf[ENTROPY_READ_LEN];
size_t todo = sizeof(buf);
if (todo > bytes_needed) {
todo = bytes_needed;
}
int want_additional_input;
if (get_seed_from_daemon(buf, todo)) {
want_additional_input = 1;
} else {
passive_get_seed_entropy(buf, todo, &want_additional_input);
}
if (boringssl_fips_break_test("CRNG")) {
// This breaks the "continuous random number generator test" defined in FIPS
// 140-2, section 4.9.2, and implemented in |rand_get_seed|.
OPENSSL_memset(buf, 0, todo);
}
BCM_rand_load_entropy(buf, todo, want_additional_input);
}
#endif // FIPS