Skip to content

aes: feature flags are not additive  #245

@SergioBenitez

Description

@SergioBenitez

The aes crate has two feature flags, both of which remove functionality:

[features]
compact = [] # Reduce code size at the cost of slower performance
force-soft = [] # Disable support for AES hardware intrinsics

This is an incorrect use of Cargo feature flags. From my comments at rwf2/cookie-rs#176 (comment), which focus on force-soft:

This seems like an ill-fitted, perhaps incorrect use of features. Features should only be used to add capabilities, but force-soft removes the ability to make use of AES-NI. The consequence is that a consumer of aes has little control over whether AES-NI is actually used: all it takes is a single dependency, direct or indirect, enabling force-soft to disable AES-NI completely, without recourse.

I would suggest what I would consider to be the "correct" approach: always enable AES-NI if it is known to statically exist, and otherwise, add a feature that adds the ability to dynamically detect its existence, which of course becomes a no-op if the first condition is met.

Somewhere in the codebase, you already have 2 versions of the code. Let's call them aes::ni and aes::soft.

Effectively, we want this:

fn aes() {
    #[cfg(have_aesni)]
    return aes::ni();

    #[cfg(feature(autodetect)]
    if detect(aes-ni) { return aes::ni() }

    aes::soft()
}

This structure makes it clear that autodetect is additive; it adds the ability to dynamically detect AES-NI and removes nothing otherwise; there is no not(feature(autodetect)). This is the only fully correct use of features. If the code that requires 1.49 is restricted to detect, then MSRV can remain at 1.41 as long as autodetect is not enabled.

The same reasoning applies to the compact feature. If it must exist at all, a non-feature --cfg aes_compact is the correct approach. This restores control of expected performance to the top-level binary as opposed to any crate in the transitive closure of dependencies.

See also the full comment thread in rwf2/cookie-rs#176.

Metadata

Metadata

Assignees

No one assigned

    Labels

    aesAES implementations

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions