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

Improve Error Handling to Prevent Exit, Crashes and Memory Leaks #1929

Draft
wants to merge 40 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
16b1a32
Bump version string; update release and security notes.
praveksharma Sep 13, 2024
e6d9a2f
Complete release notes
SWilson4 Sep 13, 2024
cda3e35
Remove references to profiling, liboqs-java, and liboqs-dotnet
SWilson4 Sep 13, 2024
3b2cd83
Bump SOVERSION
SWilson4 Sep 13, 2024
e4d0560
[#1823] replace malloc/calloc/strdup/free with openssl allocator
songlingatpan Sep 17, 2024
125027e
[#1823] update memory allocator for copy_from_upstream
songlingatpan Sep 17, 2024
0d35a14
[#1823] format code
songlingatpan Sep 17, 2024
7f3fe9c
[#1823] Use OpenSSL Memory Allocator for BIKE, FrodoKEM, and NTRUPrime
songlingatpan Sep 17, 2024
d544770
[#1823] Add Comments for Doxygen
songlingatpan Sep 17, 2024
e177d16
sig_stfl build fix
songlingatpan Sep 21, 2024
d73b469
fix ptrdiff_t failure
songlingatpan Sep 21, 2024
9e15107
include openssl/crypto.h and resolve conflict varible for ntru
songlingatpan Sep 21, 2024
a83958b
Add openssl version check to fix build error
songlingatpan Sep 21, 2024
369a268
fix implicit conversion for diff
songlingatpan Sep 21, 2024
e24b16a
fix build for tests
songlingatpan Sep 21, 2024
fdacd10
Fix build for tests
songlingatpan Sep 21, 2024
0c99451
Fix build for OQS_DLOPEN_OPENSSL
songlingatpan Sep 21, 2024
a90603f
Fix build failure
songlingatpan Sep 21, 2024
40586f8
Error Handling
songlingatpan Sep 17, 2024
b8236b1
Add NULL check for AES
songlingatpan Sep 18, 2024
fec2cdf
remove io for better performance during failure. add log later.
songlingatpan Sep 22, 2024
5e0d03b
Add NULL check for AES
songlingatpan Sep 18, 2024
0c2345b
fix OQS_OPENSSL_GUARD failure
songlingatpan Sep 22, 2024
7f6ea1b
Fix potential memory leak for do_hash
songlingatpan Sep 22, 2024
c6ace19
Fix potential memory leak for sha2_256_init
songlingatpan Sep 22, 2024
3fa49f1
Fix potential memory leak for SHA2_sha512_inc
songlingatpan Sep 22, 2024
8ab2e63
format code
songlingatpan Sep 22, 2024
1089458
Fix NULL check for ossl_sha3.c
songlingatpan Sep 22, 2024
2780fe9
Add NULL check for rand
songlingatpan Sep 18, 2024
2e6facb
format code
songlingatpan Sep 22, 2024
148b11b
Add NULL check for common
songlingatpan Sep 18, 2024
9bb0db9
fix build failure
songlingatpan Sep 22, 2024
00a9689
remove OQS_MEM_free
songlingatpan Sep 23, 2024
c02c48c
remove OQS_MEM_free
songlingatpan Sep 23, 2024
c4b6587
Add allocator check in tests/test_code_conventions.py
songlingatpan Sep 24, 2024
1fc3fee
format code
songlingatpan Sep 24, 2024
a77e2af
revert changes back for CMakeLists.txt, RELEASE.md and SECURITY.md
songlingatpan Sep 25, 2024
050a561
revert changes back for RELEASE.md and SECURITY.md
songlingatpan Sep 25, 2024
97f283f
Merge branch 'open-quantum-safe:main' into pr_shan_error_handling
songlingatpan Sep 27, 2024
8339bd6
revert back to abort() in OQS_MEM_cleanse
songlingatpan Sep 27, 2024
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: 2 additions & 2 deletions scripts/copy_from_upstream/src/kem/family/kem_scheme.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
{% endif %}
OQS_KEM *OQS_KEM_{{ family }}_{{ scheme['scheme'] }}_new(void) {

OQS_KEM *kem = malloc(sizeof(OQS_KEM));
OQS_KEM *kem = OQS_MEM_malloc(sizeof(OQS_KEM));
if (kem == NULL) {
return NULL;
}
Expand Down Expand Up @@ -42,7 +42,7 @@ OQS_KEM *OQS_KEM_{{ family }}_{{ scheme['scheme'] }}_new(void) {
/** Alias */
OQS_KEM *OQS_KEM_{{ family }}_{{ scheme['alias_scheme'] }}_new(void) {

OQS_KEM *kem = malloc(sizeof(OQS_KEM));
OQS_KEM *kem = OQS_MEM_malloc(sizeof(OQS_KEM));
if (kem == NULL) {
return NULL;
}
Expand Down
4 changes: 2 additions & 2 deletions scripts/copy_from_upstream/src/sig/family/sig_scheme.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
{% endif %}
OQS_SIG *OQS_SIG_{{ family }}_{{ scheme['scheme'] }}_new(void) {

OQS_SIG *sig = malloc(sizeof(OQS_SIG));
OQS_SIG *sig = OQS_MEM_malloc(sizeof(OQS_SIG));
if (sig == NULL) {
return NULL;
}
Expand Down Expand Up @@ -41,7 +41,7 @@ OQS_SIG *OQS_SIG_{{ family }}_{{ scheme['scheme'] }}_new(void) {
/** Alias */
OQS_SIG *OQS_SIG_{{ family }}_{{ scheme['alias_scheme'] }}_new(void) {

OQS_SIG *sig = malloc(sizeof(OQS_SIG));
OQS_SIG *sig = OQS_MEM_malloc(sizeof(OQS_SIG));
if (sig == NULL) {
return NULL;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
{%- if scheme['signed_msg_order'] == 'sig_then_msg' %}
// signed_msg = signature || msg
*signed_msg_len = signature_len + msg_len;
*signed_msg = malloc(*signed_msg_len);
*signed_msg = OQS_MEM_malloc(*signed_msg_len);
if (*signed_msg == NULL) {
return OQS_ERROR;
}
Expand All @@ -13,7 +13,7 @@
{%- elif scheme['signed_msg_order'] == 'msg_then_sig' %}
// signed_msg = msg || signature
*signed_msg_len = msg_len + signature_len;
*signed_msg = malloc(*signed_msg_len);
*signed_msg = OQS_MEM_malloc(*signed_msg_len);
if (*signed_msg == NULL) {
return OQS_ERROR;
}
Expand All @@ -24,7 +24,7 @@
// signed_msg = sig_len (2 bytes, big endian) || nonce (40 bytes) || msg || 0x29 || sig
const uint16_t signature_len_uint16 = (uint16_t)signature_len;
*signed_msg_len = 2 + signature_len_uint16 + msg_len;
*signed_msg = malloc(*signed_msg_len);
*signed_msg = OQS_MEM_malloc(*signed_msg_len);
if (*signed_msg == NULL) {
return OQS_ERROR;
}
Expand All @@ -44,7 +44,7 @@
// signed_msg = sig_len (2 bytes, big endian) || nonce (40 bytes) || msg || 0x2A || sig
const uint16_t signature_len_uint16 = (uint16_t)signature_len;
*signed_msg_len = 2 + signature_len + msg_len;
*signed_msg = malloc(*signed_msg_len);
*signed_msg = OQS_MEM_malloc(*signed_msg_len);
if (*signed_msg == NULL) {
return OQS_ERROR;
}
Expand Down
72 changes: 54 additions & 18 deletions src/common/aes/aes.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,73 +12,109 @@
static struct OQS_AES_callbacks *callbacks = &aes_default_callbacks;

OQS_API void OQS_AES_set_callbacks(struct OQS_AES_callbacks *new_callbacks) {
callbacks = new_callbacks;
if (new_callbacks != NULL) {
callbacks = new_callbacks;
}
}

void OQS_AES128_ECB_load_schedule(const uint8_t *key, void **schedule) {
callbacks->AES128_ECB_load_schedule(key, schedule);
if (key != NULL && schedule != NULL) {
callbacks->AES128_ECB_load_schedule(key, schedule);
}
}

void OQS_AES128_CTR_inc_init(const uint8_t *key, void **_schedule) {
callbacks->AES128_CTR_inc_init(key, _schedule);
if (key != NULL && _schedule != NULL) {
callbacks->AES128_CTR_inc_init(key, _schedule);
}
}

void OQS_AES128_CTR_inc_iv(const uint8_t *iv, size_t iv_len, void *_schedule) {
callbacks->AES128_CTR_inc_iv(iv, iv_len, _schedule);
if (iv != NULL && _schedule != NULL) {
callbacks->AES128_CTR_inc_iv(iv, iv_len, _schedule);
}
}

void OQS_AES128_CTR_inc_ivu64(uint64_t iv, void *_schedule) {
callbacks->AES128_CTR_inc_ivu64(iv, _schedule);
if (_schedule != NULL) {
callbacks->AES128_CTR_inc_ivu64(iv, _schedule);
}
}

void OQS_AES128_free_schedule(void *schedule) {
callbacks->AES128_free_schedule(schedule);
if (schedule != NULL) {
callbacks->AES128_free_schedule(schedule);
}
}

void OQS_AES256_ECB_load_schedule(const uint8_t *key, void **schedule) {
callbacks->AES256_ECB_load_schedule(key, schedule);
if (key != NULL && schedule != NULL) {
callbacks->AES256_ECB_load_schedule(key, schedule);
}
}

void OQS_AES256_CTR_inc_init(const uint8_t *key, void **schedule) {
callbacks->AES256_CTR_inc_init(key, schedule);
if (key != NULL && schedule != NULL) {
callbacks->AES256_CTR_inc_init(key, schedule);
}
}

void OQS_AES256_CTR_inc_iv(const uint8_t *iv, size_t iv_len, void *schedule) {
callbacks->AES256_CTR_inc_iv(iv, iv_len, schedule);
if (iv != NULL && schedule != NULL) {
callbacks->AES256_CTR_inc_iv(iv, iv_len, schedule);
}
}

void OQS_AES256_CTR_inc_ivu64(uint64_t iv, void *schedule) {
callbacks->AES256_CTR_inc_ivu64(iv, schedule);
if (schedule != NULL) {
callbacks->AES256_CTR_inc_ivu64(iv, schedule);
}
}

void OQS_AES256_free_schedule(void *schedule) {
callbacks->AES256_free_schedule(schedule);
if (schedule != NULL) {
callbacks->AES256_free_schedule(schedule);
}
}

void OQS_AES128_ECB_enc(const uint8_t *plaintext, const size_t plaintext_len, const uint8_t *key, uint8_t *ciphertext) {
callbacks->AES128_ECB_enc(plaintext, plaintext_len, key, ciphertext);
if (plaintext != NULL && key != NULL && ciphertext != NULL) {
callbacks->AES128_ECB_enc(plaintext, plaintext_len, key, ciphertext);
}
}

void OQS_AES128_ECB_enc_sch(const uint8_t *plaintext, const size_t plaintext_len, const void *schedule, uint8_t *ciphertext) {
callbacks->AES128_ECB_enc_sch(plaintext, plaintext_len, schedule, ciphertext);
if (plaintext != NULL && schedule != NULL && ciphertext != NULL) {
callbacks->AES128_ECB_enc_sch(plaintext, plaintext_len, schedule, ciphertext);
}
}

void OQS_AES128_CTR_inc_stream_iv(const uint8_t *iv, const size_t iv_len, const void *schedule, uint8_t *out, size_t out_len) {
callbacks->AES128_CTR_inc_stream_iv(iv, iv_len, schedule, out, out_len);
if (iv != NULL && schedule != NULL && out != NULL) {
callbacks->AES128_CTR_inc_stream_iv(iv, iv_len, schedule, out, out_len);
}
}

void OQS_AES256_ECB_enc(const uint8_t *plaintext, const size_t plaintext_len, const uint8_t *key, uint8_t *ciphertext) {
callbacks->AES256_ECB_enc(plaintext, plaintext_len, key, ciphertext);
if (plaintext != NULL && key != NULL && ciphertext != NULL) {
callbacks->AES256_ECB_enc(plaintext, plaintext_len, key, ciphertext);
}
}

void OQS_AES256_ECB_enc_sch(const uint8_t *plaintext, const size_t plaintext_len, const void *schedule, uint8_t *ciphertext) {
callbacks->AES256_ECB_enc_sch(plaintext, plaintext_len, schedule, ciphertext);
if (plaintext != NULL && schedule != NULL && ciphertext != NULL) {
callbacks->AES256_ECB_enc_sch(plaintext, plaintext_len, schedule, ciphertext);
}
}

void OQS_AES256_CTR_inc_stream_iv(const uint8_t *iv, const size_t iv_len, const void *schedule, uint8_t *out, size_t out_len) {
callbacks->AES256_CTR_inc_stream_iv(iv, iv_len, schedule, out, out_len);
if (iv != NULL && schedule != NULL && out != NULL) {
callbacks->AES256_CTR_inc_stream_iv(iv, iv_len, schedule, out, out_len);
}
}

void OQS_AES256_CTR_inc_stream_blks(void *schedule, uint8_t *out, size_t out_blks) {
callbacks->AES256_CTR_inc_stream_blks(schedule, out, out_blks);
if (schedule != NULL && out != NULL) {
callbacks->AES256_CTR_inc_stream_blks(schedule, out, out_blks);
}
}
19 changes: 17 additions & 2 deletions src/common/aes/aes128_armv8.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,17 @@ typedef struct {
} aes128ctx;

void oqs_aes128_load_iv_armv8(const uint8_t *iv, size_t iv_len, void *_schedule) {
if (_schedule == NULL) {
return;
}
aes128ctx *ctx = _schedule;
if (iv_len == 12) {
memcpy(ctx->iv, iv, 12);
memset(&ctx->iv[12], 0, 4);
} else if (iv_len == 16) {
memcpy(ctx->iv, iv, 16);
} else {
exit(EXIT_FAILURE);
return; /* TODO: better error handling */
}
}

Expand Down Expand Up @@ -63,12 +66,18 @@ static inline void aes128_armv8_encrypt(const unsigned char *rkeys, const unsign
}

void oqs_aes128_enc_sch_block_armv8(const uint8_t *plaintext, const void *_schedule, uint8_t *ciphertext) {
if (_schedule == NULL || plaintext == NULL || ciphertext == NULL) {
return;
}
const unsigned char *schedule = (const unsigned char *) _schedule;
aes128_armv8_encrypt(schedule, plaintext, ciphertext);
}

void oqs_aes128_ecb_enc_sch_armv8(const uint8_t *plaintext, const size_t plaintext_len, const void *schedule, uint8_t *ciphertext) {
assert(plaintext_len % 16 == 0);
if (schedule == NULL || plaintext == NULL || ciphertext == NULL) {
return;
}
const aes128ctx *ctx = (const aes128ctx *) schedule;

for (size_t block = 0; block < plaintext_len / 16; block++) {
Expand All @@ -91,6 +100,9 @@ static uint32_t UINT32_TO_BE(const uint32_t x) {


void oqs_aes128_ctr_enc_sch_upd_blks_armv8(void *schedule, uint8_t *out, size_t out_blks) {
if (schedule == NULL || out == NULL) {
return;
}
aes128ctx *ctx = (aes128ctx *) schedule;
uint8_t *block = ctx->iv;
uint32_t ctr;
Expand All @@ -108,6 +120,9 @@ void oqs_aes128_ctr_enc_sch_upd_blks_armv8(void *schedule, uint8_t *out, size_t
}

void oqs_aes128_ctr_enc_sch_armv8(const uint8_t *iv, const size_t iv_len, const void *schedule, uint8_t *out, size_t out_len) {
if (iv == NULL || schedule == NULL || out == NULL) {
return;
}
uint8_t block[16];
uint32_t ctr;
uint32_t ctr_be;
Expand All @@ -118,7 +133,7 @@ void oqs_aes128_ctr_enc_sch_armv8(const uint8_t *iv, const size_t iv_len, const
memcpy(&ctr_be, &iv[12], 4);
ctr = BE_TO_UINT32(ctr_be);
} else {
exit(EXIT_FAILURE);
return; /* TODO: better error handling */
}
while (out_len >= 16) {
ctr_be = UINT32_TO_BE(ctr);
Expand Down
32 changes: 27 additions & 5 deletions src/common/aes/aes128_ni.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,14 +49,21 @@ static inline void aes128ni_setkey_encrypt(const unsigned char *key, __m128i rke
}

void oqs_aes128_load_schedule_ni(const uint8_t *key, void **_schedule) {
*_schedule = malloc(sizeof(aes128ctx));
OQS_EXIT_IF_NULLPTR(*_schedule, "AES");
assert(*_schedule != NULL);
if (_schedule == NULL) {
return;
}
*_schedule = OQS_MEM_malloc(sizeof(aes128ctx));
if (*_schedule == NULL) {
return;
}
__m128i *schedule = ((aes128ctx *) *_schedule)->sk_exp;
aes128ni_setkey_encrypt(key, schedule);
}

void oqs_aes128_load_iv_ni(const uint8_t *iv, size_t iv_len, void *_schedule) {
if (_schedule == NULL) {
return;
}
aes128ctx *ctx = _schedule;
__m128i idx = _mm_set_epi8(8, 9, 10, 11, 12, 13, 14, 15, 7, 6, 5, 4, 3, 2, 1, 0);
if (iv_len == 12) {
Expand All @@ -65,11 +72,14 @@ void oqs_aes128_load_iv_ni(const uint8_t *iv, size_t iv_len, void *_schedule) {
} else if (iv_len == 16) {
ctx->iv = _mm_shuffle_epi8(_mm_loadu_si128((const __m128i *)iv), idx);
} else {
exit(EXIT_FAILURE);
return; /* TODO: better error handling */
}
}

void oqs_aes128_load_iv_u64_ni(uint64_t iv, void *_schedule) {
if (_schedule == NULL) {
return;
}
aes128ctx *ctx = _schedule;
ctx->iv = _mm_loadl_epi64((__m128i *)&iv);
}
Expand Down Expand Up @@ -133,18 +143,27 @@ static inline void aes128ni_encrypt_x4(const __m128i rkeys[11], __m128i n0,
}

void oqs_aes128_enc_sch_block_ni(const uint8_t *plaintext, const void *_schedule, uint8_t *ciphertext) {
if (_schedule == NULL) {
return;
}
const __m128i *schedule = ((const aes128ctx *) _schedule)->sk_exp;
aes128ni_encrypt(schedule, _mm_loadu_si128((const __m128i *)plaintext), ciphertext);
}

void oqs_aes128_ecb_enc_sch_ni(const uint8_t *plaintext, const size_t plaintext_len, const void *schedule, uint8_t *ciphertext) {
if (schedule == NULL) {
return;
}
assert(plaintext_len % 16 == 0);
for (size_t block = 0; block < plaintext_len / 16; block++) {
oqs_aes128_enc_sch_block_ni(plaintext + (16 * block), schedule, ciphertext + (16 * block));
}
}

void oqs_aes128_ctr_enc_sch_upd_blks_ni(void *schedule, uint8_t *out, size_t out_blks) {
if (schedule == NULL) {
return;
}
aes128ctx *ctx = (aes128ctx *) schedule;
const __m128i mask = _mm_set_epi8(8, 9, 10, 11, 12, 13, 14, 15, 7, 6, 5, 4, 3, 2, 1, 0);

Expand All @@ -168,6 +187,9 @@ void oqs_aes128_ctr_enc_sch_upd_blks_ni(void *schedule, uint8_t *out, size_t out
}

void oqs_aes128_ctr_enc_sch_ni(const uint8_t *iv, const size_t iv_len, const void *schedule, uint8_t *out, size_t out_len) {
if (schedule == NULL) {
return;
}
__m128i block;
__m128i mask = _mm_set_epi8(8, 9, 10, 11, 12, 13, 14, 15, 7, 6, 5, 4, 3, 2, 1, 0);
if (iv_len == 12) {
Expand All @@ -176,7 +198,7 @@ void oqs_aes128_ctr_enc_sch_ni(const uint8_t *iv, const size_t iv_len, const voi
} else if (iv_len == 16) {
block = _mm_loadu_si128((const __m128i *)iv);
} else {
exit(EXIT_FAILURE);
return; /* TODO: better error handling */
}

while (out_len >= 64) {
Expand Down
Loading
Loading