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

Fix a possible cause of crashes in free() #33

Merged
merged 1 commit into from
Sep 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .github/workflows/maven.yml
Original file line number Diff line number Diff line change
Expand Up @@ -47,4 +47,6 @@ jobs:
if: always()
with:
name: maven-surefire-reports
path: ${{ github.workspace }}/target/surefire-reports
path: |
${{ github.workspace }}/target/surefire-reports
${{ github.workspace }}/build/test/test.out
3 changes: 0 additions & 3 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -172,9 +172,6 @@
<includes>
<include>**/*Test.java</include>
</includes>
<excludes>
<exclude>**/*SecureRandomTest.java</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
Expand Down
42 changes: 20 additions & 22 deletions src/main/native/c/com_canonical_openssl_drbg_OpenSSLDrbg.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,23 +45,23 @@ void populate_params(DRBGParams *params, int strength, int prediction_resistance
JNIEXPORT jlong JNICALL Java_com_canonical_openssl_drbg_OpenSSLDrbg_init
(JNIEnv *env, jobject this, jstring name, jint strength, jboolean prediction_resistance, jboolean reseeding, jbyteArray personalization_string) {
const char *name_string = (*env)->GetStringUTFChars(env, name, 0);
byte *pstr_bytes = NULL;
byte *ps_bytes_native = NULL;
jsize pstr_length = 0;

if (personalization_string != NULL) {
pstr_length = (*env)->GetArrayLength(env, personalization_string);
pstr_bytes = (*env)->GetByteArrayElements(env, personalization_string, NULL);
byte *pstr_bytes = (*env)->GetByteArrayElements(env, personalization_string, NULL);
ps_bytes_native = (byte *)malloc(pstr_length);
memcpy(ps_bytes_native, pstr_bytes, pstr_length);
(*env)->ReleaseByteArrayElements(env, personalization_string, pstr_bytes, JNI_ABORT);
}

DRBGParams *params = (DRBGParams *)malloc(sizeof(DRBGParams));
populate_params(params, strength, prediction_resistance, reseeding, pstr_bytes, pstr_length, NULL, 0);
populate_params(params, strength, prediction_resistance, reseeding, ps_bytes_native, pstr_length, NULL, 0);

DRBG* drbg = create_DRBG_with_params(name_string, NULL, params);
(*env)->ReleaseStringUTFChars(env, name, name_string);

if (personalization_string != NULL) {
(*env)->ReleaseByteArrayElements(env, personalization_string, pstr_bytes, JNI_ABORT);
}
return (jlong)drbg;
}

Expand All @@ -72,31 +72,29 @@ JNIEXPORT jlong JNICALL Java_com_canonical_openssl_drbg_OpenSSLDrbg_init
*/
JNIEXPORT void JNICALL Java_com_canonical_openssl_drbg_OpenSSLDrbg_nextBytes0
(JNIEnv *env, jobject this, jbyteArray out_bytes, jint strength, jboolean prediction_resistance , jbyteArray additional_input) {

int additional_input_length = 0;
jbyte *additional_input_bytes = NULL;

byte *ai_bytes_native = NULL;
jsize additional_input_length = 0;
jclass clazz = (*env)->GetObjectClass(env, this);
jfieldID drbg_id = (*env)->GetFieldID(env, clazz, "drbgContext", "J");
jlong drbg_handle = (*env)->GetLongField(env, this, drbg_id);

int output_bytes_length = (*env)->GetArrayLength(env, out_bytes);
byte *output_bytes = (byte *)malloc(sizeof(output_bytes_length));
byte *output_bytes = (byte *)malloc(output_bytes_length);

if (additional_input != NULL) {
additional_input_length = (*env)->GetArrayLength(env, additional_input);
additional_input_bytes = (*env)->GetByteArrayElements(env, additional_input, NULL);
jbyte *additional_input_bytes = (*env)->GetByteArrayElements(env, additional_input, NULL);
ai_bytes_native = (byte*)malloc(additional_input_length);
memcpy(ai_bytes_native, additional_input_bytes, additional_input_length);
(*env)->ReleaseByteArrayElements(env, additional_input, additional_input_bytes, JNI_ABORT);
}

DRBGParams *params = (DRBGParams *)malloc(sizeof(DRBGParams));
populate_params(params, strength, prediction_resistance, 0, NULL, 0, (byte *)additional_input_bytes, additional_input_length);
populate_params(params, strength, prediction_resistance, 0, NULL, 0, ai_bytes_native, additional_input_length);

next_rand_with_params((DRBG *)drbg_handle, output_bytes, output_bytes_length, params);

(*env)->SetByteArrayRegion(env, out_bytes, 0, output_bytes_length, output_bytes);
if (additional_input != NULL) {
(*env)->ReleaseByteArrayElements(env, additional_input, additional_input_bytes, JNI_ABORT);
}
}

/*
Expand Down Expand Up @@ -139,6 +137,7 @@ JNIEXPORT void JNICALL Java_com_canonical_openssl_drbg_OpenSSLDrbg_reseed0
}
}

#define MAX_SEED_BYTES 256
/*
* Class: com_canonical_openssl_OpenSSLDrbg
* Method: generateSeed0
Expand All @@ -151,18 +150,17 @@ JNIEXPORT jbyteArray JNICALL Java_com_canonical_openssl_drbg_OpenSSLDrbg_generat
jfieldID drbg_id = (*env)->GetFieldID(env, clazz, "drbgContext", "J");
jlong drbg_handle = (*env)->GetLongField(env, this, drbg_id);

byte *output = (byte *)malloc(num_bytes);

if (output == NULL) {
return NULL;
if (num_bytes > 256) {
num_bytes = 256;
}

byte output[MAX_SEED_BYTES];

generate_seed((DRBG*)drbg_handle, output, num_bytes);

jbyteArray ret_array = (*env)->NewByteArray(env, num_bytes);
(*env)->SetBooleanArrayRegion(env, ret_array, 0, num_bytes, output);
(*env)->SetByteArrayRegion(env, ret_array, 0, num_bytes, output);

free(output);
return ret_array;
}

Expand Down
29 changes: 10 additions & 19 deletions src/main/native/c/drbg.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
*/
#include <drbg.h>
#include <stdio.h>
#include <sys/random.h>
#include <unistd.h>

DRBGParams NO_PARAMS = { DEFAULT_STRENGTH, 0, 0, NULL, 0, NULL, 0 };
Expand Down Expand Up @@ -57,7 +58,7 @@ DRBG* create_DRBG(const char* name, DRBG* parent) {
DRBG* create_DRBG_with_params(const char* name, DRBG* parent, DRBGParams *drbg_params) {
EVP_RAND *rand = EVP_RAND_fetch(NULL, name, NULL);
if (NULL == rand) {
fprintf(stderr, "Couldn't allocate EVP_RAND\n");
fprintf(stderr, "Couldn't allocate EVP_RAND: %s\n", name);
return NULL;
}

Expand Down Expand Up @@ -93,6 +94,9 @@ DRBG* create_DRBG_with_params(const char* name, DRBG* parent, DRBGParams *drbg_p
}

int free_DRBGParams(DRBGParams *params) {
if (params == NULL) {
return 0;
}
FREE_IF_NON_NULL(params->additional_data);
FREE_IF_NON_NULL(params->personalization_str);
FREE_IF_NON_NULL(params);
Expand All @@ -103,23 +107,10 @@ int free_DRBG(DRBG *generator) {
if (generator == NULL) {
return 0;
}

free_DRBGParams(generator->params);
free_DRBG(generator->parent);
FREE_IF_NON_NULL(generator->seed);
if (generator->context != NULL) {
EVP_RAND_CTX_free(generator->context);
generator->context = NULL;
}

if (generator->params != NULL) {
free_DRBGParams(generator->params);
generator->params = NULL;
}

if (generator->parent != NULL) {
free_DRBG(generator->parent);
generator->parent = NULL;
}

EVP_RAND_CTX_free(generator->context);
free(generator);
return 1;
}
Expand Down Expand Up @@ -157,7 +148,7 @@ int generate_seed(DRBG* generator, byte output[], int n_bytes) {
if (parent != NULL) {
return next_rand(parent, output, n_bytes);
} else {
return getentropy(output, n_bytes);
return getrandom(output, n_bytes, 0);
}
}

Expand All @@ -168,7 +159,7 @@ void reseed(DRBG* generator) {
void reseed_with_params(DRBG *generator, DRBGParams *params) {
byte seed[128]; // TODO: what should the default seed size be?
size_t length = 128;
getentropy(seed, length);
getrandom(seed, length, 0);
EVP_RAND_reseed(generator->context, params->prediction_resistance, seed, length, params->additional_data, params->additional_data_length);
}

Expand Down
1 change: 1 addition & 0 deletions src/main/native/c/signature.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
*/
#include "signature.h"
#include "jssl.h"
#include <openssl/err.h>
#include <openssl/rsa.h>
#include <openssl/core_names.h>

Expand Down
4 changes: 2 additions & 2 deletions src/test/java/SecureRandomTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -169,8 +169,8 @@ public void testDRBGCreationNextBytesWithParams() throws NoSuchAlgorithmExceptio
testArrayInequality(hash1, hash2);
}

/* disabled - needs a "double-free" investigation" */
private void testDRBGCreationWithParamsNextBytesWithParams() throws NoSuchAlgorithmException, NoSuchProviderException {
@Test
public void testDRBGCreationWithParamsNextBytesWithParams() throws NoSuchAlgorithmException, NoSuchProviderException {
SecureRandomParameters params = DrbgParameters.instantiation(128, Capability.PR_AND_RESEED, "FIPSPROTOTYPE".getBytes());
SecureRandomParameters nbParams = DrbgParameters.nextBytes(128, true, "ADDITIONALINPUT".getBytes());

Expand Down
2 changes: 1 addition & 1 deletion src/test/runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
}

def run_native_test(name):
return os.system(f"build/test/bin/{name} > /dev/null 2>&1")
return os.system(f"build/test/bin/{name} >> build/test/test.out 2>&1")

for test in tests.keys():
name = tests[test]
Expand Down