Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[FYI 3.3 backport] crypto/rand: implement Jitter Entropy based random seed source #24187

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
26 changes: 26 additions & 0 deletions .github/workflows/run-checker-daily.yml
Expand Up @@ -191,6 +191,32 @@ jobs:
if: steps.sctp_auth.outcome == 'success' && steps.sctp_auth.conclusion == 'success'
run: make test HARNESS_JOBS=${HARNESS_JOBS:-4}

rand_seed_jitter:
runs-on: ubuntu-latest
steps:
- name: checkout openssl
uses: actions/checkout@v4
- name: checkout jitter
uses: actions/checkout@v4
with:
repository: smuellerDD/jitterentropy-library
ref: v3.4.1
path: jitter
- name: build jitter
run: make -C jitter/
- name: checkout fuzz/corpora submodule
run: git submodule update --init --depth 1 fuzz/corpora
- name: config
run: ./config --with-rand-seed=jitter --with-jitter-include=jitter/ --with-jitter-lib=jitter/ && perl configdata.pm --dump
- name: make
run: make -s -j4
- name: get cpu info
run: |
cat /proc/cpuinfo
./util/opensslwrap.sh version -c
- name: make test
run: make test HARNESS_JOBS=${HARNESS_JOBS:-4}

enable_brotli_dynamic:
runs-on: ubuntu-latest
steps:
Expand Down
5 changes: 5 additions & 0 deletions CHANGES.md
Expand Up @@ -28,6 +28,11 @@ OpenSSL 3.3

### Changes between 3.2 and 3.3.0 [9 Apr 2024]

* Add a new random seed source `jitter` using a statically linked
jitterentropy library.

*Dimitri John Ledkov*

* The `-verify` option to the `openssl crl` and `openssl req` will make
the program exit with 1 on failure.

Expand Down
4 changes: 4 additions & 0 deletions Configurations/00-base-templates.conf
Expand Up @@ -59,6 +59,8 @@ my %targets=(
includes =>
sub {
my @incs = ();
push @incs, $withargs{jitter_include}
if !$disabled{jitter} && $withargs{jitter_include};
push @incs, $withargs{brotli_include}
if !$disabled{brotli} && $withargs{brotli_include};
push @incs, $withargs{zlib_include}
Expand All @@ -79,6 +81,7 @@ my %targets=(
lflags =>
sub {
my @libs = ();
push(@libs, "-L".$withargs{jitter_lib}) if $withargs{jitter_lib};
push(@libs, "-L".$withargs{zlib_lib}) if $withargs{zlib_lib};
push(@libs, "-L".$withargs{brotli_lib}) if $withargs{brotli_lib};
push(@libs, "-L".$withargs{zstd_lib}) if $withargs{zstd_lib};
Expand All @@ -87,6 +90,7 @@ my %targets=(
ex_libs =>
sub {
my @libs = ();
push(@libs, "-l:libjitterentropy.a") if !defined($disabled{jitter});
push(@libs, "-lz") if !defined($disabled{zlib}) && defined($disabled{"zlib-dynamic"});
if (!defined($disabled{brotli}) && defined($disabled{"brotli-dynamic"})) {
push(@libs, "-lbrotlienc");
Expand Down
15 changes: 14 additions & 1 deletion Configure
Expand Up @@ -471,6 +471,7 @@ my @disablables = (
"gost",
"http",
"idea",
"jitter",
"ktls",
"legacy",
"loadereng",
Expand Down Expand Up @@ -576,6 +577,7 @@ our %disabled = ( # "what" => "comment"
"external-tests" => "default",
"fuzz-afl" => "default",
"fuzz-libfuzzer" => "default",
"jitter" => "default",
"ktls" => "default",
"md2" => "default",
"msan" => "default",
Expand Down Expand Up @@ -805,7 +807,7 @@ my %cmdvars = (); # Stores FOO='blah' type arguments
my %unsupported_options = ();
my %deprecated_options = ();
# If you change this, update apps/version.c
my @known_seed_sources = qw(getrandom devrandom os egd none rdcpu librandom);
my @known_seed_sources = qw(getrandom devrandom os egd none rdcpu librandom jitter);
my @seed_sources = ();
while (@argvcopy)
{
Expand Down Expand Up @@ -1005,6 +1007,14 @@ while (@argvcopy)
{
$config{openssldir}=$1;
}
elsif (/^--with-jitter-include=(.*)$/)
{
$withargs{jitter_include}=$1;
}
elsif (/^--with-jitter-lib=(.*)$/)
{
$withargs{jitter_lib}=$1;
}
elsif (/^--with-zlib-lib=(.*)$/)
{
$withargs{zlib_lib}=$1;
Expand Down Expand Up @@ -1291,6 +1301,9 @@ if (scalar(@seed_sources) == 0) {
if (scalar(grep { $_ eq 'egd' } @seed_sources) > 0) {
delete $disabled{'egd'};
}
if (scalar(grep { $_ eq 'jitter' } @seed_sources) > 0) {
delete $disabled{'jitter'};
}
if (scalar(grep { $_ eq 'none' } @seed_sources) > 0) {
die "Cannot seed with none and anything else" if scalar(@seed_sources) > 1;
warn <<_____ if scalar(@seed_sources) == 1;
Expand Down
17 changes: 17 additions & 0 deletions INSTALL.md
Expand Up @@ -512,6 +512,23 @@ if provided by the CPU.
Use librandom (not implemented yet).
This source is ignored by the FIPS provider.

### jitter

Use
[jitterentropy-library](https://github.com/smuellerDD/jitterentropy-library) statically linked only.

Additional configuration flags available:

--with-jitter-include=DIR

The directory for the location of the jitterentropy.h include file, if
it is outside the system include path.

--with-jitter-lib=DIR

This is the directory containing the static libjitterentropy.a
library, if it is outside the system library path.

### none

Disable automatic seeding. This is the default on some operating systems where
Expand Down
12 changes: 11 additions & 1 deletion crypto/info.c
@@ -1,5 +1,5 @@
/*
* Copyright 2019-2023 The OpenSSL Project Authors. All Rights Reserved.
* Copyright 2019-2024 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
Expand All @@ -15,6 +15,11 @@
#include "internal/e_os.h"
#include "buildinf.h"

#ifdef OPENSSL_RAND_SEED_JITTER
# include <stdio.h>
# include <jitterentropy.h>
#endif

#if defined(__arm__) || defined(__arm) || defined(__aarch64__)
# include "arm_arch.h"
# define CPU_INFO_STR_LEN 128
Expand Down Expand Up @@ -141,6 +146,11 @@ DEFINE_RUN_ONCE_STATIC(init_info_strings)
add_seeds_string("rdrand ( rdseed rdrand )");
# endif
#endif
#ifdef OPENSSL_RAND_SEED_JITTER
char jent_version_string[32];
sprintf(jent_version_string, "jitterentropy (%d)", jent_version());
add_seeds_string(jent_version_string);
#endif
#ifdef OPENSSL_RAND_SEED_LIBRANDOM
add_seeds_string("C-library-random");
#endif
Expand Down
11 changes: 10 additions & 1 deletion crypto/rand/rand_lib.c
@@ -1,5 +1,5 @@
/*
* Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved.
* Copyright 1995-2024 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
Expand All @@ -20,6 +20,10 @@
#include "rand_local.h"
#include "crypto/context.h"

#ifdef OPENSSL_RAND_SEED_JITTER
#include <jitterentropy.h>
#endif

#ifndef FIPS_MODULE
# include <stdio.h>
# include <time.h>
Expand Down Expand Up @@ -62,6 +66,11 @@ DEFINE_RUN_ONCE_STATIC(do_rand_init)
if (!ossl_rand_pool_init())
goto err;

# ifdef OPENSSL_RAND_SEED_JITTER
if (jent_entropy_init_ex(0, JENT_FORCE_FIPS))
goto err;
# endif

rand_inited = 1;
return 1;

Expand Down
1 change: 1 addition & 0 deletions providers/implementations/include/prov/seeding.h
Expand Up @@ -13,6 +13,7 @@
/* Hardware-based seeding functions. */
size_t ossl_prov_acquire_entropy_from_tsc(RAND_POOL *pool);
size_t ossl_prov_acquire_entropy_from_cpu(RAND_POOL *pool);
size_t ossl_prov_acquire_entropy_from_jitter(RAND_POOL *pool);

/*
* External seeding functions from the core dispatch table.
Expand Down
2 changes: 1 addition & 1 deletion providers/implementations/rands/seeding/build.info
@@ -1,4 +1,4 @@
$COMMON=rand_unix.c rand_win.c rand_tsc.c
$COMMON=rand_unix.c rand_win.c rand_tsc.c rand_jitter.c
IF[{- $config{target} =~ /vxworks/i -}]
$COMMON=$COMMON rand_vxworks.c
ENDIF
Expand Down
82 changes: 82 additions & 0 deletions providers/implementations/rands/seeding/rand_jitter.c
@@ -0,0 +1,82 @@
/*
* Copyright 2024 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
* in the file LICENSE in the source distribution or at
* https://www.openssl.org/source/license.html
*/

#include "internal/cryptlib.h"
#include <openssl/opensslconf.h>
#include "crypto/rand_pool.h"
#include "prov/seeding.h"

#ifdef OPENSSL_RAND_SEED_JITTER
#include <jitterentropy.h>

#define JITTER_MAX_NUM_TRIES 3

static size_t get_jitter_random_value(unsigned char *buf, size_t len);

/*
* Acquire entropy from jitterentropy library
*
* Returns the total entropy count, if it exceeds the requested
* entropy count. Otherwise, returns an entropy count of 0.
*/
size_t ossl_prov_acquire_entropy_from_jitter(RAND_POOL *pool)
{
size_t bytes_needed;
unsigned char *buffer;

bytes_needed = ossl_rand_pool_bytes_needed(pool, 1 /*entropy_factor*/);
if (bytes_needed > 0) {
buffer = ossl_rand_pool_add_begin(pool, bytes_needed);

if (buffer != NULL) {
if (get_jitter_random_value(buffer, bytes_needed) == bytes_needed) {
ossl_rand_pool_add_end(pool, bytes_needed, 8 * bytes_needed);
} else {
ossl_rand_pool_add_end(pool, 0, 0);
}
}
}

return ossl_rand_pool_entropy_available(pool);
}

/* Obtain random bytes from the jitter library */
static size_t get_jitter_random_value(unsigned char *buf, size_t len)
{
struct rand_data *jitter_ec = NULL;
ssize_t result = 0;
size_t num_tries;

jitter_ec = jent_entropy_collector_alloc(0, JENT_FORCE_FIPS);
if (jitter_ec == NULL) {
return 0;
}

for (num_tries = 0; num_tries < JITTER_MAX_NUM_TRIES; num_tries++) {
// Do not use _safe API variant with built-in retries, until
// failure because it reseeds the entropy source which is not
// certifyable
result = jent_read_entropy(jitter_ec, (char *) buf, len);

// Success
if (result == len) {
jent_entropy_collector_free(jitter_ec);
return len;
}
}

jent_entropy_collector_free(jitter_ec);

// Catastrophic failure, maybe should abort here
return 0;
}

#else
NON_EMPTY_TRANSLATION_UNIT
#endif
9 changes: 8 additions & 1 deletion providers/implementations/rands/seeding/rand_unix.c
@@ -1,5 +1,5 @@
/*
* Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved.
* Copyright 1995-2024 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
Expand Down Expand Up @@ -95,6 +95,7 @@ static uint64_t get_time_stamp(void);
/* none means none. this simplifies the following logic */
# undef OPENSSL_RAND_SEED_OS
# undef OPENSSL_RAND_SEED_GETRANDOM
# undef OPENSSL_RAND_SEED_JITTER
# undef OPENSSL_RAND_SEED_LIBRANDOM
# undef OPENSSL_RAND_SEED_DEVRANDOM
# undef OPENSSL_RAND_SEED_RDTSC
Expand Down Expand Up @@ -717,6 +718,12 @@ size_t ossl_pool_acquire_entropy(RAND_POOL *pool)
return entropy_available;
# endif

# if defined(OPENSSL_RAND_SEED_JITTER)
entropy_available = ossl_prov_acquire_entropy_from_jitter(pool);
if (entropy_available > 0)
return entropy_available;
# endif

# if defined(OPENSSL_RAND_SEED_EGD)
{
static const char *paths[] = { DEVRANDOM_EGD, NULL };
Expand Down