Compare commits

..

69 commits

Author SHA1 Message Date
Richard Levitte
95b4936aa1 OSSL_FN: Add mod_mul and mod_sqr stanza tests
Some checks failed
Run-checker CI / run-checker (no-threads) (push) Has been cancelled
Run-checker CI / run-checker (no-tls) (push) Has been cancelled
Run-checker CI / run-checker (no-tls1_2) (push) Has been cancelled
Run-checker CI / run-checker (no-tls1_3) (push) Has been cancelled
Run-checker merge / run-checker (enable-asan enable-ubsan no-shared no-asm -DOPENSSL_SMALL_FOOTPRINT -fno-sanitize=function) (push) Has been cancelled
Run-checker merge / run-checker (enable-pie) (push) Has been cancelled
Run-checker merge / run-checker (enable-ubsan no-asm -DOPENSSL_SMALL_FOOTPRINT -fno-sanitize=function) (push) Has been cancelled
Run-checker merge / run-checker (enable-weak-ssl-ciphers) (push) Has been cancelled
Run-checker merge / run-checker (enable-zlib) (push) Has been cancelled
Run-checker merge / run-checker (no-dso) (push) Has been cancelled
Run-checker merge / run-checker (no-ec2m enable-fips) (push) Has been cancelled
Run-checker merge / run-checker (no-err) (push) Has been cancelled
Run-checker merge / run-checker (no-filenames) (push) Has been cancelled
Run-checker merge / run-checker (no-integrity-only-ciphers) (push) Has been cancelled
Run-checker merge / run-checker (no-module) (push) Has been cancelled
Run-checker merge / run-checker (no-ocsp) (push) Has been cancelled
Run-checker merge / run-checker (no-pinshared) (push) Has been cancelled
Run-checker merge / run-checker (no-shared) (push) Has been cancelled
Run-checker merge / run-checker (no-srp) (push) Has been cancelled
Run-checker merge / run-checker (no-srtp) (push) Has been cancelled
Run-checker merge / run-checker (no-ts) (push) Has been cancelled
Run-checker merge / run-checker (no-ui) (push) Has been cancelled
Run-checker merge / jitter (push) Has been cancelled
Run-checker merge / threads_sanitizer_atomic_fallback (push) Has been cancelled
Windows GitHub CI / plain (push) Has been cancelled
Windows GitHub CI / minimal (push) Has been cancelled
Windows GitHub CI / cygwin (windows-2022, map[arch:win64 config:-DCMAKE_C_COMPILER=gcc --strict-warnings enable-demos no-fips]) (push) Has been cancelled
Windows GitHub CI / mingw64 (map[arch:mingw config:-Wno-array-bounds -Wno-stringop-overflow target:i686]) (push) Has been cancelled
Windows GitHub CI / mingw64 (map[arch:mingw64 config:enable-demos -Wno-array-bounds target:x86_64]) (push) Has been cancelled
Run-checker CI / run-checker (no-ecx) (push) Failing after 5s
Add file_modmul() and file_modsqr() to test/fntest.c, using the
existing bntest.c counterparts as a template.  The ModMul and ModSqr
stanzas in bnmod.txt now exercise OSSL_FN_mod_mul() and
OSSL_FN_mod_sqr() through the stanza-driven test harness, providing a
real call site for the new modular operations.

Because OSSL_FN is unsigned, the operands are passed as absolute values
(via bn_get_ossl_fn()).  For mod_mul, if the operands have different
signs, the non-negative modular residue is recovered with BN_sub(ret,
m, ret) after release, keeping the sign logic at the BIGNUM boundary.
No sign fixup is needed for mod_sqr since squaring is always
non-negative.

Include bnmod.txt in 11-test_fn.t so the mod stanzas are run as part
of the regular test suite.

Related-to: doc/designs/fixed-size-large-numbers.md
Issue: https://github.com/openssl/project/issues/1932
Assisted-by: Pi:z-ai/glm-5.2
Signed-off-by: Richard Levitte <levitte@openssl.foundation>

Reviewed-by: Jakub Zelenka <jakub.zelenka@openssl.foundation>
Reviewed-by: Igor Ustinov <igus@openssl.foundation>
MergeDate: Thu Jul 23 15:02:40 2026
(Merged from https://github.com/openssl/openssl/pull/31479)
2026-07-24 12:07:38 +02:00
Richard Levitte
7a88869224 OSSL_FN: Add modular context sizing
The modular OSSL_FN operations are layered on top of each other, but
the sizing of the required OSSL_FN_CTX arena was not available as
operation-specific helpers, mirroring OSSL_FN_div_ctx_size(),
OSSL_FN_mul_ctx_size(), and OSSL_FN_sqr_ctx_size().

Add ctx-size helpers for the modular operations and compose them from
lower-level helpers.  Each helper returns arena payload bytes, accounts
for its own live temporaries, and adds the maximum nested requirement
while those temporaries are live.

Assisted-by: Pi:openai/gpt-5.5
Assisted-by: Pi:z-ai/glm-5.2
Signed-off-by: Richard Levitte <levitte@openssl.foundation>

Reviewed-by: Jakub Zelenka <jakub.zelenka@openssl.foundation>
Reviewed-by: Igor Ustinov <igus@openssl.foundation>
MergeDate: Thu Jul 23 15:02:39 2026
(Merged from https://github.com/openssl/openssl/pull/31479)
2026-07-24 12:07:38 +02:00
Richard Levitte
74084eb28e Add unit tests for OSSL_FN modular arithmetic functions
Assisted-by: Pi:moonshotai/kimi-k2.6
Assisted-by: Pi:openai/gpt-5.5
Signed-off-by: Richard Levitte <levitte@openssl.foundation>

Reviewed-by: Jakub Zelenka <jakub.zelenka@openssl.foundation>
Reviewed-by: Igor Ustinov <igus@openssl.foundation>
MergeDate: Thu Jul 23 15:02:37 2026
(Merged from https://github.com/openssl/openssl/pull/31479)
2026-07-24 12:07:38 +02:00
Richard Levitte
10a5bb87dc OSSL_FN: Add the modular arithmetic functions
- OSSL_FN_mod_add
- OSSL_FN_mod_add_quick
- OSSL_FN_mod_sub
- OSSL_FN_mod_sub_quick
- OSSL_FN_mod_mul
- OSSL_FN_mod_sqr
- OSSL_FN_mod_lshift
- OSSL_FN_mod_lshift_quick
- OSSL_FN_mod_lshift1
- OSSL_FN_mod_lshift1_quick

Related-to: doc/designs/fixed-size-large-numbers.md
Issue: https://github.com/openssl/project/issues/1932
Assisted-by: Pi:openai/gpt-5.5
Signed-off-by: Richard Levitte <levitte@openssl.foundation>

Reviewed-by: Jakub Zelenka <jakub.zelenka@openssl.foundation>
Reviewed-by: Igor Ustinov <igus@openssl.foundation>
MergeDate: Thu Jul 23 15:02:35 2026
(Merged from https://github.com/openssl/openssl/pull/31479)
2026-07-24 12:07:38 +02:00
Richard Levitte
18a19d81b9 OSSL_FN: implement internal 'ossl_fn_add_words' and 'ossl_fn_add_words'
These functions fulfill the same purpose as 'bn_add_words' and
'bn_sub_words', but adapted to OSSL_FN_ULONG arrays with varying
sizes.  They are useful for partial calculations where carry and
borrow are of interest, but also fulfill a purpose when that's not
interesting.

Assisted-by: Pi:openai/gpt-5.5
Signed-off-by: Richard Levitte <levitte@openssl.foundation>

Reviewed-by: Jakub Zelenka <jakub.zelenka@openssl.foundation>
Reviewed-by: Igor Ustinov <igus@openssl.foundation>
MergeDate: Thu Jul 23 15:02:33 2026
(Merged from https://github.com/openssl/openssl/pull/31479)
2026-07-24 12:07:38 +02:00
Billy Brumley
ab42643c66 [test] bntest: add ModInv file tests
Add file_modinv() to bntest.c, driven by a new bnmodinv.txt corpus and
wired into 10-test_bn.t.
- Positive tests assert equalBN and a mult sanity check
- Negative tests assert NULL return plus the BN_R_NO_INVERSE error
Corpus covers:
- in-range A
- out-of-range A
- positive and negative A for both of the above
- degenerate moduli M = 0 and M = 1
- RFC 4754 sourced KATs
- RFC 7091 sourced KATs

Assisted-by: Claude:claude-opus-4-8

Reviewed-by: Dmitry Belyavskiy <beldmit@gmail.com>
Reviewed-by: Tim Hudson <tjh@openssl.org>
Reviewed-by: Richard Levitte <levitte@openssl.org>
MergeDate: Thu Jul 23 14:20:08 2026
(Merged from https://github.com/openssl/openssl/pull/31985)
2026-07-24 12:07:38 +02:00
Richard Levitte
82b214d9bc OSSL_FN: Make RAND top selector count-based
Renumber OSSL_FN_RAND_TOP_ANY / _ONE / _TWO from -1 / 0 / 1 to
0 / 1 / 2, so each value is the number of high bits the result is
forced to set.  This matches the already-count-based
OSSL_FN_RAND_BOTTOM_* (0 = unconstrained, 1 = force the low bit),
making the whole selector family read the same way.

This is a deliberate departure from the BN counterpart: BN_RAND_TOP_*
stays -1 / 0 / 1, but OSSL_FN_RAND_TOP_* has no legacy tier and no
need for a sentinel, so the values are the counts themselves.
Callers that use the symbolic macros are unaffected; only raw-literal
callers would notice, and there are none in tree.

Assisted-by: Pi:z-ai/glm-5.2
Signed-off-by: Richard Levitte <levitte@openssl.foundation>

Reviewed-by: Igor Ustinov <igus@openssl.foundation>
Reviewed-by: Tomas Mraz <tomas@openssl.foundation>
MergeDate: Thu Jul 23 14:17:18 2026
(Merged from https://github.com/openssl/openssl/pull/31959)
2026-07-24 12:07:38 +02:00
Richard Levitte
1588f1f3eb OSSL_FN: Add random-number functions rand / priv_rand / range
Add OSSL_FN_rand(), OSSL_FN_priv_rand(), OSSL_FN_rand_range(), and
OSSL_FN_priv_rand_range(), the OSSL_FN counterparts of the BN_rand_ex() /
BN_priv_rand_ex() / BN_rand_range_ex() / BN_priv_rand_range_ex() family
from crypto/bn/bn_rand.c -- the first OSSL_FN random-number helpers.

The BN counterparts take a BN_CTX only to recover the library context
(via ossl_bn_get_libctx()); the OSSL_FN peers take an OSSL_LIB_CTX
directly, and per the OSSL_FN naming convention the BN _ex / _ex{n}
suffixes are dropped.

ossl_fn_rand() departs from the BN counterpart's byte-buffer mechanics:
bnrand() draws into a heap big-endian buffer and shapes via BN_bin2bn(),
whereas OSSL_FN limbs are fixed-size, so random bytes are drawn straight
into rnd->d and the top/bottom/mask shaping is done as limb value
operations (endian-neutral).  A destination too small for |bits| is an
error (OSSL_FN_R_RESULT_ARG_TOO_SMALL), not an implicit expansion.

The range variants port bnrand_range() faithfully; the range->neg
rejection is dropped (OSSL_FN is unsigned).  The leak profile matches the
BN counterpart: control flow branches on bits/top/bottom (caller-chosen,
public) and the byte-draw return value, never on the random bytes
themselves; the range loop count leaks the magnitude of |range| and the
rejection probability.  The TESTING mangle variant (BN_bntest_rand) is
deferred; a TODO(FIXNUM) marks the spot.

New error reasons: OSSL_FN_R_BITS_TOO_SMALL, OSSL_FN_R_INVALID_RANGE,
OSSL_FN_R_TOO_MANY_ITERATIONS.

Tests are property-based (random values cannot be value-compared) and
verify the bit-width, top/bottom constraints, zero-padding, and
0 <= r < range, on both 64-bit and 32-bit limb widths.

Assisted-by: Pi:z-ai/glm-5.2
Signed-off-by: Richard Levitte <levitte@openssl.foundation>

Reviewed-by: Igor Ustinov <igus@openssl.foundation>
Reviewed-by: Tomas Mraz <tomas@openssl.foundation>
MergeDate: Thu Jul 23 14:17:16 2026
(Merged from https://github.com/openssl/openssl/pull/31959)
2026-07-24 12:07:38 +02:00
Richard Levitte
d0e86cb69e OSSL_FN: Add assignment helpers set_word, one, zero
The OSSL_FN counterparts of the small BN assignment helpers that the
modular-square-root operation (and other upcoming operations) lean on:
OSSL_FN_set_word(), OSSL_FN_one(), and OSSL_FN_zero() mirror
BN_set_word(), BN_one(), and BN_zero().

The fixed-size semantics diverge where BN_set_word() grows the BIGNUM
(bn_wexpand(a, 1)) to guarantee room: OSSL_FN cannot grow, so a
zero-width destination fails with OSSL_FN_R_RESULT_ARG_TOO_SMALL
instead.

OSSL_FN_set_word() is constant-time with respect to w's value, unlike
BN_set_word() (which sets a->top = (w ? 1 : 0)); OSSL_FN has no top, so
the full dsize array always holds the value and the only branch is on
the public width.

OSSL_FN_zero() is a plain value assignment, not a secure wipe;
OSSL_FN_clear() (OPENSSL_cleanse()) is the secure-wipe counterpart,
mirroring the BN_zero() / BN_clear() split.

Tests cross-check set_word against the internal ossl_fn_set_words() and
cover the dsize == 0 error path.  Verified on both 64-bit (linux-x86_64)
and 32-bit (linux-x86) limb widths.

Assisted-by: Pi:z-ai/glm-5.2
Signed-off-by: Richard Levitte <levitte@openssl.foundation>

Reviewed-by: Igor Ustinov <igus@openssl.foundation>
Reviewed-by: Tomas Mraz <tomas@openssl.foundation>
MergeDate: Thu Jul 23 14:17:14 2026
(Merged from https://github.com/openssl/openssl/pull/31959)
2026-07-24 12:07:38 +02:00
Richard Levitte
9cc605f48e OSSL_FN: Implement OSSL_FN_add_word / OSSL_FN_sub_word
The declarations of OSSL_FN_add_word() / OSSL_FN_sub_word() have been in
include/crypto/fn.h since the initial 'add'/'sub' commit, but no
implementation ever landed -- the symbols were simply absent, with no
caller noticing.  This adds them next to OSSL_FN_add() / OSSL_FN_sub().

While here, correct the signature: the word argument was declared
'const OSSL_FN_ULONG *w' (a pointer), which matches no BN counterpart;
it is now 'OSSL_FN_ULONG w' by value, mirroring BN_add_word() /
BN_sub_word().  Safe because there was no implementation and no caller.

These are the OSSL_FN counterparts of BN_add_word() / BN_sub_word().
The fixed-size unsigned semantics diverge where the BN counterpart grows
the BIGNUM (bn_wexpand) or records a sign (a->neg, storing w - a): OSSL_FN
instead truncates a carry/borrow past the last limb, and a borrow off the
top yields the 2's-complement wrap-around.

Both are non-constant-time, matching BN_add_word()/BN_sub_word(): the
carry/borrow loop stops early once exhausted, so the number of limbs
touched depends on the operand's value.

Tests cross-check every case against OSSL_FN_add() / OSSL_FN_sub() with
a single-limb operand.  Verified on both 64-bit (linux-x86_64) and 32-bit
(linux-x86) limb widths.

Assisted-by: Pi:z-ai/glm-5.2
Signed-off-by: Richard Levitte <levitte@openssl.foundation>

Reviewed-by: Igor Ustinov <igus@openssl.foundation>
Reviewed-by: Tomas Mraz <tomas@openssl.foundation>
MergeDate: Thu Jul 23 14:17:12 2026
(Merged from https://github.com/openssl/openssl/pull/31959)
2026-07-24 12:07:38 +02:00
Richard Levitte
97618c446f OSSL_FN: Add introspection helpers is_word, is_zero, is_one, is_odd
The OSSL_FN counterparts of the small BN predicates that the
modular-square-root operation (and other upcoming operations) lean on:

  - OSSL_FN_is_word() mirrors BN_is_word() and BN_abs_is_word(), which
    collapse into one here since OSSL_FN is unsigned (no sign to ignore);
    a separate OSSL_FN_abs_is_word is therefore not added.
  - OSSL_FN_is_zero() and OSSL_FN_is_one() are kept as named predicates
    for readability at call sites rather than written inline.
  - OSSL_FN_is_odd() mirrors BN_is_odd().

The leak profile matches the BN counterparts: control flow branches only
on the operand's public width (dsize), not on limb values; limb values
are combined with constant-time selects, as in OSSL_FN_cmp() and the
fixed-top BN helpers.

Assisted-by: Pi:z-ai/glm-5.2
Signed-off-by: Richard Levitte <levitte@openssl.foundation>

Reviewed-by: Igor Ustinov <igus@openssl.foundation>
Reviewed-by: Tomas Mraz <tomas@openssl.foundation>
MergeDate: Thu Jul 23 14:17:10 2026
(Merged from https://github.com/openssl/openssl/pull/31959)
2026-07-24 12:07:38 +02:00
Richard Levitte
60551b673b OSSL_FN: Add OSSL_FN_is_bit_set()
Add OSSL_FN_is_bit_set(), the OSSL_FN counterpart of BN_is_bit_set().
The leak profile matches the BN counterpart: control flow branches only
on the operand's public width (dsize), not on limb values.

Assisted-by: Pi:z-ai/glm-5.2
Signed-off-by: Richard Levitte <levitte@openssl.foundation>

Reviewed-by: Igor Ustinov <igus@openssl.foundation>
Reviewed-by: Tomas Mraz <tomas@openssl.foundation>
MergeDate: Thu Jul 23 14:17:09 2026
(Merged from https://github.com/openssl/openssl/pull/31959)
2026-07-24 12:07:38 +02:00
Richard Levitte
ed9ea9710d OSSL_FN: Add lshift1 round-trip checks to fntest
file_lshift1() now mirrors bntest.c's file_lshift1() where OSSL_FN
primitives allow: it cross-checks LShift1 against A + A and A * 2,
then round-trips LShift1 >> 1 back to A with OSSL_FN_rshift1.

The LShift1 / 2, LShift1 % 2, and set-LSB rshift1-flooring checks
from bntest.c are deferred to a future commit: they need
OSSL_FN_div() and OSSL_FN_set_bit(), neither of which exists yet.

Issue: https://github.com/openssl/project/issues/2015
Assisted-by: Pi:z-ai/glm-5.2
Signed-off-by: Richard Levitte <levitte@openssl.foundation>

Reviewed-by: Igor Ustinov <igus@openssl.foundation>
Reviewed-by: Tomas Mraz <tomas@openssl.foundation>
MergeDate: Thu Jul 23 14:15:42 2026
(Merged from https://github.com/openssl/openssl/pull/31830)
2026-07-24 12:07:38 +02:00
Richard Levitte
10d074a041 OSSL_FN: Add OSSL_FN right-shift tests to fntest
The new file_rshift() handler is driven by the RShift stanzas already
in bnshift.txt, so no dedicated data file is added.  The N == 1
OSSL_FN_rshift1 cross-check and the file_lshift() round-trip mirror
bntest.c.

Issue: https://github.com/openssl/project/issues/2015
Assisted-by: Pi:z-ai/glm-5.2
Signed-off-by: Richard Levitte <levitte@openssl.foundation>

Reviewed-by: Igor Ustinov <igus@openssl.foundation>
Reviewed-by: Tomas Mraz <tomas@openssl.foundation>
MergeDate: Thu Jul 23 14:15:41 2026
(Merged from https://github.com/openssl/openssl/pull/31830)
2026-07-24 12:07:38 +02:00
Richard Levitte
c6866fa3d3 OSSL_FN: Add OSSL_FN right shifts
Add fixed-size right-shift operations for OSSL_FN values and cover them
with direct API tests.

The tests exercise bit and limb shifts, wider and narrower destinations,
aliasing, and invalid negative shift counts.

Related-to: doc/designs/fixed-size-large-numbers.md
Issue: https://github.com/openssl/project/issues/2015
Assisted-by: Pi:openai/gpt-5.5
Assisted-by: Pi:z-ai/glm-5.2
Signed-off-by: Richard Levitte <levitte@openssl.foundation>

Reviewed-by: Igor Ustinov <igus@openssl.foundation>
Reviewed-by: Tomas Mraz <tomas@openssl.foundation>
MergeDate: Thu Jul 23 14:15:39 2026
(Merged from https://github.com/openssl/openssl/pull/31830)
2026-07-24 12:07:38 +02:00
Richard Levitte
7593990ddf OSSL_FN: Add div and mod stanza tests
Teach fntest to run the existing quotient/remainder stanzas through
OSSL_FN_div(), and additionally check the remainder against
OSSL_FN_mod().  fntest now runs all recognized stanzas from each
data file, so 11-test_fn.t passes the files directly without any
per-stanza filtering.  Also include crypto/fn.h before crypto/bn.h
in fntest so the OSSL_FN typedef is visible where bn.h uses it.

Related-to: doc/designs/fixed-size-large-numbers.md
Issue: https://github.com/openssl/project/issues/1852
Assisted-by: Pi:openai/gpt-5.5
Assisted-by: Pi:z-ai/glm-5.2
Signed-off-by: Richard Levitte <levitte@openssl.foundation>

Reviewed-by: Jakub Zelenka <jakub.zelenka@openssl.foundation>
Reviewed-by: Igor Ustinov <igus@openssl.foundation>
Reviewed-by: Tomas Mraz <tomas@openssl.foundation>
MergeDate: Thu Jul 23 14:14:03 2026
(Merged from https://github.com/openssl/openssl/pull/30822)
2026-07-24 12:07:38 +02:00
Richard Levitte
b5aa70d2c1 OSSL_FN: Add division context sizing
Add OSSL_FN_div_ctx_size() and make OSSL_FN_mod_ctx_size() a thin
inline wrapper around it.  The sizing remains conservative: it uses
allocated operand widths and does not duplicate the runtime scan that
trims the denominator to its highest non-zero limb.  Document both
helpers with Doxygen comments matching the mul/sqr ctx_size helpers.

Related-to: doc/designs/fixed-size-large-numbers.md
Issue: https://github.com/openssl/project/issues/1852
Assisted-by: Pi:openai/gpt-5.5
Assisted-by: Pi:z-ai/glm-5.2
Signed-off-by: Richard Levitte <levitte@openssl.foundation>

Reviewed-by: Jakub Zelenka <jakub.zelenka@openssl.foundation>
Reviewed-by: Igor Ustinov <igus@openssl.foundation>
Reviewed-by: Tomas Mraz <tomas@openssl.foundation>
MergeDate: Thu Jul 23 14:14:00 2026
(Merged from https://github.com/openssl/openssl/pull/30822)
2026-07-24 12:07:38 +02:00
Richard Levitte
12929d3852 OSSL_FN: Add the 'div' and 'mod' functions
OSSL_FN_div() divides two numbers, and calculates the quotient and
the remainder.  The result OSSL_FNs may be of any size, and if they're
smaller than the results of dividing the operands, the results are
truncated to that size.

OSSL_FN_mod() is a very simple function that wraps around OSSL_FN_div()
and only returns the remainder.

Related-to: doc/designs/fixed-size-large-numbers.md
Issue: https://github.com/openssl/project/issues/1852
Assisted-by: Pi:openai/gpt-5.5
Assisted-by: Pi:z-ai/glm-5.2
Signed-off-by: Richard Levitte <levitte@openssl.foundation>

Reviewed-by: Jakub Zelenka <jakub.zelenka@openssl.foundation>
Reviewed-by: Igor Ustinov <igus@openssl.foundation>
Reviewed-by: Tomas Mraz <tomas@openssl.foundation>
MergeDate: Thu Jul 23 14:13:58 2026
(Merged from https://github.com/openssl/openssl/pull/30822)
2026-07-24 12:07:38 +02:00
Richard Levitte
496092d36f OSSL_FN: use ctx-size helpers in fntest
The mul and sqr tests in test/fntest.c sized their OSSL_FN_CTX arenas
by hand, passing fixed frame/number/limb counts to OSSL_FN_CTX_new().
Switch them to OSSL_FN_CTX_new_size() driven by OSSL_FN_mul_ctx_size()
/ OSSL_FN_sqr_ctx_size(), passing the actual result and operand
OSSL_FNs so the per-op helpers can account for aliasing and
destination width.

This gives the ctx-size helpers real callers in the tree and makes the
test sizing match what OSSL_FN_mul() / OSSL_FN_sqr() actually need
instead of the previous oversized estimates.

Assisted-by: Pi:z-ai/glm-5.2
Signed-off-by: Richard Levitte <levitte@openssl.foundation>
Assisted-by: Pi:openai/gpt-5.5

Reviewed-by: Igor Ustinov <igus@openssl.foundation>
Reviewed-by: Tomas Mraz <tomas@openssl.foundation>
MergeDate: Wed Jul 15 13:04:50 2026
(Merged from https://github.com/openssl/openssl/pull/31794)
2026-07-14 17:42:57 +02:00
Richard Levitte
9ff9bf1c0a OSSL_FN: Size contexts in bytes
OSSL_FN_CTX callers currently describe the arena in frames, numbers
and limbs.  That works for a single operation, but it makes higher
level sizing awkward because each caller has to keep redoing the same
conversion.

Add an overflow-checked OSSL_FN_CTX_size() helper that returns the
arena payload size, plus byte-sized constructors for normal and secure
contexts.  The existing frame/number/limb constructors become wrappers
around it so current callers keep working while newer code can compose
byte sizes directly.  The old internal ossl_fn_ctx_calculate_arena_size()
inline is replaced by the public, overflow-checked helper.

Add per-operation ctx-size helpers OSSL_FN_mul_ctx_size() and
OSSL_FN_sqr_ctx_size(), which fold in the aliasing and
destination-width considerations of OSSL_FN_mul() / OSSL_FN_sqr().

Assisted-by: Pi:openai/gpt-5.5
Assisted-by: Pi:z-ai/glm-5.2
Signed-off-by: Richard Levitte <levitte@openssl.foundation>

Reviewed-by: Igor Ustinov <igus@openssl.foundation>
Reviewed-by: Tomas Mraz <tomas@openssl.foundation>
MergeDate: Wed Jul 15 13:04:48 2026
(Merged from https://github.com/openssl/openssl/pull/31794)
2026-07-14 17:42:57 +02:00
Richard Levitte
3923fd51b1 OSSL_FN: unwrap BN_CTX's wrapping of OSSL_FN_CTX
The BN_CTX -> OSSL_FN_CTX acquisition machinery
(bn_ctx_acquire_ossl_fn_ctx / bn_ctx_release_ossl_fn_ctx and the
fn_ctx field on struct bignum_ctx) existed only to serve the BN_*
arithmetic wrappers that delegated to OSSL_FN.  Those wrappers were
removed in previous commits, leaving the machinery orphaned except
for the self-test that exercised it; OSSL_FN consumers obtain their
OSSL_FN_CTX directly via OSSL_FN_CTX_new() / OSSL_FN_CTX_secure_new().

Remove the wrapping machinery and its dedicated test
(test_bn_ctx_fn_ctx) by reverting:

  e3213b0c03 ("Add OSSL_FN_CTX integration with BN_CTX")

Assisted-by: Pi:z-ai/glm-5.2
Signed-off-by: Richard Levitte <levitte@openssl.foundation>

Reviewed-by: Dmitry Belyavskiy <beldmit@gmail.com>
Reviewed-by: Igor Ustinov <igus@openssl.foundation>
MergeDate: Tue Jul 14 11:06:24 2026
(Merged from https://github.com/openssl/openssl/pull/31895)
2026-07-14 16:13:07 +02:00
Richard Levitte
5c2f95c4b0 OSSL_FN: Add OSSL_FN stanza arithmetic test
Add fntest as a stanza-driven arithmetic test for the OSSL_FN
operations currently available in this branch.  The test reuses the
existing BN input files and reports known but unsupported stanza types
as skipped.

Wire the new test program into the build and add a test_fn recipe for
sum, multiplication, square, and left-shift coverage.

Assisted-by: Pi:openai/gpt-5.5
Assisted-by: Pi:z-ai/glm-5.2
Signed-off-by: Richard Levitte <levitte@openssl.foundation>
Resolves: https://github.com/openssl/project/issues/2021

Reviewed-by: Igor Ustinov <igus@openssl.foundation>
Reviewed-by: Tomas Mraz <tomas@openssl.foundation>
MergeDate: Sun Jul 12 08:37:03 2026
(Merged from https://github.com/openssl/openssl/pull/31881)
2026-07-14 16:13:07 +02:00
Richard Levitte
0df3c5e1de OSSL_FN: Add read-only BIGNUM OSSL_FN accessor
Add bn_get_ossl_fn(), a read-only counterpart to bn_acquire_ossl_fn().
Unlike the latter, it neither acquires nor resizes the BIGNUM: the
BIGNUM stays usable with BN_ functions, no bn_release() is needed, and
the returned OSSL_FN keeps the BIGNUM's current allocated width.  This
suits read-only operands at OSSL_FN call sites.

Assisted-by: Pi:openai/gpt-5.5
Signed-off-by: Richard Levitte <levitte@openssl.foundation>

Reviewed-by: Igor Ustinov <igus@openssl.foundation>
Reviewed-by: Tomas Mraz <tomas@openssl.foundation>
MergeDate: Sun Jul 12 08:37:02 2026
(Merged from https://github.com/openssl/openssl/pull/31881)
2026-07-14 16:13:07 +02:00
Richard Levitte
312250036e OSSL_FN: Expose BN OSSL_FN acquire helpers
Move the BIGNUM to OSSL_FN acquire/release helpers out of
bn_local.h and declare them in the internal BN header.  This makes
them available to call sites that need to operate temporarily on the
fixed-width representation.

Assisted-by: Pi:openai/gpt-5.5
Signed-off-by: Richard Levitte <levitte@openssl.foundation>

Reviewed-by: Igor Ustinov <igus@openssl.foundation>
Reviewed-by: Tomas Mraz <tomas@openssl.foundation>
MergeDate: Sun Jul 12 08:37:00 2026
(Merged from https://github.com/openssl/openssl/pull/31881)
2026-07-14 16:13:07 +02:00
Richard Levitte
9a90994e39 OSSL_FN: unwrap the BIGNUM shift and compare functions
Restore the top-aware implementations of BN_num_bits, BN_ucmp, BN_cmp,
BN_lshift1, and BN_lshift to their pre-wrap form, removing the OSSL_FN
call-site wrapping (the dual-path `if (a->data == NULL) { legacy } else
{ OSSL_FN_* }` branches, each marked TODO(FIXNUM): TO BE REMOVED)
introduced in:

  5072424737 ("OSSL_FN: Wrap BN shift and compare functions around OSSL_FN functions")

This also reverts the in-body tuning that landed on top of that wrapping:

  1a87fdb411 ("Check result of acquiring OSSL_FN")

The foundational BN_MAX_WORDS bound in bn_expand_internal (bn_lib.c) and
the bn_check_top dmax assert (bn_local.h), both from e3ae863a2d, are
preserved -- restoring bn_lib.c to 5072424737^ keeps them, since they
predate the shift/compare wrapper and were never modified by it.

The conversion helpers bn_acquire_ossl_fn()/bn_release() are left in
place; BN->OSSL_FN conversion moves to top-level crypto call sites
instead.

Issue: https://github.com/openssl/project/issues/2020
Assisted-by: Pi:z-ai/glm-5.2
Signed-off-by: Richard Levitte <levitte@openssl.foundation>

Reviewed-by: Igor Ustinov <igus@openssl.foundation>
Reviewed-by: Tomas Mraz <tomas@openssl.foundation>
MergeDate: Thu Jul  9 15:34:26 2026
(Merged from https://github.com/openssl/openssl/pull/31884)
2026-07-14 16:13:07 +02:00
Richard Levitte
ebc87a83dc OSSL_FN: unwrap the BIGNUM 'sqr' function
Restore the top-aware BN_sqr implementation to its pre-wrap form, removing
the OSSL_FN call-site wrapping introduced in:

  f52bf9d167 ("OSSL_FN: Wrap the BIGNUM 'sqr' function around the OSSL_FN 'sqr' function")

This also reverts the in-body tuning that landed on top of that wrapping:

  1763d6aff3 ("Acquire BN_sqr result before ctx sizing")
  a7b662c282 ("Use BN_CTX cached OSSL_FN_CTX in BN_mul() and BN_sqr()")
  cbc3f0b448 ("Check result of acquiring OSSL_FN or OSSL_FN_CTX")

(only the BN_sqr portions of a7b662c282 and cbc3f0b448 are affected).

The conversion helpers bn_acquire_ossl_fn()/bn_release() and the
foundational BN_MAX_WORDS hardening in bn_lib.c/bn_local.h are left in
place; BN->OSSL_FN conversion moves to top-level crypto call sites
instead.

Issue: https://github.com/openssl/project/issues/2020
Assisted-by: Pi:z-ai/glm-5.2
Signed-off-by: Richard Levitte <levitte@openssl.foundation>

Reviewed-by: Igor Ustinov <igus@openssl.foundation>
Reviewed-by: Tomas Mraz <tomas@openssl.foundation>
MergeDate: Thu Jul  9 15:34:24 2026
(Merged from https://github.com/openssl/openssl/pull/31884)
2026-07-14 16:13:07 +02:00
Richard Levitte
d8f17e7d37 OSSL_FN: unwrap the BIGNUM 'mul' function
Restore the top-aware BN_mul implementation to its pre-wrap form, removing
the OSSL_FN call-site wrapping introduced in:

  8f77f825fa ("OSSL_FN: Wrap BIGNUM the 'mul' function around the OSSL_FN 'mul' function")

This also reverts the in-body tuning that landed on top of that wrapping:

  06bc8339d9 ("Acquire BN_mul result before ctx sizing")
  a7b662c282 ("Use BN_CTX cached OSSL_FN_CTX in BN_mul() and BN_sqr()")
  cbc3f0b448 ("Check result of acquiring OSSL_FN or OSSL_FN_CTX")

(only the BN_mul portions of a7b662c282 and cbc3f0b448 are affected).

The conversion helpers bn_acquire_ossl_fn()/bn_release() and the
foundational BN_MAX_WORDS hardening in bn_lib.c/bn_local.h are left in
place; BN->OSSL_FN conversion moves to top-level crypto call sites
instead.

Issue: https://github.com/openssl/project/issues/2020
Assisted-by: Pi:z-ai/glm-5.2
Signed-off-by: Richard Levitte <levitte@openssl.foundation>

Reviewed-by: Igor Ustinov <igus@openssl.foundation>
Reviewed-by: Tomas Mraz <tomas@openssl.foundation>
MergeDate: Thu Jul  9 15:34:22 2026
(Merged from https://github.com/openssl/openssl/pull/31884)
2026-07-14 16:13:07 +02:00
Richard Levitte
3b2c8afdc1 OSSL_FN: unwrap the BIGNUM 'add' and 'sub' functions
Restore the top-aware BN_add/BN_sub/BN_uadd/BN_usub implementations to
their pre-wrap form, removing the OSSL_FN call-site wrapping introduced in:

  e3ae863a2d ("OSSL_FN: Wrap BIGNUM 'add' and 'sub' functions around OSSL_FN functions")

This also reverts the in-body tuning that landed on top of that wrapping:

  3eb0b45e63 ("Use top to size BN add/sub results")
  cbc3f0b448 ("Check result of acquiring OSSL_FN or OSSL_FN_CTX")

(only the BN_add/BN_sub portions of cbc3f0b448 are affected).

The conversion helpers bn_acquire_ossl_fn()/bn_release() and the
foundational BN_MAX_WORDS hardening in bn_lib.c/bn_local.h are left in
place; BN->OSSL_FN conversion moves to top-level crypto call sites
instead.

Issue: https://github.com/openssl/project/issues/2020
Assisted-by: Pi:z-ai/glm-5.2
Signed-off-by: Richard Levitte <levitte@openssl.foundation>

Reviewed-by: Igor Ustinov <igus@openssl.foundation>
Reviewed-by: Tomas Mraz <tomas@openssl.foundation>
MergeDate: Thu Jul  9 15:34:20 2026
(Merged from https://github.com/openssl/openssl/pull/31884)
2026-07-14 16:13:07 +02:00
Richard Levitte
910c2fcfc0 Decouple BIGNUM from OSSL_FN in the design doc
Reflect the decision (openssl/project#2018) to stop wrapping BN_
operator functions around OSSL_FN_ operator functions: BN functions
keep their current behaviour, and BIGNUM<->OSSL_FN conversion
happens at top-level crypto call sites.

Also drop the "Dropping top from BIGNUM" section and the stale
TODO(FIXNUM) field-removal comments, since `top` stays in BIGNUM.

Refs: https://github.com/openssl/project/issues/2019
Assisted-by: Pi:z-ai/glm-5.2
Assisted-by: Pi:openai/gpt-5.5
Signed-off-by: Richard Levitte <levitte@openssl.foundation>

Reviewed-by: Tomas Mraz <tomas@openssl.foundation>
Reviewed-by: Matt Caswell <matt@openssl.foundation>
MergeDate: Thu Jul  9 10:54:20 2026
(Merged from https://github.com/openssl/openssl/pull/31847)
2026-07-14 16:13:07 +02:00
Igor Ustinov
e3a6ede280 Check result of acquiring OSSL_FN
These calls might return NULL because they allocate memory.

Reviewed-by: Tomas Mraz <tomas@openssl.foundation>
Reviewed-by: Richard Levitte <levitte@openssl.org>
MergeDate: Tue Jun 30 06:45:42 2026
(Merged from https://github.com/openssl/openssl/pull/31754)
2026-07-14 16:13:07 +02:00
Richard Levitte
d07d760f8c OSSL_FN: Wrap BN shift and compare functions around OSSL_FN functions
Assisted-by: Pi:openai/gpt-5.5
Signed-off-by: Richard Levitte <levitte@openssl.foundation>

Reviewed-by: Igor Ustinov <igus@openssl.foundation>
Reviewed-by: Tomas Mraz <tomas@openssl.foundation>
MergeDate: Fri Jun 26 14:23:18 2026
(Merged from https://github.com/openssl/openssl/pull/31460)
2026-07-14 16:13:07 +02:00
Richard Levitte
0b478aba2c OSSL_FN: Add basic shift and compare functions
The following functions are added:

- OSSL_FN_num_bits
- OSSL_FN_cmp
- OSSL_FN_lshift
- OSSL_FN_lshift1

Assisted-by: Pi:openai/gpt-5.5
Signed-off-by: Richard Levitte <levitte@openssl.foundation>

Reviewed-by: Igor Ustinov <igus@openssl.foundation>
Reviewed-by: Tomas Mraz <tomas@openssl.foundation>
MergeDate: Fri Jun 26 14:23:17 2026
(Merged from https://github.com/openssl/openssl/pull/31460)
2026-07-14 16:13:07 +02:00
Tomas Mraz
04566a1781 Check result of acquiring OSSL_FN or OSSL_FN_CTX
These calls might return NULL because they
allocate memory.

Reviewed-by: Igor Ustinov <igus@openssl.foundation>
Reviewed-by: Daniel Kubec <kubec@openssl.foundation>
MergeDate: Fri Jun 26 14:09:33 2026
(Merged from https://github.com/openssl/openssl/pull/31613)
2026-07-14 16:13:07 +02:00
Richard Levitte
ac0e2da45e Use BN_CTX cached OSSL_FN_CTX in BN_mul() and BN_sqr()
The previous commit added bn_ctx_acquire_ossl_fn_ctx() and
bn_ctx_release_ossl_fn_ctx() to cache an OSSL_FN_CTX inside a BN_CTX.
However, BN_mul() and BN_sqr() were still creating and freeing their own
temporary OSSL_FN_CTX on every call, ignoring the passed-in BN_CTX entirely.

Update both functions to acquire the OSSL_FN_CTX from the BN_CTX and release
it afterwards, allowing the cached context to be reused across calls.

Assisted-by: Pi:moonshotai/kimi-k2.6
Signed-off-by: Richard Levitte <levitte@openssl.foundation>

Reviewed-by: Igor Ustinov <igus@openssl.foundation>
Reviewed-by: Tomas Mraz <tomas@openssl.foundation>
MergeDate: Sun Jun 14 08:40:47 2026
(Merged from https://github.com/openssl/openssl/pull/31431)
2026-07-14 16:13:07 +02:00
Richard Levitte
0e8b647fdb Add OSSL_FN_CTX integration with BN_CTX
Add an OSSL_FN_CTX * pointer to struct bignum_ctx, allowing a BN_CTX
to cache an OSSL_FN_CTX for use by BIGNUM wrapper functions.  The
pointer is freed automatically when BN_CTX_free() is called.

Also add bn_ctx_acquire_ossl_fn_ctx() and bn_ctx_release_ossl_fn_ctx():
- acquire creates (or reuses if large enough) an OSSL_FN_CTX inside
  the BN_CTX, sizing it according to the caller's needs.
- release checks that no frames remain in the cached OSSL_FN_CTX.

The acquire function respects BN_FLG_SECURE: if the BN_CTX was created
with BN_CTX_secure_new(), the OSSL_FN_CTX is also allocated in secure
memory.

Assisted-by: Pi:moonshotai/kimi-k2.6
Signed-off-by: Richard Levitte <levitte@openssl.foundation>

Reviewed-by: Igor Ustinov <igus@openssl.foundation>
Reviewed-by: Tomas Mraz <tomas@openssl.foundation>
MergeDate: Sun Jun 14 08:40:44 2026
(Merged from https://github.com/openssl/openssl/pull/31431)
2026-07-14 16:13:07 +02:00
Richard Levitte
5678648723 Expose OSSL_FN_CTX internals via fn_local.h
Move struct ossl_fn_ctx_st and struct ossl_fn_ctx_frame_st from
fn_ctx.c to fn_local.h, making them accessible to internal code in
the bn/ directory and elsewhere.  Also expose
ossl_fn_ctx_calculate_arena_size() as an inline helper so callers
can determine the required arena size without duplicating the formula.

This is groundwork for BN_CTX integration.

Assisted-by: Pi:moonshotai/kimi-k2.6
Signed-off-by: Richard Levitte <levitte@openssl.foundation>

Reviewed-by: Igor Ustinov <igus@openssl.foundation>
Reviewed-by: Tomas Mraz <tomas@openssl.foundation>
MergeDate: Sun Jun 14 08:40:42 2026
(Merged from https://github.com/openssl/openssl/pull/31431)
2026-07-14 16:13:07 +02:00
Richard Levitte
3a5594d70e Add test for OSSL_FN_CTX_peak_usage
Verify that peak_usage starts at zero, rises after frame start and
allocation, and never decreases after a frame is ended.

Also correct misleading comments that claimed OSSL_FN_CTX_new()
takes a size in bytes -- the last parameter is actually max_n_limbs.

Assisted-by: Pi:moonshotai/kimi-k2.6
Signed-off-by: Richard Levitte <levitte@openssl.foundation>

Reviewed-by: Igor Ustinov <igus@openssl.foundation>
Reviewed-by: Tomas Mraz <tomas@openssl.foundation>
MergeDate: Sun Jun 14 08:40:40 2026
(Merged from https://github.com/openssl/openssl/pull/31431)
2026-07-14 16:13:07 +02:00
Richard Levitte
e77ef33428 Add OSSL_FN_CTX_peak_usage() for arena usage instrumentation
Track the maximum number of frames, numbers and limbs ever consumed
from an OSSL_FN_CTX arena during its lifetime.  This allows callers
to empirically size their contexts instead of predicting precise
max_n_frames / max_n_numbers / max_n_limbs ahead of time.

These peak usages are updated whenever a frame is started or an OSSL_FN
is obtained.  They never decrease, reflecting the worst-case simultaneous
allocation across all nested frames.

Assisted-by: Pi:moonshotai/kimi-k2.6
Signed-off-by: Richard Levitte <levitte@openssl.foundation>

Reviewed-by: Igor Ustinov <igus@openssl.foundation>
Reviewed-by: Tomas Mraz <tomas@openssl.foundation>
MergeDate: Sun Jun 14 08:40:38 2026
(Merged from https://github.com/openssl/openssl/pull/31431)
2026-07-14 16:13:07 +02:00
Richard Levitte
277448082d Document OSSL_FN_copy zero-padding of oversized destination limbs
The OSSL_FN_copy() function already zeroes any high destination limbs
beyond the source size, but this was not stated in the public header.
Add an explicit note so callers know unused high bytes are cleared.

Assisted-by: Pi:moonshotai/kimi-k2.6
Signed-off-by: Richard Levitte <levitte@openssl.foundation>

Reviewed-by: Dmitry Belyavskiy <beldmit@gmail.com>
Reviewed-by: Igor Ustinov <igus@openssl.foundation>
Reviewed-by: Matt Caswell <matt@openssl.foundation>
MergeDate: Sun Jun 14 08:35:06 2026
(Merged from https://github.com/openssl/openssl/pull/31452)
2026-07-14 16:13:07 +02:00
Richard Levitte
96609d570a Add OSSL_FN_BITS, use it instead of 'OSSL_FN_BYTES * 8'
Reviewed-by: Dmitry Belyavskiy <beldmit@gmail.com>
Reviewed-by: Igor Ustinov <igus@openssl.foundation>
Reviewed-by: Matt Caswell <matt@openssl.foundation>
MergeDate: Sun Jun 14 08:35:04 2026
(Merged from https://github.com/openssl/openssl/pull/31452)
2026-07-14 16:13:07 +02:00
Richard Levitte
76f93f270e Acquire BN_sqr result before ctx sizing
Acquire the writable result before reading the operand dmax value for the
OSSL_FN_CTX arena size. This avoids stale context sizing when the result
aliases the operand and acquisition expands that BIGNUM.

Assisted-by: Pi:openai/gpt-5.5
Signed-off-by: Richard Levitte <levitte@openssl.foundation>

Reviewed-by: Tomas Mraz <tomas@openssl.foundation>
Reviewed-by: Igor Ustinov <igus@openssl.foundation>
MergeDate: Fri Jun 12 15:16:36 2026
(Merged from https://github.com/openssl/openssl/pull/31448)
2026-07-14 16:13:07 +02:00
Richard Levitte
f03efd47b7 Acquire BN_mul result before ctx sizing
Acquire the writable result before reading operand dmax values for the
OSSL_FN_CTX arena size. This avoids stale context sizing when the result
aliases an operand and acquisition expands that BIGNUM.

Assisted-by: Pi:openai/gpt-5.5
Signed-off-by: Richard Levitte <levitte@openssl.foundation>

Reviewed-by: Tomas Mraz <tomas@openssl.foundation>
Reviewed-by: Igor Ustinov <igus@openssl.foundation>
MergeDate: Fri Jun 12 15:16:34 2026
(Merged from https://github.com/openssl/openssl/pull/31448)
2026-07-14 16:13:07 +02:00
Richard Levitte
54f13a2ef7 Use top to size BN add/sub results
Size the acquired result OSSL_FN from the significant operand limbs instead of
the allocated operand width. This keeps BN_uadd() and BN_usub() consistent
with the other wrappers that already use top for result sizing.

This follows a realization that applying OSSL_FN semantics onto BIGNUM too much
is pointless, and as demonstrated with BN_mul(), may be harmful, especially when
the result BIGNUM as the same as one of the operands.

Assisted-by: Pi:openai/gpt-5.5
Signed-off-by: Richard Levitte <levitte@openssl.foundation>

Reviewed-by: Tomas Mraz <tomas@openssl.foundation>
Reviewed-by: Igor Ustinov <igus@openssl.foundation>
MergeDate: Fri Jun 12 15:16:33 2026
(Merged from https://github.com/openssl/openssl/pull/31448)
2026-07-14 16:13:07 +02:00
Igor Ustinov
f53cc8e213 Add an ownership token for OSSL_FN_CTX frames
This prevents ending a frame that wasn't started by the caller.

Reviewed-by: Richard Levitte <levitte@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.foundation>
MergeDate: Thu Apr 30 09:18:52 2026
(Merged from https://github.com/openssl/openssl/pull/30886)
2026-07-14 16:13:07 +02:00
Igor Ustinov
17c4d15971 Some bugfixes for OSSL_FN
- Fixed the stage 2 exit criteria in OSSL_FN_add() and OSSL_FN_sub().
- Fixed the calculation of a-b when a is shorter than b and borrow==1
  after stage 1.
- Added sanity check in OSSL_FN_CTX_end().
- Do not set the is_dynamically_allocated flag when getting a
  new OSSL_FN from OSSL_FN_CTX.
- Added units of measurement to the error message in the OSSL_FN_copy()
  function.
- is_dynamically_allocated and is_securely_allocated shouldn't be
  copied in OSSL_BN_copy().
- Fixed the comment in OSSL_FN_add().
- Added a comment to bn_mul_truncated() that it is a duty of the calling
  function to zero out the rest of r in case of rn>an+bn.

Reviewed-by: Tomas Mraz <tomas@openssl.foundation>
Reviewed-by: Richard Levitte <levitte@openssl.org>
MergeDate: Fri Apr 17 16:02:44 2026
(Merged from https://github.com/openssl/openssl/pull/30833)
2026-07-14 16:13:07 +02:00
Igor Ustinov
7d5084df86 Added OSSL_FN_truncate() function, which allows to copy a longer number
to a shorter one, truncating the high bytes.

Reviewed-by: Tomas Mraz <tomas@openssl.foundation>
Reviewed-by: Richard Levitte <levitte@openssl.org>
MergeDate: Fri Apr 17 14:09:28 2026
(Merged from https://github.com/openssl/openssl/pull/30846)
2026-06-19 10:31:49 +02:00
Richard Levitte
f52bf9d167 OSSL_FN: Wrap the BIGNUM 'sqr' function around the OSSL_FN 'sqr' function
Reviewed-by: Matt Caswell <matt@openssl.foundation>
Reviewed-by: Tomas Mraz <tomas@openssl.foundation>
MergeDate: Fri Apr  3 12:32:22 2026
(Merged from https://github.com/openssl/openssl/pull/29819)
2026-06-19 10:31:49 +02:00
Richard Levitte
929db7822d OSSL_FN: Add the 'sqr' function
OSSL_FN_sqr() takes the square of on operand.  The result OSSL_FN may be of
any size, and if it's smaller than the result of squaring the operand, the
result is truncated to that size.

This also adds OSSL_FN_sqr() testcases in test/fn_api_test.c

Related-to: doc/designs/fixed-size-large-numbers.md
Issue: https://github.com/openssl/project/issues/1654

Reviewed-by: Matt Caswell <matt@openssl.foundation>
Reviewed-by: Tomas Mraz <tomas@openssl.foundation>
MergeDate: Fri Apr  3 12:32:20 2026
(Merged from https://github.com/openssl/openssl/pull/29819)
2026-06-19 10:31:49 +02:00
Richard Levitte
7e7280f1b2 Small fixups of things that somehow passed through our tests
Reviewed-by: Matt Caswell <matt@openssl.foundation>
Reviewed-by: Tomas Mraz <tomas@openssl.foundation>
MergeDate: Fri Apr  3 12:32:17 2026
(Merged from https://github.com/openssl/openssl/pull/29819)
2026-06-19 10:31:49 +02:00
Richard Levitte
ded391d6ce OSSL_FN: Refactor OSSL_FN_add() and OSSL_FN_sub() for truncation
OSSL_FN_mul() set a path that wasn't considered for OSSL_FN_add() and
OSSL_FN_sub(); a truncated result if the result OSSL_FN isn't large
enough to contain the full result.

This is done to keep the OSSL_FN API consistent, with a (tentative)
bonus, that the function calls become more constant time accross
repeated calls with the same size for operands and result.

Reviewed-by: Matt Caswell <matt@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/29309)
2026-06-19 10:31:49 +02:00
Richard Levitte
ab79f54114 OSSL_FN: Add the OSSL_FN_ typedefs to .clang-format's TypeNames
Furthermore, reformatting left some weird commenting in fn_api_test.c
because of (legitimate) line breaks, so they get adjust for purpose.

Reviewed-by: Matt Caswell <matt@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/29412)
2026-06-19 10:31:49 +02:00
Richard Levitte
8f77f825fa OSSL_FN: Wrap BIGNUM the 'mul' function around the OSSL_FN 'mul' function
Reviewed-by: Matt Caswell <matt@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/29203)
2026-06-19 10:31:49 +02:00
Richard Levitte
5ea9b46e95 OSSL_FN: Add the 'mul' function
OSSL_FN_mul() multiplies two operands.  The result OSSL_FN may be of any
size, and if it's smaller than the result of multiplying the two operands,
the result is truncated to that size.

This also adds the function OSSL_FN_copy(), a counterpart for BN_copy(),
as well as an OSSL_FN API test program.

Finally, test/fn_api_test.c is updated with a 'struct test_case_st', used
to instruct test functions what numbers to operate on, and some conditions,
and the 'add' and 'sub' test functions are upgraded to use that structure
for their input.

Related-to: doc/designs/fixed-size-large-numbers.md
Resolves: https://github.com/openssl/openssl/issues/28934

Reviewed-by: Matt Caswell <matt@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/29203)
2026-06-19 10:31:49 +02:00
Richard Levitte
12e7939872 Add ossl_num_bits(), which returns the significant number of bits in a size_t
This existed as an isolated static function in crypto/asn1/x_long.c, but
is really a pretty generic integer function, so it will serve better by
being exactly that.

Reviewed-by: Matt Caswell <matt@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/29203)
2026-06-19 10:31:49 +02:00
Richard Levitte
2532cdf821 OSSL_FN: constify some of the internal construction and introspection functions
This should have been done when they were added.

Reviewed-by: Matt Caswell <matt@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/29203)
2026-06-19 10:31:49 +02:00
Richard Levitte
74ebdc1535 BIGNUM: add internal function 'bn_mul_truncated'
This is a variant of 'bn_mul_normal' that allows the result array to
have a smaller size than otherwise expected.

'bn_mul_normal' is refactored to be a wrapper around 'bn_mul_truncated',
with an assumed result size (which is the sum of the operands' sizes).

Reviewed-by: Matt Caswell <matt@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/29203)
2026-06-19 10:31:49 +02:00
Richard Levitte
504fb345af BIGNUM: separate out word-only helper functions from bn_mul.c
This separation will allow us to use the word-only helper functions
from OSSL_FN functions without pulling in functions that operate on
BIGNUMs.

This also starts the collection of source files with word-only BN
functions that haven't found their way into bn_asm.c for various
reasons.
To recognise them, they are prefixed 'bnw_' instead of 'bn_'.

While at it, consitification is done where appropriate among words
helpers.

Reviewed-by: Matt Caswell <matt@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/29203)
2026-06-19 10:31:49 +02:00
Richard Levitte
cf738674e1 Add the fixed number context (OSSL_FN_CTX) with (de)allocators and tests
OSSL_FN_CTX is a reimplementation of BN_CTX, with the intent to have
good enough API parity.

The distinguishing feature with OSSL_FN_CTX is that it works as an arena
allocator, so it must be allocated with an estimate of how much memory
space will be needed for all OSSL_FN instances that will be retrieved
from that arena, and a bit of overhead.

Related-to: doc/designs/fixed-size-large-numbers.md
Resolves: https://github.com/openssl/openssl/issues/28933

Reviewed-by: Matt Caswell <matt@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/29161)
2026-06-19 10:31:49 +02:00
Richard Levitte
e148c8a233 BIGNUM: fix setting of 'top' in 'bn_mul_fixed_top'
When 'bn_set_top()' was applied, a couple of spots were missed.  This
cause some test failures.

Reviewed-by: Matt Caswell <matt@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/29028)
2026-06-19 10:31:49 +02:00
Richard Levitte
e3ae863a2d OSSL_FN: Wrap BIGNUM 'add' and 'sub' functions around OSSL_FN functions
This involves the following functions:

- 'BN_add'
- 'BN_sub'
- 'BN_uadd'
- 'BN_usub'

Care is taken to use the previous (now legacy) code if any of the argument
BIGNUMs isn't backed by an OSSL_FN (i.e. if its 'data' field is NULL).

Reviewed-by: Matt Caswell <matt@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/29028)
2026-06-19 10:31:49 +02:00
Richard Levitte
1bde024e9b OSSL_FN: Add internal functions to acquire the OSSL_FN from a BIGNUM
bn_acquire_ossl_fn() returns the OSSL_FN of a BIGNUM if there is one,
expanded to a given number of limbs.
bn_release() makes necessary adjustments to the BIGNUM after a run of
OSSL_FN operations on the OSSL instance it's backed by.

These two functions are most useful with BIGNUMs used to store operation
results, and are meant to help refactoring BN operators to be wrappers
around corresponding OSSL_FN operators.

Reviewed-by: Matt Caswell <matt@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/29028)
2026-06-19 10:31:49 +02:00
Richard Levitte
23fdb656c3 OSSL_FN: Add 'add' and 'sub' functions
This also introduces 'cmp' and 'ucmp' functions, as well as an OSSL_FN
API test program.

OSSL_FNs must not be polluted, so if a BIGNUM has a non-NULL 'data'
field, bn_pollute() will not pollute it.  It may be a good idea, though,
to pollute an OSSL_FN before an operation result is written to it, for
testing purposes.

Related-to: doc/designs/fixed-size-large-numbers.md
Resolves: https://github.com/openssl/openssl/issues/28932

Reviewed-by: Matt Caswell <matt@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/29028)
2026-06-19 10:31:49 +02:00
Richard Levitte
96dc6a9ac8 OSSL_FN: Add internal construction and introspection functions
These functions will be useful with other test programs without having
to include crypto/fn/fn_local.h, making them closer to real world use.

This also introduces OSSL_FN errors

Related-to: doc/designs/fixed-size-large-numbers.md

Reviewed-by: Matt Caswell <matt@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/29028)
2026-06-19 10:31:49 +02:00
Richard Levitte
133420b172 BN_DEBUG: Refactor 'bn_check_top', 'bn_wcheck_size' into static inline functions
All the BN_DEBUG code is also moved below the definition of 'struct bignum_st',
to keep the compilers happy.

Reviewed-by: Dmitry Belyavskiy <beldmit@gmail.com>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/29015)
2026-06-19 10:31:49 +02:00
Richard Levitte
2ccd86a0b1 BIGNUM: Adjust the requirements on 'top' and the 'd' array for OSSL_FN compat
BIGNUM is quite sloppy with its contents of the 'd' array above 'top'.  This
has been further exasperated by the 'bn_pollute' macro, which makes that slop
quite explicit.

That's fine within a purely BIGNUM context.

Enter OSSL_FN, which requires that the whole 'd' array is numerically
consistent, not just the BN_ULONGs up to 'top'.

This will, of course, cause trouble as soon as an OSSL_FN that's integrated
in a BIGNUM gets passed to OSSL_FN functions.

To ensure consistency, the following updates are made:

- [only for BIGNUMs in which 'data' is non-NULL] when decreasing 'top', all
  BN_ULONGs between the preceding 'top' and the new 'top' must be made zero.
- Drop bn_pollute() entirely, as it's now more harmful than useful.
- Modify bn_check_top() to better check the consistency of BIGNUM with
  integrated OSSL_FN, by checking that the part of the 'd' array between
  'top' and 'dmax' is all zeroes.
- Add the function 'bn_set_top()', which is recommended to use instead of
  assigning 'top' directly, as it will zeroise the intermediary limbs in
  the 'd' array when 'top' decreases.

On using 'bn_set_top()', it's highly recommended to use it everywhere,
unless you can be absolutely sure that the BIGNUM that's modified will never
be checked with 'bn_check_top()' or passed to any OSSL_FN function.

Related-to: doc/designs/fixed-size-large-numbers.md

Reviewed-by: Dmitry Belyavskiy <beldmit@gmail.com>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/29015)
2026-06-19 10:31:49 +02:00
Richard Levitte
2a691a034e First integration of OSSL_FN into BIGNUM
This integration is made in such a way that OSSL_FN is an optional
'data' field in BIGNUM, i.e. it's allowed to be NULL even though
the BIGNUM's 'd' field is non-NULL.

The public BIGNUM API will do what it can to ensure that the 'data'
field becomes non-NULL, but remains lax on input BIGNUMs, for now.
This allows diverse internal bn constants and hacks to continue to
function with minimal friction.  These constants and hacks will
incrementally be modified to use OSSL_FN where they currently use
BN_ULONG.

Related-to: doc/designs/fixed-size-large-numbers.md
Resolves: https://github.com/openssl/openssl/issues/28931

Reviewed-by: Matt Caswell <matt@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/28930)
2026-06-19 10:31:49 +02:00
Richard Levitte
584e7138af Add the fixed number type (OSSL_FN) and its allocators and deallocator
This includes a small test program that performs introspection of the
OSSL_FN, to check that diverse functions do what's expected of them.

For future compatibility reasons, the limb type OSSL_FN_ULONG is based
on BN_ULONG.  This caused a slight rearrangement of public BIGNUM related
headers.

Note: experiments with changing the current BIGNUM's 'dmax' and 'top' to be
"size_t" has shown disastrous effects, due to some lower level functions
assuming that they'll receive the size in "int" form rather than "size_t"
form (on some major platforms, these two types have different sizes).
Therefore, this change deviates slightly from the design for fixed numbers
(doc/designs/fixed-size-large-numbers.md) by making OSSL_FN's 'dsize' an
"int" rather than a "size_t".

Related-to: doc/designs/fixed-size-large-numbers.md
Resolves: https://github.com/openssl/project/issues/1649

Reviewed-by: Matt Caswell <matt@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/28784)
2026-06-19 10:31:49 +02:00
Richard Levitte
a5b9c8d60f Fix spelling in doc/designs/fixed-size-large-numbers.md
Found by codespell.

payed → paid

Reviewed-by: Frederik Wedel-Heinen <fwh.openssl@gmail.com>
Reviewed-by: Shane Lontis <shane.lontis@oracle.com>
(Merged from https://github.com/openssl/openssl/pull/28787)
2026-06-19 10:03:29 +02:00
Richard Levitte
8e4c928280 design: Fixed size large numbers
For the longest time, we have mitigated security issues related to large
numbers (BIGNUM) and constant time in a piece-meal fashion, without really
looking at the problem from a zoomed out, holistic perspective.

An interesting aspect in this problem is that large numbers can vary in
size, and that depending on their combined sizes, the time to perform
mathematical calculations with them vary equally much, and may thereby
unintentionally leak information on those numbers.

To mitigate that sort of timing issue, we introduce fixed size numbers,
which are designed to have payload sizes that are pre-determined, usually by
the crypto system that uses them.  This means that even a very small number
(let's take 1 as a ridiculous example) would have the same size payload as a
much larger number, and calculations using them would perform across all
payload bits of all input numbers combined.

These fixed size numbers primarly differ from BIGNUMs in that once they have
been allocated to a certain size, that size will not change throughout its
lifetime.

Reviewed-by: Dmitry Belyavskiy <beldmit@gmail.com>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/28522)
2026-06-19 10:03:29 +02:00
710 changed files with 88071 additions and 33634 deletions

View file

@ -599,6 +599,8 @@ TypeNames:
- "ossl_finish_mutate_cb"
- "OSSL_FIPS_IND"
- "OSSL_FIPS_IND_CHECK_CB"
- "OSSL_FN_CTX"
- "OSSL_FN_ULONG"
- "OSSL_FUNC"
- "OSSL_HANDSHAKE_STATE"
- "OSSL_HASH"
@ -1375,7 +1377,6 @@ StatementMacros:
- "static_ASN1_SEQUENCE_END_cb"
- "static_ASN1_SEQUENCE_END_name"
- "static_ASN1_SEQUENCE_END_ref"
- "PROV_CIPHER_HW_aes_mode"
- "PROV_CIPHER_HW_aria_mode"
- "PROV_CIPHER_HW_camellia_mode"
- "PROV_CIPHER_HW_des_mode"

View file

@ -1,167 +0,0 @@
# Copyright 2026 The OpenSSL Project Authors. All Rights Reserved.
# Copyright (c) 2026 Intel Corporation. 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
# Run AVX512-specific tests under Intel SDE.
#
# GitHub Actions runners currently do not have AVX512 hardware.
# Intel SDE emulates AVX512 instructions and spoofs CPUID,
# so AVX512 code paths are exercised.
#
# To update Intel SDE: find the new mirror ID and file date from
# https://www.intel.com/content/www/us/en/download/684897
# and update the three env vars below.
name: AVX512 tests via Intel SDE
on:
schedule:
- cron: '30 02 * * *'
workflow_dispatch:
permissions:
contents: read
env:
SDE_VERSION: 10.8.0
SDE_DATE: 2026-03-15
SDE_MIRROR_ID: 915934
jobs:
linux:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
with:
persist-credentials: false
- name: install NASM
run: sudo apt-get install -y nasm
- name: install Intel SDE
run: |
SDE_URL="https://downloadmirror.intel.com/${SDE_MIRROR_ID}/sde-external-${SDE_VERSION}-${SDE_DATE}-lin.tar.xz"
SDE_SHA256="50b320cd226acef7a491f5b321fc1be3c3c7984f9e27a456e64894b5b0979dd3"
curl -fsSL -o /tmp/sde.tar.xz "$SDE_URL"
echo "$SDE_SHA256 /tmp/sde.tar.xz" | sha256sum -c -
mkdir /tmp/sde
tar -xf /tmp/sde.tar.xz -C /tmp/sde/
sudo mv /tmp/sde/sde-external-${SDE_VERSION}-${SDE_DATE}-lin /opt/sde
echo "/opt/sde" >> "$GITHUB_PATH"
- name: config
run: |
./config --banner=Configured --strict-warnings no-shared enable-fips
- name: build
run: make -j4
- name: show CPU and OpenSSL build info
run: |
cat /proc/cpuinfo | grep -m1 "model name"
sde64 -icx -- ./apps/openssl version -c
- name: ml_dsa_internal_test (AVX512 via SDE)
run: sde64 -icx -- ./test/ml_dsa_internal_test
- name: sha3_x4_internal_test (AVX512 via SDE)
run: sde64 -icx -- ./test/sha3_x4_internal_test
- name: fipsinstall (FIPS KAT via SDE)
run: sde64 -icx -- ./apps/openssl fipsinstall -module ./providers/fips.so -out /tmp/fipsmodule.cnf -provider_name fips
windows:
runs-on: windows-2022
env:
VCVARS: C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvars64.bat
steps:
- uses: actions/checkout@v6
with:
persist-credentials: false
- name: install nasm
if: github.repository == 'openssl/openssl'
run: |
$installer = "nasm-3.01-installer-x64.exe"
Invoke-WebRequest -Uri "https://openssl-library.org/ci-deps/$installer" -OutFile $installer
$expected = (Get-Content "$env:GITHUB_WORKSPACE\.github\ci-deps.json" -Raw | ConvertFrom-Json).$installer
$actual = (Get-FileHash $installer -Algorithm SHA256).Hash
if ($actual -ne $expected) { throw "SHA256 mismatch for $installer (expected $expected, got $actual)" }
Start-Process -FilePath ".\$installer" -ArgumentList '/S' -Wait
"C:\Program Files\NASM" | Out-File -FilePath "$env:GITHUB_PATH" -Append
- name: install nasm (forks)
if: github.repository != 'openssl/openssl'
run: |
$installer = "nasm-3.01-installer-x64.exe"
Invoke-WebRequest -Uri "https://www.nasm.us/pub/nasm/releasebuilds/3.01/win64/$installer" -OutFile $installer
Start-Process -FilePath ".\$installer" -ArgumentList '/S' -Wait
"C:\Program Files\NASM" | Out-File -FilePath "$env:GITHUB_PATH" -Append
- name: install jom
if: github.repository == 'openssl/openssl'
run: |
mkdir C:\jom
Invoke-WebRequest -Uri "https://openssl-library.org/ci-deps/jom-1.1.7.exe" -OutFile C:\jom\jom.exe
$expected = (Get-Content "$env:GITHUB_WORKSPACE\.github\ci-deps.json" -Raw | ConvertFrom-Json).'jom-1.1.7.exe'
$actual = (Get-FileHash C:\jom\jom.exe -Algorithm SHA256).Hash
if ($actual -ne $expected) { throw "SHA256 mismatch for jom.exe (expected $expected, got $actual)" }
"C:\jom" | Out-File -FilePath "$env:GITHUB_PATH" -Append
- name: install jom (forks)
if: github.repository != 'openssl/openssl'
run: |
mkdir C:\jom
Invoke-WebRequest -Uri "https://download.qt.io/official_releases/jom/jom_1_1_7.zip" -OutFile C:\jom\jom.zip
Expand-Archive -Path C:\jom\jom.zip -DestinationPath C:\jom
"C:\jom" | Out-File -FilePath "$env:GITHUB_PATH" -Append
- name: install Intel SDE
run: |
$url = "https://downloadmirror.intel.com/$env:SDE_MIRROR_ID/sde-external-$env:SDE_VERSION-$env:SDE_DATE-win.tar.xz"
$expected = "176F87C80EB42BB91B73E1428F4A0FD067DF322F901F9B4359B20B86B92C2BAE"
curl.exe -fsSL -o sde-win.tar.xz $url
$actual = (Get-FileHash sde-win.tar.xz -Algorithm SHA256).Hash
if ($actual -ne $expected) { throw "SDE SHA256 mismatch: got $actual" }
& "C:\Program Files\7-Zip\7z.exe" x sde-win.tar.xz -so | & "C:\Program Files\7-Zip\7z.exe" x -si -ttar -o"C:\sde"
$sdeRoot = "C:\sde\sde-external-$env:SDE_VERSION-$env:SDE_DATE-win"
if (-not (Test-Path "$sdeRoot\sde.exe")) { throw "sde.exe not found in $sdeRoot" }
"$sdeRoot" | Out-File -FilePath $env:GITHUB_PATH -Append
- name: prepare build directory
run: mkdir _build
- name: config
working-directory: _build
shell: cmd
run: |
call "%VCVARS%"
perl ..\Configure --banner=Configured --strict-warnings no-shared enable-fips no-makedepend
- name: build
working-directory: _build
shell: cmd
run: |
call "%VCVARS%"
jom /j4 /S
- name: show CPU and OpenSSL build info
working-directory: _build
run: sde -icx -- apps\openssl.exe version -c
- name: ml_dsa_internal_test (AVX512 via SDE)
working-directory: _build
shell: cmd
run: sde -icx -- test\ml_dsa_internal_test.exe
- name: sha3_x4_internal_test (AVX512 via SDE)
working-directory: _build
shell: cmd
run: sde -icx -- test\sha3_x4_internal_test.exe
- name: fipsinstall (FIPS KAT via SDE)
working-directory: _build
shell: cmd
run: sde -icx -- apps\openssl.exe fipsinstall -module providers\fips.dll -out fipsmodule.cnf -provider_name fips

View file

@ -1,125 +0,0 @@
# Copyright 2021-2026 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
name: Documentation and Installability CI
on: [pull_request, push]
permissions:
contents: read
env:
OSSL_RUN_CI_TESTS: 1
jobs:
check_docs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
with:
persist-credentials: false
- name: config
run: ./config --strict-warnings --banner=Configured enable-fips && perl configdata.pm --dump
- name: make build_generated
run: make -s build_generated
- name: make doc-nits
run: make doc-nits
- name: make help
run: make help
- name: make md-nits
run: |
sudo gem install mdl
make md-nits
# out-of-source-and-install checks multiple things at the same time:
# - That building, testing and installing works from an out-of-source
# build tree
# - That building, testing and installing works with a read-only source
# tree
out-of-readonly-source-and-install-ubuntu:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
with:
path: ./source
persist-credentials: false
- name: checkout fuzz/corpora submodule
run: git submodule update --init --depth 1 fuzz/corpora
working-directory: ./source
- name: make source read-only
run: chmod -R a-w ./source
- name: create build and install directories
run: |
mkdir ./build
mkdir ./install
- name: config
run: |
../source/config --banner=Configured enable-demos enable-h3demo enable-fips enable-lms enable-quic enable-acvp-tests --strict-warnings --prefix=$(cd ../install; pwd)
perl configdata.pm --dump
working-directory: ./build
- name: make
run: make -s -j4
working-directory: ./build
- name: get cpu info
run: |
cat /proc/cpuinfo
./util/opensslwrap.sh version -c
working-directory: ./build
- name: make test
run: ../source/.github/workflows/make-test
working-directory: ./build
- name: save artifacts
if: success() || failure()
uses: actions/upload-artifact@v5
with:
name: "ci@out-of-readonly-source-and-install-ubuntu"
path: build/artifacts.tar.gz
- name: make install
run: make install
working-directory: ./build
out-of-readonly-source-and-install-macos:
runs-on: macos-15
steps:
- uses: actions/checkout@v6
with:
path: ./source
persist-credentials: false
- name: checkout fuzz/corpora submodule
run: git submodule update --init --depth 1 fuzz/corpora
working-directory: ./source
- name: make source read-only
run: chmod -R a-w ./source
- name: create build and install directories
run: |
mkdir ./build
mkdir ./install
- name: config
run: |
../source/config --banner=Configured enable-fips enable-lms enable-demos enable-h3demo enable-quic enable-acvp-tests --strict-warnings --prefix=$(cd ../install; pwd)
perl configdata.pm --dump
working-directory: ./build
- name: make
run: make -s -j4
working-directory: ./build
- name: get cpu info
run: |
sysctl machdep.cpu
./util/opensslwrap.sh version -c
working-directory: ./build
- name: make test
run: ../source/.github/workflows/make-test
working-directory: ./build
- name: save artifacts
if: success() || failure()
uses: actions/upload-artifact@v5
with:
name: "ci@out-of-readonly-source-and-install-macos-15"
path: build/artifacts.tar.gz
- name: make install
run: make install
working-directory: ./build

View file

@ -7,25 +7,7 @@
name: GitHub CI
on:
pull_request:
paths-ignore:
- 'doc/**'
- '*.md'
- '*.pod'
- 'README*'
- 'funding.json'
- 'LICENSE.txt'
- 'VERSION.dat'
push:
paths-ignore:
- 'doc/**'
- '*.md'
- '*.pod'
- 'README*'
- 'funding.json'
- 'LICENSE.txt'
- 'VERSION.dat'
on: [pull_request, push]
# for some reason, this does not work:
# variables:
@ -63,6 +45,25 @@ jobs:
- name: git diff
run: git diff --exit-code
check_docs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
with:
persist-credentials: false
- name: config
run: ./config --strict-warnings --banner=Configured enable-fips && perl configdata.pm --dump
- name: make build_generated
run: make -s build_generated
- name: make doc-nits
run: make doc-nits
- name: make help
run: make help
- name: make md-nits
run: |
sudo gem install mdl
make md-nits
# This checks that we use ANSI C language syntax and semantics.
# We are not as strict with libraries, but rather adapt to what's
# expected to be available in a certain version of each platform.
@ -87,14 +88,12 @@ jobs:
run: git submodule update --init --depth 1 fuzz/corpora
- name: localegen
run: sudo locale-gen tr_TR.UTF-8
- name: cmocka
run: sudo apt-get -y install libcmocka-dev
- name: fipsvendor
# Make one fips build use a customized FIPS vendor
run: echo "FIPS_VENDOR=CI" >> VERSION.dat
- name: config
# enable-quic is on by default, but we leave it here to check we're testing the explicit enable somewhere
run: CC=gcc ./config --strict-warnings --banner=Configured enable-demos enable-h3demo enable-ec_explicit_curves enable-sslkeylog enable-fips enable-quic enable-lms enable-unit-tests && perl configdata.pm --dump
run: CC=gcc ./config --strict-warnings --banner=Configured enable-demos enable-h3demo enable-ec_explicit_curves enable-sslkeylog enable-fips enable-quic enable-lms && perl configdata.pm --dump
- name: make
run: make -s -j4
- name: get cpu info
@ -461,40 +460,6 @@ jobs:
path: artifacts.tar.gz
if-no-files-found: ignore
fuzz_tests_mfail:
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
- uses: actions/checkout@v6
with:
persist-credentials: false
- name: checkout fuzz/corpora submodule
run: git submodule update --init --depth 1 fuzz/corpora
- name: Adjust ASLR for sanitizer
run: sudo sysctl -w vm.mmap_rnd_bits=28
- name: config
run: |
./config --strict-warnings --banner=Configured --debug \
-DPEDANTIC -DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION \
enable-asan enable-ec_explicit_curves enable-ubsan \
enable-rc5 enable-md2 enable-ec_nistp_64_gcc_128 \
enable-weak-ssl-ciphers enable-nextprotoneg
perl configdata.pm --dump
- name: make
run: make -s -j4
- name: make test (fuzz with mfail)
env:
OSSL_FUZZ_TEST_BUDGET: 1200
OSSL_FUZZ_TEST_JOBS: 4
run: .github/workflows/make-test OPENSSL_TEST_RAND_ORDER=0 TESTS="test_fuzz*"
- name: save artifacts
if: success() || failure()
uses: actions/upload-artifact@v5
with:
name: "ci@fuzz_tests_mfail"
path: artifacts.tar.gz
if-no-files-found: ignore
memory_sanitizer:
runs-on: ubuntu-latest
steps:
@ -664,6 +629,95 @@ jobs:
name: "ci@legacy"
path: artifacts.tar.gz
# out-of-source-and-install checks multiple things at the same time:
# - That building, testing and installing works from an out-of-source
# build tree
# - That building, testing and installing works with a read-only source
# tree
out-of-readonly-source-and-install-ubuntu:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
with:
path: ./source
persist-credentials: false
- name: checkout fuzz/corpora submodule
run: git submodule update --init --depth 1 fuzz/corpora
working-directory: ./source
- name: make source read-only
run: chmod -R a-w ./source
- name: create build and install directories
run: |
mkdir ./build
mkdir ./install
- name: config
run: |
../source/config --banner=Configured enable-demos enable-h3demo enable-fips enable-lms enable-quic enable-acvp-tests --strict-warnings --prefix=$(cd ../install; pwd)
perl configdata.pm --dump
working-directory: ./build
- name: make
run: make -s -j4
working-directory: ./build
- name: get cpu info
run: |
cat /proc/cpuinfo
./util/opensslwrap.sh version -c
working-directory: ./build
- name: make test
run: ../source/.github/workflows/make-test
working-directory: ./build
- name: save artifacts
if: success() || failure()
uses: actions/upload-artifact@v5
with:
name: "ci@out-of-readonly-source-and-install-ubuntu"
path: build/artifacts.tar.gz
- name: make install
run: make install
working-directory: ./build
out-of-readonly-source-and-install-macos:
runs-on: macos-15
steps:
- uses: actions/checkout@v6
with:
path: ./source
persist-credentials: false
- name: checkout fuzz/corpora submodule
run: git submodule update --init --depth 1 fuzz/corpora
working-directory: ./source
- name: make source read-only
run: chmod -R a-w ./source
- name: create build and install directories
run: |
mkdir ./build
mkdir ./install
- name: config
run: |
../source/config --banner=Configured enable-fips enable-lms enable-demos enable-h3demo enable-quic enable-acvp-tests --strict-warnings --prefix=$(cd ../install; pwd)
perl configdata.pm --dump
working-directory: ./build
- name: make
run: make -s -j4
working-directory: ./build
- name: get cpu info
run: |
sysctl machdep.cpu
./util/opensslwrap.sh version -c
working-directory: ./build
- name: make test
run: ../source/.github/workflows/make-test
working-directory: ./build
- name: save artifacts
if: success() || failure()
uses: actions/upload-artifact@v5
with:
name: "ci@out-of-readonly-source-and-install-macos-15"
path: build/artifacts.tar.gz
- name: make install
run: make install
working-directory: ./build
external-tests-misc:
runs-on: ubuntu-latest
steps:
@ -675,6 +729,10 @@ jobs:
run: |
sudo apt-get update
sudo apt-get -yq install bison gettext keyutils ldap-utils libldap2-dev libkeyutils-dev python3 python3-paste python3-pyrad slapd tcsh python3-virtualenv virtualenv python3-kdcproxy gdb libtls-dev wget gpg
- name: install cpanm and Test2::V0 for gost_engine testing
uses: perl-actions/install-with-cpanm@10d60f00b4073f484fc29d45bfbe2f776397ab3d # v1.7
with:
install: Test2::V0
- name: setup hostname workaround
run: sudo hostname localhost
- name: config
@ -688,9 +746,8 @@ jobs:
run: |
cat /proc/cpuinfo
./util/opensslwrap.sh version -c
- name: test failure when selecting non-existing test case
run: |
! make test TESTS="test_external_gost_engine"
- name: test external gost-engine
run: make test TESTS="test_external_gost_engine"
- name: test external krb5
run: make test TESTS="test_external_krb5"
- name: test external tlsfuzzer

View file

@ -47,10 +47,10 @@ jobs:
MATRIX=$(cat << EOF
[{
"branch": "master",
"extra_config": "enable-fips enable-tfo enable-lms enable-crypto-mdebug enable-unit-tests"
"extra_config": "enable-fips enable-tfo enable-lms enable-crypto-mdebug enable-allocfail-tests"
}, {
"branch": "openssl-4.0",
"extra_config": "enable-fips enable-tfo enable-lms enable-crypto-mdebug"
"extra_config": "enable-fips enable-tfo enable-lms enable-crypto-mdebug enable-allocfail-tests"
},{
"branch": "openssl-3.6",
"extra_config": "no-afalgeng enable-fips enable-tfo enable-lms"
@ -93,7 +93,7 @@ jobs:
run: |
sudo apt-get update
sudo apt-get -yq install lcov
sudo apt-get -yq install bison gettext keyutils ldap-utils libcmocka-dev libldap2-dev libkeyutils-dev python3 python3-paste python3-pyrad slapd tcsh python3-virtualenv virtualenv python3-kdcproxy
sudo apt-get -yq install bison gettext keyutils ldap-utils libldap2-dev libkeyutils-dev python3 python3-paste python3-pyrad slapd tcsh python3-virtualenv virtualenv python3-kdcproxy
- name: install Test2::V0 for gost_engine testing
uses: perl-actions/install-with-cpanm@10d60f00b4073f484fc29d45bfbe2f776397ab3d #v1.7
with:

View file

@ -7,35 +7,13 @@
name: Cross Compile
on:
pull_request:
paths-ignore:
- 'doc/**'
- '*.md'
- '*.pod'
- 'README*'
- 'funding.json'
- 'LICENSE.txt'
- 'VERSION.dat'
push:
paths-ignore:
- 'doc/**'
- '*.md'
- '*.pod'
- 'README*'
- 'funding.json'
- 'LICENSE.txt'
- 'VERSION.dat'
on: [pull_request, push]
permissions:
contents: read
jobs:
cross-compilation:
# Run the full test suite on push, and on pull requests labelled with
# 'extended tests'. Other pull requests only run the EVP tests.
env:
EXTENDED: ${{ github.event_name == 'push' || contains(github.event.pull_request.labels.*.name, 'extended tests') }}
strategy:
fail-fast: false
matrix:
@ -233,19 +211,19 @@ jobs:
cat /proc/cpuinfo
QEMU_LD_PREFIX=/usr/${{ matrix.platform.arch }} ./util/opensslwrap.sh version -c
- name: make all tests
if: env.EXTENDED == 'true' && matrix.platform.tests == ''
if: github.event_name == 'push' && matrix.platform.tests == ''
run: |
.github/workflows/make-test \
TESTS="-test_afalg" \
QEMU_LD_PREFIX=/usr/${{ matrix.platform.arch }}
- name: make some tests
if: env.EXTENDED == 'true' && matrix.platform.tests != 'none' && matrix.platform.tests != ''
if: github.event_name == 'push' && matrix.platform.tests != 'none' && matrix.platform.tests != ''
run: |
.github/workflows/make-test \
TESTS="${{ matrix.platform.tests }} -test_afalg" \
QEMU_LD_PREFIX=/usr/${{ matrix.platform.arch }}
- name: make evp tests
if: env.EXTENDED != 'true' && matrix.platform.tests != 'none'
if: github.event_name == 'pull_request' && matrix.platform.tests != 'none'
run: |
.github/workflows/make-test \
TESTS="test_evp*" \

View file

@ -6,16 +6,7 @@
# https://www.openssl.org/source/license.html
name: FIPS Check and ABIDIFF
on:
pull_request:
paths-ignore:
- 'doc/**'
- '*.md'
- '*.pod'
- 'README*'
- 'funding.json'
- 'LICENSE.txt'
- 'VERSION.dat'
on: [pull_request]
permissions:
contents: read

48
.github/workflows/make-release.yml vendored Normal file
View file

@ -0,0 +1,48 @@
# Copyright 2021-2026 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
name: "Make release"
on:
push:
tags:
- "openssl-*"
permissions: {}
jobs:
release:
runs-on: "releaser"
steps:
- name: "Checkout"
uses: "actions/checkout@v6"
with:
fetch-depth: 1
ref: ${{ github.ref_name }}
github-server-url: "https://github.openssl.org/"
repository: "openssl/openssl"
token: ${{ secrets.GHE_TOKEN }}
path: ${{ github.ref_name }}
persist-credentials: false
- name: "Prepare assets"
env:
SIGNING_KEY_UID: ${{ vars.signing_key_uid }}
run: |
cd "$GITHUB_REF_NAME"
./util/mktar.sh
mkdir -p assets && mv "$GITHUB_REF_NAME.tar.gz" assets/ && cd assets
openssl sha1 -r "$GITHUB_REF_NAME.tar.gz" > "$GITHUB_REF_NAME.tar.gz.sha1"
openssl sha256 -r "$GITHUB_REF_NAME.tar.gz" > "$GITHUB_REF_NAME.tar.gz.sha256"
gpg -u "$SIGNING_KEY_UID" -o "$GITHUB_REF_NAME.tar.gz.asc" -sba "$GITHUB_REF_NAME.tar.gz"
- name: "Create release"
env:
GITHUB_TOKEN: ${{ secrets.GH_TOKEN }}
run: |
VERSION=$(echo "$GITHUB_REF_NAME" | cut -d "-" -f 2-)
PRE_RELEASE=$([[ "$GITHUB_REF_NAME" =~ alpha|beta ]] && echo "-p" || echo "")
NOTES=$(curl -s "https://api.openssl.org/release-metadata/news/?version=$VERSION&capture_title=False")
gh release create "$GITHUB_REF_NAME" $PRE_RELEASE -t "OpenSSL $VERSION" -d --notes "$NOTES" -R "$GITHUB_REPOSITORY" "$GITHUB_REF_NAME/assets/"*

View file

@ -7,25 +7,7 @@
# Jobs run per pull request submission
name: Perl-minimal-checker CI
on:
pull_request:
paths-ignore:
- 'doc/**'
- '*.md'
- '*.pod'
- 'README*'
- 'funding.json'
- 'LICENSE.txt'
- 'VERSION.dat'
push:
paths-ignore:
- 'doc/**'
- '*.md'
- '*.pod'
- 'README*'
- 'funding.json'
- 'LICENSE.txt'
- 'VERSION.dat'
on: [pull_request, push]
permissions:
contents: read

View file

@ -10,16 +10,7 @@
name: Provider compatibility for PRs
on:
pull_request:
paths-ignore:
- 'doc/**'
- '*.md'
- '*.pod'
- 'README*'
- 'funding.json'
- 'LICENSE.txt'
- 'VERSION.dat'
on: [pull_request]
permissions:
contents: read

View file

@ -10,14 +10,6 @@ name: Cross Compile for RISC-V Extensions
on:
pull_request:
types: [opened, reopened, edited, synchronize]
paths-ignore:
- 'doc/**'
- '*.md'
- '*.pod'
- 'README*'
- 'funding.json'
- 'LICENSE.txt'
- 'VERSION.dat'
push:
schedule:
- cron: '35 02 * * *'

View file

@ -7,25 +7,7 @@
# Jobs run per pull request submission
name: Run-checker CI
on:
pull_request:
paths-ignore:
- 'doc/**'
- '*.md'
- '*.pod'
- 'README*'
- 'funding.json'
- 'LICENSE.txt'
- 'VERSION.dat'
push:
paths-ignore:
- 'doc/**'
- '*.md'
- '*.pod'
- 'README*'
- 'funding.json'
- 'LICENSE.txt'
- 'VERSION.dat'
on: [pull_request, push]
permissions:
contents: read

View file

@ -7,16 +7,7 @@
name: Coding style validation
on:
pull_request:
paths-ignore:
- 'doc/**'
- '*.md'
- '*.pod'
- 'README*'
- 'funding.json'
- 'LICENSE.txt'
- 'VERSION.dat'
on: [pull_request]
jobs:
check-style:

View file

@ -7,26 +7,7 @@
name: Windows GitHub CI
on:
pull_request:
paths-ignore:
- 'doc/**'
- '*.md'
- '*.pod'
- 'README*'
- 'funding.json'
- 'LICENSE.txt'
- 'VERSION.dat'
push:
paths-ignore:
- 'doc/**'
- '*.md'
- '*.pod'
- 'README*'
- 'funding.json'
- 'LICENSE.txt'
- 'VERSION.dat'
on: [pull_request, push]
permissions:
contents: read
@ -209,59 +190,6 @@ jobs:
call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvars64.bat"
nmake test VERBOSE_FAILURE=yes HARNESS_JOBS=4
unit-tests:
runs-on: windows-2022
steps:
- uses: actions/checkout@v6
with:
persist-credentials: false
- name: checkout fuzz/corpora submodule
run: git submodule update --init --depth 1 fuzz/corpora
- name: install jom
if: github.repository == 'openssl/openssl'
run: |
mkdir C:\jom
Invoke-WebRequest -Uri "https://openssl-library.org/ci-deps/jom-1.1.7.exe" -OutFile C:\jom\jom.exe
$expected = (Get-Content "$env:GITHUB_WORKSPACE\.github\ci-deps.json" -Raw | ConvertFrom-Json).'jom-1.1.7.exe'
$actual = (Get-FileHash C:\jom\jom.exe -Algorithm SHA256).Hash
if ($actual -ne $expected) { throw "SHA256 mismatch for jom.exe (expected $expected, got $actual)" }
"C:\jom" | Out-File -FilePath "$env:GITHUB_PATH" -Append
- name: install jom (forks)
if: github.repository != 'openssl/openssl'
run: |
mkdir C:\jom
Invoke-WebRequest -Uri "https://download.qt.io/official_releases/jom/jom_1_1_7.zip" -OutFile C:\jom\jom.zip
Expand-Archive -Path C:\jom\jom.zip -DestinationPath C:\jom
"C:\jom" | Out-File -FilePath "$env:GITHUB_PATH" -Append
- name: install cmocka and detours via vcpkg
shell: pwsh
run: |
& "$env:VCPKG_INSTALLATION_ROOT\vcpkg.exe" install cmocka:x64-windows-static-md detours:x64-windows-static-md
"VCPKG_INST=$env:VCPKG_INSTALLATION_ROOT\installed\x64-windows-static-md" | Out-File -FilePath $env:GITHUB_ENV -Append
- name: prepare the build directory
run: mkdir _build
- name: config
working-directory: _build
shell: cmd
run: |
call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvars64.bat"
perl ..\Configure VC-WIN64A --banner=Configured --strict-warnings no-makedepend no-asm enable-unit-tests ^
--with-cmocka-include=%VCPKG_INST%\include --with-cmocka-lib=%VCPKG_INST%\lib ^
--with-detours-include=%VCPKG_INST%\include --with-detours-lib=%VCPKG_INST%\lib
perl configdata.pm --dump
- name: build
working-directory: _build
shell: cmd
run: |
call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvars64.bat"
jom /j4 /S
- name: test
working-directory: _build
shell: cmd
run: |
call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvars64.bat"
jom test VERBOSE=1 TESTS=test_unit
minimal:
runs-on: windows-2022
steps:

View file

@ -31,58 +31,6 @@ OpenSSL Releases
### Changes between 4.0 and 4.1 [xx XXX xxxx]
* Fixed TLS 1.3 external PSK connections being wrongly rejected when
the client sets a non-empty session ID context.
*Viktor Dukhovni*
* Fixed a TLS 1.3 server with no session ID context to accept external PSK
connections and to stop issuing unusable session tickets.
*Viktor Dukhovni*
* Added AVX512 optimized SHAKE x4 operations for ML-DSA on `x86_64`.
*Marcel Cornu and Tomasz Kantecki*
* EC key point format simplification.
The point conversion form (compressed, uncompressed, or hybrid)
is now a single value on the `EC_GROUP` and round-trips
unchanged through import and export of `EC_KEY` objects.
Freshly generated keys have their public point encoded in
uncompressed form. A `point-format` supplied at key generation
time via `OSSL_PKEY_PARAM_EC_POINT_CONVERSION_FORMAT` is
validated (an invalid value is rejected) but otherwise ignored
on the generated key. EC parameter generation continues to
honour the requested form on the group's generator; imported
keys keep their form.
The `ec_point_formats` extension no longer affects TLS 1.2
X.509 certificate selection or acceptance. OpenSSL now
accepts an EC certificate in any point form it can decode,
and sends any EC certificate it has regardless of point form.
TLS 1.3 disregards the extension entirely.
The RFC 4492/8422 section 5.1.2 requirement that the peer's
point-format list contain "uncompressed" is now enforced on
both sides (previously client-only), and only when an ECC
TLS 1.2 ciphersuite is negotiated -- a missing "uncompressed"
is ignored under TLS 1.3 or with a non-ECC cipher.
*Viktor Dukhovni*
* Added unit tests setup activated via `enable-unit-tests` option. This works
only on platforms with ld `--wrap` support (Linux, BSD).
*Jakub Zelenka*
* Deprecated the `enable-unit-test` configure option and the
`SSL_test_functions()` function. Both will be removed in OpenSSL 5.0.
*Jakub Zelenka*
* Added -testmode option for `s_time` app.
*Jakub Zelenka*
@ -93,7 +41,7 @@ OpenSSL Releases
*Adriano Sela Aviles*
* SubjectPublicKeyInfo blobs whose AlgorithmIdentifier uses id-RSAES-OAEP
(`NID_rsaesOaep`, 1.2.840.113549.1.1.7) with a plain RSAPublicKey body
(NID_rsaesOaep, 1.2.840.113549.1.1.7) with a plain RSAPublicKey body
are now decoded as RSA keys. This is required for interoperability
with TPM 1.2 Endorsement Key certificates per TCG Credential Profiles
V1.2 section 3.2.7. The OAEP AlgorithmIdentifier parameters are not
@ -116,17 +64,6 @@ OpenSSL Releases
*Jakub Zelenka*
* Windows-on-Itanium (VC-WIN64I) support was dropped - the Itanium
architecture has been discontinued and the platform is no longer
supported or tested.
*Bob Beck*
* Windows CE support was dropped - Windows CE has been unsupported since
2018 and does not have a modern C99 toolchain.
*Bob Beck*
* Improved DTLS handshake robustness under UDP reordering by buffering and
replaying early ChangeCipherSpec (CCS) records at the expected state.
@ -141,14 +78,6 @@ OpenSSL Releases
*Bob Beck*
* `ASN1_STRING_set()` and `ASN1_STRING_length()` have been
deprecated. The replacement functions `ASN1_STRING_set_data()` or
`ASN1_STRING_set_string()`, and `ASN1_STRING_length_ex()` should be
used in their place. This prepares the ASN1_STRING type to support
modern size_t length values in the future.
*Bob Beck*
* `EVP_CIPHER_CTX_get_num()` and `EVP_CIPHER_CTX_set_num()' have been deprecated.
Refer to ossl-migration-guide(7) for more info.
@ -190,12 +119,6 @@ OpenSSL Releases
*Bob Beck*
* Fixed X.509 verification of certificate chains that use DSA signatures
with SHA-384 or SHA-512 by registering `dsa_with_SHA384` and
`dsa_with_SHA512` in the signature-algorithm cross-reference table.
*John Claus*
* Added AVX2 optimized ML-DSA NTT operations on `x86_64`.
*Marcel Cornu and Tomasz Kantecki*
@ -271,11 +194,6 @@ OpenSSL Releases
*Timo Keller*
* Added `EVP_KDF_CTX_get0_kdf()` and `EVP_KDF_CTX_get1_kdf()` functions
as a replacement for the now deprecated `EVP_KDF_CTX_kdf()`.
*Leon Timmermans*
* Add `FIPS_mode()` as a convenience define to
`EVP_default_properties_is_fips_enabled(NULL)`, which is
shorthand to check whether the `fips=yes` property is currently enabled
@ -1350,9 +1268,7 @@ OpenSSL 4.0
*Tomáš Mráz*
* Removed deprecated functions `ERR_get_state()`, `ERR_remove_state()`
and `ERR_remove_thread_state()`, as well as the `ERR_FLAG_MARK`,
`ERR_FLAG_CLEAR` and `ERR_NUM_ERRORS` macros. The `ERR_STATE` object is now
always opaque.
and `ERR_remove_thread_state()`. The `ERR_STATE` object is now always opaque.
<!-- https://github.com/openssl/openssl/pull/30005 -->
*Tomáš Mráz*
@ -4175,7 +4091,7 @@ breaking changes, and mappings for the large list of deprecated functions.
* Fixed a bug in the function `OCSP_basic_verify` that verifies the signer
certificate on an OCSP response. The bug caused the function in the case
where the (non-default) flag OCSP_NOCHECKS is used to return a positive
where the (non-default) flag OCSP_NOCHECKS is used to return a postivie
response (meaning a successful verification) even in the case where the
response signing certificate fails to verify.
@ -19973,7 +19889,7 @@ s-cbc 3624.96k 5258.21k 5530.91k 5624.30k 5628.26k
The new configuration file reading functions are:
NCONF_new, NCONF_free, NCONF_load, NCONF_load_fp, NCONF_load_bio,
NCONF_get_section, NCONF_get_string, NCONF_get_number
NCONF_get_section, NCONF_get_string, NCONF_get_numbre
NCONF_default, NCONF_WIN32

View file

@ -80,37 +80,7 @@ guidelines:
git push -f [<repository> [<branch>]]
```
2. Similarly, if a non-trivial portion of a contribution was created
using an AI tool, you must declare which agent and model were used.
This is done by adding `Assisted-by: {agent}:{model}` below the commit
message:
```
One-line summary of change with AI-generated portions
Assisted-by: Claude:claude-sonnet-4-6
```
Multiple Assisted-by trailers can be included if multiple tools were used:
```
Assisted-by: Claude:claude-sonnet-4-6
Assisted-by: ChatGPT:gpt-4o
Assisted-by: GitHub Copilot:gpt-4.1
```
You will need to have signed a v1.1 or later CLA in order to
include AI-generated content in your contribution. CLAs signed
after June 2026 will have the requisite clauses.
Consult the [OpenSSL AI Code and Documentation Contribution
Policy] if an AI model assisted with the creation of your
contribution.
[OpenSSL AI Code and Documentation Contribution
Policy]: <https://openssl-library.org/policies/general/ai-policy/>
3. All source files should start with the following text (with
2. All source files should start with the following text (with
appropriate comment characters at the start of each line and the
year(s) updated):
@ -123,14 +93,12 @@ guidelines:
https://www.openssl.org/source/license.html
```
4. Patches should be as current as possible; expect to have to rebase
3. Patches should be as current as possible; expect to have to rebase
often. We do not accept merge commits, you will have to remove them
(usually by rebasing) before it will be acceptable.
5. Code provided should follow our [coding style](STYLE.md) and
[documentation policy](DOCUMENTATION.md) and compile without warnings when
using a --strict-warnings configuration.
4. Code provided should follow our [coding style] and [documentation policy]
and compile without warnings.
Consistent formatting is enforced by using `clang-format` with configuration
stored in [.clang-format](.clang-format). OpenSSL uses `WebKit` style.
You can configure git pre-commit to automatically reformat your code with
@ -144,16 +112,19 @@ guidelines:
Clean builds via GitHub Actions are required. They are started automatically
whenever a PR is created or updated by committers.
6. When at all possible, code contributions should include tests. These can
[coding style]: https://openssl-library.org/policies/technical/coding-style/
[documentation policy]: https://openssl-library.org/policies/technical/documentation-policy/
5. When at all possible, code contributions should include tests. These can
either be added to an existing test, or completely new. Please see
[test/README.md](test/README.md) for information on the test framework.
7. New features or changed functionality must include
6. New features or changed functionality must include
documentation. Please look at the `.pod` files in `doc/man[1357]` for
examples of our style. Run `make doc-nits` to make sure that your
documentation changes are clean.
8. For user visible changes (API changes, behaviour changes, ...),
7. For user visible changes (API changes, behaviour changes, ...),
consider adding a note in [CHANGES.md](CHANGES.md).
This could be a summarising description of the change, and could
explain the grander details.
@ -164,10 +135,10 @@ guidelines:
with a specific release without having to sift through the higher
noise ratio in git-log.
9. Guidelines on how to integrate error output of new crypto library modules
8. Guidelines on how to integrate error output of new crypto library modules
can be found in [crypto/err/README.md](crypto/err/README.md).
10. Once your Pull Request gets to the stage of being reviewed fixup commits
9. Once your Pull Request gets to the stage of being reviewed fixup commits
should be used where possible. Fixup commits are squashed when the PR is
finally merged. Fixup commits are done in the following way:
@ -190,11 +161,11 @@ guidelines:
git log
```
11. If a Pull Request addresses an [issue](https://github.com/openssl/openssl/issues/)
10. If a Pull Request addresses an [issue](https://github.com/openssl/openssl/issues/)
the commit should include the line:
```
Fixes: LINK
Fixes #XXXXX
```
where LINK is the https link to the issue in github.
where XXXXX is the issue number.

View file

@ -61,6 +61,70 @@ sub vc_win32_info {
return $vc_win32_info;
}
my $vc_wince_info = {};
sub vc_wince_info {
unless (%$vc_wince_info) {
# sanity check
$die->('%OSVERSION% is not defined') if (!defined(env('OSVERSION')));
$die->('%PLATFORM% is not defined') if (!defined(env('PLATFORM')));
$die->('%TARGETCPU% is not defined') if (!defined(env('TARGETCPU')));
#
# Idea behind this is to mimic flags set by eVC++ IDE...
#
my $wcevers = env('OSVERSION'); # WCENNN
my $wcevernum;
my $wceverdotnum;
if ($wcevers =~ /^WCE([1-9])([0-9]{2})$/) {
$wcevernum = "$1$2";
$wceverdotnum = "$1.$2";
} else {
$die->('%OSVERSION% value is insane');
$wcevernum = "{unknown}";
$wceverdotnum = "{unknown}";
}
my $wcecdefs = "-D_WIN32_WCE=$wcevernum -DUNDER_CE=$wcevernum"; # -D_WIN32_WCE=NNN
my $wcelflag = "/subsystem:windowsce,$wceverdotnum"; # ...,N.NN
my $wceplatf = env('PLATFORM');
$wceplatf =~ tr/a-z0-9 /A-Z0-9_/;
$wcecdefs .= " -DWCE_PLATFORM_$wceplatf";
my $wcetgt = env('TARGETCPU'); # just shorter name...
SWITCH: for($wcetgt) {
/^X86/ && do { $wcecdefs.=" -Dx86 -D_X86_ -D_i386_ -Di_386_";
$wcelflag.=" /machine:X86"; last; };
/^ARMV4[IT]/ && do { $wcecdefs.=" -DARM -D_ARM_ -D$wcetgt";
$wcecdefs.=" -DTHUMB -D_THUMB_" if($wcetgt=~/T$/);
$wcecdefs.=" -QRarch4T -QRinterwork-return";
$wcelflag.=" /machine:THUMB"; last; };
/^ARM/ && do { $wcecdefs.=" -DARM -D_ARM_ -D$wcetgt";
$wcelflag.=" /machine:ARM"; last; };
/^MIPSIV/ && do { $wcecdefs.=" -DMIPS -D_MIPS_ -DR4000 -D$wcetgt";
$wcecdefs.=" -D_MIPS64 -QMmips4 -QMn32";
$wcelflag.=" /machine:MIPSFPU"; last; };
/^MIPS16/ && do { $wcecdefs.=" -DMIPS -D_MIPS_ -DR4000 -D$wcetgt";
$wcecdefs.=" -DMIPSII -QMmips16";
$wcelflag.=" /machine:MIPS16"; last; };
/^MIPSII/ && do { $wcecdefs.=" -DMIPS -D_MIPS_ -DR4000 -D$wcetgt";
$wcecdefs.=" -QMmips2";
$wcelflag.=" /machine:MIPS"; last; };
/^R4[0-9]{3}/ && do { $wcecdefs.=" -DMIPS -D_MIPS_ -DR4000";
$wcelflag.=" /machine:MIPS"; last; };
/^SH[0-9]/ && do { $wcecdefs.=" -D$wcetgt -D_${wcetgt}_ -DSHx";
$wcecdefs.=" -Qsh4" if ($wcetgt =~ /^SH4/);
$wcelflag.=" /machine:$wcetgt"; last; };
{ $wcecdefs.=" -D$wcetgt -D_${wcetgt}_";
$wcelflag.=" /machine:$wcetgt"; last; };
}
$vc_wince_info = { cppflags => $wcecdefs,
lflags => $wcelflag };
}
return $vc_wince_info;
}
# Helper functions for the VMS configs
my $vms_info = {};
sub vms_info {
@ -906,6 +970,7 @@ my %targets = (
perlasm_scheme => 'void',
},
"linux64-sparcv9" => {
# GCC 3.1 is a requirement
inherit_from => [ "linux-generic64" ],
cflags => add("-m64 -mcpu=ultrasparc"),
cxxflags => add("-m64 -mcpu=ultrasparc"),
@ -1434,7 +1499,7 @@ my %targets = (
#### Visual C targets
#
# Win64 target, WIN64A denotes AMD64
# Win64 targets, WIN64I denotes IA-64/Itanium and WIN64A - AMD64
#
# Note about /wd4090, disable warning C4090. This warning returns false
# positives in some situations. Disabling it altogether masks both
@ -1542,6 +1607,17 @@ my %targets = (
}),
bn_ops => add("SIXTY_FOUR_BIT"),
},
"VC-WIN64I" => {
inherit_from => [ "VC-WIN64-common" ],
AS => "ias",
ASFLAGS => "-d debug",
asoutflag => "-o ",
sys_id => "WIN64I",
uplink_arch => 'ia64',
asm_arch => 'ia64',
perlasm_scheme => "ias",
multilib => "-ia64",
},
"VC-WIN64A" => {
inherit_from => [ "VC-WIN64-common" ],
AS => sub { vc_win64a_info()->{AS} },
@ -1569,6 +1645,53 @@ my %targets = (
# some installation path heuristics in windows-makefile.tmpl...
build_scheme => add("VC-WOW", { separator => undef }),
},
"VC-CE" => {
inherit_from => [ "VC-common" ],
CFLAGS => add(picker(debug => "/Od",
release => "/O1i")),
CPPDEFINES => picker(debug => [ "DEBUG", "_DEBUG" ]),
LDFLAGS => add("/nologo /opt:ref"),
cflags =>
combine('/GF /Gy',
sub { vc_wince_info()->{cflags}; },
sub { `cl 2>&1` =~ /Version ([0-9]+)\./ && $1>=14
? ($disabled{shared} ? " /MT" : ($disabled{"static-vcruntime"} ? " /MD" : ""))
: " /MC"; }),
cppflags => sub { vc_wince_info()->{cppflags}; },
lib_defines => add("NO_CHMOD", "OPENSSL_SMALL_FOOTPRINT"),
lib_cppflags => sub { vc_wince_info()->{cppflags}; },
includes =>
add(combine(sub { defined(env('WCECOMPAT'))
? '$(WCECOMPAT)/include' : (); },
sub { defined(env('PORTSDK_LIBPATH'))
? '$(PORTSDK_LIBPATH)/../../include'
: (); })),
lflags => add(combine(sub { vc_wince_info()->{lflags}; },
sub { defined(env('PORTSDK_LIBPATH'))
? "/entry:mainCRTstartup" : (); })),
sys_id => "WINCE",
bn_ops => add("BN_LLONG"),
ex_libs => add(sub {
my @ex_libs = ();
push @ex_libs, 'ws2.lib' unless $disabled{sock};
push @ex_libs, 'crypt32.lib';
if (defined(env('WCECOMPAT'))) {
my $x = '$(WCECOMPAT)/lib';
if (-f "$x/env('TARGETCPU')/wcecompatex.lib") {
$x .= '/$(TARGETCPU)/wcecompatex.lib';
} else {
$x .= '/wcecompatex.lib';
}
push @ex_libs, $x;
}
push @ex_libs, '$(PORTSDK_LIBPATH)/portlib.lib'
if (defined(env('PORTSDK_LIBPATH')));
push @ex_libs, '/nodefaultlib coredll.lib corelibc.lib'
if (env('TARGETCPU') =~ /^X86|^ARMV4[IT]/);
return join(" ", @ex_libs);
}),
},
#### MinGW
"mingw-common" => {
inherit_from => [ 'BASE_unix' ],
@ -1580,7 +1703,7 @@ my %targets = (
cppflags => combine("-DUNICODE -D_UNICODE -DWIN32_LEAN_AND_MEAN",
threads("-D_MT")),
lib_cppflags => "-DL_ENDIAN",
ex_libs => add("-lws2_32 -lgdi32 -lcrypt32 -lbcrypt"),
ex_libs => add("-lws2_32 -lgdi32 -lcrypt32"),
thread_scheme => "winthreads",
dso_scheme => "win32",
shared_target => "mingw-shared",

View file

@ -11,7 +11,6 @@
our $makedepcmd = platform->makedepcmd();
sub windowsdll { $config{target} =~ /^(?:Cygwin|mingw)/ }
sub run_on_windows { $^O =~ /^(?:cygwin|msys|MSWin32)/ }
# Shared AIX support is special. We put libcrypto[64].so.ver into
# libcrypto.a and use libcrypto_a.a as static one, unless using
@ -504,9 +503,6 @@ BIN_LDFLAGS={- join(' ', $target{bin_lflags} || (),
'$(CNF_LDFLAGS)', '$(LDFLAGS)') -}
BIN_EX_LIBS=$(CNF_EX_LIBS) $(EX_LIBS)
CMOCKA_LIBS={- $config{cmocka_libs} // '' -}
DETOURS_LIBS={- $config{detours_libs} // '' -}
# CPPFLAGS_Q is used for one thing only: to build up buildinf.h
CPPFLAGS_Q={- $cppflags1 =~ s|([\\"])|\\$1|g;
$cppflags2 =~ s|([\\"])|\\$1|g;
@ -660,8 +656,8 @@ clean: libclean ## Clean the workspace, keep the configuration
-o -path './python-ecdsa' \
-o -path './tlsfuzzer' \
-o -path './tlslite-ng' \
-o -path './wycheproof' \) \
-prune \
-o -path './wycheproof' \
-prune \) \
-o \! -type d \
\( -name '*{- platform->depext() -}' \
-o -name '*{- platform->objext() -}' \
@ -1583,24 +1579,12 @@ EOF
my $section = $1;
my $name = uc basename($args{src}, ".$section");
my $pod = $gen0;
if ($config{manpage_format} eq "mdoc") {
return <<"EOF";
$args{src}: $pod
pod2mdoc -n $name -s $section\$(MANSUFFIX) \\
-d \$(RELEASE_DATE) \\
$pod >\$\@
EOF
} elsif ($config{manpage_format} eq "roff") {
return <<"EOF";
return <<"EOF";
$args{src}: $pod
pod2man --name=$name --section=$section\$(MANSUFFIX) --center=OpenSSL \\
--date=\$(RELEASE_DATE) --release=\$(VERSION) \\
$pod >\$\@
EOF
} else {
die "Unhandled manpage format: $config{manpage_format}";
}
} elsif (platform->isdef($args{src})) {
#
# Linker script-ish generator
@ -1911,27 +1895,13 @@ $import: $full
EOF
}
}
if (!run_on_windows()) {
$recipe .= <<"EOF";
$recipe .= <<"EOF";
$full: $fulldeps
\$(CC) \$(LIB_CFLAGS) $linkflags\$(LIB_LDFLAGS)$shared_soname$shared_imp \\
-o $full$shared_def \\
$fullobjs \\
$linklibs \$(LIB_EX_LIBS)
EOF
} else {
$recipe .= <<"EOF";
$full: $fulldeps
\$(file >\$@.lst, \\
$fullobjs \\
)
\$(CC) \$(LIB_CFLAGS) $linkflags\$(LIB_LDFLAGS)$shared_soname$shared_imp \\
-o $full$shared_def \\
@\$@.lst \\
$linklibs \$(LIB_EX_LIBS)
rm -f \$@.lst
EOF
}
if (windowsdll()) {
$recipe .= <<"EOF";
rm -f apps/$full
@ -2036,15 +2006,6 @@ EOF
push @linkdirs, $d unless grep { $d eq $_ } @linkdirs;
}
}
my $wrapflags = '';
if (defined $unified_info{wraps}->{$args{bin}}) {
$wrapflags = ' ' . join(' ',
map { "-Wl,--wrap=$_" }
@{$unified_info{wraps}->{$args{bin}}});
}
my $utlibs = $unified_info{unit_test_libs}->{$args{bin}};
$utlibs = $utlibs ne '' ? ' ' . $utlibs : '' if defined $utlibs;
$utlibs //= '';
my $linkflags = join("", map { $_." " } @linkdirs);
my $linklibs = join("", map { $_." " } @linklibs);
my $cmd = '$(CC)';
@ -2062,10 +2023,10 @@ EOF
return <<"EOF";
$bin: $deps
rm -f $bin
\$\${LDCMD:-$cmd} $cmdflags $linkflags\$(BIN_LDFLAGS)$wrapflags \\
\$\${LDCMD:-$cmd} $cmdflags $linkflags\$(BIN_LDFLAGS) \\
-o $bin \\
$objs \\
$linklibs\$(BIN_EX_LIBS)$utlibs
$linklibs\$(BIN_EX_LIBS)
EOF
}
sub in2script {

View file

@ -380,9 +380,6 @@ BIN_LDFLAGS={- join(' ', $target{bin_lflags} || (),
'$(CNF_LDFLAGS)', '$(LDFLAGS)') -}
BIN_EX_LIBS=$(CNF_EX_LIBS) $(EX_LIBS)
CMOCKA_LIBS={- $config{cmocka_libs} // '' -}
DETOURS_LIBS={- $config{detours_libs} // '' -}
# CPPFLAGS_Q is used for one thing only: to build up buildinf.h
CPPFLAGS_Q={- $cppflags1 =~ s|([\\"])|\\$1|g;
$cppflags2 =~ s|([\\"])|\\$1|g;
@ -1004,14 +1001,11 @@ EOF
my $ress = join($target{ld_resp_delim}, @ress);
my $linklibs = join("", map { "$_$target{ld_resp_delim}" } @deps);
my $deps = join(" ", @objs, @ress, @deps);
my $utlibs = $unified_info{unit_test_libs}->{$args{bin}};
$utlibs = (defined $utlibs && $utlibs ne '')
? "$utlibs$target{ld_resp_delim}" : '';
return <<"EOF";
$bin: $deps
IF EXIST $bin.manifest DEL /F /Q $bin.manifest
\$(LD) \$(LDFLAGS) \$(BIN_LDFLAGS) @<<
$objs$target{ld_resp_delim}\$(LDOUTFLAG)$bin$target{ldpostoutflag}$target{ld_resp_delim}$utlibs$linklibs\$(BIN_EX_LIBS)$target{ldresflag}$target{ldresflag}$ress
$objs$target{ld_resp_delim}\$(LDOUTFLAG)$bin$target{ldpostoutflag}$target{ld_resp_delim}$linklibs\$(BIN_EX_LIBS)$target{ldresflag}$target{ldresflag}$ress
<<
IF EXIST $bin.manifest \\
\$(MT) \$(MTFLAGS) \$(MTINFLAG)$bin.manifest \$(MTOUTFLAG)$bin

111
Configure
View file

@ -27,7 +27,7 @@ use OpenSSL::config;
my $orig_death_handler = $SIG{__DIE__};
$SIG{__DIE__} = \&death_handler;
my $usage="Usage: Configure [no-<feature> ...] [enable-<feature> ...] [-Dxxx] [-lxxx] [-Lxxx] [-fxxx] [-Kxxx] [no-hw-xxx|no-hw] [[no-]threads] [[no-]thread-pool] [[no-]default-thread-pool] [[no-]shared] [[no-]zlib|zlib-dynamic] [no-asm] [no-egd] [sctp] [386] [--prefix=DIR] [--openssldir=OPENSSLDIR] [--with-xxx[=vvv]] [--config=FILE] [--manpage-format={roff,mdoc}] [--help] os/compiler[:flags]\n";
my $usage="Usage: Configure [no-<feature> ...] [enable-<feature> ...] [-Dxxx] [-lxxx] [-Lxxx] [-fxxx] [-Kxxx] [no-hw-xxx|no-hw] [[no-]threads] [[no-]thread-pool] [[no-]default-thread-pool] [[no-]shared] [[no-]zlib|zlib-dynamic] [no-asm] [no-egd] [sctp] [386] [--prefix=DIR] [--openssldir=OPENSSLDIR] [--with-xxx[=vvv]] [--config=FILE] [--help] os/compiler[:flags]\n";
my $banner = <<"EOF";
@ -295,7 +295,6 @@ my $dofile = abs2rel(catfile($srcdir, "util/dofile.pl"));
my $local_config_envname = 'OPENSSL_LOCAL_CONFIG_DIR';
$config{manpage_format} = "roff";
$config{sourcedir} = abs2rel($srcdir, $blddir);
$config{builddir} = abs2rel($blddir, $blddir);
# echo -n 'holy hand grenade of antioch' | openssl sha256
@ -578,7 +577,6 @@ my @disablables_features = (
"ubsan",
"ui-console",
"unit-test",
"unit-tests",
"uplink",
"weak-ssl-ciphers",
"zlib-dynamic",
@ -656,7 +654,6 @@ our %disabled = ( # "what" => "comment"
"trace" => "default",
"ubsan" => "default",
"unit-test" => "default",
"unit-tests" => "default",
"weak-ssl-ciphers" => "default",
"zlib" => "default",
"zlib-dynamic" => "default",
@ -726,7 +723,7 @@ my @disable_cascades = (
"stdio" => [ "apps", "egd" ],
"apps" => [ "tests" ],
"tests" => [ "external-tests", "unit-tests" ],
"tests" => [ "external-tests" ],
"comp" => [ "zlib", "brotli", "zstd" ],
"sm3" => [ "sm2" ],
sub { !$disabled{"unit-test"} } => [ "heartbeats" ],
@ -1045,10 +1042,6 @@ while (@argvcopy)
{
$config{build_type} = "release";
}
elsif (/^--manpage-format=(mdoc|roff)$/)
{
$config{manpage_format}="$1";
}
elsif (/^--pgo$/)
{
$config{build_type} = "pgo";
@ -1122,22 +1115,6 @@ while (@argvcopy)
{
$withargs{fuzzer_include}=$1;
}
elsif (/^--with-cmocka-lib=(.*)$/)
{
$withargs{cmocka_lib}=$1;
}
elsif (/^--with-cmocka-include=(.*)$/)
{
$withargs{cmocka_include}=$1;
}
elsif (/^--with-detours-lib=(.*)$/)
{
$withargs{detours_lib}=$1;
}
elsif (/^--with-detours-include=(.*)$/)
{
$withargs{detours_include}=$1;
}
elsif (/^--with-rand-seed=(.*)$/)
{
foreach my $x (split(m|,|, $1))
@ -1694,13 +1671,8 @@ unless ($disabled{asan} || defined $detected_sanitizers{asan}) {
$config{target} =~ /^VC-/ ? "/fsanitize=address" : "-fsanitize=address";
}
my %predefined_C = compiler_predefined($config{CROSS_COMPILE}.$config{CC});
unless ($disabled{ubsan} || defined $detected_sanitizers{ubsan}) {
push @{$config{cflags}}, "-fsanitize=undefined", "-fno-sanitize-recover=all", "-DPEDANTIC";
if ($predefined_C{__clang__}) {
push @{$config{cflags}}, "-fno-sanitize=function";
}
}
unless ($disabled{msan} || defined $detected_sanitizers{msan}) {
@ -1780,6 +1752,7 @@ if ($target{sys_id} ne "")
push @{$config{openssl_sys_defines}}, "OPENSSL_SYS_$target{sys_id}";
}
my %predefined_C = compiler_predefined($config{CROSS_COMPILE}.$config{CC});
my %predefined_CXX = $config{CXX}
? compiler_predefined($config{CROSS_COMPILE}.$config{CXX})
: ();
@ -1940,29 +1913,6 @@ unless ($disabled{winstore}) {
push @{$config{openssl_other_defines}}, "OPENSSL_NO_KTLS" if ($disabled{ktls});
# Keywords accepted in a build.info UNIT_TEST[] link set.
my @unit_test_keywords = qw(cmocka detours);
unless ($disabled{"unit-tests"}) {
if ($target =~ /^linux/ || $target =~ /^BSD/) {
$config{cmocka_includes} =
$withargs{cmocka_include} ? [$withargs{cmocka_include}] : [];
$config{cmocka_libs} = $withargs{cmocka_lib}
? "-L$withargs{cmocka_lib} -lcmocka" : "-lcmocka";
} elsif ($target =~ /^VC-/) {
$config{cmocka_includes} =
$withargs{cmocka_include} ? [$withargs{cmocka_include}] : [];
$config{cmocka_libs} = $withargs{cmocka_lib}
? "/LIBPATH:$withargs{cmocka_lib} cmocka.lib" : "cmocka.lib";
$config{detours_includes} =
$withargs{detours_include} ? [$withargs{detours_include}] : [];
$config{detours_libs} = $withargs{detours_lib}
? "/LIBPATH:$withargs{detours_lib} detours.lib" : "detours.lib";
} else {
disable('no-unit-test-support', 'unit-tests');
}
}
# Get the extra flags used when building shared libraries and modules. We
# do this late because some of them depend on %disabled.
@ -2187,8 +2137,6 @@ if ($builder eq "unified") {
my %includes = ();
my %defines = ();
my %depends = ();
my %unit_tests = ();
my %wraps = ();
my %generate = ();
my %imagedocs = ();
my %htmldocs = ();
@ -2444,16 +2392,6 @@ if ($builder eq "unified") {
\$attributes{depends}, $+{ATTRIBS},
tokenize($expand_variables->($+{VALUE})))
if !@skip || $skip[$#skip] > 0; },
qr/^\s* UNIT_TEST ${index_re} \s* = \s* ${value_re} \s* $/x
=> sub { $push_to->(\%unit_tests, $expand_variables->($+{INDEX}),
undef, undef,
tokenize($expand_variables->($+{VALUE})))
if !@skip || $skip[$#skip] > 0; },
qr/^\s* WRAP ${index_re} \s* = \s* ${value_re} \s* $/x
=> sub { $push_to->(\%wraps, $expand_variables->($+{INDEX}),
undef, undef,
tokenize($expand_variables->($+{VALUE})))
if !@skip || $skip[$#skip] > 0; },
qr/^\s* GENERATE ${index_re} ${attribs_re} \s* = \s* ${value_re} \s* $/x
=> sub { $push_to->(\%generate, $expand_variables->($+{INDEX}),
\$attributes{generate}, $+{ATTRIBS},
@ -2740,27 +2678,6 @@ if ($builder eq "unified") {
}
}
foreach my $dest (keys %wraps) {
my $ddest = cleanfile($buildd, $dest, $blddir);
foreach my $fn (@{$wraps{$dest}}) {
push @{$unified_info{wraps}->{$ddest}}, $fn;
}
}
foreach my $dest (keys %unit_tests) {
my $ddest = cleanfile($buildd, $dest, $blddir);
foreach my $kw (@{$unit_tests{$dest}}) {
die "***** Unknown keyword '$kw' in UNIT_TEST[$dest] at $sourced/$f\n"
unless grep { $_ eq $kw } @unit_test_keywords;
}
$unified_info{unit_tests}->{$ddest} =
[ @{$unit_tests{$dest}} ];
}
# WRAP implies cmocka unless an explicit UNIT_TEST set was given
foreach my $dest (keys %{$unified_info{wraps} // {}}) {
$unified_info{unit_tests}->{$dest} //= [ "cmocka" ];
}
foreach my $section (keys %imagedocs) {
foreach (@{$imagedocs{$section}}) {
my $imagedocs = cleanfile($buildd, $_, $blddir);
@ -3093,28 +3010,6 @@ EOF
}
}
# Attach cmocka (and, on Windows, Detours) include paths to unit tests,
# based on each test's UNIT_TEST[] link set.
if (!$disabled{"unit-tests"}) {
while (my ($dest, $libs) = each %{$unified_info{unit_tests} // {}}) {
my %want = map { $_ => 1 } @$libs;
push @{$unified_info{includes}->{$dest}}, @{$config{cmocka_includes}}
if $want{cmocka} && @{$config{cmocka_includes} // []};
push @{$unified_info{includes}->{$dest}}, @{$config{detours_includes}}
if $want{detours} && @{$config{detours_includes} // []};
}
}
if (!$disabled{"unit-tests"}) {
foreach my $dest (sort keys %{$unified_info{unit_tests} // {}}) {
my %want = map { $_ => 1 } @{$unified_info{unit_tests}->{$dest}};
my @resolved;
push @resolved, '$(CMOCKA_LIBS)' if $want{cmocka} && $config{cmocka_libs};
push @resolved, '$(DETOURS_LIBS)' if $want{detours} && $config{detours_libs};
$unified_info{unit_test_libs}->{$dest} = join(' ', @resolved);
}
}
# For the schemes that need it, we provide the old *_obj configs
# from the *_asm_obj ones
foreach (grep /_(asm|aux)_src$/, keys %target) {

View file

@ -1,194 +0,0 @@
OpenSSL Documentation Policy
============================
This document describes the code documentation and commenting requirements
for the OpenSSL project.
The project's documentation is about making the libraries and tools more
accessible to our users and making the code more maintainable. This policy
applies to new submissions; existing code does not uniformly conform to it
and will be brought up to standard gradually.
Any non-trivial change to existing code must bring the affected code into
conformance with this policy as part of the same change. In particular,
renaming or relocating functions, changes to public APIs, and any change
that would render an existing POD page or in-source comment inaccurate
require the corresponding documentation to be updated. This includes
adding documentation that was previously absent where the change brings
the affected code within the scope of this policy.
The form and style of code comments themselves -- comment markers, layout,
the use of `/**` and `/*-` blocks, doxygen markup, the structure of the
sample multi-line comment, and similar -- are described in
[STYLE.md](STYLE.md). This file describes what *must* be documented and
where; [STYLE.md](STYLE.md) describes how code comments look.
Command line commands and arguments
-----------------------------------
All new commands, as well as new or modified arguments to existing
commands, must be documented in the `doc/man1` directory. This
documentation is in POD format.
Public symbols in the libraries
-------------------------------
All new public symbols must be documented in a POD manual page in the
`doc/man3` directory. This includes types, macros, and functions.
The allowed exceptions are:
- guard macros preventing a header file being included twice
- new symbols generated automatically via `make update` (errors, objects, etc.)
Each public function's declaration in its public header must carry a
doxygen comment block. The block's `@see` must include the function's
own manual page (`name(3)`) and may include additional manual pages
that a caller needs to use the function correctly. The doxygen block
is a navigation aid pointing to the canonical reference documentation
in the corresponding POD file; see [STYLE.md](STYLE.md) for the
doxygen form.
Overviews, conventions, et al
-----------------------------
Where additional user-facing information is required, it should be
included in the `doc/man7` section. This includes, but is not limited to:
- algorithm descriptions and parameters
- architectural and subsystem overviews
- user guides and tutorials
- conventions and reference material (environment variables, glossary,
threading rules, file format conventions)
Internal functions, structures, globals and macros
--------------------------------------------------
Internal functions, structures, globals and macros are non-public
items declared in any header that is not part of the public API.
These include items declared in:
- `include/internal/` (shared across subsystems);
- `include/crypto/` (cryptographic internals);
- per-directory local headers (for example, `crypto/asn1/asn1_local.h`)
shared between source files in a single subdirectory.
These should all be documented at the declaration site -- that is,
in the header that declares them -- using a doxygen-style comment
block. For functions, this places the comment at the prototype,
where editor tooling (clangd and similar) can surface it to readers
at every call site. The comment should describe the purpose and,
for functions, the input and output arguments and the return value.
See [STYLE.md](STYLE.md) for the doxygen conventions used by OpenSSL.
For *trivial* items, where their operation is obvious from their
implementation, the documentation requirement is not mandated. The
following are generally representative of trivial items, however it is
quite possible for any of these to be non-trivial in specific instances
and therefore require documentation:
- `OSSL_DISPATCH` tables
- upref functions
- free functions
- simple getter/setter functions
- wrappers for other functions (a function that calls a more recent
`_ex` variant or a group of functions that call a common internal
routine)
For structures, each of the fields should be commented stating its
purpose. Again, a *trivial* exception applies where the purpose is
obvious. Some representative examples:
- `OSSL_LIB_CTX *ctx;` where there is only one library context referenced
in the structure.
- `struct *next;` in a linked list implementation.
- `CRYPTO_REF_COUNT refcnt;`
File-local items
----------------
These are functions, structures, globals, and macros that are local
to a single C file: `static` functions, file-scope variables,
structures, and macros defined inside a `.c` file with no declaration
in any header.
These should all be documented at the point of definition. Follow the
same rules and exceptions as for internal items above. In some cases
slightly more leniency with respect to *trivial* can be tolerated.
Code comments
-------------
The form, style, and content guidance for code comments are described in
[STYLE.md](STYLE.md). Comments are required at the points described in
the internal and static sections above, subject to the *trivial*
exception, and at the additional points described in
[STYLE.md](STYLE.md).
Assembly code
-------------
Assembly code should include a good description of the algorithm and
approach being used. This should be followed by a performance comparison
and then the assembly code itself. The assembly code should be well
commented, but it is not necessary to comment every line. A comment
describing each block of code suffices.
For pure-assembly modules (`.s` files and the perlasm scripts that
generate them), comments use the native syntax of the assembler or
generator (typically `#`). Doxygen-style markup does not apply here;
the algorithm description, performance comparison, and per-block
comments described above are still required.
For assembly that appears inline inside a C file (within an `asm()`
statement, for example), the surrounding C function is documented
with doxygen-style C comments as for any other C code; see
[STYLE.md](STYLE.md). Comments inside the `asm()` body itself use
plain C `/* */` comments.
There are no *trivial* exceptions for assembly code.
Configure options
-----------------
New options added to the configuration scripts must be documented in the
[INSTALL.md](INSTALL.md) file.
Changes and news
----------------
Significant modifications should be documented in the
[CHANGES.md](CHANGES.md) file.
Very significant features and changes should be documented in the
[NEWS.md](NEWS.md) file.
In both cases, the added note should be short and to the point, and
should be written for users of the library, focusing on impact rather
than implementation details.
Automated sanity checking
-------------------------
The `make doc-nits` command should be run before submitting a pull
request and any problems it locates must be addressed.
Language
--------
The language used for documentation shall be *British English*.
In general the language, abbreviations, layout and formatting should also
correspond to the
[LDP](https://openssl-library.org/policies/general/glossary/#ldp)
guidelines.
Common sense
------------
Comments and documentation are to improve readability and comprehension.
Where the code is obvious, there is no need to include a comment.
However, common sense applies: always err in favour of including more
comments than less or none. Code that you have just written that is
*obvious* will not necessarily be to someone else two years later. See
[STYLE.md](STYLE.md) for the form and content of code comments.

View file

@ -169,11 +169,13 @@ issue the following commands to build OpenSSL.
$ nmake test
As mentioned in the [Choices](#choices) section, you need to pick one
of the Configure targets in the first command.
of the four Configure targets in the first command.
Most likely you will be using the `VC-WIN64A`/`VC-WIN64A-HYBRIDCRT` target for
64bit Windows binaries (AMD64) or `VC-WIN32`/`VC-WIN32-HYBRIDCRT` for 32bit
Windows binaries (X86).
The other two options are `VC-WIN64I` (Intel IA64, Itanium) and
`VC-CE` (Windows CE) are rather uncommon nowadays.
Installing OpenSSL
------------------
@ -426,22 +428,6 @@ The names of the libraries are:
* brotlidec.lib
* brotlienc.lib
### with-cmocka-include
--with-cmocka-include=DIR
The directory for the location of the cmocka include file. This option is only
necessary if [enable-unit-tests](#enable-unit-tests) is used and the include
file is not already on the system include path.
### with-cmocka-lib
--with-cmocka-lib=DIR
The directory containing the cmocka library. This option is only necessary if
[enable-unit-tests](#enable-unit-tests) is used and the library is not already
on the system library path.
### with-zlib-include
--with-zlib-include=DIR
@ -832,12 +818,6 @@ external test suites are currently supported:
See the file [test/README-external.md](test/README-external.md)
for further details.
### enable-unit-tests
Enable building and running unit tests.
This works only on platforms supporting ld `--wrap` option like Linux and BSD.
### no-filenames
Don't compile in filename and line number information (e.g. for errors and
@ -1115,12 +1095,10 @@ The User Interface console method enables text based console prompts.
### enable-unit-test
Enable exposing SSL_test_functions for overwriting ssl_init_wbio_buffer.
Enable additional unit test APIs.
This should not typically be used in production deployments.
This option is deprecated and will be removed in OpenSSL 5.0.
### no-uplink
Don't build support for UPLINK interface.
@ -1223,8 +1201,7 @@ Build without support for the specified algorithm.
The `ripemd` algorithm is deprecated and if used is synonymous with `rmd160`.
Compiler-specific options
-------------------------
### Compiler-specific options
-Dxxx, -Ixxx, -Wp, -lxxx, -Lxxx, -Wl, -rpath, -R, -framework, -static
@ -1255,17 +1232,7 @@ encoding.
Take note of the [Environment Variables](#environment-variables) documentation
below and how these flags interact with those variables.
Miscellaneous options
---------------------
### --manpage-format
Specify a specific output manpage format. The supported output types are mandoc
and *roff. The *roff output format is the default for legacy and portability
reasons.
Environment Variables
---------------------
### Environment Variables
VAR=value
@ -1342,18 +1309,10 @@ If `CC` is set, it is advisable to also set `CXX` to ensure both the C and C++
compiler are in the same "family". This becomes relevant with
`enable-external-tests` and `enable-buildtest-c++`.
Reconfigure
-----------
### Reconfigure
### Make targets
`$ make reconf`
or
`$ make reconfigure`
### Description
reconf
reconfigure
Reconfigure from earlier data.
@ -1971,8 +1930,9 @@ on Cygwin, shared libraries are named `cygcrypto-1.1.dll` and `cygssl-1.1.dll`
with import libraries `libcrypto.dll.a` and `libssl.dll.a`.
On Windows build with MSVC or using MingW, shared libraries are named
`libcrypto-1_1.dll` and `libssl-1_1.dll` for 32-bit Windows, and
`libcrypto-1_1-x64.dll` and `libssl-1_1-x64.dll` for 64-bit x86_64 Windows.
`libcrypto-1_1.dll` and `libssl-1_1.dll` for 32-bit Windows,
`libcrypto-1_1-x64.dll` and `libssl-1_1-x64.dll` for 64-bit x86_64 Windows,
and `libcrypto-1_1-ia64.dll` and `libssl-1_1-ia64.dll` for IA64 Windows.
With MSVC, the import libraries are named `libcrypto.lib` and `libssl.lib`,
while with MingW, they are named `libcrypto.dll.a` and `libssl.dll.a`.

View file

@ -31,8 +31,6 @@ OpenSSL 4.1
* API calls `CRYPTO_atomic_load_ptr`, `CRYPTO_atomic_store_ptr`, and
`CRYPTO_atomic_cmp_exch_ptr` have been added.
* Fixed verification of DSA certificates signed with SHA-384 or SHA-512.
OpenSSL 4.0
-----------

View file

@ -49,7 +49,7 @@ The OpenSSL toolkit includes:
basis of the TLS implementation, but can also be used independently.
- **openssl**
the OpenSSL command line tool, a Swiss Army knife for cryptographic tasks,
the OpenSSL command line tool, a swiss army knife for cryptographic tasks,
testing and analyzing. It can be used for
- creation of key parameters
- creation of X.509 certificates, CSRs and CRLs
@ -150,10 +150,11 @@ The manual pages for the master branch and all current stable releases are
available online.
- [OpenSSL master](https://docs.openssl.org/master/)
- [OpenSSL 4.0](https://docs.openssl.org/4.0/)
- [OpenSSL 3.6](https://docs.openssl.org/3.6/)
- [OpenSSL 3.5](https://docs.openssl.org/3.5/)
- [OpenSSL 3.4](https://docs.openssl.org/3.4/)
- [OpenSSL 3.3](https://docs.openssl.org/3.3/)
- [OpenSSL 3.2](https://docs.openssl.org/3.2/)
- [OpenSSL 3.0](https://docs.openssl.org/3.0/)
Demos

1133
STYLE.md

File diff suppressed because it is too large Load diff

View file

@ -82,8 +82,7 @@ int asn1parse_main(int argc, char **argv)
const unsigned char *ctmpbuf;
int indent = 0, noout = 0, dump = 0, informat = FORMAT_PEM;
int offset = 0, ret = 1, i, j;
long num;
size_t tmplen;
long num, tmplen;
const unsigned char *tmpbuf;
unsigned int length = 0;
OPTION_CHOICE o;
@ -242,12 +241,12 @@ int asn1parse_main(int argc, char **argv)
if (sk_OPENSSL_STRING_num(osk)) {
tmpbuf = str;
tmplen = (size_t)num;
tmplen = num;
for (i = 0; i < sk_OPENSSL_STRING_num(osk); i++) {
ASN1_TYPE *atmp;
int typ;
j = strtol(sk_OPENSSL_STRING_value(osk, i), NULL, 0);
if (j <= 0 || (size_t)j >= tmplen) {
if (j <= 0 || j >= tmplen) {
BIO_printf(bio_err, "'%s' is out of range\n",
sk_OPENSSL_STRING_value(osk, i));
continue;
@ -256,7 +255,7 @@ int asn1parse_main(int argc, char **argv)
tmplen -= j;
atmp = at;
ctmpbuf = tmpbuf;
at = d2i_ASN1_TYPE(NULL, &ctmpbuf, (long)tmplen);
at = d2i_ASN1_TYPE(NULL, &ctmpbuf, tmplen);
ASN1_TYPE_free(atmp);
if (!at) {
BIO_puts(bio_err, "Error parsing structure\n");
@ -273,16 +272,11 @@ int asn1parse_main(int argc, char **argv)
}
/* hmm... this is a little evil but it works */
tmpbuf = ASN1_STRING_get0_data(at->value.asn1_string);
tmplen = ASN1_STRING_length_ex(at->value.asn1_string);
if (tmplen > INT_MAX) {
BIO_puts(bio_err, "ASN.1 string length exceeds INT_MAX\n");
ERR_print_errors(bio_err);
goto end;
}
tmplen = ASN1_STRING_length(at->value.asn1_string);
}
/* XXX casts away const */
str = (unsigned char *)tmpbuf;
num = (int)tmplen;
num = tmplen;
}
if (offset < 0 || offset >= num) {

View file

@ -1077,8 +1077,8 @@ end_of_options:
X509 *xi = sk_X509_value(cert_sk, i);
const ASN1_INTEGER *serialNumber = X509_get0_serialNumber(xi);
const unsigned char *psn = ASN1_STRING_get0_data(serialNumber);
const size_t snl = ASN1_STRING_length_ex(serialNumber);
const size_t filen_len = 2 * (snl > 0 ? snl : 1) + sizeof(".pem");
const int snl = ASN1_STRING_length(serialNumber);
const int filen_len = 2 * (snl > 0 ? snl : 1) + sizeof(".pem");
char *n = new_cert + outdirlen;
if (outdirlen + filen_len > PATH_MAX) {
@ -1089,7 +1089,7 @@ end_of_options:
if (snl > 0) {
static const char HEX_DIGITS[] = "0123456789ABCDEF";
for (j = 0; (size_t)j < snl; j++, psn++) {
for (j = 0; j < snl; j++, psn++) {
*n++ = HEX_DIGITS[*psn >> 4];
*n++ = HEX_DIGITS[*psn & 0x0F];
}
@ -1523,10 +1523,8 @@ static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509,
goto end;
}
if (type != V_ASN1_BMPSTRING && type != V_ASN1_UTF8STRING) {
size_t tmp = ASN1_STRING_length_ex(str);
if (tmp > INT_MAX)
goto end;
j = ASN1_PRINTABLE_type(ASN1_STRING_get0_data(str), (int)tmp);
j = ASN1_PRINTABLE_type(ASN1_STRING_get0_data(str),
ASN1_STRING_length(str));
if ((j == V_ASN1_T61STRING && type != V_ASN1_T61STRING)
|| (j == V_ASN1_IA5STRING && type == V_ASN1_PRINTABLESTRING)) {
BIO_puts(bio_err,
@ -1903,9 +1901,9 @@ static int do_body(X509 **xret, EVP_PKEY *pkey, X509 *x509,
/* We now just add it to the database as DB_TYPE_VAL('V') */
row[DB_type] = OPENSSL_strdup("V");
tm = X509_get0_notAfter(ret);
row[DB_exp_date] = app_malloc(ASN1_STRING_length_ex(tm) + 1, "row expdate");
memcpy(row[DB_exp_date], ASN1_STRING_get0_data(tm), ASN1_STRING_length_ex(tm));
row[DB_exp_date][ASN1_STRING_length_ex(tm)] = '\0';
row[DB_exp_date] = app_malloc(ASN1_STRING_length(tm) + 1, "row expdate");
memcpy(row[DB_exp_date], ASN1_STRING_get0_data(tm), ASN1_STRING_length(tm));
row[DB_exp_date][ASN1_STRING_length(tm)] = '\0';
row[DB_rev_date] = NULL;
row[DB_file] = OPENSSL_strdup("unknown");
if ((row[DB_type] == NULL) || (row[DB_file] == NULL)
@ -2139,9 +2137,9 @@ static int do_revoke(X509 *x509, CA_DB *db, REVINFO_TYPE rev_type,
/* We now just add it to the database as DB_TYPE_REV('V') */
row[DB_type] = OPENSSL_strdup("V");
tm = X509_get0_notAfter(x509);
row[DB_exp_date] = app_malloc(ASN1_STRING_length_ex(tm) + 1, "row exp_data");
memcpy(row[DB_exp_date], ASN1_STRING_get0_data(tm), ASN1_STRING_length_ex(tm));
row[DB_exp_date][ASN1_STRING_length_ex(tm)] = '\0';
row[DB_exp_date] = app_malloc(ASN1_STRING_length(tm) + 1, "row exp_data");
memcpy(row[DB_exp_date], ASN1_STRING_get0_data(tm), ASN1_STRING_length(tm));
row[DB_exp_date][ASN1_STRING_length(tm)] = '\0';
row[DB_rev_date] = NULL;
row[DB_file] = OPENSSL_strdup("unknown");
@ -2352,7 +2350,7 @@ static char *make_revocation_str(REVINFO_TYPE rev_type, const char *rev_arg)
const char *reason = NULL, *other = NULL;
ASN1_OBJECT *otmp;
ASN1_UTCTIME *revtm = NULL;
size_t i;
int i;
switch (rev_type) {
case REV_NONE:
@ -2409,12 +2407,12 @@ static char *make_revocation_str(REVINFO_TYPE rev_type, const char *rev_arg)
if (!revtm)
return NULL;
i = ASN1_STRING_length_ex(revtm) + 1;
i = ASN1_STRING_length(revtm) + 1;
if (reason)
i += strlen(reason) + 1;
i += (int)(strlen(reason) + 1);
if (other)
i += strlen(other) + 1;
i += (int)(strlen(other) + 1);
str = app_malloc(i, "revocation reason");
OPENSSL_strlcpy(str, (const char *)ASN1_STRING_get0_data(revtm), i);
@ -2494,7 +2492,7 @@ static int old_entry_print(const ASN1_OBJECT *obj, const ASN1_STRING *str)
{
char buf[25], *pbuf;
const char *p;
size_t j;
int j;
j = i2a_ASN1_OBJECT(bio_err, obj);
pbuf = buf;
@ -2516,7 +2514,7 @@ static int old_entry_print(const ASN1_OBJECT *obj, const ASN1_STRING *str)
BIO_printf(bio_err, "ASN.1 %2d:'", ASN1_STRING_type(str));
p = (const char *)ASN1_STRING_get0_data(str);
for (j = ASN1_STRING_length_ex(str); j > 0; j--) {
for (j = ASN1_STRING_length(str); j > 0; j--) {
if ((*p >= ' ') && (*p <= '~'))
BIO_printf(bio_err, "%c", *p);
else if (*p & 0x80)

View file

@ -2140,7 +2140,7 @@ static int add_certProfile(OSSL_CMP_CTX *ctx, const char *name)
return 0;
if ((utf8string = ASN1_UTF8STRING_new()) == NULL)
goto err;
if (!ASN1_STRING_set_string(utf8string, name)) {
if (!ASN1_STRING_set(utf8string, name, (int)strlen(name))) {
ASN1_STRING_free(utf8string);
goto err;
}
@ -2215,7 +2215,7 @@ static int handle_opt_geninfo(OSSL_CMP_CTX *ctx)
else
*end++ = '\0';
if ((text = ASN1_UTF8STRING_new()) == NULL
|| !ASN1_STRING_set_string(text, ptr))
|| !ASN1_STRING_set(text, ptr, -1))
goto oom;
ptr = end;
ASN1_TYPE_set(type, V_ASN1_UTF8STRING, text);

View file

@ -1580,15 +1580,13 @@ static void receipt_request_print(CMS_ContentInfo *cms)
ERR_print_errors(bio_err);
} else {
const char *id;
size_t idlen;
int idlen;
CMS_ReceiptRequest_get0_values(rr, &scid, &allorfirst,
&rlist, &rto);
BIO_puts(bio_err, " Signed Content ID:\n");
idlen = ASN1_STRING_length_ex(scid);
if (idlen > INT_MAX)
idlen = INT_MAX;
idlen = ASN1_STRING_length(scid);
id = (const char *)ASN1_STRING_get0_data(scid);
BIO_dump_indent(bio_err, id, (int)idlen, 4);
BIO_dump_indent(bio_err, id, idlen, 4);
BIO_puts(bio_err, " Receipts From");
if (rlist != NULL) {
BIO_puts(bio_err, " List:\n");

View file

@ -54,7 +54,7 @@ const OPTIONS ec_options[] = {
{ "check", OPT_CHECK, '-', "check key consistency" },
{ "", OPT_CIPHER, '-', "Any supported cipher" },
{ "param_enc", OPT_PARAM_ENC, 's',
"Selects between named_curve and explicit EC parameter encoding" },
"Specifies the way the ec parameters are encoded" },
{ "conv_form", OPT_CONV_FORM, 's', "Specifies the point conversion form " },
OPT_SECTION("Output"),

View file

@ -57,7 +57,7 @@ const OPTIONS ecparam_options[] = {
{ "text", OPT_TEXT, '-', "Print the ec parameters in text form" },
{ "noout", OPT_NOOUT, '-', "Do not print the ec parameter" },
{ "param_enc", OPT_PARAM_ENC, 's',
"Selects between named_curve and explicit EC parameter encoding" },
"Specifies the way the ec parameters are encoded" },
OPT_SECTION("Parameter"),
{ "check", OPT_CHECK, '-', "Validate the ec parameters" },

View file

@ -40,7 +40,6 @@
#include <openssl/ssl.h>
#include <openssl/core_names.h>
#include <openssl/encoder.h>
#include <openssl/decoder.h>
#include "s_apps.h"
#include "apps.h"
@ -606,46 +605,20 @@ EVP_PKEY *load_keyparams_suppress(const char *uri, int format, int maybe_stdin,
int suppress_decode_errors)
{
EVP_PKEY *params = NULL;
OSSL_DECODER_CTX *dctx = NULL;
BIO *file_bio = BIO_new_file(uri, "rb");
OSSL_LIB_CTX *libctx = app_get0_libctx();
const char *propq = app_get0_propq();
if (desc == NULL)
desc = "key parameters";
/*
* Use the store lookup path for anything that is not DER/ASN1 format
* Or if we are unable to opens the uri as a file.
*/
if (format != FORMAT_ASN1 || file_bio == NULL) {
(void)load_key_certs_crls(uri, format, maybe_stdin, NULL, desc,
suppress_decode_errors,
NULL, NULL, &params, NULL, NULL, NULL, NULL, NULL);
if (params != NULL && keytype != NULL && !EVP_PKEY_is_a(params, keytype)) {
ERR_print_errors(bio_err);
BIO_printf(bio_err,
"Unable to load %s from %s (unexpected parameters type)\n",
desc, uri);
EVP_PKEY_free(params);
params = NULL;
}
} else {
dctx = OSSL_DECODER_CTX_new_for_pkey(&params, NULL, NULL, keytype,
OSSL_KEYMGMT_SELECT_ALL_PARAMETERS,
libctx, propq);
if (dctx == NULL) {
ERR_print_errors(bio_err);
BIO_printf(bio_err, "Unable to allocate decoder context\n");
} else {
if (!OSSL_DECODER_from_bio(dctx, file_bio)) {
ERR_print_errors(bio_err);
BIO_printf(bio_err, "Unable to decode file %s\n", uri);
}
}
(void)load_key_certs_crls(uri, format, maybe_stdin, NULL, desc,
suppress_decode_errors,
NULL, NULL, &params, NULL, NULL, NULL, NULL, NULL);
if (params != NULL && keytype != NULL && !EVP_PKEY_is_a(params, keytype)) {
ERR_print_errors(bio_err);
BIO_printf(bio_err,
"Unable to load %s from %s (unexpected parameters type)\n",
desc, uri);
EVP_PKEY_free(params);
params = NULL;
}
BIO_free(file_bio);
OSSL_DECODER_CTX_free(dctx);
return params;
}
@ -1876,18 +1849,11 @@ CA_DB *load_index(const char *dbfile, DB_ATTR *db_attr)
goto err;
#ifndef OPENSSL_NO_POSIX_IO
if (BIO_get_fp(in, &dbfp) > 0 && dbfp != NULL) {
if (fstat(fileno(dbfp), &dbst) == -1) {
ERR_raise_data(ERR_LIB_SYS, errno,
"calling fstat(%s)", dbfile);
goto err;
}
} else {
if (stat(dbfile, &dbst) == -1) {
ERR_raise_data(ERR_LIB_SYS, errno,
"calling stat(%s)", dbfile);
goto err;
}
BIO_get_fp(in, &dbfp);
if (fstat(fileno(dbfp), &dbst) == -1) {
ERR_raise_data(ERR_LIB_SYS, errno,
"calling fstat(%s)", dbfile);
goto err;
}
#endif
@ -2833,7 +2799,7 @@ static const char *get_dp_url(DIST_POINT *dp)
for (i = 0; i < sk_GENERAL_NAME_num(gens); i++) {
gen = sk_GENERAL_NAME_value(gens, i);
uri = GENERAL_NAME_get0_value(gen, &gtype);
if (gtype == GEN_URI && ASN1_STRING_length_ex(uri) > 6) {
if (gtype == GEN_URI && ASN1_STRING_length(uri) > 6) {
const char *uptr = (const char *)ASN1_STRING_get0_data(uri);
if (IS_HTTP(uptr)) /* can/should not use HTTPS here */
@ -3151,10 +3117,14 @@ static int WIN32_rename(const char *from, const char *to)
if (tfrom == NULL)
goto err;
tto = tfrom + flen;
#if !defined(_WIN32_WCE) || _WIN32_WCE >= 101
if (!MultiByteToWideChar(CP_ACP, 0, from, (int)flen, (WCHAR *)tfrom, (int)flen))
#endif
for (i = 0; i < flen; i++)
tfrom[i] = (TCHAR)from[i];
#if !defined(_WIN32_WCE) || _WIN32_WCE >= 101
if (!MultiByteToWideChar(CP_ACP, 0, to, (int)tlen, (WCHAR *)tto, (int)tlen))
#endif
for (i = 0; i < tlen; i++)
tto[i] = (TCHAR)to[i];
}
@ -3722,7 +3692,7 @@ int has_stdin_waiting(void)
int corrupt_signature(ASN1_STRING *signature)
{
const unsigned char *valid = ASN1_STRING_get0_data(signature);
size_t length = ASN1_STRING_length_ex(signature);
int length = ASN1_STRING_length(signature);
unsigned char *s = OPENSSL_memdup(valid, length);
if (s == NULL)
@ -3730,7 +3700,7 @@ int corrupt_signature(ASN1_STRING *signature)
s[length - 1] ^= 0x1;
ASN1_STRING_set0(signature, s, (int)length);
ASN1_STRING_set0(signature, s, length);
return 1;
}

View file

@ -345,7 +345,7 @@ static OSSL_CMP_PKISI *process_cert_request(OSSL_CMP_SRV_CTX *srv_ctx,
STACK_OF(ASN1_UTF8STRING) *strs;
ASN1_UTF8STRING *str;
const char *data;
size_t len;
int len;
if (OBJ_obj2nid(obj) == NID_id_it_certProfile) {
if (!OSSL_CMP_ITAV_get0_certProfile(itav, &strs))
@ -360,7 +360,7 @@ static OSSL_CMP_PKISI *process_cert_request(OSSL_CMP_SRV_CTX *srv_ctx,
ERR_raise(ERR_LIB_CMP, ERR_R_PASSED_INVALID_ARGUMENT);
return NULL;
}
if (((len = ASN1_STRING_length_ex(str)) != sizeof("profile1") - 1)
if (((len = ASN1_STRING_length(str)) != (int)sizeof("profile1") - 1)
|| memcmp(data, "profile1", len) != 0) {
ERR_raise(ERR_LIB_CMP, CMP_R_UNEXPECTED_CERTPROFILE);
return NULL;

View file

@ -1236,7 +1236,9 @@ int opt_isdir(const char *name)
if (len_0 > MAX_PATH)
return -1;
#if !defined(_WIN32_WCE) || _WIN32_WCE >= 101
if (!MultiByteToWideChar(CP_ACP, 0, name, (int)len_0, tempname, MAX_PATH))
#endif
for (i = 0; i < len_0; i++)
tempname[i] = (WCHAR)name[i];

View file

@ -576,7 +576,6 @@ static STRINT_PAIR ssl_versions[] = {
{ "TLS 1.2", TLS1_2_VERSION },
{ "TLS 1.3", TLS1_3_VERSION },
{ "DTLS 1.0", DTLS1_VERSION },
{ "DTLS 1.2", DTLS1_2_VERSION },
{ "DTLS 1.0 (bad)", DTLS1_BAD_VER },
{ NULL }
};
@ -654,10 +653,7 @@ void msg_cb(int write_p, int version, int content_type, const void *buf,
const char *str_version, *str_content_type = "", *str_details1 = "", *str_details2 = "";
const unsigned char *bp = buf;
if (version == TLS1_VERSION || version == TLS1_1_VERSION
|| version == TLS1_2_VERSION || version == TLS1_3_VERSION
|| version == DTLS1_VERSION || version == DTLS1_2_VERSION
|| version == DTLS1_BAD_VER) {
if (version == TLS1_VERSION || version == TLS1_1_VERSION || version == TLS1_2_VERSION || version == TLS1_3_VERSION || version == DTLS1_VERSION || version == DTLS1_BAD_VER) {
str_version = lookup(version, ssl_versions, "???");
switch (content_type) {
case SSL3_RT_CHANGE_CIPHER_SPEC:
@ -779,8 +775,8 @@ static const STRINT_PAIR tlsext_types[] = {
{ NULL }
};
/* from rfc8446 4.2.3. + gost (https://tools.ietf.org/id/draft-smyshlyaev-tls12-gost-suites-04.html) */
static STRINT_PAIR signature_tls13_scheme_list[] = {
/* RFC 8446 4.2.3 */
{ "rsa_pkcs1_sha1", 0x0201 /* TLSEXT_SIGALG_rsa_pkcs1_sha1 */ },
{ "ecdsa_sha1", 0x0203 /* TLSEXT_SIGALG_ecdsa_sha1 */ },
/* {"rsa_pkcs1_sha224", 0x0301 TLSEXT_SIGALG_rsa_pkcs1_sha224}, not in rfc8446 */
@ -799,59 +795,9 @@ static STRINT_PAIR signature_tls13_scheme_list[] = {
{ "rsa_pss_pss_sha256", 0x0809 /* TLSEXT_SIGALG_rsa_pss_pss_sha256 */ },
{ "rsa_pss_pss_sha384", 0x080a /* TLSEXT_SIGALG_rsa_pss_pss_sha384 */ },
{ "rsa_pss_pss_sha512", 0x080b /* TLSEXT_SIGALG_rsa_pss_pss_sha512 */ },
/* RFC 8734 */
{ "ecdsa_brainpoolP256r1tls13_sha256", 0x81a },
{ "ecdsa_brainpoolP256r1tls13_sha384", 0x81b },
{ "ecdsa_brainpoolP256r1tls13_sha512", 0x81c },
/* RFC 8998 */
{ "sm2sig_sm3", 0x0708 /* TLSEXT_SIGALG_sm2sig_sm3 */ },
/* RFC 9367 */
{ "gostr34102012_256a", 0x709 },
{ "gostr34102012_256b", 0x70a },
{ "gostr34102012_256c", 0x70b },
{ "gostr34102012_256d", 0x70c },
{ "gostr34102012_512a", 0x70d },
{ "gostr34102012_512b", 0x70e },
{ "gostr34102012_512c", 0x70f },
/* RFC 9963 */
{ "rsa_pkcs1_sha256_legacy", 0x0420 },
{ "rsa_pkcs1_sha384_legacy", 0x0520 },
{ "rsa_pkcs1_sha512_legacy", 0x0620 },
/* IBS (https://datatracker.ietf.org/doc/html/draft-wang-tls-raw-public-key-with-ibc-02) */
{ "eccsi_sha256", 0x0704 },
{ "iso_ibs1", 0x0705 },
{ "iso_ibs2", 0x0706 },
{ "iso_chinese_ibs", 0x0707 },
/* ML-DSA (https://datatracker.ietf.org/doc/html/draft-ietf-tls-mldsa-00) */
{ "mldsa44", 0x0904 },
{ "mldsa65", 0x0905 },
{ "mldsa87", 0x0906 },
/* SLH-DSA (https://datatracker.ietf.org/doc/html/draft-reddy-tls-slhdsa-01) */
{ "slhdsa_sha2_128s", 0x0911 },
{ "slhdsa_sha2_128f", 0x0912 },
{ "slhdsa_sha2_192s", 0x0913 },
{ "slhdsa_sha2_192f", 0x0914 },
{ "slhdsa_sha2_256s", 0x0915 },
{ "slhdsa_sha2_256f", 0x0916 },
{ "slhdsa_shake_128s", 0x0917 },
{ "slhdsa_shake_128f", 0x0918 },
{ "slhdsa_shake_192s", 0x0919 },
{ "slhdsa_shake_192f", 0x091a },
{ "slhdsa_shake_256s", 0x091b },
{ "slhdsa_shake_256f", 0x091c },
/* GOST (https://tools.ietf.org/id/draft-smyshlyaev-tls12-gost-suites-04.html) */
{ "gostr34102001", 0xeded /* TLSEXT_SIGALG_gostr34102001_gostr3411 */ },
{ "gostr34102012_256", 0xeeee /* TLSEXT_SIGALG_gostr34102012_256_gostr34112012_256 */ },
{ "gostr34102012_512", 0xefef /* TLSEXT_SIGALG_gostr34102012_512_gostr34112012_512 */ },
{ NULL }
};
@ -1528,7 +1474,10 @@ static STRINT_PAIR callback_types[] = {
{ "Signature Algorithm mask", SSL_SECOP_SIGALG_MASK },
{ "Certificate chain EE key", SSL_SECOP_EE_KEY },
{ "Certificate chain CA key", SSL_SECOP_CA_KEY },
{ "Peer Chain EE key", SSL_SECOP_PEER_EE_KEY },
{ "Peer Chain CA key", SSL_SECOP_PEER_CA_KEY },
{ "Certificate chain CA digest", SSL_SECOP_CA_MD },
{ "Peer chain CA digest", SSL_SECOP_PEER_CA_MD },
{ "SSL compression", SSL_SECOP_COMPRESSION },
{ "Session ticket", SSL_SECOP_TICKET },
{ NULL }
@ -1562,6 +1511,7 @@ static int security_callback_debug(const SSL *s, const SSL_CTX *ctx,
show_nm = 0;
break;
case SSL_SECOP_CA_MD:
case SSL_SECOP_PEER_CA_MD:
cert_md = 1;
break;
case SSL_SECOP_SIGALG_SUPPORTED:

View file

@ -495,7 +495,7 @@ static int CreateSocketPair(int SocketFamily,
SocketPair[0] = SockDesc2;
SocketPair[1] = socket_fd(TcpDeviceChan);
return 0;
return (0);
}
/*----------------------------------------------------------------------------*/

View file

@ -74,7 +74,7 @@ static int do_responder(OCSP_REQUEST **preq, BIO **pcbio, BIO *acbio,
static int send_ocsp_response(BIO *cbio, const OCSP_RESPONSE *resp);
static char *prog;
#ifndef OPENSSL_NO_POSIX_IO
#ifdef HTTP_DAEMON
static int index_changed(CA_DB *);
#endif
@ -680,7 +680,7 @@ int ocsp_main(int argc, char **argv)
redo_accept:
if (acbio != NULL) {
#ifndef OPENSSL_NO_POSIX_IO
#ifdef HTTP_DAEMON
if (index_changed(rdb)) {
CA_DB *newrdb = load_index(ridx_filename, NULL);
@ -926,7 +926,7 @@ end:
return ret;
}
#ifndef OPENSSL_NO_POSIX_IO
#ifdef HTTP_DAEMON
static int index_changed(CA_DB *rdb)
{
@ -937,11 +937,7 @@ static int index_changed(CA_DB *rdb)
|| rdb->dbst.st_ctime != sb.st_ctime
|| rdb->dbst.st_ino != sb.st_ino
|| rdb->dbst.st_dev != sb.st_dev) {
#ifdef HTTP_DAEMON
syslog(LOG_INFO, "index file changed, reloading");
#else
BIO_printf(bio_err, "%s: index file changed, reloading\n", prog);
#endif
return 1;
}
}

View file

@ -833,7 +833,7 @@ int pkcs12_main(int argc, char **argv)
ASN1_INTEGER_get(pbkdf2_param->iter));
BIO_printf(bio_err, "Key length: %ld, Salt length: %d\n",
ASN1_INTEGER_get(pbkdf2_param->keylength),
(int)ASN1_STRING_length_ex(pbkdf2_param->salt->value.octet_string));
ASN1_STRING_length(pbkdf2_param->salt->value.octet_string));
if (pbkdf2_param->prf == NULL) {
prfnid = NID_hmacWithSHA1;
} else {
@ -847,8 +847,8 @@ int pkcs12_main(int argc, char **argv)
BIO_printf(bio_err, ", Iteration %ld\n",
tmaciter != NULL ? ASN1_INTEGER_get(tmaciter) : 1L);
BIO_printf(bio_err, "MAC length: %ld, salt length: %ld\n",
tmac != NULL ? (long)ASN1_STRING_length_ex(tmac) : 0L,
tsalt != NULL ? (long)ASN1_STRING_length_ex(tsalt) : 0L);
tmac != NULL ? ASN1_STRING_length(tmac) : 0L,
tsalt != NULL ? ASN1_STRING_length(tsalt) : 0L);
}
}
@ -1231,7 +1231,7 @@ static int alg_print(const X509_ALGOR *alg)
}
BIO_printf(bio_err, ", Salt length: %d, Cost(N): %ld, "
"Block size(r): %ld, Parallelism(p): %ld",
(int)ASN1_STRING_length_ex(kdf->salt),
ASN1_STRING_length(kdf->salt),
ASN1_INTEGER_get(kdf->costParameter),
ASN1_INTEGER_get(kdf->blockSize),
ASN1_INTEGER_get(kdf->parallelizationParameter));
@ -1282,25 +1282,25 @@ void print_attribute(BIO *out, const ASN1_TYPE *av)
switch (av->type) {
case V_ASN1_BMPSTRING:
value = OPENSSL_uni2asc(ASN1_STRING_get0_data(av->value.bmpstring),
(int)ASN1_STRING_length_ex(av->value.bmpstring));
ASN1_STRING_length(av->value.bmpstring));
BIO_printf(out, "%s\n", value);
OPENSSL_free(value);
break;
case V_ASN1_UTF8STRING:
BIO_printf(out, "%.*s\n", (int)ASN1_STRING_length_ex(av->value.utf8string),
BIO_printf(out, "%.*s\n", ASN1_STRING_length(av->value.utf8string),
ASN1_STRING_get0_data(av->value.utf8string));
break;
case V_ASN1_OCTET_STRING:
hex_print(out, ASN1_STRING_get0_data(av->value.octet_string),
(int)ASN1_STRING_length_ex(av->value.octet_string));
ASN1_STRING_length(av->value.octet_string));
BIO_puts(out, "\n");
break;
case V_ASN1_BIT_STRING:
hex_print(out, ASN1_STRING_get0_data(av->value.bit_string),
(int)ASN1_STRING_length_ex(av->value.bit_string));
ASN1_STRING_length(av->value.bit_string));
BIO_puts(out, "\n");
break;

View file

@ -72,7 +72,7 @@ const OPTIONS pkey_options[] = {
{ "ec_conv_form", OPT_EC_CONV_FORM, 's',
"Specifies the EC point conversion form in the encoding" },
{ "ec_param_enc", OPT_EC_PARAM_ENC, 's',
"Selects between named_curve and explicit EC parameter encoding" },
"Specifies the way the EC parameters are encoded" },
{ NULL }
};

View file

@ -23,7 +23,6 @@ typedef enum OPTION_choice {
OPT_OUT,
OPT_BASE64,
OPT_HEX,
OPT_NO_NEWLINE,
OPT_R_ENUM,
OPT_PROV_ENUM
} OPTION_CHOICE;
@ -38,7 +37,6 @@ const OPTIONS rand_options[] = {
{ "out", OPT_OUT, '>', "Output file" },
{ "base64", OPT_BASE64, '-', "Base64 encode output" },
{ "hex", OPT_HEX, '-', "Hex encode output" },
{ "n", OPT_NO_NEWLINE, '-', "Do not output the trailing newline" },
OPT_R_OPTIONS,
OPT_PROV_OPTIONS,
@ -53,7 +51,7 @@ int rand_main(int argc, char **argv)
BIO *out = NULL;
char *outfile = NULL, *prog;
OPTION_CHOICE o;
int format = FORMAT_BINARY, r, i, ret = 1, newline = 1;
int format = FORMAT_BINARY, r, i, ret = 1;
size_t buflen = (1 << 16); /* max rand chunk size is 2^16 bytes */
long num = -1;
uint64_t scaled_num = 0;
@ -84,9 +82,6 @@ int rand_main(int argc, char **argv)
case OPT_HEX:
format = FORMAT_TEXT;
break;
case OPT_NO_NEWLINE:
newline = 0;
break;
case OPT_PROV_CASES:
if (!opt_provider(o))
goto end;
@ -213,7 +208,7 @@ int rand_main(int argc, char **argv)
}
scaled_num -= chunk;
}
if (newline && format == FORMAT_TEXT)
if (format == FORMAT_TEXT)
BIO_puts(out, "\n");
if (BIO_flush(out) <= 0)
goto end;

View file

@ -1254,21 +1254,25 @@ static int prompt_info(X509_REQ *req,
if (!join(buf, sizeof(buf), type, "_value", "Name"))
goto err;
;
value = app_conf_try_string(req_conf, attr_sect, buf);
if (!join(buf, sizeof(buf), type, "_min", "Name"))
goto err;
;
if (!app_conf_try_number(req_conf, attr_sect, buf, &n_min))
n_min = -1;
if (!join(buf, sizeof(buf), type, "_max", "Name"))
goto err;
;
if (!app_conf_try_number(req_conf, attr_sect, buf, &n_max))
n_max = -1;
if (!add_attribute_object(req,
v->value, def, value, nid, n_min,
n_max, chtype))
goto err;
;
}
}
} else {

View file

@ -3049,7 +3049,6 @@ re_start:
ASN1_TYPE *atyp = NULL;
BIO *ldapbio = BIO_new(BIO_s_mem());
CONF *cnf = NCONF_new(NULL);
size_t ssl_request_len;
if (ldapbio == NULL || cnf == NULL) {
BIO_free(ldapbio);
@ -3082,18 +3081,11 @@ re_start:
BIO_puts(bio_err, "ASN1_generate_nconf failed\n");
goto end;
}
ssl_request_len = ASN1_STRING_length_ex(atyp->value.sequence);
if (ssl_request_len > INT_MAX) {
NCONF_free(cnf);
ASN1_TYPE_free(atyp);
BIO_puts(bio_err, "generated NCONF size is too large\n");
goto end;
}
NCONF_free(cnf);
/* Send SSLRequest packet */
BIO_write(sbio, ASN1_STRING_get0_data(atyp->value.sequence),
(int)ssl_request_len);
ASN1_STRING_length(atyp->value.sequence));
(void)BIO_flush(sbio);
ASN1_TYPE_free(atyp);
@ -3528,32 +3520,29 @@ shut:
print_stuff(bio_c_out, con, full_log);
do_ssl_shutdown(con);
/* The following half-close/drain workaround is TCP-specific. */
if (!isdtls && !isquic) {
/*
* If we ended with an alert being sent, but still with data in the
* network buffer to be read, then calling BIO_closesocket() will
* result in a TCP-RST being sent. On some platforms (notably
* Windows) then this will result in the peer immediately abandoning
* the connection including any buffered alert data before it has
* had a chance to be read. Shutting down the sending side first,
* and then closing the socket sends TCP-FIN first followed by
* TCP-RST. This seems to allow the peer to read the alert data.
*/
shutdown(SSL_get_fd(con), 1); /* SHUT_WR */
/*
* We just said we have nothing else to say, but it doesn't mean that
* the other side has nothing. It's even recommended to consume incoming
* data. [In testing context this ensures that alerts are passed on...]
*/
timeout.tv_sec = 0;
timeout.tv_usec = 500000; /* some extreme round-trip */
do {
FD_ZERO(&readfds);
openssl_fdset(sock, &readfds);
} while (select(sock + 1, &readfds, NULL, NULL, &timeout) > 0
&& BIO_read(sbio, sbuf, BUFSIZZ) > 0);
}
/*
* If we ended with an alert being sent, but still with data in the
* network buffer to be read, then calling BIO_closesocket() will
* result in a TCP-RST being sent. On some platforms (notably
* Windows) then this will result in the peer immediately abandoning
* the connection including any buffered alert data before it has
* had a chance to be read. Shutting down the sending side first,
* and then closing the socket sends TCP-FIN first followed by
* TCP-RST. This seems to allow the peer to read the alert data.
*/
shutdown(SSL_get_fd(con), 1); /* SHUT_WR */
/*
* We just said we have nothing else to say, but it doesn't mean that
* the other side has nothing. It's even recommended to consume incoming
* data. [In testing context this ensures that alerts are passed on...]
*/
timeout.tv_sec = 0;
timeout.tv_usec = 500000; /* some extreme round-trip */
do {
FD_ZERO(&readfds);
openssl_fdset(sock, &readfds);
} while (select(sock + 1, &readfds, NULL, NULL, &timeout) > 0
&& BIO_read(sbio, sbuf, BUFSIZZ) > 0);
BIO_closesocket(SSL_get_fd(con));
end:

View file

@ -462,7 +462,7 @@ typedef struct tlsextctx_st {
static unsigned int ech_print_cb(SSL *s, const char *str)
{
if (str != NULL)
BIO_printf(bio_s_out, "ECH Server callback printing:\n%s\n", str);
BIO_printf(bio_s_out, "ECH Server callback printing: \n%s\n", str);
return 1;
}
@ -4020,7 +4020,6 @@ static int www_body(int s, int stype, int prot, unsigned char *context)
if (rpk_files != NULL && !rpk_enable(con)) {
BIO_puts(bio_err, "Error enabling client RPK verification\n");
SSL_free(con);
goto err;
}
@ -4544,7 +4543,6 @@ static int rev_body(int s, int stype, int prot, unsigned char *context)
if (rpk_files != NULL && !rpk_enable(con)) {
BIO_puts(bio_err, "Error enabling client RPK verification\n");
ERR_print_errors(bio_err);
SSL_free(con);
goto err;
}

View file

@ -2945,7 +2945,7 @@ int speed_main(int argc, char **argv)
&outlen, loopargs[k].buf,
lengths[testnum])) {
BIO_puts(bio_err,
"\nFailed to encrypt the data\n");
"\nFailed to to encrypt the data\n");
dofail();
exit(1);
}
@ -4633,7 +4633,7 @@ static int do_multi(int multi, int size_num)
for (n = 0; n < multi; ++n) {
while (wait(&status) == -1)
if (errno != EINTR) {
BIO_printf(bio_err, "Waiting for child failed with 0x%x\n",
BIO_printf(bio_err, "Waitng for child failed with 0x%x\n",
errno);
return 1;
}

View file

@ -155,8 +155,8 @@ int spkac_main(int argc, char **argv)
if (spki == NULL)
goto end;
if (challenge != NULL
&& !ASN1_STRING_set_string(spki->spkac->challenge,
challenge))
&& !ASN1_STRING_set(spki->spkac->challenge,
challenge, (int)strlen(challenge)))
goto end;
if (!NETSCAPE_SPKI_set_pubkey(spki, pkey)) {
BIO_puts(bio_err, "Error setting public key\n");

View file

@ -583,7 +583,7 @@ static ASN1_INTEGER *create_nonce(int bits)
if ((nonce = ASN1_INTEGER_new()) == NULL)
goto err;
if (!ASN1_STRING_set_data(nonce, buf, len))
if (!ASN1_STRING_set(nonce, buf, len))
goto err;
ret = nonce;

View file

@ -36,13 +36,25 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <windows.h>
#include <tchar.h>
#include "internal/e_os.h"
#include "internal/numbers.h"
#ifndef LPDIR_H
#include "LPdir.h"
#endif
/*
* We're most likely overcautious here, but let's reserve for broken WinCE
* headers and explicitly opt for UNICODE call. Keep in mind that our WinCE
* builds are compiled with -DUNICODE [as well as -D_UNICODE].
*/
#if defined(LP_SYS_WINCE) && !defined(FindFirstFile)
#define FindFirstFile FindFirstFileW
#endif
#if defined(LP_SYS_WINCE) && !defined(FindNextFile)
#define FindNextFile FindNextFileW
#endif
#ifndef NAME_MAX
#define NAME_MAX 255
#endif

46
crypto/LPdir_wince.c Normal file
View file

@ -0,0 +1,46 @@
/*
* Copyright 2004-2016 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
*/
/*
* This file is dual-licensed and is also available under the following
* terms:
*
* Copyright (c) 2004, Richard Levitte <richard@levitte.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#define LP_SYS_WINCE
/*
* We might want to define LP_MULTIBYTE_AVAILABLE here. It's currently under
* investigation what the exact conditions would be
*/
/* clang-format off */
#include "LPdir_win.c"
/* clang-format on */

View file

@ -19,7 +19,7 @@
#endif
#include "internal/cryptlib.h"
#ifdef _WIN32
#include "internal/e_os.h"
#include <windows.h>
#else
#include <unistd.h>
#endif
@ -69,7 +69,7 @@ uint32_t OPENSSL_rdtsc(void)
/* First determine if getauxval() is available (OSSL_IMPLEMENT_GETAUXVAL) */
#if defined(__GNUC__)
#if defined(__GNUC__) && __GNUC__ >= 2
void OPENSSL_cpuid_setup(void) __attribute__((constructor));
#endif
@ -415,52 +415,15 @@ void OPENSSL_cpuid_setup(void)
if (OPENSSL_armcap_P & ARMV8_CPUID)
OPENSSL_arm_midr = _armv8_cpuid_probe();
if ((OPENSSL_armcap_P & ARMV7_NEON)
&& (MIDR_IS_CPU_MODEL(OPENSSL_arm_midr, ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A72)
|| MIDR_IS_CPU_MODEL(OPENSSL_arm_midr, ARM_CPU_IMP_ARM, ARM_CPU_PART_N1)))
if ((MIDR_IS_CPU_MODEL(OPENSSL_arm_midr, ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A72) || MIDR_IS_CPU_MODEL(OPENSSL_arm_midr, ARM_CPU_IMP_ARM, ARM_CPU_PART_N1)) && (OPENSSL_armcap_P & ARMV7_NEON)) {
OPENSSL_armv8_rsa_neonized = 1;
if ((OPENSSL_armcap_P & ARMV8_SHA3)
&& (MIDR_IS_CPU_MODEL(OPENSSL_arm_midr, ARM_CPU_IMP_ARM, ARM_CPU_PART_V1)
|| MIDR_IS_CPU_MODEL(OPENSSL_arm_midr, ARM_CPU_IMP_ARM, ARM_CPU_PART_N2)
|| MIDR_IS_CPU_MODEL(OPENSSL_arm_midr, ARM_CPU_IMP_QCOMM, QCOM_CPU_PART_ORYON_X1)
|| MIDR_IS_CPU_MODEL(OPENSSL_arm_midr, ARM_CPU_IMP_MICROSOFT, MICROSOFT_CPU_PART_COBALT_100)
|| MIDR_IS_CPU_MODEL(OPENSSL_arm_midr, ARM_CPU_IMP_ARM, ARM_CPU_PART_V2)
|| MIDR_IS_CPU_MODEL(OPENSSL_arm_midr, ARM_CPU_IMP_ARM, ARM_CPU_PART_N3)
|| MIDR_IS_CPU_MODEL(OPENSSL_arm_midr, ARM_CPU_IMP_ARM, ARM_CPU_PART_V3_AE)
|| MIDR_IS_CPU_MODEL(OPENSSL_arm_midr, ARM_CPU_IMP_ARM, ARM_CPU_PART_V3)
|| MIDR_IMPLEMENTER(OPENSSL_arm_midr) == ARM_CPU_IMP_AMPERE
|| MIDR_IS_CPU_MODEL(OPENSSL_arm_midr, ARM_CPU_IMP_NVIDIA, NVIDIA_CPU_PART_OLYMPUS)))
}
if ((MIDR_IS_CPU_MODEL(OPENSSL_arm_midr, ARM_CPU_IMP_ARM, ARM_CPU_PART_V1) || MIDR_IS_CPU_MODEL(OPENSSL_arm_midr, ARM_CPU_IMP_ARM, ARM_CPU_PART_N2) || MIDR_IS_CPU_MODEL(OPENSSL_arm_midr, ARM_CPU_IMP_QCOMM, QCOM_CPU_PART_ORYON_X1) || MIDR_IS_CPU_MODEL(OPENSSL_arm_midr, ARM_CPU_IMP_MICROSOFT, MICROSOFT_CPU_PART_COBALT_100) || MIDR_IS_CPU_MODEL(OPENSSL_arm_midr, ARM_CPU_IMP_ARM, ARM_CPU_PART_V2) || MIDR_IS_CPU_MODEL(OPENSSL_arm_midr, ARM_CPU_IMP_ARM, ARM_CPU_PART_N3) || MIDR_IS_CPU_MODEL(OPENSSL_arm_midr, ARM_CPU_IMP_ARM, ARM_CPU_PART_V3_AE) || MIDR_IS_CPU_MODEL(OPENSSL_arm_midr, ARM_CPU_IMP_ARM, ARM_CPU_PART_V3) || MIDR_IMPLEMENTER(OPENSSL_arm_midr) == ARM_CPU_IMP_AMPERE) && (OPENSSL_armcap_P & ARMV8_SHA3))
OPENSSL_armcap_P |= ARMV8_UNROLL8_EOR3;
if ((OPENSSL_armcap_P & ARMV8_SHA3)
&& (MIDR_IS_CPU_MODEL(OPENSSL_arm_midr, ARM_CPU_IMP_ARM, ARM_CPU_PART_V1)
|| MIDR_IS_CPU_MODEL(OPENSSL_arm_midr, ARM_CPU_IMP_ARM, ARM_CPU_PART_V2)
|| MIDR_IS_CPU_MODEL(OPENSSL_arm_midr, ARM_CPU_IMP_ARM, ARM_CPU_PART_V3_AE)
|| MIDR_IS_CPU_MODEL(OPENSSL_arm_midr, ARM_CPU_IMP_ARM, ARM_CPU_PART_V3)
|| MIDR_IS_CPU_MODEL(OPENSSL_arm_midr, ARM_CPU_IMP_ARM, ARM_CPU_PART_N2)
|| MIDR_IS_CPU_MODEL(OPENSSL_arm_midr, ARM_CPU_IMP_ARM, ARM_CPU_PART_N3)
|| MIDR_IMPLEMENTER(OPENSSL_arm_midr) == ARM_CPU_IMP_AMPERE
|| MIDR_IS_CPU_MODEL(OPENSSL_arm_midr, ARM_CPU_IMP_NVIDIA, NVIDIA_CPU_PART_OLYMPUS)))
if ((MIDR_IS_CPU_MODEL(OPENSSL_arm_midr, ARM_CPU_IMP_ARM, ARM_CPU_PART_V1) || MIDR_IS_CPU_MODEL(OPENSSL_arm_midr, ARM_CPU_IMP_ARM, ARM_CPU_PART_V2) || MIDR_IS_CPU_MODEL(OPENSSL_arm_midr, ARM_CPU_IMP_ARM, ARM_CPU_PART_V3_AE) || MIDR_IS_CPU_MODEL(OPENSSL_arm_midr, ARM_CPU_IMP_ARM, ARM_CPU_PART_V3) || MIDR_IS_CPU_MODEL(OPENSSL_arm_midr, ARM_CPU_IMP_ARM, ARM_CPU_PART_N2) || MIDR_IS_CPU_MODEL(OPENSSL_arm_midr, ARM_CPU_IMP_ARM, ARM_CPU_PART_N3) || MIDR_IMPLEMENTER(OPENSSL_arm_midr) == ARM_CPU_IMP_AMPERE || MIDR_IS_CPU_MODEL(OPENSSL_arm_midr, ARM_CPU_IMP_NVIDIA, NVIDIA_CPU_PART_OLYMPUS)) && (OPENSSL_armcap_P & ARMV8_SHA3))
OPENSSL_armcap_P |= ARMV8_UNROLL12_EOR3;
if ((OPENSSL_armcap_P & ARMV8_SHA3)
&& (MIDR_IS_CPU_MODEL(OPENSSL_arm_midr, ARM_CPU_IMP_APPLE, APPLE_CPU_PART_M1_FIRESTORM)
|| MIDR_IS_CPU_MODEL(OPENSSL_arm_midr, ARM_CPU_IMP_APPLE, APPLE_CPU_PART_M1_ICESTORM)
|| MIDR_IS_CPU_MODEL(OPENSSL_arm_midr, ARM_CPU_IMP_APPLE, APPLE_CPU_PART_M1_FIRESTORM_PRO)
|| MIDR_IS_CPU_MODEL(OPENSSL_arm_midr, ARM_CPU_IMP_APPLE, APPLE_CPU_PART_M1_ICESTORM_PRO)
|| MIDR_IS_CPU_MODEL(OPENSSL_arm_midr, ARM_CPU_IMP_APPLE, APPLE_CPU_PART_M1_FIRESTORM_MAX)
|| MIDR_IS_CPU_MODEL(OPENSSL_arm_midr, ARM_CPU_IMP_APPLE, APPLE_CPU_PART_M1_ICESTORM_MAX)
|| MIDR_IS_CPU_MODEL(OPENSSL_arm_midr, ARM_CPU_IMP_APPLE, APPLE_CPU_PART_M2_AVALANCHE)
|| MIDR_IS_CPU_MODEL(OPENSSL_arm_midr, ARM_CPU_IMP_APPLE, APPLE_CPU_PART_M2_BLIZZARD)
|| MIDR_IS_CPU_MODEL(OPENSSL_arm_midr, ARM_CPU_IMP_APPLE, APPLE_CPU_PART_M2_AVALANCHE_PRO)
|| MIDR_IS_CPU_MODEL(OPENSSL_arm_midr, ARM_CPU_IMP_APPLE, APPLE_CPU_PART_M2_BLIZZARD_PRO)
|| MIDR_IS_CPU_MODEL(OPENSSL_arm_midr, ARM_CPU_IMP_APPLE, APPLE_CPU_PART_M2_AVALANCHE_MAX)
|| MIDR_IS_CPU_MODEL(OPENSSL_arm_midr, ARM_CPU_IMP_APPLE, APPLE_CPU_PART_M2_BLIZZARD_MAX)
|| MIDR_IS_CPU_MODEL(OPENSSL_arm_midr, ARM_CPU_IMP_QCOMM, QCOM_CPU_PART_ORYON_X1)
|| MIDR_IS_CPU_MODEL(OPENSSL_arm_midr, ARM_CPU_IMP_NVIDIA, NVIDIA_CPU_PART_OLYMPUS)))
if ((MIDR_IS_CPU_MODEL(OPENSSL_arm_midr, ARM_CPU_IMP_APPLE, APPLE_CPU_PART_M1_FIRESTORM) || MIDR_IS_CPU_MODEL(OPENSSL_arm_midr, ARM_CPU_IMP_APPLE, APPLE_CPU_PART_M1_ICESTORM) || MIDR_IS_CPU_MODEL(OPENSSL_arm_midr, ARM_CPU_IMP_APPLE, APPLE_CPU_PART_M1_FIRESTORM_PRO) || MIDR_IS_CPU_MODEL(OPENSSL_arm_midr, ARM_CPU_IMP_APPLE, APPLE_CPU_PART_M1_ICESTORM_PRO) || MIDR_IS_CPU_MODEL(OPENSSL_arm_midr, ARM_CPU_IMP_APPLE, APPLE_CPU_PART_M1_FIRESTORM_MAX) || MIDR_IS_CPU_MODEL(OPENSSL_arm_midr, ARM_CPU_IMP_APPLE, APPLE_CPU_PART_M1_ICESTORM_MAX) || MIDR_IS_CPU_MODEL(OPENSSL_arm_midr, ARM_CPU_IMP_APPLE, APPLE_CPU_PART_M2_AVALANCHE) || MIDR_IS_CPU_MODEL(OPENSSL_arm_midr, ARM_CPU_IMP_APPLE, APPLE_CPU_PART_M2_BLIZZARD) || MIDR_IS_CPU_MODEL(OPENSSL_arm_midr, ARM_CPU_IMP_APPLE, APPLE_CPU_PART_M2_AVALANCHE_PRO) || MIDR_IS_CPU_MODEL(OPENSSL_arm_midr, ARM_CPU_IMP_APPLE, APPLE_CPU_PART_M2_BLIZZARD_PRO) || MIDR_IS_CPU_MODEL(OPENSSL_arm_midr, ARM_CPU_IMP_APPLE, APPLE_CPU_PART_M2_AVALANCHE_MAX) || MIDR_IS_CPU_MODEL(OPENSSL_arm_midr, ARM_CPU_IMP_APPLE, APPLE_CPU_PART_M2_BLIZZARD_MAX) || MIDR_IS_CPU_MODEL(OPENSSL_arm_midr, ARM_CPU_IMP_QCOMM, QCOM_CPU_PART_ORYON_X1) || MIDR_IS_CPU_MODEL(OPENSSL_arm_midr, ARM_CPU_IMP_NVIDIA, NVIDIA_CPU_PART_OLYMPUS)) && (OPENSSL_armcap_P & ARMV8_SHA3))
OPENSSL_armcap_P |= ARMV8_HAVE_SHA3_AND_WORTH_USING;
if (OPENSSL_armcap_P & ARMV9_SVE2) {
uint64_t vl_bytes = _armv8_sve_get_vl_bytes();

View file

@ -18,7 +18,7 @@
#ifndef OPENSSL_NO_DEPRECATED_4_1
int ASN1_BIT_STRING_set(ASN1_BIT_STRING *x, unsigned char *d, int len)
{
return ossl_asn1_string_set_internal(x, d, len, /*add_nul_byte=*/0);
return ASN1_STRING_set(x, d, len);
}
#endif
@ -263,9 +263,8 @@ int ASN1_BIT_STRING_set1(ASN1_BIT_STRING *abs, const uint8_t *data, size_t lengt
if (length > 0 && (data[length - 1] & ((1 << unused_bits) - 1)) != 0)
return 0;
if (!ossl_asn1_string_set_internal(abs, data, (int)length, /*add_nul_byte=*/0))
if (!ASN1_STRING_set(abs, data, (int)length))
return 0;
abs->type = V_ASN1_BIT_STRING;
ossl_asn1_bit_string_set_unused_bits(abs, unused_bits);

View file

@ -1,5 +1,5 @@
/*
* Copyright 1995-2026 The OpenSSL Project Authors. All Rights Reserved.
* Copyright 1995-2025 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
@ -141,20 +141,7 @@ int asn1_d2i_read_bio(BIO *in, BUF_MEM **pb)
i = BIO_read(in, &(b->data[len]), (int)want);
if (i <= 0) {
/*
* A read error (i < 0), an EOF in the middle of an object
* (diff != 0, some bytes already buffered), or an EOF while
* still inside an indefinite-length constructed value awaiting
* its end-of-contents octets (eos != 0) all mean the input is
* truncated. Only a clean EOF at a top-level object boundary
* (i == 0, diff == 0, eos == 0) is the normal end of input:
* fail without queuing an error so that callers looping over
* concatenated DER values (e.g. the libcrypto d2i_*_bio()
* consumers in CPython's ssl module) terminate cleanly instead
* of seeing a spurious ASN1_R_NOT_ENOUGH_DATA.
*/
if (i < 0 || diff != 0 || eos != 0)
ERR_raise(ERR_LIB_ASN1, ASN1_R_NOT_ENOUGH_DATA);
ERR_raise(ERR_LIB_ASN1, ASN1_R_NOT_ENOUGH_DATA);
goto err;
}

View file

@ -316,7 +316,7 @@ ASN1_INTEGER *ossl_c2i_ASN1_INTEGER(ASN1_INTEGER **a, const unsigned char **pp,
} else
ret = *a;
if (ASN1_STRING_set_data(ret, NULL, r) == 0) {
if (r > INT_MAX || ASN1_STRING_set(ret, NULL, (int)r) == 0) {
ERR_raise(ERR_LIB_ASN1, ERR_R_ASN1_LIB);
goto err;
}
@ -371,7 +371,7 @@ static int asn1_string_set_int64(ASN1_STRING *a, int64_t r, int itype)
off = asn1_put_uint64(tbuf, r);
a->type &= ~V_ASN1_NEG;
}
return ASN1_STRING_set_data(a, tbuf + off, (sizeof(tbuf) - off));
return ASN1_STRING_set(a, tbuf + off, (int)(sizeof(tbuf) - off));
}
static int asn1_string_get_uint64(uint64_t *pr, const ASN1_STRING *a,
@ -399,7 +399,7 @@ static int asn1_string_set_uint64(ASN1_STRING *a, uint64_t r, int itype)
a->type = itype;
off = asn1_put_uint64(tbuf, r);
return ASN1_STRING_set_data(a, tbuf + off, (sizeof(tbuf) - off));
return ASN1_STRING_set(a, tbuf + off, (int)(sizeof(tbuf) - off));
}
/*
@ -503,7 +503,7 @@ static ASN1_STRING *bn_to_asn1_string(const BIGNUM *bn, ASN1_STRING *ai,
if (len == 0)
len = 1;
if (ASN1_STRING_set_data(ret, NULL, len) == 0) {
if (ASN1_STRING_set(ret, NULL, len) == 0) {
ERR_raise(ERR_LIB_ASN1, ERR_R_ASN1_LIB);
goto err;
}

View file

@ -69,9 +69,6 @@ int ASN1_mbstring_ncopy(ASN1_STRING **out, const unsigned char *in, int len,
if (len < 0) {
ERR_raise(ERR_LIB_ASN1, ERR_R_PASSED_INVALID_ARGUMENT);
return -1;
} else if (len >= INT_MAX) {
ERR_raise(ERR_LIB_ASN1, ASN1_R_STRING_TOO_LONG);
return -1;
}
/* First do a string check and work out the number of characters */
@ -171,7 +168,7 @@ int ASN1_mbstring_ncopy(ASN1_STRING **out, const unsigned char *in, int len,
}
/* If both the same type just copy across */
if (inform == outform) {
if (!ASN1_STRING_set_data(dest, in, len)) {
if (!ASN1_STRING_set(dest, in, len)) {
if (free_out) {
ASN1_STRING_free(dest);
*out = NULL;
@ -308,7 +305,7 @@ static int out_utf8(uint32_t value, void *arg)
return len;
}
outlen = arg;
if (*outlen >= INT_MAX - len) {
if (*outlen > INT_MAX - len) {
ERR_raise(ERR_LIB_ASN1, ASN1_R_STRING_TOO_LONG);
return -1;
}

View file

@ -25,11 +25,5 @@ int ASN1_OCTET_STRING_cmp(const ASN1_OCTET_STRING *a,
int ASN1_OCTET_STRING_set(ASN1_OCTET_STRING *x, const unsigned char *d,
int len)
{
if (len < -1) {
ERR_raise(ERR_LIB_ASN1, ASN1_R_TOO_SMALL);
return 0;
}
if (len == -1)
return ASN1_STRING_set_string(x, (const char *)d);
return ASN1_STRING_set_data(x, d, len);
return ASN1_STRING_set(x, d, len);
}

View file

@ -12,7 +12,6 @@
#include "internal/cryptlib.h"
#include "internal/sizes.h"
#include "internal/unicode.h"
#include "internal/safe_math.h"
#include "crypto/asn1.h"
#include <openssl/byteorder.h>
#include <openssl/crypto.h>
@ -32,8 +31,6 @@
#define ESC_FLAGS (ASN1_STRFLGS_ESC_2253 | ASN1_STRFLGS_ESC_2254 | ASN1_STRFLGS_ESC_QUOTE | ASN1_STRFLGS_ESC_CTRL | ASN1_STRFLGS_ESC_MSB)
OSSL_SAFE_MATH_SIGNED(int, int)
/*
* Three IO functions for sending data to memory, a BIO and a FILE
* pointer.
@ -145,10 +142,6 @@ static int do_buf(const unsigned char *buf, int buflen,
const unsigned char *p, *q;
uint32_t c;
if (buflen < 0)
return -1;
if (buflen == 0)
return 0;
p = buf;
q = buf + buflen;
outlen = 0;
@ -243,10 +236,6 @@ static int do_hex_dump(char_io *io_ch, void *arg, unsigned char *buf,
unsigned char *p, *q;
char hextmp[2];
if (buflen < 0)
return -1;
if (buflen == 0)
return 0;
if (arg) {
p = buf;
q = buf + buflen;
@ -441,7 +430,6 @@ static int do_name_ex(char_io *io_ch, void *arg, const X509_NAME *n,
char objtmp[80];
const char *objbuf;
int outlen, len;
int err = 0;
char *sep_dn, *sep_mv, *sep_eq;
int sep_dn_len, sep_mv_len, sep_eq_len;
if (indent < 0)
@ -505,20 +493,14 @@ static int do_name_ex(char_io *io_ch, void *arg, const X509_NAME *n,
if (prev == X509_NAME_ENTRY_set(ent)) {
if (!io_ch(arg, sep_mv, sep_mv_len))
return -1;
outlen = safe_add_int(outlen, sep_mv_len, &err);
if (err != 0)
return -1;
outlen += sep_mv_len;
} else {
if (!io_ch(arg, sep_dn, sep_dn_len))
return -1;
outlen = safe_add_int(outlen, sep_dn_len, &err);
if (err != 0)
return -1;
outlen += sep_dn_len;
if (!do_indent(io_ch, arg, indent))
return -1;
outlen = safe_add_int(outlen, indent, &err);
if (err != 0)
return -1;
outlen += indent;
}
}
prev = X509_NAME_ENTRY_set(ent);
@ -549,18 +531,11 @@ static int do_name_ex(char_io *io_ch, void *arg, const X509_NAME *n,
if ((objlen < fld_len) && (flags & XN_FLAG_FN_ALIGN)) {
if (!do_indent(io_ch, arg, fld_len - objlen))
return -1;
outlen = safe_add_int(outlen, fld_len - objlen, &err);
if (err != 0)
return -1;
outlen += fld_len - objlen;
}
if (!io_ch(arg, sep_eq, sep_eq_len))
return -1;
outlen = safe_add_int(outlen, objlen, &err);
if (err != 0)
return -1;
outlen = safe_add_int(outlen, sep_eq_len, &err);
if (err != 0)
return -1;
outlen += objlen + sep_eq_len;
}
/*
* If the field name is unknown then fix up the DER dump flag. We
@ -575,9 +550,7 @@ static int do_name_ex(char_io *io_ch, void *arg, const X509_NAME *n,
len = do_print_ex(io_ch, arg, flags | orflags, val);
if (len < 0)
return -1;
outlen = safe_add_int(outlen, len, &err);
if (err != 0)
return -1;
outlen += len;
}
return outlen;
}

View file

@ -271,7 +271,7 @@ ASN1_TIME *ossl_asn1_time_from_tm(ASN1_TIME *s, struct tm *ts, int type)
if (tmps == NULL)
return NULL;
if (!ASN1_STRING_set_data(tmps, NULL, len))
if (!ASN1_STRING_set(tmps, NULL, len))
goto err;
tmps->type = type;

View file

@ -651,7 +651,7 @@ static ASN1_TYPE *asn1_str2type(const char *str, int format, int utype)
ERR_raise(ERR_LIB_ASN1, ERR_R_ASN1_LIB);
goto bad_str;
}
if (!ASN1_STRING_set_string(atmp->value.asn1_string, str)) {
if (!ASN1_STRING_set(atmp->value.asn1_string, str, -1)) {
ERR_raise(ERR_LIB_ASN1, ERR_R_ASN1_LIB);
goto bad_str;
}
@ -706,7 +706,7 @@ static ASN1_TYPE *asn1_str2type(const char *str, int format, int utype)
atmp->value.asn1_string->length = rdlen;
atmp->value.asn1_string->type = utype;
} else if (format == ASN1_GEN_FORMAT_ASCII) {
if (!ASN1_STRING_set_string(atmp->value.asn1_string, str)) {
if (!ASN1_STRING_set(atmp->value.asn1_string, str, -1)) {
ERR_raise(ERR_LIB_ASN1, ERR_R_ASN1_LIB);
goto bad_str;
}

View file

@ -265,8 +265,7 @@ int ASN1_STRING_copy(ASN1_STRING *dst, const ASN1_STRING *str)
if (str == NULL)
return 0;
dst->type = str->type;
if (!ossl_asn1_string_set_internal(dst, str->data, str->length,
/*add_nul_byte=*/0))
if (!ASN1_STRING_set(dst, str->data, str->length))
return 0;
/* Copy flags but preserve embed value */
dst->flags &= ASN1_STRING_FLAG_EMBED;
@ -290,18 +289,12 @@ ASN1_STRING *ASN1_STRING_dup(const ASN1_STRING *str)
return ret;
}
int ossl_asn1_string_set_internal(ASN1_STRING *str, const uint8_t *data,
int len_in, int add_nul_byte)
int ASN1_STRING_set(ASN1_STRING *str, const void *_data, int len_in)
{
size_t len, alloc_len;
unsigned char *c;
const char *data = _data;
size_t len;
#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
/*
* Force no NUL byte for callers that are requesting it
* 0 length object data will be NULL
*/
add_nul_byte = 0;
#endif
if (len_in < -1) {
ERR_raise(ERR_LIB_ASN1, ASN1_R_TOO_SMALL);
return 0;
@ -309,17 +302,16 @@ int ossl_asn1_string_set_internal(ASN1_STRING *str, const uint8_t *data,
if (len_in == -1) {
if (data == NULL)
return 0;
len = strlen((const char *)data);
len = strlen(data);
} else {
len = (size_t)len_in;
}
/*
* Add one to the length to allow for adding an a '\0' terminator
* "even though this isn't strictly necessary".
* Verify that the length fits within an integer for assignment to
* str->length below. The additional 1 is subtracted to allow for the
* '\0' terminator even though this isn't strictly necessary.
*/
alloc_len = add_nul_byte ? len + 1 : len;
if (alloc_len > INT_MAX) {
if (len > INT_MAX - 1) {
ERR_raise(ERR_LIB_ASN1, ASN1_R_TOO_LARGE);
return 0;
}
@ -330,47 +322,39 @@ int ossl_asn1_string_set_internal(ASN1_STRING *str, const uint8_t *data,
str->flags &= ~ASN1_STRING_FLAG_DATA_NOT_OWNED;
}
/* Ensure copying a 0 length data field is defined. */
if (alloc_len == 0) {
OPENSSL_free(str->data);
str->data = NULL;
str->length = 0;
return 1;
}
if ((size_t)str->length != alloc_len) {
uint8_t *c;
c = OPENSSL_realloc(str->length == 0 ? NULL : str->data, alloc_len);
if (c == NULL)
if ((size_t)str->length <= len || str->data == NULL) {
c = str->data;
#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
/* No NUL terminator in fuzzing builds */
str->data = OPENSSL_realloc(c, len != 0 ? len : 1);
#else
str->data = OPENSSL_realloc(c, len + 1);
#endif
if (str->data == NULL) {
str->data = c;
return 0;
str->data = c;
}
/* length never includes the added \0 byte */
str->length = (int)len;
if (data != NULL && str->data != NULL) {
memcpy(str->data, data, len);
if (add_nul_byte) {
/*
* Add a '\0' terminator. This should not be necessary - but we add it as
* a safety precaution
*/
str->data[len] = '\0';
}
}
str->length = (int)len;
if (data != NULL) {
memcpy(str->data, data, len);
#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
/* Set the unused byte to something non NUL and printable. */
if (len == 0)
str->data[len] = '~';
#else
/*
* Add a NUL terminator. This should not be necessary - but we add it as
* a safety precaution
*/
str->data[len] = '\0';
#endif
}
ossl_asn1_bit_string_clear_unused_bits(str);
return 1;
}
#ifndef OPENSSL_NO_DEPRECATED_4_1
int ASN1_STRING_set(ASN1_STRING *str, const void *_data, int len_in)
{
return ossl_asn1_string_set_internal(str, (const uint8_t *)_data, len_in,
/*add_nul_byte=*/1);
}
#endif
void ASN1_STRING_set0(ASN1_STRING *str, void *data, int len)
{
if (!(str->flags & ASN1_STRING_FLAG_DATA_NOT_OWNED)) {
@ -381,26 +365,6 @@ void ASN1_STRING_set0(ASN1_STRING *str, void *data, int len)
str->length = len;
}
int ASN1_STRING_set_data(ASN1_STRING *str, const uint8_t *data, size_t len_in)
{
if (str->type == V_ASN1_BIT_STRING) {
ERR_raise(ERR_LIB_ASN1, ASN1_R_ILLEGAL_BITSTRING_FORMAT);
return 0;
}
/* This will go away once ASN1_STRING can size_t internally */
if (len_in > INT_MAX) {
ERR_raise(ERR_LIB_ASN1, ASN1_R_TOO_LARGE);
return 0;
}
return ossl_asn1_string_set_internal(str, data, (int)len_in, /*add_nul_byte=*/0);
}
int ASN1_STRING_set_string(ASN1_STRING *str, const char *c_string)
{
return ASN1_STRING_set_data(str, (const uint8_t *)c_string,
strlen(c_string));
}
ASN1_STRING *ASN1_STRING_new(void)
{
return ASN1_STRING_type_new(V_ASN1_OCTET_STRING);
@ -505,17 +469,10 @@ int ASN1_STRING_cmp(const ASN1_STRING *a, const ASN1_STRING *b)
}
}
#ifndef OPENSSL_NO_DEPRECATED_4_1
int ASN1_STRING_length(const ASN1_STRING *x)
{
return x->length;
}
#endif
size_t ASN1_STRING_length_ex(const ASN1_STRING *x)
{
return (size_t)x->length;
}
#ifndef OPENSSL_NO_DEPRECATED_3_0
void ASN1_STRING_length_set(ASN1_STRING *x, int len)
@ -552,7 +509,7 @@ char *ossl_sk_ASN1_UTF8STRING2text(STACK_OF(ASN1_UTF8STRING) *text,
current = sk_ASN1_UTF8STRING_value(text, i);
if (i > 0)
length += sep_len;
length += ASN1_STRING_length_ex(current);
length += ASN1_STRING_length(current);
if (max_len != 0 && length > max_len)
return NULL;
}
@ -562,7 +519,7 @@ char *ossl_sk_ASN1_UTF8STRING2text(STACK_OF(ASN1_UTF8STRING) *text,
p = result;
for (i = 0; i < sk_ASN1_UTF8STRING_num(text); i++) {
current = sk_ASN1_UTF8STRING_value(text, i);
length = ASN1_STRING_length_ex(current);
length = ASN1_STRING_length(current);
if (i > 0 && sep_len > 0) {
strncpy(p, sep, sep_len + 1); /* using + 1 to silence gcc warning */
p += sep_len;

View file

@ -12,7 +12,6 @@
#if !defined(OSSL_LIBCRYPTO_ASN1_ASN1_LOCAL_H)
#define OSSL_LIBCRYPTO_ASN1_ASN1_LOCAL_H
#include <openssl/asn1t.h>
#include "crypto/asn1.h"
typedef const ASN1_VALUE const_ASN1_VALUE;
@ -100,9 +99,5 @@ int ossl_asn1_item_ex_new_intern(ASN1_VALUE **pval, const ASN1_ITEM *it,
OSSL_LIB_CTX *libctx, const char *propq);
int ossl_asn1_time_time_t_to_tm(const time_t *time, struct tm *out_tm);
int ossl_asn1_time_tm_to_time_t(const struct tm *tm, time_t *out);
int ossl_asn1_call_aux_cb(const ASN1_AUX *aux, int operation,
const ASN1_VALUE **in, const ASN1_ITEM *it, void *exarg);
int ossl_asn1_string_set_internal(ASN1_STRING *str, const uint8_t *data,
int len_in, int add_nul_byte);
#endif /* !defined(OSSL_LIBCRYPTO_ASN1_ASN1_LOCAL_H) */

View file

@ -34,7 +34,6 @@ int ASN1_TYPE_set_octetstring(ASN1_TYPE *a, unsigned char *data, int len)
int ASN1_TYPE_get_octetstring(const ASN1_TYPE *a, unsigned char *data, int max_len)
{
int ret, num;
size_t tmp;
const unsigned char *p;
if ((a->type != V_ASN1_OCTET_STRING) || (a->value.octet_string == NULL)) {
@ -42,13 +41,7 @@ int ASN1_TYPE_get_octetstring(const ASN1_TYPE *a, unsigned char *data, int max_l
return -1;
}
p = ASN1_STRING_get0_data(a->value.octet_string);
tmp = ASN1_STRING_length_ex(a->value.octet_string);
if (tmp > INT_MAX) {
ERR_raise(ERR_LIB_ASN1, ASN1_R_TOO_LARGE);
return -1;
}
ret = (int)tmp;
ret = ASN1_STRING_length(a->value.octet_string);
if (ret < max_len)
num = ret;
else
@ -76,19 +69,11 @@ static ossl_inline void asn1_type_init_oct(ASN1_OCTET_STRING *oct,
static int asn1_type_get_int_oct(ASN1_OCTET_STRING *oct, int32_t anum,
long *num, unsigned char *data, int max_len)
{
int ret, n;
size_t tmp;
int ret = ASN1_STRING_length(oct), n;
if (num != NULL)
*num = anum;
tmp = ASN1_STRING_length_ex(oct);
if (tmp > INT_MAX)
tmp = INT_MAX;
ret = (int)tmp;
if (max_len > ret)
n = ret;
else

View file

@ -173,7 +173,7 @@ static X509_ALGOR *pkcs5_scrypt_set(const unsigned char *salt, int saltlen,
saltlen = PKCS5_DEFAULT_PBE2_SALT_LEN;
/* This will either copy salt or grow the buffer */
if (ASN1_STRING_set_data(sparam->salt, salt, saltlen) == 0) {
if (ASN1_STRING_set(sparam->salt, salt, saltlen) == 0) {
ERR_raise(ERR_LIB_ASN1, ERR_R_ASN1_LIB);
goto err;
}

View file

@ -72,13 +72,11 @@ int PKCS8_pkey_get0(const ASN1_OBJECT **ppkalg,
const unsigned char **pk, int *ppklen,
const X509_ALGOR **pa, const PKCS8_PRIV_KEY_INFO *p8)
{
if (ASN1_STRING_length_ex(p8->pkey) > INT_MAX)
return 0;
if (ppkalg)
*ppkalg = p8->pkeyalg->algorithm;
if (pk) {
*pk = ASN1_STRING_get0_data(p8->pkey);
*ppklen = (int)ASN1_STRING_length_ex(p8->pkey);
*ppklen = ASN1_STRING_length(p8->pkey);
}
if (pa)
*pa = p8->pkeyalg;

View file

@ -983,7 +983,7 @@ static int asn1_ex_c2i(ASN1_VALUE **pval, const unsigned char *cont, long len,
ASN1_STRING_set0(stmp, (unsigned char *)cont /* UGLY CAST! */, ilen);
*free_cont = 0;
} else {
if (!ASN1_STRING_set_data(stmp, cont, len)) {
if (!ASN1_STRING_set(stmp, cont, ilen)) {
ERR_raise(ERR_LIB_ASN1, ERR_R_ASN1_LIB);
ASN1_STRING_free(stmp);
*pval = NULL;

View file

@ -85,10 +85,16 @@ int ASN1_item_ex_i2d(const ASN1_VALUE **pval, unsigned char **out,
int i, seqcontlen, seqlen, ndef = 1;
const ASN1_EXTERN_FUNCS *ef;
const ASN1_AUX *aux = it->funcs;
ASN1_aux_const_cb *asn1_cb = NULL;
if ((it->itype != ASN1_ITYPE_PRIMITIVE) && *pval == NULL)
return 0;
if (aux != NULL) {
asn1_cb = ((aux->flags & ASN1_AFLG_CONST_CB) != 0) ? aux->asn1_const_cb
: (ASN1_aux_const_cb *)aux->asn1_cb; /* backward compatibility */
}
switch (it->itype) {
case ASN1_ITYPE_PRIMITIVE:
@ -117,7 +123,7 @@ int ASN1_item_ex_i2d(const ASN1_VALUE **pval, unsigned char **out,
ERR_raise(ERR_LIB_ASN1, ASN1_R_BAD_TEMPLATE);
return -1;
}
if (!ossl_asn1_call_aux_cb(aux, ASN1_OP_I2D_PRE, pval, it, NULL))
if (asn1_cb && !asn1_cb(ASN1_OP_I2D_PRE, pval, it, NULL))
return 0;
i = ossl_asn1_get_choice_selector_const(pval, it);
if ((i >= 0) && (i < it->tcount)) {
@ -128,7 +134,7 @@ int ASN1_item_ex_i2d(const ASN1_VALUE **pval, unsigned char **out,
return asn1_template_ex_i2d(pchval, out, chtt, -1, aclass);
}
/* Fixme: error condition if selector out of range */
if (!ossl_asn1_call_aux_cb(aux, ASN1_OP_I2D_POST, pval, it, NULL))
if (asn1_cb && !asn1_cb(ASN1_OP_I2D_POST, pval, it, NULL))
return 0;
break;
@ -160,7 +166,7 @@ int ASN1_item_ex_i2d(const ASN1_VALUE **pval, unsigned char **out,
aclass = (aclass & ~ASN1_TFLG_TAG_CLASS)
| V_ASN1_UNIVERSAL;
}
if (!ossl_asn1_call_aux_cb(aux, ASN1_OP_I2D_PRE, pval, it, NULL))
if (asn1_cb && !asn1_cb(ASN1_OP_I2D_PRE, pval, it, NULL))
return 0;
/* First work out sequence content length */
for (i = 0, tt = it->templates; i < it->tcount; tt++, i++) {
@ -194,7 +200,7 @@ int ASN1_item_ex_i2d(const ASN1_VALUE **pval, unsigned char **out,
}
if (ndef == 2)
ASN1_put_eoc(out);
if (!ossl_asn1_call_aux_cb(aux, ASN1_OP_I2D_POST, pval, it, NULL))
if (asn1_cb && !asn1_cb(ASN1_OP_I2D_POST, pval, it, NULL))
return 0;
return seqlen;

View file

@ -138,12 +138,15 @@ static int asn1_item_print_ctx(BIO *out, const ASN1_VALUE **fld, int indent,
const ASN1_EXTERN_FUNCS *ef;
const ASN1_VALUE **tmpfld;
const ASN1_AUX *aux = it->funcs;
ASN1_aux_const_cb *asn1_cb = NULL;
ASN1_PRINT_ARG parg;
int i;
if (aux != NULL) {
parg.out = out;
parg.indent = indent;
parg.pctx = pctx;
asn1_cb = ((aux->flags & ASN1_AFLG_CONST_CB) != 0) ? aux->asn1_const_cb
: (ASN1_aux_const_cb *)aux->asn1_cb; /* backward compatibility */
}
if (((it->itype != ASN1_ITYPE_PRIMITIVE)
@ -217,11 +220,13 @@ static int asn1_item_print_ctx(BIO *out, const ASN1_VALUE **fld, int indent,
}
}
i = ossl_asn1_call_aux_cb(aux, ASN1_OP_PRINT_PRE, fld, it, &parg);
if (i == 0)
return 0;
if (i == 2)
return 1;
if (asn1_cb) {
i = asn1_cb(ASN1_OP_PRINT_PRE, fld, it, &parg);
if (i == 0)
return 0;
if (i == 2)
return 1;
}
/* Print each field entry */
for (i = 0, tt = it->templates; i < it->tcount; i++, tt++) {
@ -239,9 +244,11 @@ static int asn1_item_print_ctx(BIO *out, const ASN1_VALUE **fld, int indent,
return 0;
}
i = ossl_asn1_call_aux_cb(aux, ASN1_OP_PRINT_POST, fld, it, &parg);
if (i == 0)
return 0;
if (asn1_cb) {
i = asn1_cb(ASN1_OP_PRINT_POST, fld, it, &parg);
if (i == 0)
return 0;
}
break;
default:

View file

@ -288,19 +288,3 @@ err:
ERR_raise(ERR_LIB_ASN1, ASN1_R_UNSUPPORTED_ANY_DEFINED_BY_TYPE);
return NULL;
}
int ossl_asn1_call_aux_cb(const ASN1_AUX *aux, int operation,
const ASN1_VALUE **in, const ASN1_ITEM *it, void *exarg)
{
if (aux == NULL)
return 1;
if ((aux->flags & ASN1_AFLG_CONST_CB) != 0) {
if (aux->asn1_const_cb != NULL)
return aux->asn1_const_cb(operation, in, it, exarg);
} else if (aux->asn1_cb != NULL) {
return aux->asn1_cb(operation, (ASN1_VALUE **)in, it, exarg);
}
return 1;
}

View file

@ -8,8 +8,8 @@
*/
#include <stdio.h>
#include "internal/cryptlib.h"
#include <openssl/asn1t.h>
#include "crypto/cryptlib.h"
#define COPY_SIZE(a, b) (sizeof(a) < sizeof(b) ? sizeof(a) : sizeof(b))
@ -56,31 +56,6 @@ static void long_free(ASN1_VALUE **pval, const ASN1_ITEM *it)
memcpy(pval, &it->size, COPY_SIZE(*pval, it->size));
}
/*
* Originally BN_num_bits_word was called to perform this operation, but
* trouble is that there is no guarantee that sizeof(long) equals to
* sizeof(BN_ULONG). BN_ULONG is a configurable type that can be as wide
* as long, but also double or half...
*/
static int num_bits_ulong(unsigned long value)
{
size_t i;
unsigned long ret = 0;
/*
* It is argued that *on average* constant counter loop performs
* not worse [if not better] than one with conditional break or
* mask-n-table-lookup-style, because of branch misprediction
* penalties.
*/
for (i = 0; i < sizeof(value) * 8; i++) {
ret += (value != 0);
value >>= 1;
}
return (int)ret;
}
static int long_i2c(const ASN1_VALUE **pval, unsigned char *cont, int *putype,
const ASN1_ITEM *it)
{
@ -103,7 +78,7 @@ static int long_i2c(const ASN1_VALUE **pval, unsigned char *cont, int *putype,
sign = 0;
utmp = ltmp;
}
clen = num_bits_ulong(utmp);
clen = (int)ossl_num_bits(utmp);
/* If MSB of leading octet set we need to pad */
if (!(clen & 0x7))
pad = 1;

View file

@ -12,7 +12,7 @@
#ifdef ASYNC_WIN
#include "internal/e_os.h"
#include <windows.h>
#include "internal/cryptlib.h"
int ASYNC_is_capable(void)

View file

@ -21,7 +21,6 @@
#include <openssl/crypto.h>
#include <openssl/e_os2.h>
#include <internal/e_os.h>
typedef struct async_ctx_st async_ctx;
typedef struct async_pool_st async_pool;
@ -30,6 +29,7 @@ typedef struct async_pool_st async_pool;
#define ASYNC_WIN
#define ASYNC_ARCH
#include <windows.h>
#include "internal/cryptlib.h"
typedef struct async_fibre_st {

View file

@ -116,22 +116,24 @@ BIO *BIO_new(const BIO_METHOD *method)
return BIO_new_ex(NULL, method);
}
static int BIO_free_int(BIO *a, int *ret)
int BIO_free(BIO *a)
{
int ret;
if (a == NULL)
return 0;
if (CRYPTO_DOWN_REF(&a->references, ret) <= 0)
if (CRYPTO_DOWN_REF(&a->references, &ret) <= 0)
return 0;
REF_PRINT_COUNT("BIO", *ret, a);
if (*ret > 0)
REF_PRINT_COUNT("BIO", ret, a);
if (ret > 0)
return 1;
REF_ASSERT_ISNT(*ret < 0);
REF_ASSERT_ISNT(ret < 0);
if (HAS_CALLBACK(a)) {
if ((int)bio_call_callback(a, BIO_CB_FREE, NULL, 0, 0, 0L, 1L, NULL) <= 0)
ret = (int)bio_call_callback(a, BIO_CB_FREE, NULL, 0, 0, 0L, 1L, NULL);
if (ret <= 0)
return 0;
}
@ -147,13 +149,6 @@ static int BIO_free_int(BIO *a, int *ret)
return 1;
}
int BIO_free(BIO *b)
{
int ref;
return BIO_free_int(b, &ref);
}
void BIO_set_data(BIO *a, void *ptr)
{
a->ptr = ptr;
@ -193,7 +188,7 @@ int BIO_up_ref(BIO *a)
{
int i;
if (!CRYPTO_UP_REF(&a->references, &i))
if (CRYPTO_UP_REF(&a->references, &i) <= 0)
return 0;
REF_PRINT_COUNT("BIO", i, a);
@ -879,11 +874,11 @@ void BIO_free_all(BIO *bio)
while (bio != NULL) {
b = bio;
CRYPTO_GET_REF(&b->references, &ref);
bio = bio->next_bio;
ref = 0;
BIO_free_int(b, &ref);
/* Since ref count > 0, don't free anyone else. */
if (ref > 0)
BIO_free(b);
/* Since ref count > 1, don't free anyone else. */
if (ref > 1)
break;
}
}

View file

@ -74,7 +74,6 @@ struct bio_addrinfo_st {
#include "internal/cryptlib.h"
#include "internal/bio.h"
#include "internal/refcount.h"
#include "internal/time.h"
typedef struct bio_f_buffer_ctx_struct {
/*-
@ -123,87 +122,6 @@ struct bio_st {
};
#ifndef OPENSSL_NO_SOCK
typedef struct bio_connect_st {
int state;
int connect_family;
int connect_sock_type;
char *param_hostname;
char *param_service;
int connect_mode;
#ifndef OPENSSL_NO_KTLS
unsigned char record_type;
#endif
int tfo_first;
BIO_ADDRINFO *addr_first;
const BIO_ADDRINFO *addr_iter;
/*
* int socket; this will be kept in bio->num so that it is compatible
* with the bss_sock bio
*/
/*
* called when the connection is initially made callback(BIO,state,ret);
* The callback should return 'ret'. state is for compatibility with the
* ssl info_callback
*/
BIO_info_cb *info_callback;
/*
* Used when connect_sock_type is SOCK_DGRAM. Owned by us; we forward
* read/write(mmsg) calls to this if present.
*/
BIO *dgram_bio;
} BIO_CONNECT;
typedef struct bio_accept_st {
int state;
int accept_family;
int bind_mode; /* Socket mode for BIO_listen */
int accepted_mode; /* Socket mode for BIO_accept (set on accepted sock) */
char *param_addr;
char *param_serv;
int accept_sock;
BIO_ADDRINFO *addr_first;
const BIO_ADDRINFO *addr_iter;
BIO_ADDR cache_accepting_addr; /* Useful if we asked for port 0 */
char *cache_accepting_name, *cache_accepting_serv;
BIO_ADDR cache_peer_addr;
char *cache_peer_name, *cache_peer_serv;
BIO *bio_chain;
} BIO_ACCEPT;
#ifndef OPENSSL_NO_DGRAM
typedef struct bio_dgram_data_st {
BIO_ADDR peer;
BIO_ADDR local_addr;
unsigned int connected;
unsigned int _errno;
unsigned int mtu;
OSSL_TIME next_timeout;
OSSL_TIME socket_timeout;
unsigned int peekmode;
char local_addr_enabled;
} bio_dgram_data;
#endif
#define BIO_CONN_S_BEFORE 1
#define BIO_CONN_S_GET_ADDR 2
#define BIO_CONN_S_CREATE_SOCKET 3
#define BIO_CONN_S_CONNECT 4
#define BIO_CONN_S_OK 5
#define BIO_CONN_S_BLOCKED_CONNECT 6
#define BIO_CONN_S_CONNECT_ERROR 7
#define BIO_ACPT_S_BEFORE 1
#define BIO_ACPT_S_GET_ADDR 2
#define BIO_ACPT_S_CREATE_SOCKET 3
#define BIO_ACPT_S_LISTEN 4
#define BIO_ACPT_S_ACCEPT 5
#define BIO_ACPT_S_OK 6
#ifdef OPENSSL_SYS_VMS
typedef unsigned int socklen_t;
#endif

View file

@ -111,7 +111,7 @@ int BIO_vprintf(BIO *bio, const char *format, va_list args)
*/
sz = vsnprintf(buf, sizeof(buf), format, args);
if (sz >= 0) {
if ((size_t)sz >= sizeof(buf)) {
if ((size_t)sz > sizeof(buf)) {
sz += 1;
abuf = (char *)OPENSSL_malloc(sz);
if (abuf == NULL) {

View file

@ -15,6 +15,26 @@
#ifndef OPENSSL_NO_SOCK
typedef struct bio_accept_st {
int state;
int accept_family;
int bind_mode; /* Socket mode for BIO_listen */
int accepted_mode; /* Socket mode for BIO_accept (set on accepted sock) */
char *param_addr;
char *param_serv;
int accept_sock;
BIO_ADDRINFO *addr_first;
const BIO_ADDRINFO *addr_iter;
BIO_ADDR cache_accepting_addr; /* Useful if we asked for port 0 */
char *cache_accepting_name, *cache_accepting_serv;
BIO_ADDR cache_peer_addr;
char *cache_peer_name, *cache_peer_serv;
BIO *bio_chain;
} BIO_ACCEPT;
static int acpt_write(BIO *h, const char *buf, int num);
static int acpt_read(BIO *h, char *buf, int size);
static int acpt_puts(BIO *h, const char *str);
@ -26,6 +46,13 @@ static void acpt_close_socket(BIO *data);
static BIO_ACCEPT *BIO_ACCEPT_new(void);
static void BIO_ACCEPT_free(BIO_ACCEPT *a);
#define ACPT_S_BEFORE 1
#define ACPT_S_GET_ADDR 2
#define ACPT_S_CREATE_SOCKET 3
#define ACPT_S_LISTEN 4
#define ACPT_S_ACCEPT 5
#define ACPT_S_OK 6
static const BIO_METHOD methods_acceptp = {
BIO_TYPE_ACCEPT,
"socket accept",
@ -56,7 +83,7 @@ static int acpt_new(BIO *bi)
if ((ba = BIO_ACCEPT_new()) == NULL)
return 0;
bi->ptr = (char *)ba;
ba->state = BIO_ACPT_S_BEFORE;
ba->state = ACPT_S_BEFORE;
bi->shutdown = 1;
return 1;
}
@ -125,7 +152,7 @@ static int acpt_state(BIO *b, BIO_ACCEPT *c)
for (;;) {
switch (c->state) {
case BIO_ACPT_S_BEFORE:
case ACPT_S_BEFORE:
if (c->param_addr == NULL && c->param_serv == NULL) {
ERR_raise_data(ERR_LIB_BIO,
BIO_R_NO_ACCEPT_ADDR_OR_SERVICE_SPECIFIED,
@ -147,10 +174,10 @@ static int acpt_state(BIO *b, BIO_ACCEPT *c)
OPENSSL_free(c->cache_peer_serv);
c->cache_peer_serv = NULL;
c->state = BIO_ACPT_S_GET_ADDR;
c->state = ACPT_S_GET_ADDR;
break;
case BIO_ACPT_S_GET_ADDR: {
case ACPT_S_GET_ADDR: {
int family = AF_UNSPEC;
switch (c->accept_family) {
case BIO_FAMILY_IPV6:
@ -186,10 +213,10 @@ static int acpt_state(BIO *b, BIO_ACCEPT *c)
goto exit_loop;
}
c->addr_iter = c->addr_first;
c->state = BIO_ACPT_S_CREATE_SOCKET;
c->state = ACPT_S_CREATE_SOCKET;
break;
case BIO_ACPT_S_CREATE_SOCKET:
case ACPT_S_CREATE_SOCKET:
ERR_set_mark();
s = BIO_socket(BIO_ADDRINFO_family(c->addr_iter),
BIO_ADDRINFO_socktype(c->addr_iter),
@ -211,11 +238,11 @@ static int acpt_state(BIO *b, BIO_ACCEPT *c)
}
c->accept_sock = s;
b->num = s;
c->state = BIO_ACPT_S_LISTEN;
c->state = ACPT_S_LISTEN;
s = -1;
break;
case BIO_ACPT_S_LISTEN: {
case ACPT_S_LISTEN: {
if (!BIO_listen(c->accept_sock,
BIO_ADDRINFO_address(c->addr_iter),
c->bind_mode)) {
@ -244,14 +271,14 @@ static int acpt_state(BIO *b, BIO_ACCEPT *c)
OPENSSL_free(c->cache_accepting_serv);
c->cache_accepting_name = BIO_ADDR_hostname_string(&c->cache_accepting_addr, 1);
c->cache_accepting_serv = BIO_ADDR_service_string(&c->cache_accepting_addr, 1);
c->state = BIO_ACPT_S_ACCEPT;
c->state = ACPT_S_ACCEPT;
s = -1;
ret = 1;
goto end;
case BIO_ACPT_S_ACCEPT:
case ACPT_S_ACCEPT:
if (b->next_bio != NULL) {
c->state = BIO_ACPT_S_OK;
c->state = ACPT_S_OK;
break;
}
BIO_clear_retry_flags(b);
@ -307,14 +334,14 @@ static int acpt_state(BIO *b, BIO_ACCEPT *c)
c->cache_peer_name = BIO_ADDR_hostname_string(&c->cache_peer_addr, 1);
c->cache_peer_serv = BIO_ADDR_service_string(&c->cache_peer_addr, 1);
c->state = BIO_ACPT_S_OK;
c->state = ACPT_S_OK;
bio = NULL;
ret = 1;
goto end;
case BIO_ACPT_S_OK:
case ACPT_S_OK:
if (b->next_bio == NULL) {
c->state = BIO_ACPT_S_ACCEPT;
c->state = ACPT_S_ACCEPT;
break;
}
ret = 1;
@ -385,7 +412,7 @@ static long acpt_ctrl(BIO *b, int cmd, long num, void *ptr)
switch (cmd) {
case BIO_CTRL_RESET:
ret = 0;
data->state = BIO_ACPT_S_BEFORE;
data->state = ACPT_S_BEFORE;
acpt_close_socket(b);
BIO_ADDRINFO_free(data->addr_first);
data->addr_first = NULL;
@ -447,7 +474,7 @@ static long acpt_ctrl(BIO *b, int cmd, long num, void *ptr)
case BIO_C_SET_FD:
b->num = *((int *)ptr);
data->accept_sock = b->num;
data->state = BIO_ACPT_S_ACCEPT;
data->state = ACPT_S_ACCEPT;
b->shutdown = (int)num;
b->init = 1;
break;

View file

@ -16,6 +16,37 @@
#ifndef OPENSSL_NO_SOCK
typedef struct bio_connect_st {
int state;
int connect_family;
int connect_sock_type;
char *param_hostname;
char *param_service;
int connect_mode;
#ifndef OPENSSL_NO_KTLS
unsigned char record_type;
#endif
int tfo_first;
BIO_ADDRINFO *addr_first;
const BIO_ADDRINFO *addr_iter;
/*
* int socket; this will be kept in bio->num so that it is compatible
* with the bss_sock bio
*/
/*
* called when the connection is initially made callback(BIO,state,ret);
* The callback should return 'ret'. state is for compatibility with the
* ssl info_callback
*/
BIO_info_cb *info_callback;
/*
* Used when connect_sock_type is SOCK_DGRAM. Owned by us; we forward
* read/write(mmsg) calls to this if present.
*/
BIO *dgram_bio;
} BIO_CONNECT;
static int conn_write(BIO *h, const char *buf, int num);
static int conn_read(BIO *h, char *buf, int size);
static int conn_puts(BIO *h, const char *str);
@ -34,6 +65,14 @@ static void conn_close_socket(BIO *data);
static BIO_CONNECT *BIO_CONNECT_new(void);
static void BIO_CONNECT_free(BIO_CONNECT *a);
#define BIO_CONN_S_BEFORE 1
#define BIO_CONN_S_GET_ADDR 2
#define BIO_CONN_S_CREATE_SOCKET 3
#define BIO_CONN_S_CONNECT 4
#define BIO_CONN_S_OK 5
#define BIO_CONN_S_BLOCKED_CONNECT 6
#define BIO_CONN_S_CONNECT_ERROR 7
static const BIO_METHOD methods_connectp = {
BIO_TYPE_CONNECT,
"socket connect",

View file

@ -14,6 +14,7 @@
#include <stdio.h>
#include <errno.h>
#include "internal/time.h"
#include "bio_local.h"
#ifndef OPENSSL_NO_DGRAM
@ -212,7 +213,21 @@ static const BIO_METHOD methods_dgramp_sctp = {
NULL, /* sendmmsg */
NULL, /* recvmmsg */
};
#endif
typedef struct bio_dgram_data_st {
BIO_ADDR peer;
BIO_ADDR local_addr;
unsigned int connected;
unsigned int _errno;
unsigned int mtu;
OSSL_TIME next_timeout;
OSSL_TIME socket_timeout;
unsigned int peekmode;
char local_addr_enabled;
} bio_dgram_data;
#ifndef OPENSSL_NO_SCTP
typedef struct bio_dgram_sctp_save_message_st {
BIO *bio;
char *data;

View file

@ -332,13 +332,7 @@ static long file_ctrl(BIO *b, int cmd, long num, void *ptr)
/* the ptr parameter is actually a FILE ** in this case. */
if (ptr != NULL) {
fpp = (FILE **)ptr;
if (BIO_FLAGS_UPLINK_INTERNAL == 0
|| b->flags & BIO_FLAGS_UPLINK_INTERNAL) {
*fpp = (FILE *)b->ptr;
} else { /* avoid returning internal FILE * to the app */
*fpp = NULL;
ret = 0;
}
*fpp = (FILE *)b->ptr;
}
break;
case BIO_CTRL_GET_CLOSE:

View file

@ -22,7 +22,8 @@
#include "bio_local.h"
#include "internal/cryptlib.h"
#if defined(OPENSSL_SYS_WIN32)
#if defined(OPENSSL_SYS_WINCE)
#elif defined(OPENSSL_SYS_WIN32)
#elif defined(__wasi__)
#define NO_SYSLOG
#elif defined(OPENSSL_SYS_VMS)

View file

@ -8,7 +8,7 @@
*/
#include "../bn_local.h"
#if !defined(__GNUC__)
#if !(defined(__GNUC__) && __GNUC__ >= 2)
/* clang-format off */
# include "../bn_asm.c" /* kind of dirty hack for Sun Studio */
/* clang-format on */
@ -261,7 +261,7 @@ BN_ULONG bn_sub_words(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,
#else
/* Simics 1.4<7 has buggy sbbq:-( */
#define BN_MASK2 0xffffffffffffffffL
BN_ULONG bn_sub_words(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n)
BN_ULONG bn_sub_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b, int n)
{
BN_ULONG t1, t2;
int c = 0;
@ -408,7 +408,7 @@ BN_ULONG bn_sub_words(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n)
#define sqr_add_c2(a, i, j, c0, c1, c2) \
mul_add_c2((a)[i], (a)[j], c0, c1, c2)
void bn_mul_comba8(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b)
void bn_mul_comba8(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b)
{
BN_ULONG c1, c2, c3;
@ -511,7 +511,7 @@ void bn_mul_comba8(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b)
r[15] = c1;
}
void bn_mul_comba4(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b)
void bn_mul_comba4(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b)
{
BN_ULONG c1, c2, c3;

View file

@ -96,9 +96,7 @@ int BN_uadd(BIGNUM *r, const BIGNUM *a, const BIGNUM *b)
if (bn_wexpand(r, max + 1) == NULL)
return 0;
r->top = max;
if (max == 0)
goto end;
bn_set_top(r, max);
ap = a->d;
bp = b->d;
@ -116,9 +114,8 @@ int BN_uadd(BIGNUM *r, const BIGNUM *a, const BIGNUM *b)
carry &= (t2 == 0);
}
*rp = carry;
r->top += (int)carry;
bn_set_top(r, r->top + (int)carry);
end:
r->neg = 0;
bn_check_top(r);
return 1;
@ -146,9 +143,6 @@ int BN_usub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b)
if (bn_wexpand(r, max) == NULL)
return 0;
if (max == 0)
goto end;
ap = a->d;
bp = b->d;
rp = r->d;
@ -168,10 +162,8 @@ int BN_usub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b)
while (max && *--rp == 0)
max--;
end:
r->top = max;
bn_set_top(r, max);
r->neg = 0;
bn_pollute(r);
return 1;
}

View file

@ -622,7 +622,7 @@ BN_ULONG bn_sub_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b,
mul_add_c2((a)[i], (a)[j], c0, c1, c2)
#endif /* !BN_LLONG */
void bn_mul_comba8(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b)
void bn_mul_comba8(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b)
{
BN_ULONG c1, c2, c3;
@ -725,7 +725,7 @@ void bn_mul_comba8(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b)
r[15] = c1;
}
void bn_mul_comba4(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b)
void bn_mul_comba4(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b)
{
BN_ULONG c1, c2, c3;
@ -1006,7 +1006,7 @@ void bn_sqr_comba8(BN_ULONG *r, const BN_ULONG *a)
bn_sqr_normal(r, a, 8, t);
}
void bn_mul_comba4(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b)
void bn_mul_comba4(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b)
{
r[4] = bn_mul_words(&(r[0]), a, 4, b[0]);
r[5] = bn_mul_add_words(&(r[1]), a, 4, b[1]);
@ -1014,7 +1014,7 @@ void bn_mul_comba4(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b)
r[7] = bn_mul_add_words(&(r[3]), a, 4, b[3]);
}
void bn_mul_comba8(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b)
void bn_mul_comba8(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b)
{
r[8] = bn_mul_words(&(r[0]), a, 8, b[0]);
r[9] = bn_mul_add_words(&(r[1]), a, 8, b[1]);

View file

@ -185,7 +185,7 @@ int BN_BLINDING_invert_ex(BIGNUM *n, const BIGNUM *r, BN_BLINDING *b,
}
mask = (BN_ULONG)0 - ((rtop - ntop) >> (8 * sizeof(ntop) - 1));
/* always true, if (rtop >= ntop) n->top = r->top; */
n->top = (int)((rtop & ~mask) | (ntop & mask));
bn_set_top(n, (int)((rtop & ~mask) | (ntop & mask)));
n->flags |= (BN_FLG_FIXED_TOP & ~mask);
}
ret = bn_mul_mont_fixed_top(n, n, r, b->m_ctx, ctx);

View file

@ -178,7 +178,7 @@ int BN_hex2bn(BIGNUM **bn, const char *a)
}
j -= BN_BYTES * 2;
}
ret->top = h;
bn_set_top(ret, h);
bn_correct_top(ret);
*bn = ret;

View file

@ -1374,50 +1374,53 @@ static const BN_ULONG ffdhe8192_q[] = {
#define make_dh_bn(x) \
extern const BIGNUM ossl_bignum_##x; \
const BIGNUM ossl_bignum_##x = { \
(BN_ULONG *)x, \
OSSL_NELEM(x), \
OSSL_NELEM(x), \
0, BN_FLG_STATIC_DATA \
};
.d = (BN_ULONG *)x, \
.top = OSSL_NELEM(x), \
.dmax = OSSL_NELEM(x), \
.flags = BN_FLG_STATIC_DATA, \
}
static const BN_ULONG value_2 = 2;
const BIGNUM ossl_bignum_const_2 = {
(BN_ULONG *)&value_2, 1, 1, 0, BN_FLG_STATIC_DATA
.d = (BN_ULONG *)&value_2,
.top = 1,
.dmax = 1,
.flags = BN_FLG_STATIC_DATA,
};
make_dh_bn(dh1024_160_p)
make_dh_bn(dh1024_160_q)
make_dh_bn(dh1024_160_g)
make_dh_bn(dh2048_224_p)
make_dh_bn(dh2048_224_q)
make_dh_bn(dh2048_224_g)
make_dh_bn(dh2048_256_p)
make_dh_bn(dh2048_256_q)
make_dh_bn(dh2048_256_g)
make_dh_bn(dh1024_160_p);
make_dh_bn(dh1024_160_q);
make_dh_bn(dh1024_160_g);
make_dh_bn(dh2048_224_p);
make_dh_bn(dh2048_224_q);
make_dh_bn(dh2048_224_g);
make_dh_bn(dh2048_256_p);
make_dh_bn(dh2048_256_q);
make_dh_bn(dh2048_256_g);
make_dh_bn(ffdhe2048_p)
make_dh_bn(ffdhe2048_q)
make_dh_bn(ffdhe3072_p)
make_dh_bn(ffdhe3072_q)
make_dh_bn(ffdhe4096_p)
make_dh_bn(ffdhe4096_q)
make_dh_bn(ffdhe6144_p)
make_dh_bn(ffdhe6144_q)
make_dh_bn(ffdhe8192_p)
make_dh_bn(ffdhe8192_q)
make_dh_bn(ffdhe2048_p);
make_dh_bn(ffdhe2048_q);
make_dh_bn(ffdhe3072_p);
make_dh_bn(ffdhe3072_q);
make_dh_bn(ffdhe4096_p);
make_dh_bn(ffdhe4096_q);
make_dh_bn(ffdhe6144_p);
make_dh_bn(ffdhe6144_q);
make_dh_bn(ffdhe8192_p);
make_dh_bn(ffdhe8192_q);
#ifndef FIPS_MODULE
make_dh_bn(modp_1536_p)
make_dh_bn(modp_1536_q)
make_dh_bn(modp_1536_p);
make_dh_bn(modp_1536_q);
#endif
make_dh_bn(modp_2048_p)
make_dh_bn(modp_2048_q)
make_dh_bn(modp_3072_p)
make_dh_bn(modp_3072_q)
make_dh_bn(modp_4096_p)
make_dh_bn(modp_4096_q)
make_dh_bn(modp_6144_p)
make_dh_bn(modp_6144_q)
make_dh_bn(modp_8192_p)
make_dh_bn(modp_8192_q)
make_dh_bn(modp_2048_p);
make_dh_bn(modp_2048_q);
make_dh_bn(modp_3072_p);
make_dh_bn(modp_3072_q);
make_dh_bn(modp_4096_p);
make_dh_bn(modp_4096_q);
make_dh_bn(modp_6144_p);
make_dh_bn(modp_6144_q);
make_dh_bn(modp_8192_p);
make_dh_bn(modp_8192_q);

View file

@ -61,7 +61,7 @@ int BN_div(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m, const BIGNUM *d,
BN_zero(dv);
if (bn_wexpand(dv, 1) == NULL)
goto end;
dv->top = 1;
bn_set_top(dv, 1);
if (!BN_lshift(D, D, nm - nd))
goto end;
@ -160,7 +160,7 @@ static int bn_left_align(BIGNUM *num)
#if !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM) \
&& !defined(PEDANTIC) && !defined(BN_DIV3W)
#if defined(__GNUC__)
#if defined(__GNUC__) && __GNUC__ >= 2
#if defined(__i386) || defined(__i386__)
/*-
* There were two reasons for implementing this template:
@ -310,7 +310,9 @@ int bn_div_fixed_top(BIGNUM *dv, BIGNUM *rm, const BIGNUM *num,
if (bn_wexpand(snum, div_n + 1) == NULL)
goto err;
memset(&(snum->d[num_n]), 0, (div_n - num_n + 1) * sizeof(BN_ULONG));
snum->top = num_n = div_n + 1;
num_n = div_n + 1;
bn_set_top(snum, num_n);
snum->flags |= BN_FLG_FIXED_TOP;
}
loop = num_n - div_n;
@ -330,13 +332,15 @@ int bn_div_fixed_top(BIGNUM *dv, BIGNUM *rm, const BIGNUM *num,
goto err;
num_neg = num->neg;
res->neg = (num_neg ^ divisor->neg);
res->top = loop;
bn_set_top(res, loop);
res->flags |= BN_FLG_FIXED_TOP;
resp = &(res->d[loop]);
/* space for temp */
if (!bn_wexpand(tmp, (div_n + 1)))
goto err;
tmp->top = div_n + 1;
tmp->flags |= BN_FLG_FIXED_TOP;
for (i = 0; i < loop; i++, wnumtop--) {
BN_ULONG q, l0;
@ -446,7 +450,7 @@ int bn_div_fixed_top(BIGNUM *dv, BIGNUM *rm, const BIGNUM *num,
}
/* snum holds remainder, it's as wide as divisor */
snum->neg = num_neg;
snum->top = div_n;
bn_set_top(snum, div_n);
snum->flags |= BN_FLG_FIXED_TOP;
if (rm != NULL && bn_rshift_fixed_top(rm, snum, norm_shift) == 0)

View file

@ -402,7 +402,7 @@ int BN_mod_exp_mont(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
r->d[0] = (0 - m->d[0]) & BN_MASK2;
for (i = 1; i < j; i++)
r->d[i] = (~m->d[i]) & BN_MASK2;
r->top = j;
bn_set_top(r, j);
r->flags |= BN_FLG_FIXED_TOP;
} else
#endif
@ -468,7 +468,8 @@ int BN_mod_exp_mont(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
val[0]->d[0] = 1; /* borrow val[0] */
for (i = 1; i < j; i++)
val[0]->d[i] = 0;
val[0]->top = j;
bn_set_top(val[0], j);
val[0]->flags |= BN_FLG_FIXED_TOP;
if (!BN_mod_mul_montgomery(rr, r, val[0], mont, ctx))
goto err;
} else
@ -581,7 +582,7 @@ static int MOD_EXP_CTIME_COPY_FROM_PREBUF(BIGNUM *b, int top,
}
}
b->top = top;
bn_set_top(b, top);
b->flags |= BN_FLG_FIXED_TOP;
return 1;
}
@ -612,7 +613,7 @@ int bn_mod_exp_mont_fixed_top(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
unsigned char *powerbufFree = NULL;
int powerbufLen = 0;
unsigned char *powerbuf = NULL;
BIGNUM tmp, am;
BIGNUM tmp = { .data = NULL }, am = { .data = NULL };
#if defined(SPARC_T4_MONT)
unsigned int t4 = 0;
#endif
@ -681,7 +682,7 @@ int bn_mod_exp_mont_fixed_top(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
goto err;
RSAZ_1024_mod_exp_avx2(rr->d, a->d, p->d, m->d, mont->RR.d,
mont->n0[0]);
rr->top = 16;
bn_set_top(rr, 16);
rr->neg = 0;
bn_correct_top(rr);
ret = 1;
@ -690,7 +691,7 @@ int bn_mod_exp_mont_fixed_top(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
if (NULL == bn_wexpand(rr, 8))
goto err;
RSAZ_512_mod_exp(rr->d, a->d, p->d, m->d, mont->n0[0], mont->RR.d);
rr->top = 8;
bn_set_top(rr, 8);
rr->neg = 0;
bn_correct_top(rr);
ret = 1;
@ -1488,12 +1489,12 @@ int BN_mod_exp_mont_consttime_x2(BIGNUM *rr1, const BIGNUM *a1, const BIGNUM *p1
mont2->RR.d, mont2->n0[0],
mod_bits);
rr1->top = topn;
bn_set_top(rr1, topn);
rr1->neg = 0;
bn_correct_top(rr1);
bn_check_top(rr1);
rr2->top = topn;
bn_set_top(rr2, topn);
rr2->neg = 0;
bn_correct_top(rr2);
bn_check_top(rr2);

View file

@ -267,7 +267,7 @@ int BN_GF2m_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b)
r->d[i] = at->d[i];
}
r->top = at->top;
bn_set_top(r, at->top);
bn_correct_top(r);
return 1;
@ -305,7 +305,7 @@ int BN_GF2m_mod_arr(BIGNUM *r, const BIGNUM *a, const int p[])
for (j = 0; j < a->top; j++) {
r->d[j] = a->d[j];
}
r->top = a->top;
bn_set_top(r, a->top);
}
z = r->d;
@ -419,7 +419,7 @@ int BN_GF2m_mod_mul_arr(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
zlen = a->top + b->top + 4;
if (!bn_wexpand(s, zlen))
goto err;
s->top = zlen;
bn_set_top(s, zlen);
for (i = 0; i < zlen; i++)
s->d[i] = 0;
@ -498,7 +498,7 @@ int BN_GF2m_mod_sqr_arr(BIGNUM *r, const BIGNUM *a, const int p[],
s->d[2 * i] = SQR0(a->d[i]);
}
s->top = 2 * a->top;
bn_set_top(s, 2 * a->top);
bn_correct_top(s);
if (!BN_GF2m_mod_arr(r, s, p))
goto err;
@ -618,20 +618,20 @@ static int BN_GF2m_mod_inv_vartime(BIGNUM *r, const BIGNUM *a,
udp = u->d;
for (i = u->top; i < top; i++)
udp[i] = 0;
u->top = top;
bn_set_top(u, top);
if (!bn_wexpand(b, top))
goto err;
bdp = b->d;
bdp[0] = 1;
for (i = 1; i < top; i++)
bdp[i] = 0;
b->top = top;
bn_set_top(b, top);
if (!bn_wexpand(c, top))
goto err;
cdp = c->d;
for (i = 0; i < top; i++)
cdp[i] = 0;
c->top = top;
bn_set_top(c, top);
vdp = v->d; /* It pays off to "cache" *->d pointers,
* because it allows optimizer to be more
* aggressive. But we don't have to "cache"

View file

@ -174,7 +174,9 @@ void bn_set_static_words(BIGNUM *a, const BN_ULONG *words, int size)
* |const| qualifier omission is compensated by BN_FLG_STATIC_DATA
* flag, which effectively means "read-only data".
*/
a->data = NULL;
a->d = (BN_ULONG *)words;
/* No need to call bn_set_top() in this case */
a->dmax = a->top = size;
a->neg = 0;
a->flags |= BN_FLG_STATIC_DATA;
@ -188,8 +190,10 @@ int bn_set_words(BIGNUM *a, const BN_ULONG *words, int num_words)
return 0;
}
/* TODO(FIXNUM): In the future, we'll use an OSSL_FN function on a->data */
memcpy(a->d, words, sizeof(BN_ULONG) * num_words);
a->top = num_words;
bn_set_top(a, num_words);
bn_correct_top(a);
return 1;
}

View file

@ -1,5 +1,5 @@
/*
* Copyright 1995-2026 The OpenSSL Project Authors. All Rights Reserved.
* Copyright 1995-2025 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
@ -9,11 +9,14 @@
#include <assert.h>
#include <limits.h>
#include <stdbool.h>
#include <openssl/bn.h>
#include <openssl/opensslconf.h>
#include "internal/cryptlib.h"
#include "internal/endian.h"
#include "bn_local.h"
#include <openssl/opensslconf.h>
#include "internal/constant_time.h"
#include "crypto/fn.h"
#include "bn_local.h"
/* This stuff appears to be completely unused, so is deprecated */
#ifndef OPENSSL_NO_DEPRECATED_0_9_8
@ -83,12 +86,24 @@ const BIGNUM *BN_value_one(void)
{
static const BN_ULONG data_one = 1L;
static const BIGNUM const_one = {
(BN_ULONG *)&data_one, 1, 1, 0, BN_FLG_STATIC_DATA
.d = (BN_ULONG *)&data_one,
.top = 1,
.dmax = 1,
.flags = BN_FLG_STATIC_DATA,
};
return &const_one;
}
/*
* Old Visual Studio ARM compiler miscompiles BN_num_bits_word()
* https://mta.openssl.org/pipermail/openssl-users/2018-August/008465.html
*/
#if defined(_MSC_VER) && defined(_ARM_) && defined(_WIN32_WCE) \
&& _MSC_VER >= 1400 && _MSC_VER < 1501
#define MS_BROKEN_BN_num_bits_word
#pragma optimize("", off)
#endif
int BN_num_bits_word(BN_ULONG l)
{
BN_ULONG x, mask;
@ -133,6 +148,9 @@ int BN_num_bits_word(BN_ULONG l)
return bits;
}
#ifdef MS_BROKEN_BN_num_bits_word
#pragma optimize("", on)
#endif
/*
* This function still leaks `a->dmax`: it's caller's responsibility to
@ -187,7 +205,7 @@ int BN_num_bits(const BIGNUM *a)
return ((i * BN_BITS2) + BN_num_bits_word(a->d[i]));
}
static void bn_free_d(BIGNUM *a, int clear)
static void bn_free_d(BIGNUM *a, bool clear)
{
if (BN_get_flags(a, BN_FLG_SECURE))
OPENSSL_secure_clear_free(a->d, a->dmax * sizeof(a->d[0]));
@ -201,8 +219,12 @@ void BN_clear_free(BIGNUM *a)
{
if (a == NULL)
return;
if (a->d != NULL && !BN_get_flags(a, BN_FLG_STATIC_DATA))
bn_free_d(a, 1);
if (!BN_get_flags(a, BN_FLG_STATIC_DATA)) {
if (a->data != NULL)
OSSL_FN_clear_free(a->data);
else
bn_free_d(a, true);
}
if (BN_get_flags(a, BN_FLG_MALLOCED)) {
OPENSSL_cleanse(a, sizeof(*a));
OPENSSL_free(a);
@ -213,8 +235,12 @@ void BN_free(BIGNUM *a)
{
if (a == NULL)
return;
if (!BN_get_flags(a, BN_FLG_STATIC_DATA))
bn_free_d(a, 0);
if (!BN_get_flags(a, BN_FLG_STATIC_DATA)) {
if (a->data != NULL)
OSSL_FN_free(a->data);
else
bn_free_d(a, false);
}
if (a->flags & BN_FLG_MALLOCED)
OPENSSL_free(a);
}
@ -249,11 +275,11 @@ BIGNUM *BN_secure_new(void)
/* This is used by bn_expand2() */
/* The caller MUST check that words > b->dmax before calling this */
static BN_ULONG *bn_expand_internal(const BIGNUM *b, int words)
static OSSL_FN *bn_expand_internal(const BIGNUM *b, int words)
{
BN_ULONG *a = NULL;
OSSL_FN *a = NULL;
if (ossl_unlikely(words > (INT_MAX / (4 * BN_BITS2)))) {
if (ossl_unlikely(words > BN_MAX_WORDS)) {
ERR_raise(ERR_LIB_BN, BN_R_BIGNUM_TOO_LONG);
return NULL;
}
@ -262,15 +288,19 @@ static BN_ULONG *bn_expand_internal(const BIGNUM *b, int words)
return NULL;
}
if (BN_get_flags(b, BN_FLG_SECURE))
a = OPENSSL_secure_calloc(words, sizeof(*a));
a = OSSL_FN_secure_new_limbs(words);
else
a = OPENSSL_calloc(words, sizeof(*a));
a = OSSL_FN_new_limbs(words);
if (ossl_unlikely(a == NULL))
return NULL;
assert(b->top <= words);
if (b->top > 0)
memcpy(a, b->d, sizeof(*a) * b->top);
if (b->top > 0) {
if (b->data != NULL)
ossl_fn_copy_internal(a, b->data, -1);
else if (b->d != NULL)
ossl_fn_copy_internal_limbs(a, b->d, b->top);
}
return a;
}
@ -286,19 +316,58 @@ static BN_ULONG *bn_expand_internal(const BIGNUM *b, int words)
BIGNUM *bn_expand2(BIGNUM *b, int words)
{
if (ossl_likely(words > b->dmax)) {
BN_ULONG *a = bn_expand_internal(b, words);
OSSL_FN *a = bn_expand_internal(b, words);
if (ossl_unlikely(!a))
return NULL;
if (b->d != NULL)
bn_free_d(b, 1);
b->d = a;
b->dmax = words;
if (b->data != NULL)
OSSL_FN_clear_free(b->data);
else if (b->d != NULL)
bn_free_d(b, true);
b->data = a;
/* TODO(FIXNUM) The following is TO BE REMOVED */
b->d = b->data->d;
b->dmax = b->data->dsize;
}
return b;
}
OSSL_FN *bn_acquire_ossl_fn(BIGNUM *b, int limbs)
{
if (ossl_unlikely(b == NULL))
return NULL;
if (bn_wexpand(b, limbs) == NULL)
return NULL;
/* TODO(FIXNUM): should we add a flag bit for this in b->flags ? */
return b->data;
}
void bn_release(BIGNUM *b, int limbs)
{
if (ossl_unlikely(b == NULL || b->data == NULL))
return;
int fixed_top = (b->flags & BN_FLG_FIXED_TOP) != 0;
bn_set_top(b, limbs);
/* Don't correct top if BN_FLG_FIXED_TOP was set */
if (fixed_top)
return;
bn_correct_top(b);
}
OSSL_FN *bn_get_ossl_fn(const BIGNUM *bn)
{
if (ossl_unlikely(bn == NULL))
return NULL;
return bn->data;
}
BIGNUM *BN_dup(const BIGNUM *a)
{
BIGNUM *t;
@ -331,11 +400,14 @@ BIGNUM *BN_copy(BIGNUM *a, const BIGNUM *b)
if (ossl_unlikely(bn_wexpand(a, bn_words) == NULL))
return NULL;
if (ossl_likely(b->top > 0))
memcpy(a->d, b->d, sizeof(b->d[0]) * bn_words);
if (ossl_likely(bn_words > 0)) {
if (b->data != NULL)
ossl_fn_copy_internal(a->data, b->data, bn_words);
else if (b->d != NULL)
ossl_fn_copy_internal_limbs(a->data, b->d, bn_words);
}
a->neg = b->neg;
a->top = b->top;
bn_set_top(a, b->top);
a->flags |= b->flags & BN_FLG_FIXED_TOP;
bn_check_top(a);
return a;
@ -347,6 +419,7 @@ BIGNUM *BN_copy(BIGNUM *a, const BIGNUM *b)
void BN_swap(BIGNUM *a, BIGNUM *b)
{
int flags_old_a, flags_old_b;
OSSL_FN *tmp_data;
BN_ULONG *tmp_d;
int tmp_top, tmp_dmax, tmp_neg;
@ -356,16 +429,19 @@ void BN_swap(BIGNUM *a, BIGNUM *b)
flags_old_a = a->flags;
flags_old_b = b->flags;
tmp_data = a->data;
tmp_d = a->d;
tmp_top = a->top;
tmp_dmax = a->dmax;
tmp_neg = a->neg;
a->data = b->data;
a->d = b->d;
a->top = b->top;
a->dmax = b->dmax;
a->neg = b->neg;
b->data = tmp_data;
b->d = tmp_d;
b->top = tmp_top;
b->dmax = tmp_dmax;
@ -382,10 +458,12 @@ void BN_clear(BIGNUM *a)
if (a == NULL)
return;
bn_check_top(a);
if (a->d != NULL)
if (a->data != NULL)
OSSL_FN_clear(a->data);
else if (a->d != NULL)
OPENSSL_cleanse(a->d, sizeof(*a->d) * a->dmax);
a->neg = 0;
a->top = 0;
bn_set_top(a, 0);
a->flags &= ~BN_FLG_FIXED_TOP;
}
@ -402,11 +480,11 @@ BN_ULONG BN_get_word(const BIGNUM *a)
int BN_set_word(BIGNUM *a, BN_ULONG w)
{
bn_check_top(a);
if (bn_expand(a, (int)sizeof(BN_ULONG) * 8) == NULL)
if (bn_wexpand(a, 1) == NULL)
return 0;
a->neg = 0;
a->d[0] = w;
a->top = (w ? 1 : 0);
bn_set_top(a, (w ? 1 : 0));
a->flags &= ~BN_FLG_FIXED_TOP;
bn_check_top(a);
return 1;
@ -488,7 +566,7 @@ static BIGNUM *bin2bn(const unsigned char *s, int len, BIGNUM *ret,
}
/* If it was all zeros, we're done */
if (len == 0) {
ret->top = 0;
bn_set_top(ret, 0);
return ret;
}
n = ((len - 1) / BN_BYTES) + 1; /* Number of resulting bignum chunks */
@ -496,7 +574,7 @@ static BIGNUM *bin2bn(const unsigned char *s, int len, BIGNUM *ret,
BN_free(bn);
return NULL;
}
ret->top = n;
bn_set_top(ret, n);
ret->neg = neg;
for (i = 0; n-- > 0; i++) {
BN_ULONG l = 0; /* Accumulator */
@ -696,37 +774,19 @@ int BN_ucmp(const BIGNUM *a, const BIGNUM *b)
int i;
BN_ULONG t1, t2, *ap, *bp;
/*
* As it is a public API function, we should handle NULL parameters in
* some way. The function cant return an error, so lets define that NULL
* is less than any BIGNUM.
*/
if (!ossl_assert(a != NULL && b != NULL))
return (b == NULL) - (a == NULL);
ap = a->d;
bp = b->d;
if (BN_get_flags(a, BN_FLG_CONSTTIME)
|| BN_get_flags(b, BN_FLG_CONSTTIME)) {
&& a->top == b->top) {
int res = 0;
int min_top = a->top < b->top ? a->top : b->top;
for (i = 0; i < min_top; i++) {
for (i = 0; i < b->top; i++) {
res = constant_time_select_int((int)constant_time_lt_bn(ap[i], bp[i]),
-1, res);
res = constant_time_select_int((int)constant_time_lt_bn(bp[i], ap[i]),
1, res);
}
for (i = min_top; i < a->top; ++i)
res = constant_time_select_int((int)constant_time_is_zero_bn(ap[i]),
res, 1);
for (i = min_top; i < b->top; ++i)
res = constant_time_select_int((int)constant_time_is_zero_bn(bp[i]),
res, -1);
return res;
}
@ -795,7 +855,7 @@ int BN_cmp(const BIGNUM *a, const BIGNUM *b)
int BN_set_bit(BIGNUM *a, int n)
{
int i, j, k;
int i, j;
if (n < 0)
return 0;
@ -805,9 +865,12 @@ int BN_set_bit(BIGNUM *a, int n)
if (a->top <= i) {
if (bn_wexpand(a, i + 1) == NULL)
return 0;
for (k = a->top; k < i + 1; k++)
a->d[k] = 0;
a->top = i + 1;
/*
* If 'a' is actually expanded, we know that the expanded
* part of the 'd' array is zeroed during allocation, so
* no need to zero it again here.
*/
bn_set_top(a, i + 1);
a->flags &= ~BN_FLG_FIXED_TOP;
}
@ -860,9 +923,9 @@ int ossl_bn_mask_bits_fixed_top(BIGNUM *a, int n)
if (w >= a->top)
return 0;
if (b == 0)
a->top = w;
bn_set_top(a, w);
else {
a->top = w + 1;
bn_set_top(a, w + 1);
a->d[w] &= ~(BN_MASK2 << b);
}
a->flags |= BN_FLG_FIXED_TOP;
@ -1029,7 +1092,7 @@ int BN_security_bits(int L, int N)
void BN_zero_ex(BIGNUM *a)
{
a->neg = 0;
a->top = 0;
bn_set_top(a, 0);
a->flags &= ~BN_FLG_FIXED_TOP;
}
@ -1040,7 +1103,12 @@ int BN_abs_is_word(const BIGNUM *a, const BN_ULONG w)
int BN_is_zero(const BIGNUM *a)
{
return a->top == 0;
if ((a->flags & BN_FLG_FIXED_TOP) == 0)
return a->top == 0;
for (size_t i = a->top; i-- > 0;)
if (a->d[i] != (BN_ULONG)0)
return 0;
return 1;
}
int BN_is_one(const BIGNUM *a)
@ -1087,6 +1155,7 @@ int BN_to_montgomery(BIGNUM *r, const BIGNUM *a, BN_MONT_CTX *mont,
void BN_with_flags(BIGNUM *dest, const BIGNUM *b, int flags)
{
dest->data = b->data;
dest->d = b->d;
dest->top = b->top;
dest->dmax = b->dmax;
@ -1170,6 +1239,11 @@ void bn_correct_top_consttime(BIGNUM *a)
}
mask = constant_time_eq_int(atop, 0);
/*
* We just went through the whole 'd' array to identify where
* any leading set of zeros are located, so there's no need to
* call bn_set_top() here.
*/
a->top = atop;
a->neg = constant_time_select_int(mask, 0, a->neg);
a->flags &= ~BN_FLG_FIXED_TOP;
@ -1186,10 +1260,14 @@ void bn_correct_top(BIGNUM *a)
if (*ftl != 0)
break;
}
/*
* We just verified that the BN_ULONGs between a->top and
* tmp_top are all zero, so there's no need to call
* bn_set_top() here.
*/
a->top = tmp_top;
}
if (a->top == 0)
a->neg = 0;
a->flags &= ~BN_FLG_FIXED_TOP;
bn_pollute(a);
}

View file

@ -10,27 +10,24 @@
#ifndef OSSL_CRYPTO_BN_LOCAL_H
#define OSSL_CRYPTO_BN_LOCAL_H
#include <assert.h>
#include <string.h>
#include <openssl/opensslconf.h>
#include "internal/cryptlib.h"
#include "internal/numbers.h"
#include "crypto/bn.h"
#include "../fn/fn_local.h"
/*
* These preprocessor symbols control various aspects of the bignum headers
* and library code. They're not defined by any "normal" configuration, as
* they are intended for development and testing purposes. NB: defining
* them can be useful for debugging application code as well as openssl
* itself. BN_DEBUG - turn on various debugging alterations to the bignum
* code BN_RAND_DEBUG - uses random poisoning of unused words to trip up
* mismanagement of bignum internals. Enable BN_RAND_DEBUG is known to
* break some of the OpenSSL tests.
* BN_RAND_DEBUG was historically used to poison unused words in bignum data,
* for integrity debugging purposes. This isn't done any more, but enabling
* BN_RAND_DEBUG also defined BN_DEBUG, which we preserve for the moment.
*/
#if defined(BN_RAND_DEBUG) && !defined(BN_DEBUG)
#define BN_DEBUG
#endif
#if defined(BN_RAND_DEBUG)
#include <openssl/rand.h>
#endif
/*
* This should limit the stack usage due to alloca to about 4K.
@ -120,32 +117,65 @@ typedef unsigned long long BN_ULLONG;
#define BN_DEC_FMT2 "%09u"
#endif
#define BN_MAX_WORDS (INT_MAX / (4 * BN_BITS2))
BN_ULONG bn_mul_add_words(BN_ULONG *rp, const BN_ULONG *ap, int num,
BN_ULONG w);
BN_ULONG bn_mul_words(BN_ULONG *rp, const BN_ULONG *ap, int num, BN_ULONG w);
void bn_sqr_words(BN_ULONG *rp, const BN_ULONG *ap, int num);
BN_ULONG bn_div_words(BN_ULONG h, BN_ULONG l, BN_ULONG d);
BN_ULONG bn_add_words(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,
int num);
BN_ULONG bn_sub_words(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,
int num);
struct bignum_st {
/* The number itself is a FIXNUM */
OSSL_FN *data;
/* Some of these flags are replicated in OSSL_FN, some are not */
int flags;
BN_ULONG *d; /* Pointer to |data->d| */
int top; /* Index of last used d +1. */
/* The next are internal book keeping for bn_expand. */
int dmax; /* Copy of |data->dsize| */
int neg; /* One if the number is negative */
};
/*-
* Bignum consistency macros
*
* There is one "API" macro, bn_fix_top(), for stripping leading zeroes from
* bignum data after direct manipulations on the data. There is also an
* "internal" macro, bn_check_top(), for verifying that there are no leading
* zeroes. Unfortunately, some auditing is required due to the fact that
* bn_fix_top() has become an overabused duct-tape because bignum data is
* occasionally passed around in an inconsistent state. So the following
* changes have been made to sort this out;
* zeroes, and in case the BIGNUM has an integrated OSSL_FN, check the
* consistency of the integration, including that the unused part of the
* data is all zeros.
*
* Unfortunately, some auditing is required due to the fact that bn_fix_top()
* has become an overabused duck-tape because bignum data is occasionally
* passed around in an inconsistent state. So the following changes have been
* made to sort this out;
*
* - bn_fix_top()s implementation has been moved to bn_correct_top()
* - if BN_DEBUG isn't defined, bn_fix_top() maps to bn_correct_top(), and
* bn_check_top() is as before.
* - if BN_DEBUG *is* defined;
* - bn_check_top() tries to pollute unused words even if the bignum 'top' is
* consistent. (ed: only if BN_RAND_DEBUG is defined)
* - if BN_DEBUG isn't defined:
* - bn_check_top() does nothing.
* - bn_fix_top() maps to bn_correct_top()
* - if BN_DEBUG is defined:
* - bn_check_top() performs its consistency checks
* - bn_fix_top() maps to bn_check_top() rather than "fixing" anything.
*
* The idea is to have debug builds flag up inconsistent bignums when they
* occur. If that occurs in a bn_fix_top(), we examine the code in question; if
* the use of bn_fix_top() was appropriate (ie. it follows directly after code
* that manipulates the bignum) it is converted to bn_correct_top(), and if it
* was not appropriate, we convert it permanently to bn_check_top() and track
* down the cause of the bug. Eventually, no internal code should be using the
* bn_fix_top() macro. External applications and libraries should try this with
* their own code too, both in terms of building against the openssl headers
* with BN_DEBUG defined *and* linking with a version of OpenSSL built with it
* defined. This not only improves external code, it provides more test
* occur. If that occurs in a bn_fix_top(), we examine the code in question;
* if the use of bn_fix_top() was appropriate (ie. it follows directly after
* code that manipulates the bignum) it is converted to bn_correct_top(),
* and if it was not appropriate, we convert it permanently to bn_check_top()
* and track down the cause of the bug. Eventually, no internal code should be
* using the bn_fix_top() macro. External applications and libraries should try
* this with their own code too, both in terms of building against the openssl
* headers with BN_DEBUG defined *and* linking with a version of OpenSSL built
* with it defined. This not only improves external code, it provides more test
* coverage for openssl's own code.
*/
@ -164,54 +194,49 @@ typedef unsigned long long BN_ULLONG;
* all operations manipulating the bit in question in non-BN_DEBUG build.
*/
#define BN_FLG_FIXED_TOP 0x10000
#ifdef BN_RAND_DEBUG
#define bn_pollute(a) \
do { \
const BIGNUM *_bnum1 = (a); \
if (_bnum1->top < _bnum1->dmax) { \
unsigned char _tmp_char; \
/* We cast away const without the compiler knowing, any \
* *genuinely* constant variables that aren't mutable \
* wouldn't be constructed with top!=dmax. */ \
BN_ULONG *_not_const; \
memcpy(&_not_const, &_bnum1->d, sizeof(_not_const)); \
(void)RAND_bytes(&_tmp_char, 1); /* Debug only - safe to ignore error return */ \
memset(_not_const + _bnum1->top, _tmp_char, \
sizeof(*_not_const) * (_bnum1->dmax - _bnum1->top)); \
} \
} while (0)
#else
#define bn_pollute(a)
#endif
#define bn_check_top(a) \
do { \
const BIGNUM *_bnum2 = (a); \
if (_bnum2 != NULL) { \
int _top = _bnum2->top; \
if (_top == 0) { \
assert(!_bnum2->neg); \
} else if ((_bnum2->flags & BN_FLG_FIXED_TOP) == 0) { \
assert(_bnum2->d[_top - 1] != 0); \
} \
bn_pollute(_bnum2); \
} \
} while (0)
static ossl_inline bool bn_check_zero(BN_ULONG *words, int num_words)
{
for (int i = 0; i < num_words; i++)
if (words[i] != 0)
return false;
return true;
}
static ossl_inline void bn_check_top(const BIGNUM *bn)
{
if (bn != NULL) {
/* BIGNUM <-> OSSL_FN compat checks */
if (bn->data != NULL) {
/* TODO(FIXNUM): Assertion for the future */
/* assert(_bnum2->d == NULL); */
assert(bn->d == bn->data->d);
assert(bn->dmax == bn->data->dsize);
assert(bn_check_zero(&bn->d[bn->top], bn->dmax - bn->top));
}
/* BIGNUM specific checks */
if (bn->top == 0) {
assert(!bn->neg);
} else if ((bn->flags & BN_FLG_FIXED_TOP) == 0) {
assert(bn->d[bn->top - 1] != 0);
}
assert(bn->dmax >= 0 && bn->dmax <= BN_MAX_WORDS);
}
}
#define bn_fix_top(a) bn_check_top(a)
static ossl_inline void bn_wcheck_size(const BIGNUM *bn, int words)
{
assert(words <= bn->dmax);
assert(words >= bn->top);
}
#define bn_check_size(bn, bits) bn_wcheck_size(bn, ((bits + BN_BITS2 - 1)) / BN_BITS2)
#define bn_wcheck_size(bn, words) \
do { \
const BIGNUM *_bnum2 = (bn); \
assert((words) <= (_bnum2)->dmax && (words) >= (_bnum2)->top); \
/* avoid unused variable warning with NDEBUG */ \
(void)(_bnum2); \
} while (0)
#else /* !BN_DEBUG */
#define BN_FLG_FIXED_TOP 0
#define bn_pollute(a)
#define bn_check_top(a)
#define bn_fix_top(a) bn_correct_top(a)
#define bn_check_size(bn, bits)
@ -219,29 +244,6 @@ typedef unsigned long long BN_ULLONG;
#endif
BN_ULONG bn_mul_add_words(BN_ULONG *rp, const BN_ULONG *ap, int num,
BN_ULONG w);
BN_ULONG bn_mul_words(BN_ULONG *rp, const BN_ULONG *ap, int num, BN_ULONG w);
void bn_sqr_words(BN_ULONG *rp, const BN_ULONG *ap, int num);
BN_ULONG bn_div_words(BN_ULONG h, BN_ULONG l, BN_ULONG d);
BN_ULONG bn_add_words(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,
int num);
BN_ULONG bn_sub_words(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,
int num);
struct bignum_st {
BN_ULONG *d; /*
* Pointer to an array of 'BN_BITS2' bit
* chunks. These chunks are organised in
* a least significant chunk first order.
*/
int top; /* Index of last used d +1. */
/* The next are internal book keeping for bn_expand. */
int dmax; /* Size of the d array. */
int neg; /* one if the number is negative */
int flags;
};
/* Used for montgomery multiplication */
struct bn_mont_ctx_st {
BIGNUM RR; /* used to convert to montgomery form,
@ -380,7 +382,7 @@ struct bn_gencb_st {
#if defined(__DECC)
#include <c_asm.h>
#define BN_UMULT_HIGH(a, b) (BN_ULONG)asm("umulh %a0,%a1,%v0", (a), (b))
#elif defined(__GNUC__)
#elif defined(__GNUC__) && __GNUC__ >= 2
#define BN_UMULT_HIGH(a, b) ({ \
register BN_ULONG ret; \
asm ("umulh %1,%2,%0" \
@ -389,7 +391,7 @@ struct bn_gencb_st {
ret; })
#endif /* compiler */
#elif defined(_ARCH_PPC64) && defined(SIXTY_FOUR_BIT_LONG)
#if defined(__GNUC__)
#if defined(__GNUC__) && __GNUC__ >= 2
#define BN_UMULT_HIGH(a, b) ({ \
register BN_ULONG ret; \
asm ("mulhdu %0,%1,%2" \
@ -398,7 +400,7 @@ struct bn_gencb_st {
ret; })
#endif /* compiler */
#elif (defined(__x86_64) || defined(__x86_64__)) && (defined(SIXTY_FOUR_BIT_LONG) || defined(SIXTY_FOUR_BIT))
#if defined(__GNUC__)
#if defined(__GNUC__) && __GNUC__ >= 2
#define BN_UMULT_HIGH(a, b) ({ \
register BN_ULONG ret,discard; \
asm ("mulq %3" \
@ -422,7 +424,7 @@ unsigned __int64 _umul128(unsigned __int64 a, unsigned __int64 b,
#define BN_UMULT_LOHI(low, high, a, b) ((low) = _umul128((a), (b), &(high)))
#endif
#elif defined(__mips) && (defined(SIXTY_FOUR_BIT) || defined(SIXTY_FOUR_BIT_LONG))
#if defined(__GNUC__)
#if defined(__GNUC__) && __GNUC__ >= 2
#define BN_UMULT_HIGH(a, b) ({ \
register BN_ULONG ret; \
asm ("dmultu %1,%2" \
@ -435,7 +437,7 @@ unsigned __int64 _umul128(unsigned __int64 a, unsigned __int64 b,
: "r"(a), "r"(b));
#endif
#elif defined(__aarch64__) && defined(SIXTY_FOUR_BIT_LONG)
#if defined(__GNUC__)
#if defined(__GNUC__) && __GNUC__ >= 2
#define BN_UMULT_HIGH(a, b) ({ \
register BN_ULONG ret; \
asm ("umulh %0,%1,%2" \
@ -643,21 +645,21 @@ void BN_RECP_CTX_init(BN_RECP_CTX *recp);
void BN_MONT_CTX_init(BN_MONT_CTX *ctx);
void bn_init(BIGNUM *a);
void bn_mul_normal(BN_ULONG *r, BN_ULONG *a, int na, BN_ULONG *b, int nb);
void bn_mul_comba8(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b);
void bn_mul_comba4(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b);
void bn_mul_normal(BN_ULONG *r, const BN_ULONG *a, int na, const BN_ULONG *b, int nb);
void bn_mul_comba8(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b);
void bn_mul_comba4(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b);
void bn_sqr_normal(BN_ULONG *r, const BN_ULONG *a, int n, BN_ULONG *tmp);
void bn_sqr_comba8(BN_ULONG *r, const BN_ULONG *a);
void bn_sqr_comba4(BN_ULONG *r, const BN_ULONG *a);
int bn_cmp_words(const BN_ULONG *a, const BN_ULONG *b, int n);
int bn_cmp_part_words(const BN_ULONG *a, const BN_ULONG *b, int cl, int dl);
void bn_mul_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n2,
void bn_mul_recursive(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b, int n2,
int dna, int dnb, BN_ULONG *t);
void bn_mul_part_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b,
void bn_mul_part_recursive(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b,
int n, int tna, int tnb, BN_ULONG *t);
void bn_sqr_recursive(BN_ULONG *r, const BN_ULONG *a, int n2, BN_ULONG *t);
void bn_mul_low_normal(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n);
void bn_mul_low_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n2,
void bn_mul_low_normal(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b, int n);
void bn_mul_low_recursive(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b, int n2,
BN_ULONG *t);
BN_ULONG bn_sub_part_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b,
int cl, int dl);
@ -667,6 +669,7 @@ void bn_correct_top_consttime(BIGNUM *a);
BIGNUM *int_bn_mod_inverse(BIGNUM *in,
const BIGNUM *a, const BIGNUM *n, BN_CTX *ctx,
int *noinv);
void bn_mul_truncated(BN_ULONG *r, int nr, const BN_ULONG *a, int na, const BN_ULONG *b, int nb);
static ossl_inline BIGNUM *bn_expand(BIGNUM *a, int bits)
{
@ -682,4 +685,29 @@ static ossl_inline BIGNUM *bn_expand(BIGNUM *a, int bits)
int ossl_bn_check_prime(const BIGNUM *w, int checks, BN_CTX *ctx,
int do_trial_division, BN_GENCB *cb);
/**
* Set top on a given BIGNUM. If it has an associated OSSL_FN (the 'data'
* field is non-NULL), and the new 'top' is less than the existing 'top',
* zeroise the space between them.
*
* @param[in] b The BIGNUM instance to zeroise
* @param[in] newtop The new 'top'
* @returns the new 'top'
* @pre b must not be NULL and newtop must be zero or positive
*/
static ossl_inline int bn_set_top(BIGNUM *b, int newtop)
{
assert(b != NULL && newtop >= 0);
if (b->data != NULL && newtop < b->top) {
BN_ULONG *start = &(b->d[newtop]);
size_t bytes = sizeof(BN_ULONG) * (b->top - newtop);
memset(start, 0, bytes);
}
b->top = newtop;
return b->top;
}
#endif

View file

@ -90,7 +90,7 @@ int bn_mod_add_fixed_top(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
rp[i] = (carry & tp[i]) | (~carry & rp[i]);
((volatile BN_ULONG *)tp)[i] = 0;
}
r->top = (int)mtop;
bn_set_top(r, (int)mtop);
r->flags |= BN_FLG_FIXED_TOP;
r->neg = 0;
@ -176,7 +176,7 @@ int bn_mod_sub_fixed_top(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
carry += (rp[i] < ta);
}
r->top = (int)mtop;
bn_set_top(r, (int)mtop);
r->flags |= BN_FLG_FIXED_TOP;
r->neg = 0;

View file

@ -46,7 +46,7 @@ int bn_mul_mont_fixed_top(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
return 0;
if (bn_mul_mont(r->d, a->d, b->d, mont->N.d, mont->n0, num)) {
r->neg = a->neg ^ b->neg;
r->top = num;
bn_set_top(r, num);
r->flags |= BN_FLG_FIXED_TOP;
return 1;
}
@ -94,7 +94,7 @@ static int bn_from_montgomery_word(BIGNUM *ret, BIGNUM *r, BN_MONT_CTX *mont)
n = &(mont->N);
nl = n->top;
if (nl == 0) {
ret->top = 0;
bn_set_top(ret, 0);
return 1;
}
@ -112,7 +112,7 @@ static int bn_from_montgomery_word(BIGNUM *ret, BIGNUM *r, BN_MONT_CTX *mont)
rp[i] &= v;
}
r->top = max;
bn_set_top(r, max);
r->flags |= BN_FLG_FIXED_TOP;
n0 = mont->n0[0];
@ -131,7 +131,7 @@ static int bn_from_montgomery_word(BIGNUM *ret, BIGNUM *r, BN_MONT_CTX *mont)
if (bn_wexpand(ret, nl) == NULL)
return 0;
ret->top = nl;
bn_set_top(ret, nl);
ret->flags |= BN_FLG_FIXED_TOP;
ret->neg = r->neg;
@ -325,7 +325,7 @@ int BN_MONT_CTX_set(BN_MONT_CTX *mont, const BIGNUM *mod, BN_CTX *ctx)
Ri->neg = 0;
Ri->d[0] = BN_MASK2;
Ri->d[1] = BN_MASK2;
Ri->top = 2;
bn_set_top(Ri, 2);
}
if (!BN_div(Ri, NULL, Ri, &tmod, ctx))
goto err;

View file

@ -65,7 +65,7 @@ BIGNUM *BN_mpi2bn(const unsigned char *d, int n, BIGNUM *ain)
if (len == 0) {
a->neg = 0;
a->top = 0;
bn_set_top(a, 0);
return a;
}
d += 4;

View file

@ -11,479 +11,6 @@
#include "internal/cryptlib.h"
#include "bn_local.h"
#if defined(OPENSSL_NO_ASM) || !defined(OPENSSL_BN_ASM_PART_WORDS)
/*
* Here follows specialised variants of bn_add_words() and bn_sub_words().
* They have the property performing operations on arrays of different sizes.
* The sizes of those arrays is expressed through cl, which is the common
* length ( basically, min(len(a),len(b)) ), and dl, which is the delta
* between the two lengths, calculated as len(a)-len(b). All lengths are the
* number of BN_ULONGs... For the operations that require a result array as
* parameter, it must have the length cl+abs(dl). These functions should
* probably end up in bn_asm.c as soon as there are assembler counterparts
* for the systems that use assembler files.
*/
BN_ULONG bn_sub_part_words(BN_ULONG *r,
const BN_ULONG *a, const BN_ULONG *b,
int cl, int dl)
{
BN_ULONG c, t;
assert(cl >= 0);
c = bn_sub_words(r, a, b, cl);
if (dl == 0)
return c;
r += cl;
a += cl;
b += cl;
if (dl < 0) {
for (;;) {
t = b[0];
r[0] = (0 - t - c) & BN_MASK2;
if (t != 0)
c = 1;
if (++dl >= 0)
break;
t = b[1];
r[1] = (0 - t - c) & BN_MASK2;
if (t != 0)
c = 1;
if (++dl >= 0)
break;
t = b[2];
r[2] = (0 - t - c) & BN_MASK2;
if (t != 0)
c = 1;
if (++dl >= 0)
break;
t = b[3];
r[3] = (0 - t - c) & BN_MASK2;
if (t != 0)
c = 1;
if (++dl >= 0)
break;
b += 4;
r += 4;
}
} else {
int save_dl = dl;
while (c) {
t = a[0];
r[0] = (t - c) & BN_MASK2;
if (t != 0)
c = 0;
if (--dl <= 0)
break;
t = a[1];
r[1] = (t - c) & BN_MASK2;
if (t != 0)
c = 0;
if (--dl <= 0)
break;
t = a[2];
r[2] = (t - c) & BN_MASK2;
if (t != 0)
c = 0;
if (--dl <= 0)
break;
t = a[3];
r[3] = (t - c) & BN_MASK2;
if (t != 0)
c = 0;
if (--dl <= 0)
break;
save_dl = dl;
a += 4;
r += 4;
}
if (dl > 0) {
if (save_dl > dl) {
switch (save_dl - dl) {
case 1:
r[1] = a[1];
if (--dl <= 0)
break;
/* fall through */
case 2:
r[2] = a[2];
if (--dl <= 0)
break;
/* fall through */
case 3:
r[3] = a[3];
if (--dl <= 0)
break;
}
a += 4;
r += 4;
}
}
if (dl > 0) {
for (;;) {
r[0] = a[0];
if (--dl <= 0)
break;
r[1] = a[1];
if (--dl <= 0)
break;
r[2] = a[2];
if (--dl <= 0)
break;
r[3] = a[3];
if (--dl <= 0)
break;
a += 4;
r += 4;
}
}
}
return c;
}
#endif
#ifndef OPENSSL_SMALL_FOOTPRINT
/*
* Karatsuba recursive multiplication algorithm (cf. Knuth, The Art of
* Computer Programming, Vol. 2)
*/
/*-
* r is 2*n2 words in size,
* a and b are both n2 words in size.
* n2 must be a power of 2.
* We multiply and return the result.
* t must be 2*n2 words in size
* We calculate
* a[0]*b[0]
* a[0]*b[0]+a[1]*b[1]+(a[0]-a[1])*(b[1]-b[0])
* a[1]*b[1]
*/
/* dnX may not be positive, but n2/2+dnX has to be */
void bn_mul_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n2,
int dna, int dnb, BN_ULONG *t)
{
int n = n2 / 2, c1, c2;
int tna = n + dna, tnb = n + dnb;
unsigned int neg, zero;
BN_ULONG ln, lo, *p;
/*
* Only call bn_mul_comba 8 if n2 == 8 and the two arrays are complete
* [steve]
*/
if (n2 == 8 && dna == 0 && dnb == 0) {
bn_mul_comba8(r, a, b);
return;
}
/* Else do normal multiply */
if (n2 < BN_MUL_RECURSIVE_SIZE_NORMAL) {
bn_mul_normal(r, a, n2 + dna, b, n2 + dnb);
if ((dna + dnb) < 0)
memset(&r[2 * n2 + dna + dnb], 0,
sizeof(BN_ULONG) * -(dna + dnb));
return;
}
/* r=(a[0]-a[1])*(b[1]-b[0]) */
c1 = bn_cmp_part_words(a, &(a[n]), tna, n - tna);
c2 = bn_cmp_part_words(&(b[n]), b, tnb, tnb - n);
zero = neg = 0;
switch (c1 * 3 + c2) {
case -4:
bn_sub_part_words(t, &(a[n]), a, tna, tna - n); /* - */
bn_sub_part_words(&(t[n]), b, &(b[n]), tnb, n - tnb); /* - */
break;
case -3:
zero = 1;
break;
case -2:
bn_sub_part_words(t, &(a[n]), a, tna, tna - n); /* - */
bn_sub_part_words(&(t[n]), &(b[n]), b, tnb, tnb - n); /* + */
neg = 1;
break;
case -1:
case 0:
case 1:
zero = 1;
break;
case 2:
bn_sub_part_words(t, a, &(a[n]), tna, n - tna); /* + */
bn_sub_part_words(&(t[n]), b, &(b[n]), tnb, n - tnb); /* - */
neg = 1;
break;
case 3:
zero = 1;
break;
case 4:
bn_sub_part_words(t, a, &(a[n]), tna, n - tna);
bn_sub_part_words(&(t[n]), &(b[n]), b, tnb, tnb - n);
break;
}
if (n == 4 && dna == 0 && dnb == 0) { /* XXX: bn_mul_comba4 could take
* extra args to do this well */
if (!zero)
bn_mul_comba4(&(t[n2]), t, &(t[n]));
else
memset(&t[n2], 0, sizeof(*t) * 8);
bn_mul_comba4(r, a, b);
bn_mul_comba4(&(r[n2]), &(a[n]), &(b[n]));
} else if (n == 8 && dna == 0 && dnb == 0) { /* XXX: bn_mul_comba8 could
* take extra args to do
* this well */
if (!zero)
bn_mul_comba8(&(t[n2]), t, &(t[n]));
else
memset(&t[n2], 0, sizeof(*t) * 16);
bn_mul_comba8(r, a, b);
bn_mul_comba8(&(r[n2]), &(a[n]), &(b[n]));
} else {
p = &(t[n2 * 2]);
if (!zero)
bn_mul_recursive(&(t[n2]), t, &(t[n]), n, 0, 0, p);
else
memset(&t[n2], 0, sizeof(*t) * n2);
bn_mul_recursive(r, a, b, n, 0, 0, p);
bn_mul_recursive(&(r[n2]), &(a[n]), &(b[n]), n, dna, dnb, p);
}
/*-
* t[32] holds (a[0]-a[1])*(b[1]-b[0]), c1 is the sign
* r[10] holds (a[0]*b[0])
* r[32] holds (b[1]*b[1])
*/
c1 = (int)(bn_add_words(t, r, &(r[n2]), n2));
if (neg) { /* if t[32] is negative */
c1 -= (int)(bn_sub_words(&(t[n2]), t, &(t[n2]), n2));
} else {
/* Might have a carry */
c1 += (int)(bn_add_words(&(t[n2]), &(t[n2]), t, n2));
}
/*-
* t[32] holds (a[0]-a[1])*(b[1]-b[0])+(a[0]*b[0])+(a[1]*b[1])
* r[10] holds (a[0]*b[0])
* r[32] holds (b[1]*b[1])
* c1 holds the carry bits
*/
c1 += (int)(bn_add_words(&(r[n]), &(r[n]), &(t[n2]), n2));
if (c1) {
p = &(r[n + n2]);
lo = *p;
ln = (lo + c1) & BN_MASK2;
*p = ln;
/*
* The overflow will stop before we over write words we should not
* overwrite
*/
if (ln < (BN_ULONG)c1) {
do {
p++;
lo = *p;
ln = (lo + 1) & BN_MASK2;
*p = ln;
} while (ln == 0);
}
}
}
/*
* n+tn is the word length t needs to be n*4 is size, as does r
*/
/* tnX may not be negative but less than n */
void bn_mul_part_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n,
int tna, int tnb, BN_ULONG *t)
{
int i, j, n2 = n * 2;
int c1, c2, neg;
BN_ULONG ln, lo, *p;
if (n < 8) {
bn_mul_normal(r, a, n + tna, b, n + tnb);
return;
}
/* r=(a[0]-a[1])*(b[1]-b[0]) */
c1 = bn_cmp_part_words(a, &(a[n]), tna, n - tna);
c2 = bn_cmp_part_words(&(b[n]), b, tnb, tnb - n);
neg = 0;
switch (c1 * 3 + c2) {
case -4:
bn_sub_part_words(t, &(a[n]), a, tna, tna - n); /* - */
bn_sub_part_words(&(t[n]), b, &(b[n]), tnb, n - tnb); /* - */
break;
case -3:
case -2:
bn_sub_part_words(t, &(a[n]), a, tna, tna - n); /* - */
bn_sub_part_words(&(t[n]), &(b[n]), b, tnb, tnb - n); /* + */
neg = 1;
break;
case -1:
case 0:
case 1:
case 2:
bn_sub_part_words(t, a, &(a[n]), tna, n - tna); /* + */
bn_sub_part_words(&(t[n]), b, &(b[n]), tnb, n - tnb); /* - */
neg = 1;
break;
case 3:
case 4:
bn_sub_part_words(t, a, &(a[n]), tna, n - tna);
bn_sub_part_words(&(t[n]), &(b[n]), b, tnb, tnb - n);
break;
}
/*
* The zero case isn't yet implemented here. The speedup would probably
* be negligible.
*/
#if 0
if (n == 4) {
bn_mul_comba4(&(t[n2]), t, &(t[n]));
bn_mul_comba4(r, a, b);
bn_mul_normal(&(r[n2]), &(a[n]), tn, &(b[n]), tn);
memset(&r[n2 + tn * 2], 0, sizeof(*r) * (n2 - tn * 2));
} else
#endif
if (n == 8) {
bn_mul_comba8(&(t[n2]), t, &(t[n]));
bn_mul_comba8(r, a, b);
bn_mul_normal(&(r[n2]), &(a[n]), tna, &(b[n]), tnb);
memset(&r[n2 + tna + tnb], 0, sizeof(*r) * (n2 - tna - tnb));
} else {
p = &(t[n2 * 2]);
bn_mul_recursive(&(t[n2]), t, &(t[n]), n, 0, 0, p);
bn_mul_recursive(r, a, b, n, 0, 0, p);
i = n / 2;
/*
* If there is only a bottom half to the number, just do it
*/
if (tna > tnb)
j = tna - i;
else
j = tnb - i;
if (j == 0) {
bn_mul_recursive(&(r[n2]), &(a[n]), &(b[n]),
i, tna - i, tnb - i, p);
memset(&r[n2 + i * 2], 0, sizeof(*r) * (n2 - i * 2));
} else if (j > 0) { /* eg, n == 16, i == 8 and tn == 11 */
bn_mul_part_recursive(&(r[n2]), &(a[n]), &(b[n]),
i, tna - i, tnb - i, p);
memset(&(r[n2 + tna + tnb]), 0,
sizeof(BN_ULONG) * (n2 - tna - tnb));
} else { /* (j < 0) eg, n == 16, i == 8 and tn == 5 */
memset(&r[n2], 0, sizeof(*r) * n2);
if (tna < BN_MUL_RECURSIVE_SIZE_NORMAL
&& tnb < BN_MUL_RECURSIVE_SIZE_NORMAL) {
bn_mul_normal(&(r[n2]), &(a[n]), tna, &(b[n]), tnb);
} else {
for (;;) {
i /= 2;
/*
* these simplified conditions work exclusively because
* difference between tna and tnb is 1 or 0
*/
if (i < tna || i < tnb) {
bn_mul_part_recursive(&(r[n2]),
&(a[n]), &(b[n]),
i, tna - i, tnb - i, p);
break;
} else if (i == tna || i == tnb) {
bn_mul_recursive(&(r[n2]),
&(a[n]), &(b[n]),
i, tna - i, tnb - i, p);
break;
}
}
}
}
}
/*-
* t[32] holds (a[0]-a[1])*(b[1]-b[0]), c1 is the sign
* r[10] holds (a[0]*b[0])
* r[32] holds (b[1]*b[1])
*/
c1 = (int)(bn_add_words(t, r, &(r[n2]), n2));
if (neg) { /* if t[32] is negative */
c1 -= (int)(bn_sub_words(&(t[n2]), t, &(t[n2]), n2));
} else {
/* Might have a carry */
c1 += (int)(bn_add_words(&(t[n2]), &(t[n2]), t, n2));
}
/*-
* t[32] holds (a[0]-a[1])*(b[1]-b[0])+(a[0]*b[0])+(a[1]*b[1])
* r[10] holds (a[0]*b[0])
* r[32] holds (b[1]*b[1])
* c1 holds the carry bits
*/
c1 += (int)(bn_add_words(&(r[n]), &(r[n]), &(t[n2]), n2));
if (c1) {
p = &(r[n + n2]);
lo = *p;
ln = (lo + c1) & BN_MASK2;
*p = ln;
/*
* The overflow will stop before we over write words we should not
* overwrite
*/
if (ln < (BN_ULONG)c1) {
do {
p++;
lo = *p;
ln = (lo + 1) & BN_MASK2;
*p = ln;
} while (ln == 0);
}
}
}
/*-
* a and b must be the same size, which is n2.
* r needs to be n2 words and t needs to be n2*2
*/
void bn_mul_low_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n2,
BN_ULONG *t)
{
int n = n2 / 2;
bn_mul_recursive(r, a, b, n, 0, 0, &(t[0]));
if (n >= BN_MUL_LOW_RECURSIVE_SIZE_NORMAL) {
bn_mul_low_recursive(&(t[0]), &(a[0]), &(b[n]), n, &(t[n2]));
bn_add_words(&(r[n]), &(r[n]), &(t[0]), n);
bn_mul_low_recursive(&(t[0]), &(a[n]), &(b[0]), n, &(t[n2]));
bn_add_words(&(r[n]), &(r[n]), &(t[0]), n);
} else {
bn_mul_low_normal(&(t[0]), &(a[0]), &(b[n]), n);
bn_mul_low_normal(&(t[n]), &(a[n]), &(b[0]), n);
bn_add_words(&(r[n]), &(r[n]), &(t[0]), n);
bn_add_words(&(r[n]), &(r[n]), &(t[n]), n);
}
}
#endif /* OPENSSL_SMALL_FOOTPRINT */
int BN_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
{
int ret = bn_mul_fixed_top(r, a, b, ctx);
@ -501,8 +28,6 @@ int bn_mul_fixed_top(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
BIGNUM *rr;
#if !defined(OPENSSL_SMALL_FOOTPRINT)
int i;
BIGNUM *t = NULL;
int j = 0, k;
#endif
bn_check_top(a);
@ -533,7 +58,8 @@ int bn_mul_fixed_top(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
if (al == 4) {
if (bn_wexpand(rr, 8) == NULL)
goto err;
rr->top = 8;
rr->flags |= BN_FLG_FIXED_TOP;
bn_set_top(rr, 8);
bn_mul_comba4(rr->d, a->d, b->d);
goto end;
}
@ -541,7 +67,8 @@ int bn_mul_fixed_top(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
if (al == 8) {
if (bn_wexpand(rr, 16) == NULL)
goto err;
rr->top = 16;
rr->flags |= BN_FLG_FIXED_TOP;
bn_set_top(rr, 16);
bn_mul_comba8(rr->d, a->d, b->d);
goto end;
}
@ -549,6 +76,9 @@ int bn_mul_fixed_top(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
if ((al >= BN_MULL_SIZE_NORMAL) && (bl >= BN_MULL_SIZE_NORMAL)) {
if (i >= -1 && i <= 1) {
BIGNUM *t = NULL;
int j = 0, k;
/*
* Find out the power of two lower or equal to the longest of the
* two numbers
@ -568,26 +98,33 @@ int bn_mul_fixed_top(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
if (al > j || bl > j) {
if (bn_wexpand(t, k * 4) == NULL)
goto err;
t->top = k * 4;
t->flags |= BN_FLG_FIXED_TOP;
if (bn_wexpand(rr, k * 4) == NULL)
goto err;
bn_set_top(rr, k * 4);
rr->flags |= BN_FLG_FIXED_TOP;
bn_mul_part_recursive(rr->d, a->d, b->d,
j, al - j, bl - j, t->d);
} else { /* al <= j || bl <= j */
if (bn_wexpand(t, k * 2) == NULL)
goto err;
t->top = k * 2;
t->flags |= BN_FLG_FIXED_TOP;
if (bn_wexpand(rr, k * 2) == NULL)
goto err;
bn_set_top(rr, k * 2);
rr->flags |= BN_FLG_FIXED_TOP;
bn_mul_recursive(rr->d, a->d, b->d, j, al - j, bl - j, t->d);
}
rr->top = top;
bn_set_top(rr, top);
goto end;
}
}
#endif /* OPENSSL_SMALL_FOOTPRINT */
if (bn_wexpand(rr, top) == NULL)
goto err;
rr->top = top;
bn_set_top(rr, top);
bn_mul_normal(rr->d, a->d, al, b->d, bl);
#if !defined(OPENSSL_SMALL_FOOTPRINT)
@ -604,66 +141,3 @@ err:
BN_CTX_end(ctx);
return ret;
}
void bn_mul_normal(BN_ULONG *r, BN_ULONG *a, int na, BN_ULONG *b, int nb)
{
BN_ULONG *rr;
if (na < nb) {
int itmp;
BN_ULONG *ltmp;
itmp = na;
na = nb;
nb = itmp;
ltmp = a;
a = b;
b = ltmp;
}
rr = &(r[na]);
if (nb <= 0) {
(void)bn_mul_words(r, a, na, 0);
return;
} else
rr[0] = bn_mul_words(r, a, na, b[0]);
for (;;) {
if (--nb <= 0)
return;
rr[1] = bn_mul_add_words(&(r[1]), a, na, b[1]);
if (--nb <= 0)
return;
rr[2] = bn_mul_add_words(&(r[2]), a, na, b[2]);
if (--nb <= 0)
return;
rr[3] = bn_mul_add_words(&(r[3]), a, na, b[3]);
if (--nb <= 0)
return;
rr[4] = bn_mul_add_words(&(r[4]), a, na, b[4]);
rr += 4;
r += 4;
b += 4;
}
}
void bn_mul_low_normal(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n)
{
bn_mul_words(r, a, n, b[0]);
for (;;) {
if (--n <= 0)
return;
bn_mul_add_words(&(r[1]), a, n, b[1]);
if (--n <= 0)
return;
bn_mul_add_words(&(r[2]), a, n, b[2]);
if (--n <= 0)
return;
bn_mul_add_words(&(r[3]), a, n, b[3]);
if (--n <= 0)
return;
bn_mul_add_words(&(r[4]), a, n, b[4]);
r += 4;
b += 4;
}
}

View file

@ -184,43 +184,38 @@ static const BN_ULONG _nist_p_521_sqr[] = {
#endif
static const BIGNUM ossl_bignum_nist_p_192 = {
(BN_ULONG *)_nist_p_192[0],
BN_NIST_192_TOP,
BN_NIST_192_TOP,
0,
BN_FLG_STATIC_DATA
.d = (BN_ULONG *)_nist_p_192[0],
.top = BN_NIST_192_TOP,
.dmax = BN_NIST_192_TOP,
.flags = BN_FLG_STATIC_DATA,
};
static const BIGNUM ossl_bignum_nist_p_224 = {
(BN_ULONG *)_nist_p_224[0],
BN_NIST_224_TOP,
BN_NIST_224_TOP,
0,
BN_FLG_STATIC_DATA
.d = (BN_ULONG *)_nist_p_224[0],
.top = BN_NIST_224_TOP,
.dmax = BN_NIST_224_TOP,
.flags = BN_FLG_STATIC_DATA,
};
static const BIGNUM ossl_bignum_nist_p_256 = {
(BN_ULONG *)_nist_p_256[0],
BN_NIST_256_TOP,
BN_NIST_256_TOP,
0,
BN_FLG_STATIC_DATA
.d = (BN_ULONG *)_nist_p_256[0],
.top = BN_NIST_256_TOP,
.dmax = BN_NIST_256_TOP,
.flags = BN_FLG_STATIC_DATA,
};
static const BIGNUM ossl_bignum_nist_p_384 = {
(BN_ULONG *)_nist_p_384[0],
BN_NIST_384_TOP,
BN_NIST_384_TOP,
0,
BN_FLG_STATIC_DATA
.d = (BN_ULONG *)_nist_p_384[0],
.top = BN_NIST_384_TOP,
.dmax = BN_NIST_384_TOP,
.flags = BN_FLG_STATIC_DATA,
};
static const BIGNUM ossl_bignum_nist_p_521 = {
(BN_ULONG *)_nist_p_521,
BN_NIST_521_TOP,
BN_NIST_521_TOP,
0,
BN_FLG_STATIC_DATA
.d = (BN_ULONG *)_nist_p_521,
.top = BN_NIST_521_TOP,
.dmax = BN_NIST_521_TOP,
.flags = BN_FLG_STATIC_DATA,
};
const BIGNUM *BN_get0_nist_prime_192(void)
@ -359,10 +354,10 @@ int BN_nist_mod_192(BIGNUM *r, const BIGNUM *a, const BIGNUM *field,
} buf;
BN_ULONG c_d[BN_NIST_192_TOP], *res;
static const BIGNUM ossl_bignum_nist_p_192_sqr = {
(BN_ULONG *)_nist_p_192_sqr,
OSSL_NELEM(_nist_p_192_sqr),
OSSL_NELEM(_nist_p_192_sqr),
0, BN_FLG_STATIC_DATA
.d = (BN_ULONG *)_nist_p_192_sqr,
.top = OSSL_NELEM(_nist_p_192_sqr),
.dmax = OSSL_NELEM(_nist_p_192_sqr),
.flags = BN_FLG_STATIC_DATA,
};
field = &ossl_bignum_nist_p_192; /* just to make sure */
@ -462,7 +457,7 @@ int BN_nist_mod_192(BIGNUM *r, const BIGNUM *a, const BIGNUM *field,
? r_d
: c_d;
nist_cp_bn(r_d, res, BN_NIST_192_TOP);
r->top = BN_NIST_192_TOP;
bn_set_top(r, BN_NIST_192_TOP);
bn_correct_top(r);
return 1;
@ -495,10 +490,10 @@ int BN_nist_mod_224(BIGNUM *r, const BIGNUM *a, const BIGNUM *field,
BN_ULONG c_d[BN_NIST_224_TOP], *res;
bn_addsub_f adjust;
static const BIGNUM ossl_bignum_nist_p_224_sqr = {
(BN_ULONG *)_nist_p_224_sqr,
OSSL_NELEM(_nist_p_224_sqr),
OSSL_NELEM(_nist_p_224_sqr),
0, BN_FLG_STATIC_DATA
.d = (BN_ULONG *)_nist_p_224_sqr,
.top = OSSL_NELEM(_nist_p_224_sqr),
.dmax = OSSL_NELEM(_nist_p_224_sqr),
.flags = BN_FLG_STATIC_DATA,
};
field = &ossl_bignum_nist_p_224; /* just to make sure */
@ -630,7 +625,7 @@ int BN_nist_mod_224(BIGNUM *r, const BIGNUM *a, const BIGNUM *field,
? r_d
: c_d;
nist_cp_bn(r_d, res, BN_NIST_224_TOP);
r->top = BN_NIST_224_TOP;
bn_set_top(r, BN_NIST_224_TOP);
bn_correct_top(r);
return 1;
@ -661,10 +656,10 @@ int BN_nist_mod_256(BIGNUM *r, const BIGNUM *a, const BIGNUM *field,
BN_ULONG c_d[BN_NIST_256_TOP], *res;
bn_addsub_f adjust;
static const BIGNUM ossl_bignum_nist_p_256_sqr = {
(BN_ULONG *)_nist_p_256_sqr,
OSSL_NELEM(_nist_p_256_sqr),
OSSL_NELEM(_nist_p_256_sqr),
0, BN_FLG_STATIC_DATA
.d = (BN_ULONG *)_nist_p_256_sqr,
.top = OSSL_NELEM(_nist_p_256_sqr),
.dmax = OSSL_NELEM(_nist_p_256_sqr),
.flags = BN_FLG_STATIC_DATA,
};
field = &ossl_bignum_nist_p_256; /* just to make sure */
@ -859,7 +854,7 @@ int BN_nist_mod_256(BIGNUM *r, const BIGNUM *a, const BIGNUM *field,
? r_d
: c_d;
nist_cp_bn(r_d, res, BN_NIST_256_TOP);
r->top = BN_NIST_256_TOP;
bn_set_top(r, BN_NIST_256_TOP);
bn_correct_top(r);
return 1;
@ -894,10 +889,10 @@ int BN_nist_mod_384(BIGNUM *r, const BIGNUM *a, const BIGNUM *field,
BN_ULONG c_d[BN_NIST_384_TOP], *res;
bn_addsub_f adjust;
static const BIGNUM ossl_bignum_nist_p_384_sqr = {
(BN_ULONG *)_nist_p_384_sqr,
OSSL_NELEM(_nist_p_384_sqr),
OSSL_NELEM(_nist_p_384_sqr),
0, BN_FLG_STATIC_DATA
.d = (BN_ULONG *)_nist_p_384_sqr,
.top = OSSL_NELEM(_nist_p_384_sqr),
.dmax = OSSL_NELEM(_nist_p_384_sqr),
.flags = BN_FLG_STATIC_DATA,
};
field = &ossl_bignum_nist_p_384; /* just to make sure */
@ -1126,7 +1121,7 @@ int BN_nist_mod_384(BIGNUM *r, const BIGNUM *a, const BIGNUM *field,
? r_d
: c_d;
nist_cp_bn(r_d, res, BN_NIST_384_TOP);
r->top = BN_NIST_384_TOP;
bn_set_top(r, BN_NIST_384_TOP);
bn_correct_top(r);
return 1;
@ -1142,10 +1137,10 @@ int BN_nist_mod_521(BIGNUM *r, const BIGNUM *a, const BIGNUM *field,
int top = a->top, i;
BN_ULONG *r_d, *a_d = a->d, t_d[BN_NIST_521_TOP], val, tmp, *res;
static const BIGNUM ossl_bignum_nist_p_521_sqr = {
(BN_ULONG *)_nist_p_521_sqr,
OSSL_NELEM(_nist_p_521_sqr),
OSSL_NELEM(_nist_p_521_sqr),
0, BN_FLG_STATIC_DATA
.d = (BN_ULONG *)_nist_p_521_sqr,
.top = OSSL_NELEM(_nist_p_521_sqr),
.dmax = OSSL_NELEM(_nist_p_521_sqr),
.flags = BN_FLG_STATIC_DATA,
};
field = &ossl_bignum_nist_p_521; /* just to make sure */
@ -1197,7 +1192,7 @@ int BN_nist_mod_521(BIGNUM *r, const BIGNUM *a, const BIGNUM *field,
? r_d
: t_d;
nist_cp_bn(r_d, res, BN_NIST_521_TOP);
r->top = BN_NIST_521_TOP;
bn_set_top(r, BN_NIST_521_TOP);
bn_correct_top(r);
return 1;

View file

@ -55,11 +55,10 @@ static const BN_ULONG small_prime_factors[] = {
#define BN_SMALL_PRIME_FACTORS_TOP OSSL_NELEM(small_prime_factors)
static const BIGNUM _bignum_small_prime_factors = {
(BN_ULONG *)small_prime_factors,
BN_SMALL_PRIME_FACTORS_TOP,
BN_SMALL_PRIME_FACTORS_TOP,
0,
BN_FLG_STATIC_DATA
.d = (BN_ULONG *)small_prime_factors,
.top = BN_SMALL_PRIME_FACTORS_TOP,
.dmax = BN_SMALL_PRIME_FACTORS_TOP,
.flags = BN_FLG_STATIC_DATA,
};
const BIGNUM *ossl_bn_get0_small_factors(void)

View file

@ -41,11 +41,10 @@ static const BN_ULONG inv_sqrt_2_val[] = {
};
const BIGNUM ossl_bn_inv_sqrt_2 = {
(BN_ULONG *)inv_sqrt_2_val,
OSSL_NELEM(inv_sqrt_2_val),
OSSL_NELEM(inv_sqrt_2_val),
0,
BN_FLG_STATIC_DATA
.d = (BN_ULONG *)inv_sqrt_2_val,
.top = OSSL_NELEM(inv_sqrt_2_val),
.dmax = OSSL_NELEM(inv_sqrt_2_val),
.flags = BN_FLG_STATIC_DATA,
};
/*

View file

@ -20,20 +20,16 @@
#include <unistd.h>
#include <errno.h>
/*
* Returns 1 for success, 0 for failure, and -1 to tell the caller to use the
* SW-fallback.
*/
static int s390x_mod_exp_hw(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
const BIGNUM *m)
{
struct ica_rsa_modexpo me;
unsigned char *buffer;
size_t size;
int res = -1;
int res = 0;
if (OPENSSL_s390xcex == -1 || OPENSSL_s390xcex_nodev)
return -1;
return 0;
size = BN_num_bytes(m);
buffer = OPENSSL_calloc(size, 4);
if (buffer == NULL)
@ -46,15 +42,11 @@ static int s390x_mod_exp_hw(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
me.n_modulus = buffer + 3 * size;
if (BN_bn2binpad(a, me.inputdata, size) == -1
|| BN_bn2binpad(p, me.b_key, size) == -1
|| BN_bn2binpad(m, me.n_modulus, size) == -1) {
res = 0;
|| BN_bn2binpad(m, me.n_modulus, size) == -1)
goto dealloc;
}
if (ioctl(OPENSSL_s390xcex, ICARSAMODEXPO, &me) != -1) {
if (BN_bin2bn(me.outputdata, size, r) != NULL)
res = 1;
else
res = 0;
} else if (errno == EBADF || errno == ENOTTY) {
/*
* In this cases, someone (e.g. a sandbox) closed the fd.
@ -79,34 +71,27 @@ dealloc:
int s390x_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx)
{
int rc;
rc = s390x_mod_exp_hw(r, a, p, m);
if (rc < 0)
return BN_mod_exp_mont(r, a, p, m, ctx, m_ctx);
return rc;
if (s390x_mod_exp_hw(r, a, p, m) == 1)
return 1;
return BN_mod_exp_mont(r, a, p, m, ctx, m_ctx);
}
/*
* Returns 1 for success, 0 for failure, and -1 to tell the caller to use the
* SW-fallback.
*/
int s390x_crt(BIGNUM *r, const BIGNUM *i, const BIGNUM *p, const BIGNUM *q,
const BIGNUM *dmp, const BIGNUM *dmq, const BIGNUM *iqmp)
{
struct ica_rsa_modexpo_crt crt;
unsigned char *buffer, *part;
size_t size, plen, qlen;
int res = -1;
int res = 0;
if (OPENSSL_s390xcex == -1 || OPENSSL_s390xcex_nodev)
return -1;
return 0;
/*-
* Hardware-accelerated CRT can only deal with p>q. Fall back to
* software in the (hopefully rare) other cases.
*/
if (BN_ucmp(p, q) != 1)
return -1;
return 0;
plen = BN_num_bytes(p);
qlen = BN_num_bytes(q);
size = (plen > qlen ? plen : qlen);
@ -134,15 +119,11 @@ int s390x_crt(BIGNUM *r, const BIGNUM *i, const BIGNUM *p, const BIGNUM *q,
|| BN_bn2binpad(q, crt.nq_prime, size) == -1
|| BN_bn2binpad(dmp, crt.bp_key, size + 8) == -1
|| BN_bn2binpad(dmq, crt.bq_key, size) == -1
|| BN_bn2binpad(iqmp, crt.u_mult_inv, size + 8) == -1) {
res = 0;
|| BN_bn2binpad(iqmp, crt.u_mult_inv, size + 8) == -1)
goto dealloc;
}
if (ioctl(OPENSSL_s390xcex, ICARSACRT, &crt) != -1) {
if (BN_bin2bn(crt.outputdata, crt.outputdatalength, r) != NULL)
res = 1;
else
res = 0;
} else if (errno == EBADF || errno == ENOTTY) {
/*
* In this cases, someone (e.g. a sandbox) closed the fd.

View file

@ -23,7 +23,7 @@ int BN_lshift1(BIGNUM *r, const BIGNUM *a)
r->neg = a->neg;
if (bn_wexpand(r, a->top + 1) == NULL)
return 0;
r->top = a->top;
bn_set_top(r, a->top);
} else {
if (bn_wexpand(r, a->top + 1) == NULL)
return 0;
@ -37,7 +37,7 @@ int BN_lshift1(BIGNUM *r, const BIGNUM *a)
c = t >> (BN_BITS2 - 1);
}
*rp = c;
r->top += (int)c;
bn_set_top(r, r->top + (int)c);
bn_check_top(r);
return 1;
}
@ -62,11 +62,10 @@ int BN_rshift1(BIGNUM *r, const BIGNUM *a)
r->neg = a->neg;
}
rp = r->d;
r->top = i;
t = ap[--i];
rp[i] = t >> 1;
c = t << (BN_BITS2 - 1);
r->top -= (t == 1);
bn_set_top(r, i + (t > 1));
while (i > 0) {
t = ap[--i];
rp[i] = ((t >> 1) & BN_MASK2) | c;
@ -141,7 +140,7 @@ int bn_lshift_fixed_top(BIGNUM *r, const BIGNUM *a, int n)
memset(r->d, 0, sizeof(*t) * nw);
r->neg = a->neg;
r->top = a->top + nw + 1;
bn_set_top(r, a->top + nw + 1);
r->flags |= BN_FLG_FIXED_TOP;
return 1;
@ -209,7 +208,7 @@ int bn_rshift_fixed_top(BIGNUM *r, const BIGNUM *a, int n)
t[i] = l >> rb;
r->neg = a->neg;
r->top = top;
bn_set_top(r, top);
r->flags |= BN_FLG_FIXED_TOP;
return 1;

View file

@ -34,7 +34,7 @@ int bn_sqr_fixed_top(BIGNUM *r, const BIGNUM *a, BN_CTX *ctx)
al = a->top;
if (al <= 0) {
r->top = 0;
bn_set_top(r, 0);
r->neg = 0;
return 1;
}
@ -91,8 +91,12 @@ int bn_sqr_fixed_top(BIGNUM *r, const BIGNUM *a, BN_CTX *ctx)
#endif
}
/* Ensure that tmp won't cause any trouble */
tmp->top = tmp->dmax;
tmp->flags |= BN_FLG_FIXED_TOP;
rr->neg = 0;
rr->top = max;
bn_set_top(rr, max);
rr->flags |= BN_FLG_FIXED_TOP;
if (r != rr && BN_copy(r, rr) == NULL)
goto err;
@ -100,7 +104,6 @@ int bn_sqr_fixed_top(BIGNUM *r, const BIGNUM *a, BN_CTX *ctx)
ret = 1;
err:
bn_check_top(rr);
bn_check_top(tmp);
BN_CTX_end(ctx);
return ret;
}

View file

@ -49,11 +49,10 @@ static const BN_ULONG bn_group_1024_value[] = {
};
const BIGNUM ossl_bn_group_1024 = {
(BN_ULONG *)bn_group_1024_value,
OSSL_NELEM(bn_group_1024_value),
OSSL_NELEM(bn_group_1024_value),
0,
BN_FLG_STATIC_DATA
.d = (BN_ULONG *)bn_group_1024_value,
.top = OSSL_NELEM(bn_group_1024_value),
.dmax = OSSL_NELEM(bn_group_1024_value),
.flags = BN_FLG_STATIC_DATA,
};
static const BN_ULONG bn_group_1536_value[] = {
@ -84,11 +83,10 @@ static const BN_ULONG bn_group_1536_value[] = {
};
const BIGNUM ossl_bn_group_1536 = {
(BN_ULONG *)bn_group_1536_value,
OSSL_NELEM(bn_group_1536_value),
OSSL_NELEM(bn_group_1536_value),
0,
BN_FLG_STATIC_DATA
.d = (BN_ULONG *)bn_group_1536_value,
.top = OSSL_NELEM(bn_group_1536_value),
.dmax = OSSL_NELEM(bn_group_1536_value),
.flags = BN_FLG_STATIC_DATA,
};
static const BN_ULONG bn_group_2048_value[] = {
@ -127,11 +125,10 @@ static const BN_ULONG bn_group_2048_value[] = {
};
const BIGNUM ossl_bn_group_2048 = {
(BN_ULONG *)bn_group_2048_value,
OSSL_NELEM(bn_group_2048_value),
OSSL_NELEM(bn_group_2048_value),
0,
BN_FLG_STATIC_DATA
.d = (BN_ULONG *)bn_group_2048_value,
.top = OSSL_NELEM(bn_group_2048_value),
.dmax = OSSL_NELEM(bn_group_2048_value),
.flags = BN_FLG_STATIC_DATA,
};
static const BN_ULONG bn_group_3072_value[] = {
@ -186,11 +183,10 @@ static const BN_ULONG bn_group_3072_value[] = {
};
const BIGNUM ossl_bn_group_3072 = {
(BN_ULONG *)bn_group_3072_value,
OSSL_NELEM(bn_group_3072_value),
OSSL_NELEM(bn_group_3072_value),
0,
BN_FLG_STATIC_DATA
.d = (BN_ULONG *)bn_group_3072_value,
.top = OSSL_NELEM(bn_group_3072_value),
.dmax = OSSL_NELEM(bn_group_3072_value),
.flags = BN_FLG_STATIC_DATA,
};
static const BN_ULONG bn_group_4096_value[] = {
@ -261,11 +257,10 @@ static const BN_ULONG bn_group_4096_value[] = {
};
const BIGNUM ossl_bn_group_4096 = {
(BN_ULONG *)bn_group_4096_value,
OSSL_NELEM(bn_group_4096_value),
OSSL_NELEM(bn_group_4096_value),
0,
BN_FLG_STATIC_DATA
.d = (BN_ULONG *)bn_group_4096_value,
.top = OSSL_NELEM(bn_group_4096_value),
.dmax = OSSL_NELEM(bn_group_4096_value),
.flags = BN_FLG_STATIC_DATA,
};
static const BN_ULONG bn_group_6144_value[] = {
@ -368,11 +363,10 @@ static const BN_ULONG bn_group_6144_value[] = {
};
const BIGNUM ossl_bn_group_6144 = {
(BN_ULONG *)bn_group_6144_value,
OSSL_NELEM(bn_group_6144_value),
OSSL_NELEM(bn_group_6144_value),
0,
BN_FLG_STATIC_DATA
.d = (BN_ULONG *)bn_group_6144_value,
.top = OSSL_NELEM(bn_group_6144_value),
.dmax = OSSL_NELEM(bn_group_6144_value),
.flags = BN_FLG_STATIC_DATA,
};
static const BN_ULONG bn_group_8192_value[] = {
@ -507,39 +501,35 @@ static const BN_ULONG bn_group_8192_value[] = {
};
const BIGNUM ossl_bn_group_8192 = {
(BN_ULONG *)bn_group_8192_value,
OSSL_NELEM(bn_group_8192_value),
OSSL_NELEM(bn_group_8192_value),
0,
BN_FLG_STATIC_DATA
.d = (BN_ULONG *)bn_group_8192_value,
.top = OSSL_NELEM(bn_group_8192_value),
.dmax = OSSL_NELEM(bn_group_8192_value),
.flags = BN_FLG_STATIC_DATA,
};
static const BN_ULONG bn_generator_19_value[] = { 19 };
const BIGNUM ossl_bn_generator_19 = {
(BN_ULONG *)bn_generator_19_value,
1,
1,
0,
BN_FLG_STATIC_DATA
.d = (BN_ULONG *)bn_generator_19_value,
.top = 1,
.dmax = 1,
.flags = BN_FLG_STATIC_DATA,
};
static const BN_ULONG bn_generator_5_value[] = { 5 };
const BIGNUM ossl_bn_generator_5 = {
(BN_ULONG *)bn_generator_5_value,
1,
1,
0,
BN_FLG_STATIC_DATA
.d = (BN_ULONG *)bn_generator_5_value,
.top = 1,
.dmax = 1,
.flags = BN_FLG_STATIC_DATA,
};
static const BN_ULONG bn_generator_2_value[] = { 2 };
const BIGNUM ossl_bn_generator_2 = {
(BN_ULONG *)bn_generator_2_value,
1,
1,
0,
BN_FLG_STATIC_DATA
.d = (BN_ULONG *)bn_generator_2_value,
.top = 1,
.dmax = 1,
.flags = BN_FLG_STATIC_DATA,
};
#endif

Some files were not shown because too many files have changed in this diff Show more