Thanks to visit codestin.com
Credit goes to github.com

Skip to content

fuzz/provider.c: fix API call order in do_evp_cipher and do_evp_md#30331

Closed
OwenSanzas wants to merge 5 commits into
openssl:masterfrom
OwenSanzas:fix/provider-fuzzer-api-order
Closed

fuzz/provider.c: fix API call order in do_evp_cipher and do_evp_md#30331
OwenSanzas wants to merge 5 commits into
openssl:masterfrom
OwenSanzas:fix/provider-fuzzer-api-order

Conversation

@OwenSanzas
Copy link
Copy Markdown
Contributor

Summary

do_evp_cipher() and do_evp_md() call parameter-setting functions (EVP_CIPHER_CTX_set_params / EVP_MD_CTX_set_params) before initializing the algorithm context (EVP_EncryptInit_ex2 / EVP_DigestInit_ex2). Since the context has no algorithm associated at that point, set_params always returns 0 and the function early-returns, making the cipher and digest paths dead code (~20% of all fuzzer inputs).

This PR swaps the call order so the context is initialized before parameters are set.

Additionally, key/iv buffers are now heap-allocated and sized to the cipher's actual key and IV length, since some ciphers (e.g. DES-EDE3-OFB) require buffers larger than the previous fixed 16/8-byte stack arrays.

Verification

PoC (single input, cipher path operation % 10 == 1):

Version Execution time Result
Original 0 ms Dead code — set_params fails, function returns immediately
Fixed 19 ms Cipher actually executes

Same for digest path (operation % 10 == 0): 0 ms → 23 ms.

Fuzzing (60s, ASan, fork mode):

Version Crashes Note
Original 0 Cipher path never reached
Fixed 44 Cipher path now active, finds real stack-use-after-return in DES OFB

KDF path (unmodified control): identical behavior in both versions (18–19 ms).

Fixes #30281

Both do_evp_cipher() and do_evp_md() call the parameter-setting
function (EVP_CIPHER_CTX_set_params / EVP_MD_CTX_set_params) before
initializing the algorithm context (EVP_EncryptInit_ex2 /
EVP_DigestInit_ex2). Since the context has no algorithm associated
at that point, set_params always returns 0 and the function
early-returns, making the cipher and digest paths dead code (~20%
of all fuzzer inputs).

Fix by swapping the call order so the context is initialized first.

Additionally, heap-allocate key/iv buffers sized to the cipher's
actual key and IV length, since some ciphers (e.g. DES-EDE3-OFB)
require buffers larger than the previous fixed 16/8-byte arrays.

Fixes openssl#30281
@nhorman
Copy link
Copy Markdown
Contributor

nhorman commented Mar 9, 2026

given that this is a non-trivial change, we will need you to submit a CLA prior to reviewing/accepting this change. If you could please fill out the form here:
https://openssl-library.org/policies/cla/

If you could submit the online form on that page, we will get you into our CLA database, and start taking a look at this.

Thank you!

paulidale
paulidale previously approved these changes Mar 10, 2026
@openssl-machine openssl-machine added the approval: review pending This pull request needs review by a committer label Mar 10, 2026
npajkovsky
npajkovsky previously approved these changes Mar 10, 2026
Comment thread fuzz/provider.c Outdated
if (!EVP_CIPHER_CTX_set_params(ctx, param)) {
EVP_CIPHER_CTX_free(ctx);
OPENSSL_free(key);
OPENSSL_free(iv);
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nitpick: iv, key, and ctx can be set to NULL in the declaration, and then at the end of the function, you can have

err:
    EVP_CIPHER_CTX_free(ctx);
    OPENSSL_free(key);
    OPENSSL_free(iv);
    return 0;
}

that will make the err path slightly nicer.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the suggestion! I've updated the code — key, iv, and ctx are now initialized to NULL and all error paths go through a single err: label. Please take a look when you get a chance.

@openssl-machine openssl-machine added approval: done This pull request has the required number of approvals and removed approval: review pending This pull request needs review by a committer labels Mar 10, 2026
@npajkovsky npajkovsky closed this Mar 10, 2026
@npajkovsky npajkovsky reopened this Mar 10, 2026
Initialize key, iv, and ctx to NULL at declaration and consolidate
all cleanup into a single err label, as suggested by @npajkovsky.
@OwenSanzas OwenSanzas dismissed stale reviews from npajkovsky and paulidale via d5d2057 March 10, 2026 07:57
@openssl-machine openssl-machine added approval: review pending This pull request needs review by a committer and removed approval: done This pull request has the required number of approvals labels Mar 10, 2026
npajkovsky
npajkovsky previously approved these changes Mar 10, 2026
Comment thread fuzz/provider.c Outdated
iv = OPENSSL_zalloc(iv_len);
if (key == NULL || iv == NULL)
goto err;
for (i = 0; i < key_len && i < 16; i++)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why the && i < 16?

Drop the `&& i < 16` and `&& i < 8` guards that were carried over from
the original fixed-size arrays. The loops now fill the entire
heap-allocated buffer, with values wrapping naturally via unsigned char.
@openssl-machine openssl-machine removed the hold: cla required The contributor needs to submit a license agreement label Mar 10, 2026
kroeckx
kroeckx previously approved these changes Mar 10, 2026
kroeckx
kroeckx previously approved these changes Mar 10, 2026
npajkovsky
npajkovsky previously approved these changes Mar 10, 2026
@openssl-machine openssl-machine added approval: done This pull request has the required number of approvals and removed approval: review pending This pull request needs review by a committer labels Mar 10, 2026
@t8m t8m added the branch: master Applies to master branch label Mar 10, 2026
@t8m t8m added triaged: feature The issue/pr requests/adds a feature tests: exempted The PR is exempt from requirements for testing labels Mar 10, 2026
@t8m
Copy link
Copy Markdown
Member

t8m commented Mar 10, 2026

The check style CI failure is relevant.

@nhorman
Copy link
Copy Markdown
Contributor

nhorman commented Mar 10, 2026

@OwenSanzas as @t8m notes, this still needs to be fixed up:
https://github.com/openssl/openssl/actions/runs/22896362493/job/66439333050?pr=30331
That job provides a patch to apply to your PR that will fix the issue

@OwenSanzas OwenSanzas dismissed stale reviews from npajkovsky and kroeckx via 32a30ba March 10, 2026 16:11
@openssl-machine openssl-machine added approval: review pending This pull request needs review by a committer and removed approval: done This pull request has the required number of approvals labels Mar 10, 2026
@OwenSanzas
Copy link
Copy Markdown
Contributor Author

Done, thanks for pointing that out.

@openssl-machine openssl-machine added approval: done This pull request has the required number of approvals approval: ready to merge The 24 hour grace period has passed, ready to merge and removed approval: review pending This pull request needs review by a committer approval: done This pull request has the required number of approvals labels Mar 10, 2026
@openssl-machine
Copy link
Copy Markdown
Collaborator

This pull request is ready to merge

@nhorman
Copy link
Copy Markdown
Contributor

nhorman commented Mar 11, 2026

merged to master, thank you!

@nhorman nhorman closed this Mar 11, 2026
openssl-machine pushed a commit that referenced this pull request Mar 11, 2026
Both do_evp_cipher() and do_evp_md() call the parameter-setting
function (EVP_CIPHER_CTX_set_params / EVP_MD_CTX_set_params) before
initializing the algorithm context (EVP_EncryptInit_ex2 /
EVP_DigestInit_ex2). Since the context has no algorithm associated
at that point, set_params always returns 0 and the function
early-returns, making the cipher and digest paths dead code (~20%
of all fuzzer inputs).

Fix by swapping the call order so the context is initialized first.

Additionally, heap-allocate key/iv buffers sized to the cipher's
actual key and IV length, since some ciphers (e.g. DES-EDE3-OFB)
require buffers larger than the previous fixed 16/8-byte arrays.

Fixes #30281

Reviewed-by: Neil Horman <[email protected]>
Reviewed-by: Kurt Roeckx <[email protected]>
MergeDate: Wed Mar 11 20:58:44 2026
(Merged from #30331)
openssl-machine pushed a commit that referenced this pull request Mar 11, 2026
Initialize key, iv, and ctx to NULL at declaration and consolidate
all cleanup into a single err label, as suggested by @npajkovsky.

Reviewed-by: Neil Horman <[email protected]>
Reviewed-by: Kurt Roeckx <[email protected]>
MergeDate: Wed Mar 11 20:58:47 2026
(Merged from #30331)
openssl-machine pushed a commit that referenced this pull request Mar 11, 2026
Drop the `&& i < 16` and `&& i < 8` guards that were carried over from
the original fixed-size arrays. The loops now fill the entire
heap-allocated buffer, with values wrapping naturally via unsigned char.

Reviewed-by: Neil Horman <[email protected]>
Reviewed-by: Kurt Roeckx <[email protected]>
MergeDate: Wed Mar 11 20:58:49 2026
(Merged from #30331)
openssl-machine pushed a commit that referenced this pull request Mar 11, 2026
Reviewed-by: Neil Horman <[email protected]>
Reviewed-by: Kurt Roeckx <[email protected]>
MergeDate: Wed Mar 11 20:58:51 2026
(Merged from #30331)
openssl-machine pushed a commit that referenced this pull request Mar 11, 2026
Reviewed-by: Neil Horman <[email protected]>
Reviewed-by: Kurt Roeckx <[email protected]>
MergeDate: Wed Mar 11 20:58:54 2026
(Merged from #30331)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

approval: ready to merge The 24 hour grace period has passed, ready to merge branch: master Applies to master branch tests: exempted The PR is exempt from requirements for testing triaged: feature The issue/pr requests/adds a feature

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fuzz/provider.c: incorrect API call sequence makes cipher and digest paths dead code

7 participants