[openssl] master update

Richard Levitte levitte at openssl.org
Thu Oct 10 12:15:35 UTC 2019


The branch master has been updated
       via  600703f4f4d4bbe7016a8704a0f2195e370648c0 (commit)
       via  ddd21319e94636f308e115fd05cc48e7a8eadc55 (commit)
       via  af3e7e1bccbed8e3b958488a07daf5a8f4115fa9 (commit)
       via  604e884bb8aba9b549c7e5effe01e406ccab3bcd (commit)
       via  7c214f1092f7622a1c2fdc5cfe70ddc94918daa3 (commit)
       via  e42cf7180b4fb32e985f15484e04c7fb8afc11ab (commit)
       via  5687e357c60b31dc274c6d14f1cd623d0cff469b (commit)
       via  dec95d75897125133380c7ce3c6ce58c93c06f10 (commit)
       via  e805c2d6d36d6be3db8141abc98f3ce5c6fa9776 (commit)
       via  bdea50ca802f7645774a359960e3b6ee9c352921 (commit)
       via  9eba5933a5ae80030ba66f79e625c4382811769e (commit)
       via  285daccdc0e20fa70ddda9ddcd1f22191425de8a (commit)
      from  12a765a5235f181c2f4992b615eb5f892c368e88 (commit)


- Log -----------------------------------------------------------------
commit 600703f4f4d4bbe7016a8704a0f2195e370648c0
Author: Richard Levitte <levitte at openssl.org>
Date:   Fri Oct 4 15:37:14 2019 +0200

    Cleanup: move provider mains up
    
    providers/default/defltprov.c and providers/legacy/legacyprov.c
    are moved up to providers/ and providers/build.info is adjusted
    accordingly.
    
    Reviewed-by: Matt Caswell <matt at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/10088)

commit ddd21319e94636f308e115fd05cc48e7a8eadc55
Author: Richard Levitte <levitte at openssl.org>
Date:   Fri Oct 4 15:25:59 2019 +0200

    Cleanup: move remaining providers/common/include/internal/*.h
    
    The end up in providers/common/include/prov/.
    All inclusions are adjusted accordingly.
    
    Reviewed-by: Matt Caswell <matt at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/10088)

commit af3e7e1bccbed8e3b958488a07daf5a8f4115fa9
Author: Richard Levitte <levitte at openssl.org>
Date:   Fri Oct 4 15:20:48 2019 +0200

    Cleanup: move providers/common/include/internal/provider_args.h
    
    New name is providers/implementations/include/prov/implementations.h
    All inclusions are adapted accordingly.
    
    Reviewed-by: Matt Caswell <matt at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/10088)

commit 604e884bb8aba9b549c7e5effe01e406ccab3bcd
Author: Richard Levitte <levitte at openssl.org>
Date:   Fri Oct 4 14:44:42 2019 +0200

    Providers: move all ciphers
    
    From providers/{common,default}/ to providers/implementations/
    
    Except for common code, which remains in providers/common/ciphers/.
    However, we do move providers/common/include/internal/ciphers/*.h
    to providers/common/include/prov/, and adjust all source including
    any of those header files.
    
    Reviewed-by: Matt Caswell <matt at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/10088)

commit 7c214f1092f7622a1c2fdc5cfe70ddc94918daa3
Author: Richard Levitte <levitte at openssl.org>
Date:   Fri Oct 4 12:30:33 2019 +0200

    Providers: move all digests
    
    From providers/{common,default,legacy}/ to providers/implementations/
    However, providers/common/digests/digest_common.c stays where it is,
    because it's support code rather than an implementation.
    
    To better support all kinds of implementations with common code, we
    add the library providers/libcommon.a.  Code that ends up in this
    library must be FIPS agnostic.
    
    While we're moving things around, though, we move digestscommon.h
    from providers/common/include/internal to providers/common/include/prov,
    thereby starting on a provider specific include structure, which
    follows the line of thoughts of the recent header file reorganization.
    We modify the affected '#include "internal/something.h"' to
    '#include "prov/something.h"'.
    
    Reviewed-by: Matt Caswell <matt at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/10088)

commit e42cf7180b4fb32e985f15484e04c7fb8afc11ab
Author: Richard Levitte <levitte at openssl.org>
Date:   Fri Oct 4 11:28:20 2019 +0200

    Providers: move default kdfs,macs
    
    From providers/default/ to providers/implementations/
    
    Reviewed-by: Matt Caswell <matt at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/10088)

commit 5687e357c60b31dc274c6d14f1cd623d0cff469b
Author: Richard Levitte <levitte at openssl.org>
Date:   Fri Oct 4 10:24:09 2019 +0200

    Providers: move common exchange,kdfs,keymgmt,macs,signature
    
    From providers/common/ to providers/implementations/
    
    Reviewed-by: Matt Caswell <matt at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/10088)

commit dec95d75897125133380c7ce3c6ce58c93c06f10
Author: Richard Levitte <levitte at openssl.org>
Date:   Fri Oct 4 01:38:17 2019 +0200

    Rework how our providers are built
    
    We put almost everything in these internal static libraries:
    
    libcommon               Block building code that can be used by all
                            our implementations, legacy and non-legacy
                            alike.
    libimplementations      All non-legacy algorithm implementations and
                            only them.  All the code that ends up here is
                            agnostic to the definitions of FIPS_MODE.
    liblegacy               All legacy implementations.
    
    libnonfips              Support code for the algorithm implementations.
                            Built with FIPS_MODE undefined.  Any code that
                            checks that FIPS_MODE isn't defined must end
                            up in this library.
    libfips                 Support code for the algorithm implementations.
                            Built with FIPS_MODE defined.  Any code that
                            checks that FIPS_MODE is defined must end up
                            in this library.
    
    The FIPS provider module is built from providers/fips/*.c and linked
    with libimplementations, libcommon and libfips.
    
    The Legacy provider module is built from providers/legacy/*.c and
    linked with liblegacy, libcommon and libcrypto.
    If module building is disabled, the object files from liblegacy and
    libcommon are added to libcrypto and the Legacy provider becomes a
    built-in provider.
    
    The Default provider module is built-in, so it ends up being linked
    with libimplementations, libcommon and libnonfips.  For libcrypto in
    form of static library, the object files from those other libraries
    are simply being added to libcrypto.
    
    Reviewed-by: Matt Caswell <matt at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/10088)

commit e805c2d6d36d6be3db8141abc98f3ce5c6fa9776
Author: Richard Levitte <levitte at openssl.org>
Date:   Fri Oct 4 00:08:01 2019 +0200

    Build files: Make it possible to source libraries into other libraries
    
    Added functionality to use static libraries as source for other
    libraries.  When done this way, the target library will use the object
    files from the sourced static libraries, making the sourced libraries
    work as "containers" for object files.
    
    We also need to make sure that the Unix Makefile template knows how to
    deal with shared libraries and modules that depend on static libraries.
    That's new situation we haven't had before.
    
    Reviewed-by: Matt Caswell <matt at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/10088)

commit bdea50ca802f7645774a359960e3b6ee9c352921
Author: Richard Levitte <levitte at openssl.org>
Date:   Thu Oct 3 23:42:46 2019 +0200

    Configurations/common.tmpl: Rework dependency resolution
    
    The dependency resolution is made uniquely to resolve proper library
    order when linking a program, a module or a shared library.
    
    resolvedepends() did a little too much at once, so it's now reduced to
    only collect dependencies (and is renamed to collectdepends()), while
    a new function, expanddepends(), expands a list of dependency to
    insure that dependent libraries are present after depending libraries,
    and finally there is reducedepends() which removes unnecessary
    duplicates, leaving only the last one.
    
    resolvedepends() is now a simple utility routine that calls the three
    mentioned above in correct order.
    
    As part of this, we implement weak dependencies through the 'weak'
    build.info attribute.  This is meant to cause a specific order between
    libraries without requiring that they are all present.
    
    Reviewed-by: Matt Caswell <matt at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/10088)

commit 9eba5933a5ae80030ba66f79e625c4382811769e
Author: Richard Levitte <levitte at openssl.org>
Date:   Fri Oct 4 00:00:24 2019 +0200

    Configure: Implement attributes for DEPEND[xxx]
    
    We want to attach attributes on dependencies.
    
    Reviewed-by: Matt Caswell <matt at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/10088)

commit 285daccdc0e20fa70ddda9ddcd1f22191425de8a
Author: Richard Levitte <levitte at openssl.org>
Date:   Thu Oct 3 23:30:58 2019 +0200

    Configure: rework build.info grammar and attributes
    
    The build.info grammar's regular expressions were a horrible read.
    By assigning certain sub-expressions to variables, we hope to make
    it a little more readable.
    
    Also, the handling of build.info attributes is reworked to use a
    common function instead of having copies of the same code.
    
    Finally, the attributes are reorganized to specify if they belong with
    programs, libraries, modules or scripts.  This will enable more
    intricate attribute assignment in changes to come.
    
    Reviewed-by: Matt Caswell <matt at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/10088)

-----------------------------------------------------------------------

Summary of changes:
 Configurations/common.tmpl                         | 339 +++++++++++++++++----
 Configurations/descrip.mms.tmpl                    |  24 +-
 Configurations/platform/BASE.pm                    |  10 +-
 Configurations/platform/mingw.pm                   |   3 +
 Configurations/unix-Makefile.tmpl                  | 107 ++++---
 Configurations/windows-makefile.tmpl               |  30 +-
 Configure                                          | 211 ++++++-------
 crypto/aes/build.info                              |   4 +-
 crypto/blake2/m_blake2b.c                          |   2 +-
 crypto/blake2/m_blake2s.c                          |   2 +-
 crypto/bn/build.info                               |   4 +-
 crypto/buffer/build.info                           |   2 +-
 crypto/build.info                                  |   6 +-
 crypto/cmac/build.info                             |   2 +-
 crypto/des/build.info                              |   2 +-
 crypto/ec/build.info                               |   4 +-
 crypto/err/err_all.c                               |   2 +-
 crypto/err/openssl.ec                              |   2 +-
 crypto/evp/build.info                              |   2 +-
 crypto/evp/legacy_md5_sha1.c                       |   2 +-
 crypto/hmac/build.info                             |   2 +-
 crypto/initthread.c                                |   2 +-
 crypto/lhash/build.info                            |   2 +-
 crypto/md5/md5_sha1.c                              |   2 +-
 crypto/modes/build.info                            |   4 +-
 crypto/property/build.info                         |   2 +-
 crypto/rand/build.info                             |   2 +-
 crypto/rand/drbg_hash.c                            |   2 +-
 crypto/rand/drbg_hmac.c                            |   2 +-
 crypto/sha/build.info                              |   4 +-
 crypto/stack/build.info                            |   2 +-
 doc/internal/man3/ossl_prov_util_nid_to_name.pod   |   2 +-
 providers/build.info                               | 152 ++++++++-
 providers/common/build.info                        |   9 +-
 providers/common/ciphers/block.c                   |   2 +-
 providers/common/ciphers/build.info                |  24 +-
 providers/common/ciphers/cipher_ccm.c              |   6 +-
 providers/common/ciphers/cipher_ccm_hw.c           |   4 +-
 providers/common/ciphers/cipher_common.c           |   4 +-
 providers/common/ciphers/cipher_common_hw.c        |   2 +-
 providers/common/ciphers/cipher_gcm.c              |   8 +-
 providers/common/ciphers/cipher_gcm_hw.c           |   4 +-
 providers/common/ciphers/cipher_local.h            |   2 +-
 providers/common/digests/build.info                |   7 +-
 providers/common/digests/digest_common.c           |   4 +-
 providers/common/exchange/build.info               |   7 -
 .../{internal/ciphers => prov}/cipher_aead.h       |   0
 .../{internal/ciphers => prov}/cipher_ccm.h        |   0
 .../{internal/ciphers => prov}/cipher_gcm.h        |   0
 .../{internal/ciphers => prov}/ciphercommon.h      |   0
 .../include/{internal => prov}/digestcommon.h      |   0
 .../include/{internal => prov}/provider_ctx.h      |   0
 .../include/{internal => prov}/provider_util.h     |   0
 .../include/{internal => prov}/providercommon.h    |   0
 .../include/{internal => prov}/providercommonerr.h |   0
 providers/common/kdfs/build.info                   |  13 -
 providers/common/keymgmt/build.info                |   9 -
 providers/common/macs/build.info                   |  15 -
 providers/common/provider_err.c                    |   2 +-
 providers/common/provider_util.c                   |   2 +-
 providers/common/provlib.c                         |   2 +-
 providers/common/signature/build.info              |   7 -
 providers/default/build.info                       |   6 -
 providers/default/ciphers/build.info               |  26 +-
 providers/default/digests/build.info               |  15 -
 providers/default/kdfs/build.info                  |   3 -
 providers/default/macs/build.info                  |  15 -
 providers/{default => }/defltprov.c                |   2 +-
 providers/fips/build.info                          |   1 +
 providers/fips/fipsprov.c                          |   6 +-
 providers/implementations/build.info               |   1 +
 providers/implementations/ciphers/build.info       | 102 +++++++
 .../ciphers/cipher_aes.c                           |   2 +-
 .../ciphers/cipher_aes.h                           |   2 +-
 .../ciphers/cipher_aes_ccm.c                       |   6 +-
 .../ciphers/cipher_aes_ccm_hw.c                    |   4 +-
 .../ciphers/cipher_aes_ccm_hw_aesni.inc            |   0
 .../ciphers/cipher_aes_ccm_hw_s390x.inc            |   0
 .../ciphers/cipher_aes_ccm_hw_t4.inc               |   0
 .../ciphers/cipher_aes_gcm.c                       |   6 +-
 .../ciphers/cipher_aes_gcm_hw.c                    |   4 +-
 .../ciphers/cipher_aes_gcm_hw_aesni.inc            |   0
 .../ciphers/cipher_aes_gcm_hw_s390x.inc            |   0
 .../ciphers/cipher_aes_gcm_hw_t4.inc               |   0
 .../ciphers/cipher_aes_hw.c                        |   2 +-
 .../ciphers/cipher_aes_hw_aesni.inc                |   0
 .../ciphers/cipher_aes_hw_s390x.inc                |   0
 .../ciphers/cipher_aes_hw_t4.inc                   |   0
 .../ciphers/cipher_aes_ocb.c                       |   6 +-
 .../ciphers/cipher_aes_ocb.h                       |   2 +-
 .../ciphers/cipher_aes_ocb_hw.c                    |   0
 .../ciphers/cipher_aes_wrp.c                       |   4 +-
 .../ciphers/cipher_aes_xts.c                       |  10 +-
 .../ciphers/cipher_aes_xts.h                       |   8 +-
 .../ciphers/cipher_aes_xts_fips.c}                 |  11 +-
 .../ciphers/cipher_aes_xts_hw.c                    |   0
 .../ciphers/cipher_aria.c                          |   2 +-
 .../ciphers/cipher_aria.h                          |   2 +-
 .../ciphers/cipher_aria_ccm.c                      |   2 +-
 .../ciphers/cipher_aria_ccm.h                      |   4 +-
 .../ciphers/cipher_aria_ccm_hw.c                   |   0
 .../ciphers/cipher_aria_gcm.c                      |   2 +-
 .../ciphers/cipher_aria_gcm.h                      |   4 +-
 .../ciphers/cipher_aria_gcm_hw.c                   |   0
 .../ciphers/cipher_aria_hw.c                       |   0
 .../ciphers/cipher_blowfish.c                      |   2 +-
 .../ciphers/cipher_blowfish.h                      |   2 +-
 .../ciphers/cipher_blowfish_hw.c                   |   0
 .../ciphers/cipher_camellia.c                      |   2 +-
 .../ciphers/cipher_camellia.h                      |   2 +-
 .../ciphers/cipher_camellia_hw.c                   |   0
 .../ciphers/cipher_camellia_hw_t4.inc              |   0
 .../ciphers/cipher_cast.h                          |   2 +-
 .../ciphers/cipher_cast5.c                         |   2 +-
 .../ciphers/cipher_cast5_hw.c                      |   0
 .../ciphers/cipher_des.c                           |   6 +-
 .../ciphers/cipher_des.h                           |   0
 .../ciphers/cipher_des_hw.c                        |   2 +-
 .../ciphers/cipher_desx.c                          |   2 +-
 .../ciphers/cipher_desx_hw.c                       |   0
 .../ciphers/cipher_idea.c                          |   2 +-
 .../ciphers/cipher_idea.h                          |   2 +-
 .../ciphers/cipher_idea_hw.c                       |   0
 .../ciphers/cipher_rc2.c                           |   4 +-
 .../ciphers/cipher_rc2.h                           |   2 +-
 .../ciphers/cipher_rc2_hw.c                        |   0
 .../ciphers/cipher_rc4.c                           |   2 +-
 .../ciphers/cipher_rc4.h                           |   2 +-
 .../ciphers/cipher_rc4_hw.c                        |   0
 .../ciphers/cipher_rc5.c                           |   4 +-
 .../ciphers/cipher_rc5.h                           |   2 +-
 .../ciphers/cipher_rc5_hw.c                        |   0
 .../ciphers/cipher_seed.c                          |   2 +-
 .../ciphers/cipher_seed.h                          |   2 +-
 .../ciphers/cipher_seed_hw.c                       |   0
 .../ciphers/cipher_sm4.c                           |   2 +-
 .../ciphers/cipher_sm4.h                           |   2 +-
 .../ciphers/cipher_sm4_hw.c                        |   0
 .../ciphers/cipher_tdes.c                          |   8 +-
 .../ciphers/cipher_tdes.h                          |   0
 .../ciphers/cipher_tdes_default.c                  |   2 +-
 .../ciphers/cipher_tdes_default.h                  |   4 +-
 .../ciphers/cipher_tdes_default_hw.c               |   0
 .../ciphers/cipher_tdes_hw.c                       |   4 +-
 .../ciphers/cipher_tdes_wrap.c                     |   4 +-
 .../ciphers/cipher_tdes_wrap_hw.c                  |   0
 .../digests/blake2_impl.h                          |   0
 .../digests/blake2_prov.c                          |   6 +-
 .../digests/blake2b_prov.c                         |   2 +-
 .../digests/blake2s_prov.c                         |   2 +-
 providers/implementations/digests/build.info       |  52 ++++
 .../{legacy => implementations}/digests/md2_prov.c |   4 +-
 .../{legacy => implementations}/digests/md4_prov.c |   4 +-
 .../digests/md5_prov.c                             |   4 +-
 .../digests/md5_sha1_prov.c                        |   6 +-
 .../digests/mdc2_prov.c                            |   6 +-
 .../digests/ripemd_prov.c                          |   4 +-
 .../digests/sha2_prov.c                            |   4 +-
 .../digests/sha3_prov.c                            |   6 +-
 .../digests/sm3_prov.c                             |   4 +-
 .../{legacy => implementations}/digests/wp_prov.c  |   4 +-
 providers/implementations/exchange/build.info      |   8 +
 .../{common => implementations}/exchange/dh_exch.c |   2 +-
 .../include/prov}/blake2.h                         |   0
 .../include/prov/implementations.h}                |   0
 .../include/prov}/md5_sha1.h                       |   0
 providers/implementations/kdfs/build.info          |  29 ++
 providers/{common => implementations}/kdfs/hkdf.c  |   8 +-
 providers/{common => implementations}/kdfs/kbkdf.c |   8 +-
 .../{common => implementations}/kdfs/pbkdf2.c      |  20 +-
 .../kdfs/pbkdf2.h}                                 |   6 +-
 .../kdfs/pbkdf2_fips.c}                            |  12 +-
 .../{default => implementations}/kdfs/scrypt.c     |   8 +-
 .../{default => implementations}/kdfs/sshkdf.c     |   8 +-
 providers/{common => implementations}/kdfs/sskdf.c |   8 +-
 .../{common => implementations}/kdfs/tls1_prf.c    |   8 +-
 .../{default => implementations}/kdfs/x942kdf.c    |   8 +-
 providers/implementations/keymgmt/build.info       |  12 +
 .../{common => implementations}/keymgmt/dh_kmgmt.c |   2 +-
 .../keymgmt/dsa_kmgmt.c                            |   2 +-
 .../macs/blake2_mac_impl.c                         |   6 +-
 .../macs/blake2b_mac.c                             |   0
 .../macs/blake2s_mac.c                             |   0
 providers/implementations/macs/build.info          |  32 ++
 .../{common => implementations}/macs/cmac_prov.c   |   6 +-
 .../{common => implementations}/macs/gmac_prov.c   |   8 +-
 .../{common => implementations}/macs/hmac_prov.c   |   6 +-
 .../{common => implementations}/macs/kmac_prov.c   |   8 +-
 .../macs/poly1305_prov.c                           |   4 +-
 .../macs/siphash_prov.c                            |   4 +-
 providers/implementations/signature/build.info     |  10 +
 .../{common => implementations}/signature/dsa.c    |   4 +-
 providers/legacy/build.info                        |   8 -
 providers/legacy/digests/build.info                |  30 --
 providers/{legacy => }/legacyprov.c                |   2 +-
 195 files changed, 1136 insertions(+), 654 deletions(-)
 delete mode 100644 providers/common/exchange/build.info
 rename providers/common/include/{internal/ciphers => prov}/cipher_aead.h (100%)
 rename providers/common/include/{internal/ciphers => prov}/cipher_ccm.h (100%)
 rename providers/common/include/{internal/ciphers => prov}/cipher_gcm.h (100%)
 rename providers/common/include/{internal/ciphers => prov}/ciphercommon.h (100%)
 rename providers/common/include/{internal => prov}/digestcommon.h (100%)
 copy providers/common/include/{internal => prov}/provider_ctx.h (100%)
 rename providers/common/include/{internal => prov}/provider_util.h (100%)
 copy providers/common/include/{internal => prov}/providercommon.h (100%)
 rename providers/common/include/{internal => prov}/providercommonerr.h (100%)
 delete mode 100644 providers/common/kdfs/build.info
 delete mode 100644 providers/common/keymgmt/build.info
 delete mode 100644 providers/common/macs/build.info
 delete mode 100644 providers/common/signature/build.info
 delete mode 100644 providers/default/build.info
 delete mode 100644 providers/default/digests/build.info
 delete mode 100644 providers/default/kdfs/build.info
 delete mode 100644 providers/default/macs/build.info
 rename providers/{default => }/defltprov.c (99%)
 create mode 100644 providers/implementations/build.info
 create mode 100644 providers/implementations/ciphers/build.info
 rename providers/{common => implementations}/ciphers/cipher_aes.c (98%)
 rename providers/{common => implementations}/ciphers/cipher_aes.h (98%)
 rename providers/{common => implementations}/ciphers/cipher_aes_ccm.c (91%)
 rename providers/{common => implementations}/ciphers/cipher_aes_ccm_hw.c (96%)
 rename providers/{common => implementations}/ciphers/cipher_aes_ccm_hw_aesni.inc (100%)
 rename providers/{common => implementations}/ciphers/cipher_aes_ccm_hw_s390x.inc (100%)
 rename providers/{common => implementations}/ciphers/cipher_aes_ccm_hw_t4.inc (100%)
 rename providers/{common => implementations}/ciphers/cipher_aes_gcm.c (91%)
 rename providers/{common => implementations}/ciphers/cipher_aes_gcm_hw.c (96%)
 rename providers/{common => implementations}/ciphers/cipher_aes_gcm_hw_aesni.inc (100%)
 rename providers/{common => implementations}/ciphers/cipher_aes_gcm_hw_s390x.inc (100%)
 rename providers/{common => implementations}/ciphers/cipher_aes_gcm_hw_t4.inc (100%)
 rename providers/{common => implementations}/ciphers/cipher_aes_hw.c (99%)
 rename providers/{common => implementations}/ciphers/cipher_aes_hw_aesni.inc (100%)
 rename providers/{common => implementations}/ciphers/cipher_aes_hw_s390x.inc (100%)
 rename providers/{common => implementations}/ciphers/cipher_aes_hw_t4.inc (100%)
 rename providers/{default => implementations}/ciphers/cipher_aes_ocb.c (99%)
 rename providers/{default => implementations}/ciphers/cipher_aes_ocb.h (96%)
 rename providers/{default => implementations}/ciphers/cipher_aes_ocb_hw.c (100%)
 rename providers/{common => implementations}/ciphers/cipher_aes_wrp.c (99%)
 rename providers/{common => implementations}/ciphers/cipher_aes_xts.c (97%)
 rename providers/{common => implementations}/ciphers/cipher_aes_xts.h (82%)
 rename providers/{common/include/internal/providercommon.h => implementations/ciphers/cipher_aes_xts_fips.c} (68%)
 rename providers/{common => implementations}/ciphers/cipher_aes_xts_hw.c (100%)
 rename providers/{default => implementations}/ciphers/cipher_aria.c (98%)
 rename providers/{default => implementations}/ciphers/cipher_aria.h (96%)
 rename providers/{default => implementations}/ciphers/cipher_aria_ccm.c (96%)
 rename providers/{default => implementations}/ciphers/cipher_aria_ccm.h (88%)
 rename providers/{default => implementations}/ciphers/cipher_aria_ccm_hw.c (100%)
 rename providers/{default => implementations}/ciphers/cipher_aria_gcm.c (96%)
 rename providers/{default => implementations}/ciphers/cipher_aria_gcm.h (87%)
 rename providers/{default => implementations}/ciphers/cipher_aria_gcm_hw.c (100%)
 rename providers/{default => implementations}/ciphers/cipher_aria_hw.c (100%)
 rename providers/{default => implementations}/ciphers/cipher_blowfish.c (97%)
 rename providers/{default => implementations}/ciphers/cipher_blowfish.h (94%)
 rename providers/{default => implementations}/ciphers/cipher_blowfish_hw.c (100%)
 rename providers/{default => implementations}/ciphers/cipher_camellia.c (98%)
 rename providers/{default => implementations}/ciphers/cipher_camellia.h (96%)
 rename providers/{default => implementations}/ciphers/cipher_camellia_hw.c (100%)
 rename providers/{default => implementations}/ciphers/cipher_camellia_hw_t4.inc (100%)
 rename providers/{default => implementations}/ciphers/cipher_cast.h (94%)
 rename providers/{default => implementations}/ciphers/cipher_cast5.c (97%)
 rename providers/{default => implementations}/ciphers/cipher_cast5_hw.c (100%)
 rename providers/{default => implementations}/ciphers/cipher_des.c (98%)
 rename providers/{default => implementations}/ciphers/cipher_des.h (100%)
 rename providers/{default => implementations}/ciphers/cipher_des_hw.c (99%)
 rename providers/{default => implementations}/ciphers/cipher_desx.c (92%)
 rename providers/{default => implementations}/ciphers/cipher_desx_hw.c (100%)
 rename providers/{default => implementations}/ciphers/cipher_idea.c (97%)
 rename providers/{default => implementations}/ciphers/cipher_idea.h (94%)
 rename providers/{default => implementations}/ciphers/cipher_idea_hw.c (100%)
 rename providers/{default => implementations}/ciphers/cipher_rc2.c (99%)
 rename providers/{default => implementations}/ciphers/cipher_rc2.h (95%)
 rename providers/{default => implementations}/ciphers/cipher_rc2_hw.c (100%)
 rename providers/{default => implementations}/ciphers/cipher_rc4.c (99%)
 rename providers/{default => implementations}/ciphers/cipher_rc4.h (93%)
 rename providers/{default => implementations}/ciphers/cipher_rc4_hw.c (100%)
 rename providers/{default => implementations}/ciphers/cipher_rc5.c (98%)
 rename providers/{default => implementations}/ciphers/cipher_rc5.h (95%)
 rename providers/{default => implementations}/ciphers/cipher_rc5_hw.c (100%)
 rename providers/{default => implementations}/ciphers/cipher_seed.c (97%)
 rename providers/{default => implementations}/ciphers/cipher_seed.h (94%)
 rename providers/{default => implementations}/ciphers/cipher_seed_hw.c (100%)
 rename providers/{default => implementations}/ciphers/cipher_sm4.c (97%)
 rename providers/{default => implementations}/ciphers/cipher_sm4.h (95%)
 rename providers/{default => implementations}/ciphers/cipher_sm4_hw.c (100%)
 rename providers/{common => implementations}/ciphers/cipher_tdes.c (95%)
 rename providers/{common/include/internal => implementations}/ciphers/cipher_tdes.h (100%)
 rename providers/{default => implementations}/ciphers/cipher_tdes_default.c (97%)
 rename providers/{default => implementations}/ciphers/cipher_tdes_default.h (91%)
 rename providers/{default => implementations}/ciphers/cipher_tdes_default_hw.c (100%)
 rename providers/{common => implementations}/ciphers/cipher_tdes_hw.c (97%)
 rename providers/{default => implementations}/ciphers/cipher_tdes_wrap.c (99%)
 rename providers/{default => implementations}/ciphers/cipher_tdes_wrap_hw.c (100%)
 rename providers/{default => implementations}/digests/blake2_impl.h (100%)
 rename providers/{default => implementations}/digests/blake2_prov.c (92%)
 rename providers/{default => implementations}/digests/blake2b_prov.c (99%)
 rename providers/{default => implementations}/digests/blake2s_prov.c (99%)
 create mode 100644 providers/implementations/digests/build.info
 rename providers/{legacy => implementations}/digests/md2_prov.c (88%)
 rename providers/{legacy => implementations}/digests/md4_prov.c (88%)
 rename providers/{default => implementations}/digests/md5_prov.c (88%)
 rename providers/{default => implementations}/digests/md5_sha1_prov.c (94%)
 rename providers/{legacy => implementations}/digests/mdc2_prov.c (93%)
 rename providers/{legacy => implementations}/digests/ripemd_prov.c (89%)
 rename providers/{common => implementations}/digests/sha2_prov.c (97%)
 rename providers/{common => implementations}/digests/sha3_prov.c (99%)
 rename providers/{default => implementations}/digests/sm3_prov.c (88%)
 rename providers/{legacy => implementations}/digests/wp_prov.c (89%)
 create mode 100644 providers/implementations/exchange/build.info
 rename providers/{common => implementations}/exchange/dh_exch.c (99%)
 rename providers/{default/include/internal => implementations/include/prov}/blake2.h (100%)
 rename providers/{common/include/internal/provider_algs.h => implementations/include/prov/implementations.h} (100%)
 rename providers/{default/include/internal => implementations/include/prov}/md5_sha1.h (100%)
 create mode 100644 providers/implementations/kdfs/build.info
 rename providers/{common => implementations}/kdfs/hkdf.c (98%)
 rename providers/{common => implementations}/kdfs/kbkdf.c (98%)
 rename providers/{common => implementations}/kdfs/pbkdf2.c (96%)
 copy providers/{common/include/internal/provider_ctx.h => implementations/kdfs/pbkdf2.h} (68%)
 rename providers/{common/include/internal/provider_ctx.h => implementations/kdfs/pbkdf2_fips.c} (58%)
 rename providers/{default => implementations}/kdfs/scrypt.c (98%)
 rename providers/{default => implementations}/kdfs/sshkdf.c (98%)
 rename providers/{common => implementations}/kdfs/sskdf.c (99%)
 rename providers/{common => implementations}/kdfs/tls1_prf.c (98%)
 rename providers/{default => implementations}/kdfs/x942kdf.c (98%)
 create mode 100644 providers/implementations/keymgmt/build.info
 rename providers/{common => implementations}/keymgmt/dh_kmgmt.c (98%)
 rename providers/{common => implementations}/keymgmt/dsa_kmgmt.c (98%)
 rename providers/{default => implementations}/macs/blake2_mac_impl.c (98%)
 rename providers/{default => implementations}/macs/blake2b_mac.c (100%)
 rename providers/{default => implementations}/macs/blake2s_mac.c (100%)
 create mode 100644 providers/implementations/macs/build.info
 rename providers/{common => implementations}/macs/cmac_prov.c (98%)
 rename providers/{common => implementations}/macs/gmac_prov.c (97%)
 rename providers/{common => implementations}/macs/hmac_prov.c (98%)
 rename providers/{common => implementations}/macs/kmac_prov.c (99%)
 rename providers/{default => implementations}/macs/poly1305_prov.c (98%)
 rename providers/{default => implementations}/macs/siphash_prov.c (98%)
 create mode 100644 providers/implementations/signature/build.info
 rename providers/{common => implementations}/signature/dsa.c (99%)
 delete mode 100644 providers/legacy/build.info
 delete mode 100644 providers/legacy/digests/build.info
 rename providers/{legacy => }/legacyprov.c (99%)

diff --git a/Configurations/common.tmpl b/Configurations/common.tmpl
index 62b1102c79..a2591da727 100644
--- a/Configurations/common.tmpl
+++ b/Configurations/common.tmpl
@@ -2,37 +2,99 @@
 
  use File::Basename;
 
+ my $debug_resolvedepends = $ENV{BUILDFILE_DEBUG_DEPENDS};
+ my $debug_rules = $ENV{BUILDFILE_DEBUG_RULES};
+
  # A cache of objects for which a recipe has already been generated
  my %cache;
 
- # resolvedepends and reducedepends work in tandem to make sure
- # there are no duplicate dependencies and that they are in the
- # right order.  This is especially used to sort the list of
- # libraries that a build depends on.
+ # collectdepends, expanddepends and reducedepends work together to make
+ # sure there are no duplicate or weak dependencies and that they are in
+ # the right order.  This is used to sort the list of libraries  that a
+ # build depends on.
  sub extensionlesslib {
      my @result = map { $_ =~ /(\.a)?$/; $` } @_;
      return @result if wantarray;
      return $result[0];
  }
- sub resolvedepends {
+
+ # collectdepends dives into the tree of dependencies and returns
+ # a list of all the non-weak ones.
+ sub collectdepends {
+     return () unless @_;
+
      my $thing = shift;
      my $extensionlessthing = extensionlesslib($thing);
      my @listsofar = @_;    # to check if we're looping
      my @list = @{$unified_info{depends}->{$thing} //
                       $unified_info{depends}->{$extensionlessthing}};
      my @newlist = ();
-     if (scalar @list) {
-         foreach my $item (@list) {
-             my $extensionlessitem = extensionlesslib($item);
-             # It's time to break off when the dependency list starts looping
-             next if grep { extensionlesslib($_) eq $extensionlessitem } @listsofar;
-             push @newlist, $item, resolvedepends($item, @listsofar, $item);
-         }
+
+     print STDERR "DEBUG[collectdepends] $thing > ", join(' ', @listsofar), "\n"
+         if $debug_resolvedepends;
+     foreach my $item (@list) {
+         my $extensionlessitem = extensionlesslib($item);
+         # It's time to break off when the dependency list starts looping
+         next if grep { extensionlesslib($_) eq $extensionlessitem } @listsofar;
+         # Don't add anything here if the dependency is weak
+         next if defined $unified_info{attributes}->{depends}->{$thing}->{$item}->{'weak'};
+         my @resolved = collectdepends($item, @listsofar, $item);
+         push @newlist, $item, @resolved;
      }
+     print STDERR "DEBUG[collectdepends] $thing < ", join(' ', @newlist), "\n"
+         if $debug_resolvedepends;
      @newlist;
  }
+
+ # expanddepends goes through a list of stuff, checks if they have any
+ # dependencies, and adds them at the end of the current position if
+ # they aren't already present later on.
+ sub expanddepends {
+     my @after = ( @_ );
+     print STDERR "DEBUG[expanddepends]> ", join(' ', @after), "\n"
+         if $debug_resolvedepends;
+     my @before = ();
+     while (@after) {
+         my $item = shift @after;
+         print STDERR "DEBUG[expanddepends]\\  ", join(' ', @before), "\n"
+             if $debug_resolvedepends;
+         print STDERR "DEBUG[expanddepends] - ", $item, "\n"
+             if $debug_resolvedepends;
+         my @middle = (
+             $item,
+             map {
+                 my $x = $_;
+                 my $extlessx = extensionlesslib($x);
+                 if (grep { $extlessx eq extensionlesslib($_) } @before
+                     and
+                     !grep { $extlessx eq extensionlesslib($_) } @after) {
+                     print STDERR "DEBUG[expanddepends] + ", $x, "\n"
+                         if $debug_resolvedepends;
+                     ( $x )
+                 } else {
+                     print STDERR "DEBUG[expanddepends] ! ", $x, "\n"
+                         if $debug_resolvedepends;
+                     ()
+                 }
+             } @{$unified_info{depends}->{$item} // []}
+         );
+         print STDERR "DEBUG[expanddepends] = ", join(' ', @middle), "\n"
+             if $debug_resolvedepends;
+         print STDERR "DEBUG[expanddepends]/  ", join(' ', @after), "\n"
+             if $debug_resolvedepends;
+         push @before, @middle;
+     }
+     print STDERR "DEBUG[expanddepends]< ", join(' ', @before), "\n"
+         if $debug_resolvedepends;
+     @before;
+ }
+
+ # reducedepends looks through a list, and checks if each item is
+ # repeated later on.  If it is, the earlier copy is dropped.
  sub reducedepends {
      my @list = @_;
+     print STDERR "DEBUG[reducedepends]> ", join(' ', @list), "\n"
+         if $debug_resolvedepends;
      my @newlist = ();
      my %replace = ();
      while (@list) {
@@ -49,7 +111,25 @@
              push @newlist, $item;
          }
      }
-     map { $replace{$_} // $_; } @newlist;
+     @newlist = map { $replace{$_} // $_; } @newlist;
+     print STDERR "DEBUG[reducedepends]< ", join(' ', @newlist), "\n"
+         if $debug_resolvedepends;
+     @newlist;
+ }
+
+ # Do it all
+ # This takes multiple inputs and combine them into a single list of
+ # interdependent things.  The returned value will include all the input.
+ # Callers are responsible for taking away the things they are building.
+ sub resolvedepends {
+     print STDERR "DEBUG[resolvedepends] START (", join(', ', @_), ")\n"
+         if $debug_resolvedepends;
+     my @all =
+         reducedepends(expanddepends(map { ( $_, collectdepends($_) ) } @_));
+     print STDERR "DEBUG[resolvedepends] END (", join(', ', @_), ") : ",
+         join(',', map { "\n    $_" } @all), "\n"
+         if $debug_resolvedepends;
+     @all;
  }
 
  # dogenerate is responsible for producing all the recipes that build
@@ -91,14 +171,30 @@
      my $bin = shift;
      my %opts = @_;
      if (@{$unified_info{sources}->{$obj}}) {
-         $OUT .= src2obj(obj => $obj,
-                         product => $bin,
-                         srcs => $unified_info{sources}->{$obj},
-                         deps => $unified_info{depends}->{$obj},
-                         incs => [ @{$unified_info{includes}->{$obj}},
-                                   @{$unified_info{includes}->{$bin}} ],
-                         defs => [ @{$unified_info{defines}->{$obj}},
-                                   @{$unified_info{defines}->{$bin}} ],
+         my @srcs = @{$unified_info{sources}->{$obj}};
+         my @deps = @{$unified_info{depends}->{$obj}};
+         my @incs = ( @{$unified_info{includes}->{$obj}},
+                      @{$unified_info{includes}->{$bin}} );
+         my @defs = ( @{$unified_info{defines}->{$obj}},
+                      @{$unified_info{defines}->{$bin}} );
+         print STDERR "DEBUG[doobj] \@srcs for $obj ($bin) : ",
+             join(",", map { "\n    $_" } @srcs), "\n"
+             if $debug_rules;
+         print STDERR "DEBUG[doobj] \@deps for $obj ($bin) : ",
+             join(",", map { "\n    $_" } @deps), "\n"
+             if $debug_rules;
+         print STDERR "DEBUG[doobj] \@incs for $obj ($bin) : ",
+             join(",", map { "\n    $_" } @incs), "\n"
+             if $debug_rules;
+         print STDERR "DEBUG[doobj] \@defs for $obj ($bin) : ",
+             join(",", map { "\n    $_" } @defs), "\n"
+             if $debug_rules;
+         print STDERR "DEBUG[doobj] \%opts for $obj ($bin) : ", ,
+             join(",", map { "\n    $_ = $opts{$_}" } sort keys %opts), "\n"
+             if $debug_rules;
+         $OUT .= src2obj(obj => $obj, product => $bin,
+                         srcs => [ @srcs ], deps => [ @deps ],
+                         incs => [ @incs ], defs => [ @defs ],
                          %opts);
          foreach ((@{$unified_info{sources}->{$obj}},
                    @{$unified_info{depends}->{$obj}})) {
@@ -108,37 +204,152 @@
      $cache{$obj} = 1;
  }
 
+ # Helper functions to grab all applicable intermediary files.
+ # This is particularly useful when a library is given as source
+ # rather than a dependency.  In that case, we consider it to be a
+ # container with object file references, or possibly references
+ # to further libraries to pilfer in the same way.
+ sub getsrclibs {
+     my $section = shift;
+
+     # For all input, see if it sources static libraries.  If it does,
+     # return them together with the result of a recursive call.
+     map { ( $_, getsrclibs($section, $_) ) }
+     grep { $_ =~ m|\.a$| }
+     map { @{$unified_info{$section}->{$_} // []} }
+     @_;
+ }
+
+ sub getlibobjs {
+     my $section = shift;
+
+     # For all input, see if it's an intermediary file (library or object).
+     # If it is, collect the result of a recursive call, or if that returns
+     # an empty list, the element itself.  Return the result.
+     map {
+         my @x = getlibobjs($section, @{$unified_info{$section}->{$_}});
+         @x ? @x : ( $_ );
+     }
+     grep { defined $unified_info{$section}->{$_} }
+     @_;
+ }
+
  # dolib is responsible for building libraries.  It will call
- # obj2shlib is shared libraries are produced, and obj2lib in all
+ # obj2shlib if shared libraries are produced, and obj2lib in all
  # cases.  It also makes sure all object files for the library are
  # built.
  sub dolib {
      my $lib = shift;
      return "" if $cache{$lib};
+
+     my %attrs = %{$unified_info{attributes}->{libraries}->{$lib}};
+
+     my @deps = ( resolvedepends(getsrclibs('sources', $lib)) );
+
+     # We support two types of objs, those who are specific to this library
+     # (they end up in @objs) and those that we get indirectly, via other
+     # libraries (they end up in @foreign_objs).  We get the latter any time
+     # someone has done something like this in build.info:
+     #     SOURCE[libfoo.a]=libbar.a
+     # The indirect object files must be kept in a separate array so they
+     # don't get rebuilt unnecessarily (and with incorrect auxiliary
+     # information).
+     #
+     # Object files can't be collected commonly for shared and static
+     # libraries, because we contain their respective object files in
+     # {shared_sources} and {sources}, and because the implications are
+     # slightly different for each library form.
+     #
+     # We grab all these "foreign" object files recursively with getlibobjs().
+
      unless ($disabled{shared} || $lib =~ /\.a$/) {
          my $obj2shlib = defined &obj2shlib ? \&obj2shlib : \&libobj2shlib;
+         # If this library sources other static libraries and those
+         # libraries are marked {noinst}, there's no need to include
+         # all of their object files.  Instead, we treat those static
+         # libraries as dependents alongside any other library this
+         # one depends on, and let symbol resolution do its job.
+         my @sourced_libs = ();
+         my @objs = ();
+         my @foreign_objs = ();
+         my @deps = ();
+         foreach (@{$unified_info{shared_sources}->{$lib}}) {
+             if ($_ !~ m|\.a$|) {
+                 push @objs, $_;
+             } elsif ($unified_info{attributes}->{libraries}->{$_}->{noinst}) {
+                 push @deps, $_;
+             } else {
+                 push @deps, getsrclibs('sources', $_);
+                 push @foreign_objs, getlibobjs('sources', $_);
+             }
+         }
+         @deps = ( grep { $_ ne $lib } resolvedepends($lib, @deps) );
+         print STDERR "DEBUG[dolib:shlib] \%attrs for $lib : ", ,
+             join(",", map { "\n    $_ = $attrs{$_}" } sort keys %attrs), "\n"
+             if %attrs && $debug_rules;
+         print STDERR "DEBUG[dolib:shlib] \@deps for $lib : ",
+             join(",", map { "\n    $_" } @deps), "\n"
+             if @deps && $debug_rules;
+         print STDERR "DEBUG[dolib:shlib] \@objs for $lib : ",
+             join(",", map { "\n    $_" } @objs), "\n"
+             if @objs && $debug_rules;
+         print STDERR "DEBUG[dolib:shlib] \@foreign_objs for $lib : ",
+             join(",", map { "\n    $_" } @foreign_objs), "\n"
+             if @foreign_objs && $debug_rules;
          $OUT .= $obj2shlib->(lib => $lib,
-                              attrs => $unified_info{attributes}->{$lib},
-                              objs => $unified_info{shared_sources}->{$lib},
-                              deps => [ reducedepends(resolvedepends($lib)) ]);
-         foreach ((@{$unified_info{shared_sources}->{$lib}},
-                   @{$unified_info{sources}->{$lib}})) {
+                              attrs => { %attrs },
+                              objs => [ @objs, @foreign_objs ],
+                              deps => [ @deps ]);
+         foreach (@objs) {
              # If this is somehow a compiled object, take care of it that way
              # Otherwise, it might simply be generated
              if (defined $unified_info{sources}->{$_}) {
-                 doobj($_, $lib, intent => "shlib",
-                       attrs => $unified_info{attributes}->{$lib});
+                 if($_ =~ /\.a$/) {
+                     dolib($_);
+                 } else {
+                     doobj($_, $lib, intent => "shlib", attrs => { %attrs });
+                 }
              } else {
                  dogenerate($_, undef, undef, intent => "lib");
              }
          }
      }
-     $OUT .= obj2lib(lib => $lib,
-                     attrs => $unified_info{attributes}->{$lib},
-                     objs => [ @{$unified_info{sources}->{$lib}} ]);
-     foreach (@{$unified_info{sources}->{$lib}}) {
-         doobj($_, $lib, intent => "lib",
-               attrs => $unified_info{attributes}->{$lib});
+     {
+         # When putting static libraries together, we cannot rely on any
+         # symbol resolution, so for all static libraries used as source for
+         # this one, as well as other libraries they depend on, we simply
+         # grab all their object files unconditionally,
+         # Symbol resolution will happen when any program, module or shared
+         # library is linked with this one.
+         my @objs = ();
+         my @sourcedeps = ();
+         my @foreign_objs = ();
+         foreach (@{$unified_info{sources}->{$lib}}) {
+             if ($_ !~ m|\.a$|) {
+                 push @objs, $_;
+             } else {
+                 push @sourcedeps, $_;
+             }
+         }
+         @sourcedeps = ( grep { $_ ne $lib } resolvedepends(@sourcedeps) );
+         print STDERR "DEBUG[dolib:lib] : \@sourcedeps for $_ : ",
+             join(",", map { "\n    $_" } @sourcedeps), "\n"
+             if @sourcedeps && $debug_rules;
+         @foreign_objs = getlibobjs('sources', @sourcedeps);
+         print STDERR "DEBUG[dolib:lib] \%attrs for $lib : ", ,
+             join(",", map { "\n    $_ = $attrs{$_}" } sort keys %attrs), "\n"
+             if %attrs && $debug_rules;
+         print STDERR "DEBUG[dolib:lib] \@objs for $lib : ",
+             join(",", map { "\n    $_" } @objs), "\n"
+             if @objs && $debug_rules;
+         print STDERR "DEBUG[dolib:lib] \@foreign_objs for $lib : ",
+             join(",", map { "\n    $_" } @foreign_objs), "\n"
+             if @foreign_objs && $debug_rules;
+         $OUT .= obj2lib(lib => $lib, attrs => { %attrs },
+                         objs => [ @objs, @foreign_objs ]);
+         foreach (@objs) {
+             doobj($_, $lib, intent => "lib", attrs => { %attrs });
+         }
      }
      $cache{$lib} = 1;
  }
@@ -147,23 +358,35 @@
  # obj2dso, and also makes sure all object files for the library
  # are built.
  sub domodule {
-     my $lib = shift;
-     return "" if $cache{$lib};
-     $OUT .= obj2dso(lib => $lib,
-                     attrs => $unified_info{attributes}->{$lib},
-                     objs => $unified_info{sources}->{$lib},
-                     deps => [ resolvedepends($lib) ]);
-     foreach (@{$unified_info{sources}->{$lib}}) {
+     my $module = shift;
+     return "" if $cache{$module};
+     my %attrs = %{$unified_info{attributes}->{modules}->{$module}};
+     my @objs = @{$unified_info{sources}->{$module}};
+     my @deps = ( grep { $_ ne $module }
+                  resolvedepends($module) );
+     print STDERR "DEBUG[domodule] \%attrs for $module :",
+         join(",", map { "\n    $_ = $attrs{$_}" } sort keys %attrs), "\n"
+         if $debug_rules;
+     print STDERR "DEBUG[domodule] \@objs for $module : ",
+         join(",", map { "\n    $_" } @objs), "\n"
+         if $debug_rules;
+     print STDERR "DEBUG[domodule] \@deps for $module : ",
+         join(",", map { "\n    $_" } @deps), "\n"
+         if $debug_rules;
+     $OUT .= obj2dso(module => $module,
+                     attrs => { %attrs },
+                     objs => [ @objs ],
+                     deps => [ @deps ]);
+     foreach (@{$unified_info{sources}->{$module}}) {
          # If this is somehow a compiled object, take care of it that way
          # Otherwise, it might simply be generated
          if (defined $unified_info{sources}->{$_}) {
-             doobj($_, $lib, intent => "dso",
-                   attrs => $unified_info{attributes}->{$lib});
+             doobj($_, $module, intent => "dso", attrs => { %attrs });
          } else {
-             dogenerate($_, undef, $lib, intent => "dso");
+             dogenerate($_, undef, $module, intent => "dso");
          }
      }
-     $cache{$lib} = 1;
+     $cache{$module} = 1;
  }
 
  # dobin is responsible for building programs.  It will call obj2bin,
@@ -171,14 +394,24 @@
  sub dobin {
      my $bin = shift;
      return "" if $cache{$bin};
-     my $deps = [ reducedepends(resolvedepends($bin)) ];
+     my %attrs = %{$unified_info{attributes}->{programs}->{$bin}};
+     my @objs = @{$unified_info{sources}->{$bin}};
+     my @deps = ( grep { $_ ne $bin } resolvedepends($bin) );
+     print STDERR "DEBUG[dobin] \%attrs for $bin : ",
+         join(",", map { "\n    $_ = $attrs{$_}" } sort keys %attrs), "\n"
+         if %attrs && $debug_rules;
+     print STDERR "DEBUG[dobin] \@objs for $bin : ",
+         join(",", map { "\n    $_" } @objs), "\n"
+         if @objs && $debug_rules;
+     print STDERR "DEBUG[dobin] \@deps for $bin : ",
+         join(",", map { "\n    $_" } @deps), "\n"
+         if @deps && $debug_rules;
      $OUT .= obj2bin(bin => $bin,
-                     attrs => $unified_info{attributes}->{$bin},
-                     objs => [ @{$unified_info{sources}->{$bin}} ],
-                     deps => $deps);
-     foreach (@{$unified_info{sources}->{$bin}}) {
-         doobj($_, $bin, intent => "bin",
-               attrs => $unified_info{attributes}->{$bin});
+                     attrs => { %attrs },
+                     objs => [ @objs ],
+                     deps => [ @deps ]);
+     foreach (@objs) {
+         doobj($_, $bin, intent => "bin", attrs => { %attrs });
      }
      $cache{$bin} = 1;
  }
diff --git a/Configurations/descrip.mms.tmpl b/Configurations/descrip.mms.tmpl
index 892102dd91..e177f2202e 100644
--- a/Configurations/descrip.mms.tmpl
+++ b/Configurations/descrip.mms.tmpl
@@ -48,26 +48,26 @@
       @{$unified_info{libraries}};
   our @install_libs =
       map { platform->staticname($_) }
-      grep { !$unified_info{attributes}->{$_}->{noinst} }
+      grep { !$unified_info{attributes}->{libraries}->{$_}->{noinst} }
       @{$unified_info{libraries}};
   our @install_shlibs =
       map { platform->sharedname($_) // () }
-      grep { !$unified_info{attributes}->{$_}->{noinst} }
+      grep { !$unified_info{attributes}->{libraries}->{$_}->{noinst} }
       @{$unified_info{libraries}};
   our @install_engines =
-      grep { !$unified_info{attributes}->{$_}->{noinst}
-             && $unified_info{attributes}->{$_}->{engine} }
+      grep { !$unified_info{attributes}->{modules}->{$_}->{noinst}
+             && $unified_info{attributes}->{modules}->{$_}->{engine} }
       @{$unified_info{modules}};
   our @install_programs =
-      grep { !$unified_info{attributes}->{$_}->{noinst} }
+      grep { !$unified_info{attributes}->{programs}->{$_}->{noinst} }
       @{$unified_info{programs}};
   our @install_bin_scripts =
-      grep { !$unified_info{attributes}->{$_}->{noinst}
-             && !$unified_info{attributes}->{$_}->{misc} }
+      grep { !$unified_info{attributes}->{scripts}->{$_}->{noinst}
+             && !$unified_info{attributes}->{scripts}->{$_}->{misc} }
       @{$unified_info{scripts}};
   our @install_misc_scripts =
-      grep { !$unified_info{attributes}->{$_}->{noinst}
-             && $unified_info{attributes}->{$_}->{misc} }
+      grep { !$unified_info{attributes}->{scripts}->{$_}->{noinst}
+             && $unified_info{attributes}->{scripts}->{$_}->{misc} }
       @{$unified_info{scripts}};
 
   # This is a horrible hack, but is needed because recursive inclusion of files
@@ -704,7 +704,7 @@ reconfigure reconf :
       # On Unix platforms, we depend on {shlibname}.so
       return map {
           { lib   => platform->sharedlib($_) // platform->staticlib($_),
-            attrs => $unified_info{attributes}->{$_} }
+            attrs => $unified_info{attributes}->{libraries}->{$_} }
       } @_;
   }
 
@@ -1014,8 +1014,8 @@ EOF
   }
   sub obj2dso {
       my %args = @_;
-      my $dsoname = platform->dsoname($args{lib});
-      my $dso = platform->dso($args{lib});
+      my $dsoname = platform->dsoname($args{module});
+      my $dso = platform->dso($args{module});
       my @objs = map { platform->convertext($_) }
                  grep { platform->isobj($_) }
                  @{$args{objs}};
diff --git a/Configurations/platform/BASE.pm b/Configurations/platform/BASE.pm
index fcd7b70ccf..1ab4bf18e9 100644
--- a/Configurations/platform/BASE.pm
+++ b/Configurations/platform/BASE.pm
@@ -52,11 +52,13 @@ sub isdef       { return $_[1] =~ m|\.ld$|;   }
 sub isobj       { return $_[1] =~ m|\.o$|;    }
 sub isres       { return $_[1] =~ m|\.res$|;  }
 sub isasm       { return $_[1] =~ m|\.[Ss]$|; }
+sub isstaticlib { return $_[1] =~ m|\.a$|;    }
 sub convertext {
-    if ($_[0]->isdef($_[1]))    { return $_[0]->def($_[1]); }
-    if ($_[0]->isobj($_[1]))    { return $_[0]->obj($_[1]); }
-    if ($_[0]->isres($_[1]))    { return $_[0]->res($_[1]); }
-    if ($_[0]->isasm($_[1]))    { return $_[0]->asm($_[1]); }
+    if ($_[0]->isdef($_[1]))        { return $_[0]->def($_[1]); }
+    if ($_[0]->isobj($_[1]))        { return $_[0]->obj($_[1]); }
+    if ($_[0]->isres($_[1]))        { return $_[0]->res($_[1]); }
+    if ($_[0]->isasm($_[1]))        { return $_[0]->asm($_[1]); }
+    if ($_[0]->isstaticlib($_[1]))  { return $_[0]->staticlib($_[1]); }
     return $_[1];
 }
 
diff --git a/Configurations/platform/mingw.pm b/Configurations/platform/mingw.pm
index 5788a36e77..7dacb32a31 100644
--- a/Configurations/platform/mingw.pm
+++ b/Configurations/platform/mingw.pm
@@ -17,6 +17,9 @@ sub objext              { '.obj' }
 sub libext              { '.a' }
 sub dsoext              { '.dll' }
 sub defext              { '.def' }
+
+# Other extra that aren't defined in platform::BASE
+sub resext              { '.res.obj' }
 sub shlibext            { '.dll' }
 sub shlibextimport      { $target{shared_import_extension} || '.dll.a' }
 sub shlibextsimple      { undef }
diff --git a/Configurations/unix-Makefile.tmpl b/Configurations/unix-Makefile.tmpl
index 74b9079219..7c44a04224 100644
--- a/Configurations/unix-Makefile.tmpl
+++ b/Configurations/unix-Makefile.tmpl
@@ -54,44 +54,44 @@ GENERATED={- # common0.tmpl provides @generated
 
 INSTALL_LIBS={-
         join(" ", map { platform->staticlib($_) // () }
-                  grep { !$unified_info{attributes}->{$_}->{noinst} }
+                  grep { !$unified_info{attributes}->{libraries}->{$_}->{noinst} }
                   @{$unified_info{libraries}})
 -}
 INSTALL_SHLIBS={-
         join(" ", map { platform->sharedlib($_) // () }
-                  grep { !$unified_info{attributes}->{$_}->{noinst} }
+                  grep { !$unified_info{attributes}->{libraries}->{$_}->{noinst} }
                   @{$unified_info{libraries}})
 -}
 INSTALL_SHLIB_INFO={-
         join(" ", map { my $x = platform->sharedlib($_);
                         my $y = platform->sharedlib_simple($_);
                         $x ? "\"$x;$y\"" : () }
-                  grep { !$unified_info{attributes}->{$_}->{noinst} }
+                  grep { !$unified_info{attributes}->{libraries}->{$_}->{noinst} }
                   @{$unified_info{libraries}})
 -}
 INSTALL_ENGINES={-
         join(" ", map { platform->dso($_) }
-                  grep { !$unified_info{attributes}->{$_}->{noinst}
-                         && $unified_info{attributes}->{$_}->{engine} }
+                  grep { !$unified_info{attributes}->{modules}->{$_}->{noinst}
+                         && $unified_info{attributes}->{modules}->{$_}->{engine} }
                   @{$unified_info{modules}})
 -}
 INSTALL_PROGRAMS={-
         join(" ", map { platform->bin($_) }
-                  grep { !$unified_info{attributes}->{$_}->{noinst} }
+                  grep { !$unified_info{attributes}->{programs}->{$_}->{noinst} }
                   @{$unified_info{programs}})
 -}
 BIN_SCRIPTS={-
-        join(" ", map { my $x = $unified_info{attributes}->{$_}->{linkname};
+        join(" ", map { my $x = $unified_info{attributes}->{scripts}->{$_}->{linkname};
                         $x ? "$_:$x" : $_ }
-                  grep { !$unified_info{attributes}->{$_}->{noinst}
-                         && !$unified_info{attributes}->{$_}->{misc} }
+                  grep { !$unified_info{attributes}->{scripts}->{$_}->{noinst}
+                         && !$unified_info{attributes}->{scripts}->{$_}->{misc} }
                   @{$unified_info{scripts}})
 -}
 MISC_SCRIPTS={-
-        join(" ", map { my $x = $unified_info{attributes}->{$_}->{linkname};
+        join(" ", map { my $x = $unified_info{attributes}->{scripts}->{$_}->{linkname};
                         $x ? "$_:$x" : $_ }
-                  grep { !$unified_info{attributes}->{$_}->{noinst}
-                         && $unified_info{attributes}->{$_}->{misc} }
+                  grep { !$unified_info{attributes}->{scripts}->{$_}->{noinst}
+                         && $unified_info{attributes}->{scripts}->{$_}->{misc} }
                   @{$unified_info{scripts}})
 -}
 
@@ -1015,7 +1015,7 @@ EOF
   # last in the line.  We may therefore need to put back a line ending.
   sub src2obj {
       my %args = @_;
-      my $obj = platform->obj($args{obj});
+      my $obj = platform->convertext($args{obj});
       my $dep = platform->dep($args{obj});
       my @srcs = @{$args{srcs}};
       my $srcs = join(" ",  @srcs);
@@ -1095,15 +1095,22 @@ EOF
   sub obj2shlib {
       my %args = @_;
       my @linkdirs = ();
-      foreach (@{args{deps}}) {
-          my $d = dirname($_);
-          push @linkdirs, $d unless grep { $d eq $_ } @linkdirs;
+      my @linklibs = ();
+      foreach (@{$args{deps}}) {
+          if (platform->isstaticlib($_)) {
+              push @linklibs, platform->convertext($_);
+          } else {
+              my $d = "-L" . dirname($_);
+              my $l = basename($_);
+              $l =~ s/^lib//;
+              $l = "-l" . $l;
+              push @linklibs, $l;
+              push @linkdirs, $d unless grep { $d eq $_ } @linkdirs;
+          }
       }
-      my $linkflags = join("", map { "-L$_ " } @linkdirs);
-      my $linklibs = join("", map { my $f = basename($_);
-                                    (my $l = $f) =~ s/^lib//;
-                                    " -l$l" } @{$args{deps}});
-      my @objs = map { platform->obj($_) }
+      my $linkflags = join("", map { $_." " } @linkdirs);
+      my $linklibs = join("", map { $_." " } @linklibs);
+      my @objs = map { platform->convertext($_) }
                  grep { !platform->isdef($_) }
                  @{$args{objs}};
       my @defs = map { platform->def($_) }
@@ -1156,17 +1163,25 @@ EOF
   }
   sub obj2dso {
       my %args = @_;
-      my $dso = platform->dso($args{lib});
+      my $dso = platform->dso($args{module});
       my @linkdirs = ();
-      foreach (@{args{deps}}) {
-          my $d = dirname($_);
-          push @linkdirs, $d unless grep { $d eq $_ } @linkdirs;
+      my @linklibs = ();
+      foreach (@{$args{deps}}) {
+          next unless defined $_;
+          if (platform->isstaticlib($_)) {
+              push @linklibs, platform->convertext($_);
+          } else {
+              my $d = "-L" . dirname($_);
+              my $l = basename($_);
+              $l =~ s/^lib//;
+              $l = "-l" . $l;
+              push @linklibs, $l;
+              push @linkdirs, $d unless grep { $d eq $_ } @linkdirs;
+          }
       }
-      my $linkflags = join("", map { "-L$_ " } @linkdirs);
-      my $linklibs = join("", map { my $f = basename($_);
-                                    (my $l = $f) =~ s/^lib//;
-                                    " -l$l" } @{$args{deps}});
-      my @objs = map { platform->obj($_) }
+      my $linkflags = join("", map { $_." " } @linkdirs);
+      my $linklibs = join("", map { $_." " } @linklibs);
+      my @objs = map { platform->convertext($_) }
                  grep { !platform->isdef($_) }
                  @{$args{objs}};
       my @defs = map { platform->def($_) }
@@ -1180,7 +1195,7 @@ EOF
 $dso: $deps
 	\$(CC) \$(DSO_CFLAGS) $linkflags\$(DSO_LDFLAGS) \\
 		-o $dso$shared_def $objs \\
-                $linklibs \$(DSO_EX_LIBS)
+                $linklibs\$(DSO_EX_LIBS)
 EOF
   }
   sub obj2lib {
@@ -1200,20 +1215,22 @@ EOF
       my $objs = join(" ", map { platform->obj($_) } @{$args{objs}});
       my $deps = join(" ", compute_lib_depends(@{$args{deps}}));
       my @linkdirs = ();
-      foreach (@{args{deps}}) {
-          next if $_ =~ /\.a$/;
-          my $d = dirname($_);
-          push @linkdirs, $d unless grep { $d eq $_ } @linkdirs;
+      my @linklibs = ();
+      foreach (@{$args{deps}}) {
+          next unless defined $_;
+          if (platform->isstaticlib($_)) {
+              push @linklibs, platform->convertext($_);
+          } else {
+              my $d = "-L" . dirname($_);
+              my $l = basename($_);
+              $l =~ s/^lib//;
+              $l = "-l" . $l;
+              push @linklibs, $l;
+              push @linkdirs, $d unless grep { $d eq $_ } @linkdirs;
+          }
       }
-      my $linkflags = join("", map { "-L$_ " } @linkdirs);
-      my $linklibs = join("", map { if ($_ =~ m/\.a$/) {
-                                        " ".platform->staticlib($_);
-                                    } else {
-                                        my $f = basename($_);
-                                        (my $l = $f) =~ s/^lib//;
-                                        " -l$l"
-                                    }
-                                  } @{$args{deps}});
+      my $linkflags = join("", map { $_." " } @linkdirs);
+      my $linklibs = join("", map { $_." " } @linklibs);
       my $cmd = '$(CC)';
       my $cmdflags = '$(BIN_CFLAGS)';
       if (grep /_cc\.o$/, @{$args{objs}}) {
@@ -1225,7 +1242,7 @@ $bin: $objs $deps
 	rm -f $bin
 	\$\${LDCMD:-$cmd} $cmdflags $linkflags\$(BIN_LDFLAGS) \\
 		-o $bin $objs \\
-		$linklibs \$(BIN_EX_LIBS)
+		$linklibs\$(BIN_EX_LIBS)
 EOF
   }
   sub in2script {
diff --git a/Configurations/windows-makefile.tmpl b/Configurations/windows-makefile.tmpl
index bfe88f6cc9..4a83d0cee6 100644
--- a/Configurations/windows-makefile.tmpl
+++ b/Configurations/windows-makefile.tmpl
@@ -62,53 +62,53 @@ GENERATED={- # common0.tmpl provides @generated
 INSTALL_LIBS={-
         join(" ", map { quotify1(platform->sharedlib_import($_)
                                  // platform->staticlib($_)) }
-                  grep { !$unified_info{attributes}->{$_}->{noinst} }
+                  grep { !$unified_info{attributes}->{libraries}->{$_}->{noinst} }
                   @{$unified_info{libraries}})
 -}
 INSTALL_SHLIBS={-
         join(" ", map { my $x = platform->sharedlib($_);
                         $x ? quotify_l($x) : () }
-                  grep { !$unified_info{attributes}->{$_}->{noinst} }
+                  grep { !$unified_info{attributes}->{libraries}->{$_}->{noinst} }
                   @{$unified_info{libraries}})
 -}
 INSTALL_SHLIBPDBS={-
         join(" ", map { my $x = platform->sharedlibpdb($_);
                         $x ? quotify_l($x) : () }
-                  grep { !$unified_info{attributes}->{$_}->{noinst} }
+                  grep { !$unified_info{attributes}->{libraries}->{$_}->{noinst} }
                   @{$unified_info{libraries}})
 -}
 INSTALL_ENGINES={-
         join(" ", map { quotify1(platform->dso($_)) }
-                  grep { !$unified_info{attributes}->{$_}->{noinst}
-                         && $unified_info{attributes}->{$_}->{engine} }
+                  grep { !$unified_info{attributes}->{modules}->{$_}->{noinst}
+                         && $unified_info{attributes}->{modules}->{$_}->{engine} }
                   @{$unified_info{modules}})
 -}
 INSTALL_ENGINEPDBS={-
         join(" ", map { quotify1(platform->dsopdb($_)) }
-                  grep { !$unified_info{attributes}->{$_}->{noinst}
-                         && $unified_info{attributes}->{$_}->{engine} }
+                  grep { !$unified_info{attributes}->{modules}->{$_}->{noinst}
+                         && $unified_info{attributes}->{modules}->{$_}->{engine} }
                   @{$unified_info{modules}})
 -}
 INSTALL_PROGRAMS={-
         join(" ", map { quotify1(platform->bin($_)) }
-                  grep { !$unified_info{attributes}->{$_}->{noinst} }
+                  grep { !$unified_info{attributes}->{programs}->{$_}->{noinst} }
                   @{$unified_info{programs}})
 -}
 INSTALL_PROGRAMPDBS={-
         join(" ", map { quotify1(platform->binpdb($_)) }
-                  grep { !$unified_info{attributes}->{$_}->{noinst} }
+                  grep { !$unified_info{attributes}->{programs}->{$_}->{noinst} }
                   @{$unified_info{programs}})
 -}
 BIN_SCRIPTS={-
         join(" ", map { quotify1($_) }
-                  grep { !$unified_info{attributes}->{$_}->{noinst}
-                         && !$unified_info{attributes}->{$_}->{misc} }
+                  grep { !$unified_info{attributes}->{scripts}->{$_}->{noinst}
+                         && !$unified_info{attributes}->{scripts}->{$_}->{misc} }
                   @{$unified_info{scripts}})
 -}
 MISC_SCRIPTS={-
         join(" ", map { quotify1($_) }
-                  grep { !$unified_info{attributes}->{$_}->{noinst}
-                         && $unified_info{attributes}->{$_}->{misc} }
+                  grep { !$unified_info{attributes}->{scripts}->{$_}->{noinst}
+                         && $unified_info{attributes}->{scripts}->{$_}->{misc} }
                   @{$unified_info{scripts}})
 -}
 
@@ -714,8 +714,8 @@ EOF
  }
  sub obj2dso {
      my %args = @_;
-     my $dso = platform->dso($args{lib});
-     my $dso_n = platform->dsoname($args{lib});
+     my $dso = platform->dso($args{module});
+     my $dso_n = platform->dsoname($args{module});
      my @objs = map { platform->convertext($_) }
                 grep { platform->isobj($_) || platform->isres($_) }
                 @{$args{objs}};
diff --git a/Configure b/Configure
index 3a29d90329..7ea13c1a51 100755
--- a/Configure
+++ b/Configure
@@ -1724,7 +1724,6 @@ if ($builder eq "unified") {
         my @modules = ();
         my @scripts = ();
 
-        my %attributes = ();
         my %sources = ();
         my %shared_sources = ();
         my %includes = ();
@@ -1737,7 +1736,7 @@ if ($builder eq "unified") {
         # contains a dollar sign, it had better be escaped, or it will be
         # taken for a variable name prefix.
         my %variables = ();
-        my $variable_re = qr/\$([[:alpha:]][[:alnum:]_]*)/;
+        my $variable_re = qr/\$(?P<VARIABLE>[[:alpha:]][[:alnum:]_]*)/;
         my $expand_variables = sub {
             my $value = '';
             my $value_rest = shift;
@@ -1748,7 +1747,7 @@ if ($builder eq "unified") {
             }
             while ($value_rest =~ /(?<!\\)${variable_re}/) {
                 $value .= $`;
-                $value .= $variables{$1};
+                $value .= $variables{$+{VARIABLE}};
                 $value_rest = $';
             }
             if ($ENV{CONFIGURE_DEBUG_VARIABLE_EXPAND}) {
@@ -1758,6 +1757,35 @@ if ($builder eq "unified") {
             return $value . $value_rest;
         };
 
+        # Support for attributes in build.info files
+        my %attributes = ();
+        my $handle_attributes = sub {
+            my $attr_str = shift;
+            my $ref = shift;
+            my @goals = @_;
+
+            return unless defined $attr_str;
+
+            my @a = tokenize($attr_str, qr|\s*,\s*|);
+            foreach my $a (@a) {
+                my $ac = 1;
+                my $ak = $a;
+                my $av = 1;
+                if ($a =~ m|^(!)?(.*?)\s* = \s*(.*?)$|) {
+                    $ac = ! $1;
+                    $ak = $1;
+                    $av = $2;
+                }
+                foreach my $g (@goals) {
+                    if ($ac) {
+                        $$ref->{$g}->{$ak} = $av;
+                    } else {
+                        delete $$ref->{$g}->{$ak};
+                    }
+                }
+            }
+        };
+
         # We want to detect configdata.pm in the source tree, so we
         # don't use it if the build tree is different.
         my $src_configdata = cleanfile($srcdir, "configdata.pm", $blddir);
@@ -1787,153 +1815,129 @@ if ($builder eq "unified") {
         # 1 last was positive (don't skip lines until next ELSE, ELSIF or ENDIF)
         # 2 positive ELSE (following ELSIF should fail)
         my @skip = ();
+
+        # A few useful generic regexps
+        my $index_re = qr/\[\s*(?P<INDEX>(?:\\.|.)*?)\s*\]/;
+        my $cond_re = qr/\[\s*(?P<COND>(?:\\.|.)*?)\s*\]/;
+        my $attribs_re = qr/(?:\{\s*(?P<ATTRIBS>(?:\\.|.)*?)\s*\})?/;
+        my $value_re = qr/\s*(?P<VALUE>.*?)\s*/;
         collect_information(
             collect_from_array([ @text ],
                                qr/\\$/ => sub { my $l1 = shift; my $l2 = shift;
                                                 $l1 =~ s/\\$//; $l1.$l2 }),
             # Info we're looking for
-            qr/^\s*IF\[((?:\\.|[^\\\]])*)\]\s*$/
+            qr/^\s* IF ${cond_re} \s*$/x
             => sub {
                 if (! @skip || $skip[$#skip] > 0) {
-                    push @skip, !! $expand_variables->($1);
+                    push @skip, !! $expand_variables->($+{COND});
                 } else {
                     push @skip, -1;
                 }
             },
-            qr/^\s*ELSIF\[((?:\\.|[^\\\]])*)\]\s*$/
+            qr/^\s* ELSIF ${cond_re} \s*$/x
             => sub { die "ELSIF out of scope" if ! @skip;
                      die "ELSIF following ELSE" if abs($skip[$#skip]) == 2;
                      $skip[$#skip] = -1 if $skip[$#skip] != 0;
-                     $skip[$#skip] = !! $expand_variables->($1)
+                     $skip[$#skip] = !! $expand_variables->($+{COND})
                          if $skip[$#skip] == 0; },
-            qr/^\s*ELSE\s*$/
+            qr/^\s* ELSE \s*$/x
             => sub { die "ELSE out of scope" if ! @skip;
                      $skip[$#skip] = -2 if $skip[$#skip] != 0;
                      $skip[$#skip] = 2 if $skip[$#skip] == 0; },
-            qr/^\s*ENDIF\s*$/
+            qr/^\s* ENDIF \s*$/x
             => sub { die "ENDIF out of scope" if ! @skip;
                      pop @skip; },
-            qr/^\s*${variable_re}\s*=\s*(.*?)\s*$/
+            qr/^\s* ${variable_re} \s* = ${value_re} $/x
             => sub {
                 if (!@skip || $skip[$#skip] > 0) {
-                    my $n = $1;
-                    my $v = $2;
-                    $variables{$n} = $expand_variables->($v);
+                    $variables{$+{VARIABLE}} = $expand_variables->($+{VALUE});
                 }
             },
-            qr/^\s*SUBDIRS\s*=\s*(.*)\s*$/
+            qr/^\s* SUBDIRS \s* = ${value_re} $/x
             => sub {
                 if (!@skip || $skip[$#skip] > 0) {
-                    foreach (tokenize($expand_variables->($1))) {
+                    foreach (tokenize($expand_variables->($+{VALUE}))) {
                         push @build_dirs, [ @curd, splitdir($_, 1) ];
                     }
                 }
             },
-            qr/^\s*PROGRAMS(?:{([\w=]+(?:\s*,\s*[\w=]+)*)})?\s*=\s*(.*)\s*$/
+            qr/^\s* PROGRAMS ${attribs_re} \s* =  ${value_re} $/x
             => sub {
                 if (!@skip || $skip[$#skip] > 0) {
-                    my @a = tokenize($1, qr|\s*,\s*|);
-                    my @p = tokenize($expand_variables->($2));
+                    my @p = tokenize($expand_variables->($+{VALUE}));
                     push @programs, @p;
-                    foreach my $a (@a) {
-                        my $ak = $a;
-                        my $av = 1;
-                        if ($a =~ m|^(.*?)\s*=\s*(.*?)$|) {
-                            $ak = $1;
-                            $av = $2;
-                        }
-                        foreach my $p (@p) {
-                            $attributes{$p}->{$ak} = $av;
-                        }
-                    }
+                    $handle_attributes->($+{ATTRIBS},
+                                         \$attributes{programs},
+                                         @p);
                 }
             },
-            qr/^\s*LIBS(?:{([\w=]+(?:\s*,\s*[\w=]+)*)})?\s*=\s*(.*)\s*$/
+            qr/^\s* LIBS ${attribs_re} \s* =  ${value_re} $/x
             => sub {
                 if (!@skip || $skip[$#skip] > 0) {
-                    my @a = tokenize($1, qr|\s*,\s*|);
-                    my @l = tokenize($expand_variables->($2));
+                    my @l = tokenize($expand_variables->($+{VALUE}));
                     push @libraries, @l;
-                    foreach my $a (@a) {
-                        my $ak = $a;
-                        my $av = 1;
-                        if ($a =~ m|^(.*?)\s*=\s*(.*?)$|) {
-                            $ak = $1;
-                            $av = $2;
-                        }
-                        foreach my $l (@l) {
-                            $attributes{$l}->{$ak} = $av;
-                        }
-                    }
+                    $handle_attributes->($+{ATTRIBS},
+                                         \$attributes{libraries},
+                                         @l);
                 }
             },
-            qr/^\s*MODULES(?:{([\w=]+(?:\s*,\s*[\w=]+)*)})?\s*=\s*(.*)\s*$/
+            qr/^\s* MODULES ${attribs_re} \s* =  ${value_re} $/x
             => sub {
                 if (!@skip || $skip[$#skip] > 0) {
-                    my @a = tokenize($1, qr|\s*,\s*|);
-                    my @m = tokenize($expand_variables->($2));
+                    my @m = tokenize($expand_variables->($+{VALUE}));
                     push @modules, @m;
-                    foreach my $a (@a) {
-                        my $ak = $a;
-                        my $av = 1;
-                        if ($a =~ m|^(.*?)\s*=\s*(.*?)$|) {
-                            $ak = $1;
-                            $av = $2;
-                        }
-                        foreach my $m (@m) {
-                            $attributes{$m}->{$ak} = $av;
-                        }
-                    }
+                    $handle_attributes->($+{ATTRIBS},
+                                         \$attributes{modules},
+                                         @m);
                 }
             },
-            qr/^\s*SCRIPTS(?:{([\w=]+(?:\s*,\s*[\w=]+)*)})?\s*=\s*(.*)\s*$/
+            qr/^\s* SCRIPTS ${attribs_re} \s* =  ${value_re} $/x
             => sub {
                 if (!@skip || $skip[$#skip] > 0) {
-                    my @a = tokenize($1, qr|\s*,\s*|);
-                    my @s = tokenize($expand_variables->($2));
+                    my @s = tokenize($expand_variables->($+{VALUE}));
                     push @scripts, @s;
-                    foreach my $a (@a) {
-                        my $ak = $a;
-                        my $av = 1;
-                        if ($a =~ m|^(.*?)\s*=\s*(.*?)$|) {
-                            $ak = $1;
-                            $av = $2;
-                        }
-                        foreach my $s (@s) {
-                            $attributes{$s}->{$ak} = $av;
-                        }
-                    }
+                    $handle_attributes->($+{ATTRIBS},
+                                         \$attributes{scripts},
+                                         @s);
                 }
             },
 
-            qr/^\s*ORDINALS\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/,
-            => sub { push @{$ordinals{$expand_variables->($1)}},
-                         tokenize($expand_variables->($2))
+            qr/^\s* ORDINALS ${index_re} = ${value_re} $/x
+            => sub { push @{$ordinals{$expand_variables->($+{INDEX})}},
+                         tokenize($expand_variables->($+{VALUE}))
                          if !@skip || $skip[$#skip] > 0 },
-            qr/^\s*SOURCE\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/
-            => sub { push @{$sources{$expand_variables->($1)}},
-                         tokenize($expand_variables->($2))
+            qr/^\s* SOURCE ${index_re} = ${value_re} $/x
+            => sub { push @{$sources{$expand_variables->($+{INDEX})}},
+                         tokenize($expand_variables->($+{VALUE}))
                          if !@skip || $skip[$#skip] > 0 },
-            qr/^\s*SHARED_SOURCE\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/
-            => sub { push @{$shared_sources{$expand_variables->($1)}},
-                         tokenize($expand_variables->($2))
+            qr/^\s* SHARED_SOURCE ${index_re} = ${value_re} $/x
+            => sub { push @{$shared_sources{$expand_variables->($+{INDEX})}},
+                         tokenize($expand_variables->($+{VALUE}))
                          if !@skip || $skip[$#skip] > 0 },
-            qr/^\s*INCLUDE\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/
-            => sub { push @{$includes{$expand_variables->($1)}},
-                         tokenize($expand_variables->($2))
+            qr/^\s* INCLUDE ${index_re} = ${value_re} $/x
+            => sub { push @{$includes{$expand_variables->($+{INDEX})}},
+                         tokenize($expand_variables->($+{VALUE}))
                          if !@skip || $skip[$#skip] > 0 },
-            qr/^\s*DEFINE\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/
-            => sub { push @{$defines{$expand_variables->($1)}},
-                         tokenize($expand_variables->($2))
+            qr/^\s* DEFINE ${index_re} = ${value_re} $/x
+            => sub { push @{$defines{$expand_variables->($+{INDEX})}},
+                         tokenize($expand_variables->($+{VALUE}))
                          if !@skip || $skip[$#skip] > 0 },
-            qr/^\s*DEPEND\[((?:\\.|[^\\\]])*)\]\s*=\s*(.*)\s*$/
-            => sub { push @{$depends{$expand_variables->($1)}},
-                         tokenize($expand_variables->($2))
-                         if !@skip || $skip[$#skip] > 0 },
-            qr/^\s*GENERATE\[((?:\\.|[^\\\]])+)\]\s*=\s*(.*)\s*$/
-            => sub { push @{$generate{$expand_variables->($1)}}, $2
+            qr/^\s* DEPEND ${index_re} ${attribs_re} = ${value_re} $/x
+            => sub {
+                if (!@skip || $skip[$#skip] > 0) {
+                    my $i = $expand_variables->($+{INDEX});
+                    my @d = tokenize($expand_variables->($+{VALUE}));
+                    push @{$depends{$i}}, @d;
+                    $handle_attributes->($+{ATTRIBS},
+                                         \$attributes{depends}->{$i},
+                                         @d);
+                }
+            },
+            qr/^\s* GENERATE ${index_re} = ${value_re} $/x
+            => sub { push @{$generate{$expand_variables->($+{INDEX})}},
+                         $+{VALUE}
                          if !@skip || $skip[$#skip] > 0 },
-            qr/^\s*(?:#.*)?$/ => sub { },
+            qr/^\s* (?:\#.*)? $/x => sub { },
             "OTHERWISE" => sub { die "Something wrong with this line:\n$_\nat $sourced/$f" },
             "BEFORE" => sub {
                 if ($buildinfo_debug) {
@@ -1949,7 +1953,7 @@ if ($builder eq "unified") {
             );
         die "runaway IF?" if (@skip);
 
-        if (grep { defined $attributes{$_}->{engine} } keys %attributes
+        if (grep { defined $attributes{modules}->{$_}->{engine} } keys %attributes
                 and !$config{dynamic_engines}) {
             die <<"EOF"
 ENGINES can only be used if configured with 'dynamic-engine'.
@@ -1957,15 +1961,6 @@ This is usually a fault in a build.info file.
 EOF
         }
 
-        foreach (keys %attributes) {
-            my $dest = $_;
-            my $ddest = cleanfile($buildd, $_, $blddir);
-            foreach (keys %{$attributes{$dest} // {}}) {
-                $unified_info{attributes}->{$ddest}->{$_} =
-                    $attributes{$dest}->{$_};
-            }
-        }
-
         {
             my %infos = ( programs  => [ @programs  ],
                           libraries => [ @libraries ],
@@ -1975,6 +1970,11 @@ EOF
                 foreach (@{$infos{$k}}) {
                     my $item = cleanfile($buildd, $_, $blddir);
                     $unified_info{$k}->{$item} = 1;
+
+                    # Fix up associated attributes
+                    $unified_info{attributes}->{$k}->{$item} =
+                        $attributes{$k}->{$_}
+                        if defined $attributes{$k}->{$_};
                 }
             }
         }
@@ -2103,6 +2103,11 @@ EOF
                 my $e = $1 // "";
                 $d = $`.$e;
                 $unified_info{depends}->{$ddest}->{$d} = 1;
+
+                # Fix up associated attributes
+                $unified_info{attributes}->{depends}->{$ddest}->{$d} =
+                    $attributes{depends}->{$dest}->{$_}
+                    if defined $attributes{depends}->{$dest}->{$_};
             }
         }
 
diff --git a/crypto/aes/build.info b/crypto/aes/build.info
index aac88012b4..59c009761e 100644
--- a/crypto/aes/build.info
+++ b/crypto/aes/build.info
@@ -62,8 +62,8 @@ ENDIF
 $COMMON=aes_misc.c aes_ecb.c $AESASM
 SOURCE[../../libcrypto]=$COMMON aes_cfb.c aes_ofb.c aes_ige.c aes_wrap.c
 DEFINE[../../libcrypto]=$AESDEF
-SOURCE[../../providers/fips]=$COMMON
-DEFINE[../../providers/fips]=$AESDEF
+SOURCE[../../providers/libfips.a]=$COMMON
+DEFINE[../../providers/libfips.a]=$AESDEF
 
 GENERATE[aes-ia64.s]=asm/aes-ia64.S
 
diff --git a/crypto/blake2/m_blake2b.c b/crypto/blake2/m_blake2b.c
index 816dd06b6c..bb3f145abd 100644
--- a/crypto/blake2/m_blake2b.c
+++ b/crypto/blake2/m_blake2b.c
@@ -12,7 +12,7 @@
 # include <stddef.h>
 # include <openssl/obj_mac.h>
 # include "crypto/evp.h"
-# include "internal/blake2.h"
+# include "prov/blake2.h"
 
 static int init(EVP_MD_CTX *ctx)
 {
diff --git a/crypto/blake2/m_blake2s.c b/crypto/blake2/m_blake2s.c
index caf8a6657a..b04d63ec38 100644
--- a/crypto/blake2/m_blake2s.c
+++ b/crypto/blake2/m_blake2s.c
@@ -12,7 +12,7 @@
 # include <stddef.h>
 # include <openssl/obj_mac.h>
 # include "crypto/evp.h"
-# include "internal/blake2.h"
+# include "prov/blake2.h"
 
 static int init(EVP_MD_CTX *ctx)
 {
diff --git a/crypto/bn/build.info b/crypto/bn/build.info
index 18b5950f6d..75b84d0df6 100644
--- a/crypto/bn/build.info
+++ b/crypto/bn/build.info
@@ -109,8 +109,8 @@ $COMMON=bn_add.c bn_div.c bn_exp.c bn_lib.c bn_ctx.c bn_mul.c \
         bn_rsa_fips186_4.c $BNASM
 SOURCE[../../libcrypto]=$COMMON bn_print.c bn_err.c bn_depr.c bn_srp.c
 DEFINE[../../libcrypto]=$BNDEF
-SOURCE[../../providers/fips]=$COMMON
-DEFINE[../../providers/fips]=$BNDEF
+SOURCE[../../providers/libfips.a]=$COMMON
+DEFINE[../../providers/libfips.a]=$BNDEF
 
 INCLUDE[../../libcrypto]=../../crypto/include
 
diff --git a/crypto/buffer/build.info b/crypto/buffer/build.info
index 63de1a570f..6f31397be7 100644
--- a/crypto/buffer/build.info
+++ b/crypto/buffer/build.info
@@ -1,3 +1,3 @@
 LIBS=../../libcrypto
 SOURCE[../../libcrypto]=buffer.c buf_err.c
-SOURCE[../../providers/fips]=buffer.c
+SOURCE[../../providers/libfips.a]=buffer.c
diff --git a/crypto/build.info b/crypto/build.info
index 5d3b123d69..f41ecf448f 100644
--- a/crypto/build.info
+++ b/crypto/build.info
@@ -63,7 +63,7 @@ $CORE_COMMON=provider_core.c provider_predefined.c \
         core_fetch.c core_algorithm.c core_namemap.c
 
 SOURCE[../libcrypto]=$CORE_COMMON provider_conf.c
-SOURCE[../providers/fips]=$CORE_COMMON
+SOURCE[../providers/libfips.a]=$CORE_COMMON
 
 # Central utilities
 $UTIL_COMMON=\
@@ -78,8 +78,8 @@ SOURCE[../libcrypto]=$UTIL_COMMON \
         o_fopen.c getenv.c o_init.c o_fips.c init.c trace.c provider.c \
         $UPLINKSRC
 DEFINE[../libcrypto]=$UTIL_DEFINE $UPLINKDEF
-SOURCE[../providers/fips]=$UTIL_COMMON
-DEFINE[../providers/fips]=$UTIL_DEFINE
+SOURCE[../providers/libfips.a]=$UTIL_COMMON
+DEFINE[../providers/libfips.a]=$UTIL_DEFINE
 
 
 DEPEND[info.o]=buildinf.h
diff --git a/crypto/cmac/build.info b/crypto/cmac/build.info
index f6c8bfabbc..a2f6f218c2 100644
--- a/crypto/cmac/build.info
+++ b/crypto/cmac/build.info
@@ -3,4 +3,4 @@ LIBS=../../libcrypto
 $COMMON=cmac.c
 
 SOURCE[../../libcrypto]=$COMMON cm_ameth.c
-SOURCE[../../providers/fips]=$COMMON
+SOURCE[../../providers/libfips.a]=$COMMON
diff --git a/crypto/des/build.info b/crypto/des/build.info
index 774bad754b..b1c1e624c2 100644
--- a/crypto/des/build.info
+++ b/crypto/des/build.info
@@ -20,7 +20,7 @@ SOURCE[../../libcrypto]=$COMMON\
         ofb64ede.c ofb64enc.c ofb_enc.c \
         str2key.c  pcbc_enc.c qud_cksm.c rand_key.c \
         fcrypt.c xcbc_enc.c cbc_cksm.c
-SOURCE[../../providers/fips]=$COMMON
+SOURCE[../../providers/libfips.a]=$COMMON
 
 GENERATE[des_enc-sparc.S]=asm/des_enc.m4
 GENERATE[dest4-sparcv9.S]=asm/dest4-sparcv9.pl
diff --git a/crypto/ec/build.info b/crypto/ec/build.info
index d140b5d64b..40aef36798 100644
--- a/crypto/ec/build.info
+++ b/crypto/ec/build.info
@@ -57,8 +57,8 @@ $COMMON=ec_lib.c ecp_smpl.c ecp_mont.c ecp_nist.c ec_cvt.c ec_mult.c \
 SOURCE[../../libcrypto]=$COMMON ec_ameth.c ec_pmeth.c ecx_meth.c ec_err.c \
                         ecdh_kdf.c eck_prn.c
 DEFINE[../../libcrypto]=$ECDEF
-SOURCE[../../providers/fips]=$COMMON
-DEFINE[../../providers/fips]=$ECDEF
+SOURCE[../../providers/libfips.a]=$COMMON
+DEFINE[../../providers/libfips.a]=$ECDEF
 
 GENERATE[ecp_nistz256-x86.s]=asm/ecp_nistz256-x86.pl
 
diff --git a/crypto/err/err_all.c b/crypto/err/err_all.c
index 5957730d18..13bef4a7a8 100644
--- a/crypto/err/err_all.c
+++ b/crypto/err/err_all.c
@@ -41,7 +41,7 @@
 #include <openssl/storeerr.h>
 #include <openssl/esserr.h>
 #include "internal/propertyerr.h"
-#include "internal/providercommonerr.h"
+#include "prov/providercommonerr.h"
 
 int err_load_crypto_strings_int(void)
 {
diff --git a/crypto/err/openssl.ec b/crypto/err/openssl.ec
index 179a3baa05..65633717ee 100644
--- a/crypto/err/openssl.ec
+++ b/crypto/err/openssl.ec
@@ -39,7 +39,7 @@ L SM2           include/crypto/sm2.h            crypto/sm2/sm2_err.c
 L OSSL_STORE    include/openssl/store.h         crypto/store/store_err.c
 L ESS           include/openssl/ess.h           crypto/ess/ess_err.c
 L PROP          include/internal/property.h     crypto/property/property_err.c
-L PROV          providers/common/include/internal/providercommon.h providers/common/provider_err.c
+L PROV          providers/common/include/prov/providercommon.h providers/common/provider_err.c
 
 # additional header files to be scanned for function names
 L NONE          include/openssl/x509_vfy.h      NONE
diff --git a/crypto/evp/build.info b/crypto/evp/build.info
index 9c71930c05..94f033bbc1 100644
--- a/crypto/evp/build.info
+++ b/crypto/evp/build.info
@@ -18,7 +18,7 @@ SOURCE[../../libcrypto]=$COMMON\
         e_chacha20_poly1305.c \
         pkey_mac.c exchange.c \
         legacy_sha.c legacy_md5_sha1.c
-SOURCE[../../providers/fips]=$COMMON
+SOURCE[../../providers/libfips.a]=$COMMON
 
 INCLUDE[e_aes.o]=.. ../modes
 INCLUDE[e_aes_cbc_hmac_sha1.o]=../modes
diff --git a/crypto/evp/legacy_md5_sha1.c b/crypto/evp/legacy_md5_sha1.c
index cba37bacd8..a23febfd53 100644
--- a/crypto/evp/legacy_md5_sha1.c
+++ b/crypto/evp/legacy_md5_sha1.c
@@ -9,7 +9,7 @@
 
 #include <openssl/opensslconf.h>
 
-#include "internal/md5_sha1.h"   /* diverse MD5_SHA1 macros */
+#include "prov/md5_sha1.h"   /* diverse MD5_SHA1 macros */
 
 #ifndef OPENSSL_NO_MD5
 
diff --git a/crypto/hmac/build.info b/crypto/hmac/build.info
index 56ad67ef8f..4ed90c09f4 100644
--- a/crypto/hmac/build.info
+++ b/crypto/hmac/build.info
@@ -3,4 +3,4 @@ LIBS=../../libcrypto
 $COMMON=hmac.c
 
 SOURCE[../../libcrypto]=$COMMON hm_ameth.c
-SOURCE[../../providers/fips]=$COMMON
+SOURCE[../../providers/libfips.a]=$COMMON
diff --git a/crypto/initthread.c b/crypto/initthread.c
index 930b94a817..da30d59fec 100644
--- a/crypto/initthread.c
+++ b/crypto/initthread.c
@@ -10,7 +10,7 @@
 #include <openssl/crypto.h>
 #include <openssl/core_numbers.h>
 #include "crypto/cryptlib.h"
-#include "internal/providercommon.h"
+#include "prov/providercommon.h"
 #include "internal/thread_once.h"
 
 #ifdef FIPS_MODE
diff --git a/crypto/lhash/build.info b/crypto/lhash/build.info
index 0aa12a1eb3..b3176b8358 100644
--- a/crypto/lhash/build.info
+++ b/crypto/lhash/build.info
@@ -1,5 +1,5 @@
 LIBS=../../libcrypto
 SOURCE[../../libcrypto]=\
         lhash.c lh_stats.c
-SOURCE[../../providers/fips]=\
+SOURCE[../../providers/libfips.a]=\
         lhash.c
diff --git a/crypto/md5/md5_sha1.c b/crypto/md5/md5_sha1.c
index 5d5fac95bd..32bf9a13fc 100644
--- a/crypto/md5/md5_sha1.c
+++ b/crypto/md5/md5_sha1.c
@@ -7,7 +7,7 @@
  * https://www.openssl.org/source/license.html
  */
 #include <string.h>
-#include "internal/md5_sha1.h"
+#include "prov/md5_sha1.h"
 #include <openssl/evp.h>
 
 int md5_sha1_init(MD5_SHA1_CTX *mctx)
diff --git a/crypto/modes/build.info b/crypto/modes/build.info
index 8a8aead651..4ae0d8b011 100644
--- a/crypto/modes/build.info
+++ b/crypto/modes/build.info
@@ -54,8 +54,8 @@ SOURCE[../../libcrypto]=$COMMON \
         cts128.c ocb128.c siv128.c
 
 DEFINE[../../libcrypto]=$MODESDEF
-SOURCE[../../providers/fips]=$COMMON
-DEFINE[../../providers/fips]=$MODESDEF
+SOURCE[../../providers/libfips.a]=$COMMON
+DEFINE[../../providers/libfips.a]=$MODESDEF
 
 INCLUDE[gcm128.o]=..
 
diff --git a/crypto/property/build.info b/crypto/property/build.info
index db3c944498..bfa1f0602f 100644
--- a/crypto/property/build.info
+++ b/crypto/property/build.info
@@ -1,4 +1,4 @@
 LIBS=../../libcrypto
 $COMMON=property_string.c property_parse.c property.c defn_cache.c
 SOURCE[../../libcrypto]=$COMMON property_err.c
-SOURCE[../../providers/fips]=$COMMON
+SOURCE[../../providers/libfips.a]=$COMMON
diff --git a/crypto/rand/build.info b/crypto/rand/build.info
index 3e0a9c7432..0925c4b2de 100644
--- a/crypto/rand/build.info
+++ b/crypto/rand/build.info
@@ -4,4 +4,4 @@ $COMMON=rand_lib.c rand_crng_test.c rand_win.c rand_unix.c  rand_vms.c \
         drbg_lib.c drbg_ctr.c rand_vxworks.c drbg_hash.c drbg_hmac.c
 
 SOURCE[../../libcrypto]=$COMMON randfile.c rand_err.c rand_egd.c
-SOURCE[../../providers/fips]=$COMMON
+SOURCE[../../providers/libfips.a]=$COMMON
diff --git a/crypto/rand/drbg_hash.c b/crypto/rand/drbg_hash.c
index 4a64992af2..72068c67c0 100644
--- a/crypto/rand/drbg_hash.c
+++ b/crypto/rand/drbg_hash.c
@@ -14,7 +14,7 @@
 #include <openssl/err.h>
 #include <openssl/rand.h>
 #include "internal/thread_once.h"
-#include "internal/providercommon.h"
+#include "prov/providercommon.h"
 #include "rand_local.h"
 
 /* 440 bits from SP800-90Ar1 10.1 table 2 */
diff --git a/crypto/rand/drbg_hmac.c b/crypto/rand/drbg_hmac.c
index 4d7676d21b..0289070f81 100644
--- a/crypto/rand/drbg_hmac.c
+++ b/crypto/rand/drbg_hmac.c
@@ -13,7 +13,7 @@
 #include <openssl/err.h>
 #include <openssl/rand.h>
 #include "internal/thread_once.h"
-#include "internal/providercommon.h"
+#include "prov/providercommon.h"
 #include "rand_local.h"
 
 /*
diff --git a/crypto/sha/build.info b/crypto/sha/build.info
index 67d9fd4723..25c64a0e2c 100644
--- a/crypto/sha/build.info
+++ b/crypto/sha/build.info
@@ -76,8 +76,8 @@ ENDIF
 $COMMON=sha1dgst.c sha256.c sha512.c sha3.c $SHA1ASM $KECCAK1600ASM
 SOURCE[../../libcrypto]=$COMMON sha1_one.c
 DEFINE[../../libcrypto]=$SHA1DEF $KECCAK1600DEF
-SOURCE[../../providers/fips]= $COMMON
-DEFINE[../../providers/fips]= $SHA1DEF $KECCAK1600DEF
+SOURCE[../../providers/libfips.a]= $COMMON
+DEFINE[../../providers/libfips.a]= $SHA1DEF $KECCAK1600DEF
 
 GENERATE[sha1-586.s]=asm/sha1-586.pl
 DEPEND[sha1-586.s]=../perlasm/x86asm.pl
diff --git a/crypto/stack/build.info b/crypto/stack/build.info
index e4183e089c..23d83a6f11 100644
--- a/crypto/stack/build.info
+++ b/crypto/stack/build.info
@@ -1,3 +1,3 @@
 LIBS=../../libcrypto
 SOURCE[../../libcrypto]=stack.c
-SOURCE[../../providers/fips]=stack.c
+SOURCE[../../providers/libfips.a]=stack.c
diff --git a/doc/internal/man3/ossl_prov_util_nid_to_name.pod b/doc/internal/man3/ossl_prov_util_nid_to_name.pod
index dce4ba60ac..31eec076c5 100644
--- a/doc/internal/man3/ossl_prov_util_nid_to_name.pod
+++ b/doc/internal/man3/ossl_prov_util_nid_to_name.pod
@@ -7,7 +7,7 @@ ossl_prov_util_nid_to_name
 
 =head1 SYNOPSIS
 
- #include "internal/providercommon.h"
+ #include "prov/providercommon.h"
 
  const char *ossl_prov_util_nid_to_name(int nid);
 
diff --git a/providers/build.info b/providers/build.info
index 80b2952494..c31c4271de 100644
--- a/providers/build.info
+++ b/providers/build.info
@@ -1,30 +1,152 @@
-SUBDIRS=common default
+# We place all implementations in static libraries, and then let the
+# provider mains pilfer what they want through symbol resolution when
+# linking.
+#
+# The non-legacy implementations (libimplementations) must be made FIPS
+# agnostic as much as possible, as well as the common building blocks
+# (libcommon).  The legacy implementations (liblegacy) will never be
+# part of the FIPS provider.
+#
+# If there is anything that isn't FIPS agnostic, it should be set aside
+# in its own source file, which is then included directly into other
+# static libraries geared for FIPS and non-FIPS providers, and built
+# separately.
+#
+# libcommon.a           Contains common building blocks, potentially
+#                       needed both by non-legacy and legacy code.
+#
+# libimplementations.a  Contains all non-legacy implementations.
+# liblegacy.a           Contains all legacy implementaions.
+#
+# libfips.a             Contains all things needed to support
+#                       FIPS implementations, such as code from
+#                       crypto/ and object files that contain
+#                       FIPS-specific code.  FIPS_MODE is defined
+#                       for this library.  The FIPS module uses
+#                       this.
+# libnonfips.a          Corresponds to libfips.a, but built with
+#                       FIPS_MODE undefined.  The default and legacy
+#                       providers use this.
+
+SUBDIRS=common implementations
 
 INCLUDE[../libcrypto]=common/include
 
+# Libraries we're dealing with
+$LIBCOMMON=libcommon.a
+$LIBIMPLEMENTATIONS=libimplementations.a
+$LIBLEGACY=liblegacy.a
+$LIBNONFIPS=libnonfips.a
+$LIBFIPS=libfips.a
+
+# Enough of our implementations include prov/ciphercommon.h (present in
+# providers/common/include), which includes crypto/ciphermode_platform.h
+# (present in include), which in turn may include very internal header
+# files in crypto/, so let's have a common include list for them all.
+$COMMON_INCLUDES=../crypto ../include common/include
+
+INCLUDE[$LIBCOMMON]=$COMMON_INCLUDES
+INCLUDE[$LIBIMPLEMENTATIONS]=.. $COMMON_INCLUDES implementations/include
+INCLUDE[$LIBLEGACY]=$COMMON_INCLUDES implementations/include
+INCLUDE[$LIBNONFIPS]=$COMMON_INCLUDES
+INCLUDE[$LIBFIPS]=.. $COMMON_INCLUDES
+DEFINE[$LIBFIPS]=FIPS_MODE
+
+# Weak dependencies to provide library order information.
+# We make it weak so they aren't both used always; what is
+# actually used is determined by non-weak dependencies.
+DEPEND[$LIBIMPLEMENTATIONS]{weak}=$LIBFIPS $LIBNONFIPS
+DEPEND[$LIBCOMMON]{weak}=$LIBFIPS
+
+# Strong dependencies.  This ensures that any time libimplementations
+# is used, libcommon gets included as well.
+DEPEND[$LIBIMPLEMENTATIONS]=$LIBCOMMON
+DEPEND[$LIBNONFIPS]=../libcrypto
+# It's tempting to make libcommon depend on ../libcrypto.  However,
+# since the FIPS provider module must NOT depend on ../libcrypto, we
+# need to set that dependency up specifically for the final products
+# that use $LIBCOMMON or anything that depends on it.
+
+# Libraries common to all providers, must be built regardless
+LIBS{noinst}=$LIBCOMMON
+# Libraries that are common for all non-FIPS providers, must be built regardless
+LIBS{noinst}=$LIBNONFIPS $LIBIMPLEMENTATIONS
+
+#
+# Default provider stuff
+#
+# Because the default provider is built in, it means that libcrypto must
+# include all the object files that are needed (we do that indirectly,
+# by using the appropriate libraries as source).  Note that for shared
+# libraries, SOURCEd libraries are considered as if the where specified
+# with DEPEND.
+$DEFAULTGOAL=../libcrypto
+SOURCE[$DEFAULTGOAL]=$LIBIMPLEMENTATIONS $LIBNONFIPS
+SOURCE[$DEFAULTGOAL]=defltprov.c
+# Some legacy implementations depend on provider header files
+INCLUDE[../libcrypto]=implementations/include
+
+LIBS=$DEFAULTGOAL
+
+#
+# FIPS provider stuff
+#
+# We define it this way to ensure that configdata.pm will have all the
+# necessary information even if we don't build the module.  This will allow
+# us to make all kinds of checks on the source, based on what we specify in
+# diverse build.info files.  libfips.a, fips.so and their sources aren't
+# built unless the proper LIBS or MODULES statement has been seen, so we
+# have those and only those within a condition.
+SUBDIRS=fips
+$FIPSGOAL=fips
+DEPEND[$FIPSGOAL]=$LIBIMPLEMENTATIONS $LIBFIPS
+INCLUDE[$FIPSGOAL]=../include
+IF[{- defined $target{shared_defflag} -}]
+  SOURCE[$FIPSGOAL]=fips.ld
+  GENERATE[fips.ld]=../util/providers.num
+ENDIF
+
 IF[{- !$disabled{fips} -}]
-  SUBDIRS=fips
-  MODULES=fips
-  IF[{- defined $target{shared_defflag} -}]
-    SOURCE[fips]=fips.ld
-    GENERATE[fips.ld]=../util/providers.num
-  ENDIF
-  INCLUDE[fips]=.. ../include common/include
-  DEFINE[fips]=FIPS_MODE
+  # This is the trigger to actually build the FIPS module.  Without these
+  # statements, the final build file will not have a trace of it.
+  MODULES=$FIPSGOAL
+  LIBS{noinst}=$LIBFIPS
 ENDIF
 
+#
+# Legacy provider stuff
+#
 IF[{- !$disabled{legacy} -}]
-  SUBDIRS=legacy
+  # The legacy implementation library
+  LIBS{noinst}=$LIBLEGACY
+  DEPEND[$LIBLEGACY]=$LIBCOMMON $LIBNONFIPS
+
+  # The Legacy provider
   IF[{- $disabled{module} -}]
-    LIBS=../libcrypto
-    DEFINE[../libcrypto]=STATIC_LEGACY
+    # Become built in
+    # In this case, we need to do the same thing a for the default provider,
+    # and make the liblegacy object files end up in libcrypto.  We could also
+    # just say that for the built-in legacy, we put the source directly in
+    # libcrypto instead of going via liblegacy, but that makes writing the
+    # implementation specific build.info files harder to write, so we don't.
+    $LEGACYGOAL=../libcrypto
+    SOURCE[$LEGACYGOAL]=$LIBLEGACY
+    DEFINE[$LIBLEGACY]=STATIC_LEGACY
+    DEFINE[$LEGACYGOAL]=STATIC_LEGACY
   ELSE
-    MODULES=legacy
+    # Become a module
+    # In this case, we can work with dependencies
+    $LEGACYGOAL=legacy
+    MODULES=$LEGACYGOAL
+    DEPEND[$LEGACYGOAL]=$LIBLEGACY
     IF[{- defined $target{shared_defflag} -}]
       SOURCE[legacy]=legacy.ld
       GENERATE[legacy.ld]=../util/providers.num
     ENDIF
-    DEPEND[legacy]=../libcrypto
-    INCLUDE[legacy]=.. ../include common/include
   ENDIF
+
+  # Common things that are valid no matter what form the Legacy provider
+  # takes.
+  SOURCE[$LEGACYGOAL]=legacyprov.c
+  INCLUDE[$LEGACYGOAL]=../include implementations/include
 ENDIF
diff --git a/providers/common/build.info b/providers/common/build.info
index 916cc3e4ea..4e662eb97a 100644
--- a/providers/common/build.info
+++ b/providers/common/build.info
@@ -1,5 +1,6 @@
-SUBDIRS=digests ciphers macs kdfs exchange keymgmt signature
-$COMMON=provider_util.c
+SUBDIRS=digests ciphers
 
-SOURCE[../../libcrypto]=$COMMON provider_err.c provlib.c
-SOURCE[../fips]=$COMMON
+SOURCE[../libcommon.a]=provider_err.c provlib.c
+$FIPSCOMMON=provider_util.c
+SOURCE[../libnonfips.a]=$FIPSCOMMON
+SOURCE[../libfips.a]=$FIPSCOMMON
diff --git a/providers/common/ciphers/block.c b/providers/common/ciphers/block.c
index ec2dab6849..95acfaf323 100644
--- a/providers/common/ciphers/block.c
+++ b/providers/common/ciphers/block.c
@@ -9,7 +9,7 @@
 
 #include <assert.h>
 #include "cipher_local.h"
-#include "internal/providercommonerr.h"
+#include "prov/providercommonerr.h"
 
 /*
  * Fills a single block of buffered data from the input, and returns the amount
diff --git a/providers/common/ciphers/build.info b/providers/common/ciphers/build.info
index 0969e6d378..b76b8ba10a 100644
--- a/providers/common/ciphers/build.info
+++ b/providers/common/ciphers/build.info
@@ -1,21 +1,5 @@
-LIBS=../../../libcrypto
-
-IF[{- !$disabled{des} -}]
-  $COMMON_DES=cipher_tdes.c cipher_tdes_hw.c
-ENDIF
-
-$COMMON=cipher_common.c cipher_common_hw.c block.c \
-        cipher_aes.c cipher_aes_hw.c \
-        cipher_aes_xts.c cipher_aes_xts_hw.c \
+# This source is common building blocks for all ciphers in all our providers.
+SOURCE[../../libcommon.a]=\
+        cipher_common.c cipher_common_hw.c block.c \
         cipher_gcm.c cipher_gcm_hw.c \
-        cipher_aes_gcm.c cipher_aes_gcm_hw.c \
-        cipher_ccm.c cipher_ccm_hw.c \
-        cipher_aes_ccm.c cipher_aes_ccm_hw.c \
-        cipher_aes_wrp.c \
-        $COMMON_DES
-        
-SOURCE[../../../libcrypto]=$COMMON
-INCLUDE[../../../libcrypto]=. ../../../crypto
-
-SOURCE[../../fips]=$COMMON
-INCLUDE[../../fips]=. ../../../crypto
+        cipher_ccm.c cipher_ccm_hw.c
diff --git a/providers/common/ciphers/cipher_ccm.c b/providers/common/ciphers/cipher_ccm.c
index 3fbaef9a46..904af3a5e0 100644
--- a/providers/common/ciphers/cipher_ccm.c
+++ b/providers/common/ciphers/cipher_ccm.c
@@ -9,9 +9,9 @@
 
 /* Dispatch functions for ccm mode */
 
-#include "cipher_local.h"
-#include "internal/ciphers/cipher_ccm.h"
-#include "internal/providercommonerr.h"
+#include "prov/ciphercommon.h"
+#include "prov/cipher_ccm.h"
+#include "prov/providercommonerr.h"
 
 static int ccm_cipher_internal(PROV_CCM_CTX *ctx, unsigned char *out,
                                size_t *padlen, const unsigned char *in,
diff --git a/providers/common/ciphers/cipher_ccm_hw.c b/providers/common/ciphers/cipher_ccm_hw.c
index b093b768e7..5503a41687 100644
--- a/providers/common/ciphers/cipher_ccm_hw.c
+++ b/providers/common/ciphers/cipher_ccm_hw.c
@@ -7,8 +7,8 @@
  * https://www.openssl.org/source/license.html
  */
 
-#include "internal/ciphers/ciphercommon.h"
-#include "internal/ciphers/cipher_ccm.h"
+#include "prov/ciphercommon.h"
+#include "prov/cipher_ccm.h"
 
 int ccm_generic_setiv(PROV_CCM_CTX *ctx, const unsigned char *nonce,
                       size_t nlen, size_t mlen)
diff --git a/providers/common/ciphers/cipher_common.c b/providers/common/ciphers/cipher_common.c
index 2577d94d7a..d06e7b8004 100644
--- a/providers/common/ciphers/cipher_common.c
+++ b/providers/common/ciphers/cipher_common.c
@@ -12,8 +12,8 @@
  */
 
 #include "cipher_local.h"
-#include "internal/provider_ctx.h"
-#include "internal/providercommonerr.h"
+#include "prov/provider_ctx.h"
+#include "prov/providercommonerr.h"
 
 /*-
  * Generic cipher functions for OSSL_PARAM gettables and settables
diff --git a/providers/common/ciphers/cipher_common_hw.c b/providers/common/ciphers/cipher_common_hw.c
index 6f1b4babd8..f1c466edc8 100644
--- a/providers/common/ciphers/cipher_common_hw.c
+++ b/providers/common/ciphers/cipher_common_hw.c
@@ -7,7 +7,7 @@
  * https://www.openssl.org/source/license.html
  */
 
-#include "cipher_local.h"
+#include "prov/ciphercommon.h"
 
 /*-
  * The generic cipher functions for cipher modes cbc, ecb, ofb, cfb and ctr.
diff --git a/providers/common/ciphers/cipher_gcm.c b/providers/common/ciphers/cipher_gcm.c
index 59368dc81e..580928fdde 100644
--- a/providers/common/ciphers/cipher_gcm.c
+++ b/providers/common/ciphers/cipher_gcm.c
@@ -9,11 +9,11 @@
 
 /* Dispatch functions for gcm mode */
 
-#include "cipher_local.h"
-#include "internal/ciphers/cipher_gcm.h"
-#include "internal/providercommonerr.h"
+#include "prov/ciphercommon.h"
+#include "prov/cipher_gcm.h"
+#include "prov/providercommonerr.h"
 #include "crypto/rand.h"
-#include "internal/provider_ctx.h"
+#include "prov/provider_ctx.h"
 
 static int gcm_tls_init(PROV_GCM_CTX *dat, unsigned char *aad, size_t aad_len);
 static int gcm_tls_iv_set_fixed(PROV_GCM_CTX *ctx, unsigned char *iv,
diff --git a/providers/common/ciphers/cipher_gcm_hw.c b/providers/common/ciphers/cipher_gcm_hw.c
index 1d9c3ea49c..09e3c27400 100644
--- a/providers/common/ciphers/cipher_gcm_hw.c
+++ b/providers/common/ciphers/cipher_gcm_hw.c
@@ -7,8 +7,8 @@
  * https://www.openssl.org/source/license.html
  */
 
-#include "cipher_local.h"
-#include "internal/ciphers/cipher_gcm.h"
+#include "prov/ciphercommon.h"
+#include "prov/cipher_gcm.h"
 
 
 int gcm_setiv(PROV_GCM_CTX *ctx, const unsigned char *iv, size_t ivlen)
diff --git a/providers/common/ciphers/cipher_local.h b/providers/common/ciphers/cipher_local.h
index 898c99b1d3..1c4716f357 100644
--- a/providers/common/ciphers/cipher_local.h
+++ b/providers/common/ciphers/cipher_local.h
@@ -7,7 +7,7 @@
  * https://www.openssl.org/source/license.html
  */
 
-#include "internal/ciphers/ciphercommon.h"
+#include "prov/ciphercommon.h"
 
 void padblock(unsigned char *buf, size_t *buflen, size_t blocksize);
 int unpadblock(unsigned char *buf, size_t *buflen, size_t blocksize);
diff --git a/providers/common/digests/build.info b/providers/common/digests/build.info
index fbbce36e87..730046d670 100644
--- a/providers/common/digests/build.info
+++ b/providers/common/digests/build.info
@@ -1,5 +1,2 @@
-$COMMON=sha2_prov.c sha3_prov.c digest_common.c
-
-SOURCE[../../../libcrypto]=$COMMON
-SOURCE[../../fips]=$COMMON
-SOURCE[../../legacy]= digest_common.c
+# This source is common for all digests in all our providers.
+SOURCE[../../libcommon.a]=digest_common.c
diff --git a/providers/common/digests/digest_common.c b/providers/common/digests/digest_common.c
index 062209f329..9d30b2be2c 100644
--- a/providers/common/digests/digest_common.c
+++ b/providers/common/digests/digest_common.c
@@ -8,8 +8,8 @@
  */
 
 #include "openssl/err.h"
-#include "internal/digestcommon.h"
-#include "internal/providercommonerr.h"
+#include "prov/digestcommon.h"
+#include "prov/providercommonerr.h"
 
 int digest_default_get_params(OSSL_PARAM params[], size_t blksz, size_t paramsz,
                               unsigned long flags)
diff --git a/providers/common/exchange/build.info b/providers/common/exchange/build.info
deleted file mode 100644
index c99c9d81b5..0000000000
--- a/providers/common/exchange/build.info
+++ /dev/null
@@ -1,7 +0,0 @@
-LIBS=../../../libcrypto
-IF[{- !$disabled{dh} -}]
-  SOURCE[../../../libcrypto]=\
-          dh_exch.c
-ENDIF
-
-
diff --git a/providers/common/include/internal/ciphers/cipher_aead.h b/providers/common/include/prov/cipher_aead.h
similarity index 100%
rename from providers/common/include/internal/ciphers/cipher_aead.h
rename to providers/common/include/prov/cipher_aead.h
diff --git a/providers/common/include/internal/ciphers/cipher_ccm.h b/providers/common/include/prov/cipher_ccm.h
similarity index 100%
rename from providers/common/include/internal/ciphers/cipher_ccm.h
rename to providers/common/include/prov/cipher_ccm.h
diff --git a/providers/common/include/internal/ciphers/cipher_gcm.h b/providers/common/include/prov/cipher_gcm.h
similarity index 100%
rename from providers/common/include/internal/ciphers/cipher_gcm.h
rename to providers/common/include/prov/cipher_gcm.h
diff --git a/providers/common/include/internal/ciphers/ciphercommon.h b/providers/common/include/prov/ciphercommon.h
similarity index 100%
rename from providers/common/include/internal/ciphers/ciphercommon.h
rename to providers/common/include/prov/ciphercommon.h
diff --git a/providers/common/include/internal/digestcommon.h b/providers/common/include/prov/digestcommon.h
similarity index 100%
rename from providers/common/include/internal/digestcommon.h
rename to providers/common/include/prov/digestcommon.h
diff --git a/providers/common/include/internal/provider_ctx.h b/providers/common/include/prov/provider_ctx.h
similarity index 100%
copy from providers/common/include/internal/provider_ctx.h
copy to providers/common/include/prov/provider_ctx.h
diff --git a/providers/common/include/internal/provider_util.h b/providers/common/include/prov/provider_util.h
similarity index 100%
rename from providers/common/include/internal/provider_util.h
rename to providers/common/include/prov/provider_util.h
diff --git a/providers/common/include/internal/providercommon.h b/providers/common/include/prov/providercommon.h
similarity index 100%
copy from providers/common/include/internal/providercommon.h
copy to providers/common/include/prov/providercommon.h
diff --git a/providers/common/include/internal/providercommonerr.h b/providers/common/include/prov/providercommonerr.h
similarity index 100%
rename from providers/common/include/internal/providercommonerr.h
rename to providers/common/include/prov/providercommonerr.h
diff --git a/providers/common/kdfs/build.info b/providers/common/kdfs/build.info
deleted file mode 100644
index 8a723d488d..0000000000
--- a/providers/common/kdfs/build.info
+++ /dev/null
@@ -1,13 +0,0 @@
-$COMMON=tls1_prf.c hkdf.c kbkdf.c pbkdf2.c sskdf.c
-
-LIBS=../../../libcrypto
-SOURCE[../../../libcrypto]=$COMMON
-INCLUDE[../../../libcrypto]=. ../../../crypto
-
-IF[{- !$disabled{fips} -}]
-  MODULES=../../fips
-  SOURCE[../../fips]=$COMMON
-  INCLUDE[../../fips]=. ../../../crypto
-ENDIF
-
-        
diff --git a/providers/common/keymgmt/build.info b/providers/common/keymgmt/build.info
deleted file mode 100644
index e66190c401..0000000000
--- a/providers/common/keymgmt/build.info
+++ /dev/null
@@ -1,9 +0,0 @@
-LIBS=../../../libcrypto
-IF[{- !$disabled{dh} -}]
-  SOURCE[../../../libcrypto]=\
-          dh_kmgmt.c
-ENDIF
-IF[{- !$disabled{dsa} -}]
-  SOURCE[../../../libcrypto]=\
-          dsa_kmgmt.c
-ENDIF
diff --git a/providers/common/macs/build.info b/providers/common/macs/build.info
deleted file mode 100644
index 832a1e76ec..0000000000
--- a/providers/common/macs/build.info
+++ /dev/null
@@ -1,15 +0,0 @@
-$COMMON=gmac_prov.c hmac_prov.c kmac_prov.c
-
-IF[{- !$disabled{cmac} -}]
-  $COMMON=$COMMON cmac_prov.c
-ENDIF
-
-LIBS=../../../libcrypto
-SOURCE[../../../libcrypto]=$COMMON
-INCLUDE[../../../libcrypto]=. ../../../crypto
-
-IF[{- !$disabled{fips} -}]
-  MODULES=../../fips
-  SOURCE[../../fips]=$COMMON
-  INCLUDE[../../fips]=. ../../../crypto
-ENDIF
diff --git a/providers/common/provider_err.c b/providers/common/provider_err.c
index 5216baf918..ae1552283d 100644
--- a/providers/common/provider_err.c
+++ b/providers/common/provider_err.c
@@ -9,7 +9,7 @@
  */
 
 #include <openssl/err.h>
-#include "internal/providercommonerr.h"
+#include "prov/providercommonerr.h"
 
 #ifndef OPENSSL_NO_ERR
 
diff --git a/providers/common/provider_util.c b/providers/common/provider_util.c
index 8384cdc2a0..bdc86b1c05 100644
--- a/providers/common/provider_util.c
+++ b/providers/common/provider_util.c
@@ -9,7 +9,7 @@
 
 #include <openssl/evp.h>
 #include <openssl/core_names.h>
-#include "internal/provider_util.h"
+#include "prov/provider_util.h"
 
 void ossl_prov_cipher_reset(PROV_CIPHER *pc)
 {
diff --git a/providers/common/provlib.c b/providers/common/provlib.c
index 2bab77dba0..e754b84d35 100644
--- a/providers/common/provlib.c
+++ b/providers/common/provlib.c
@@ -8,7 +8,7 @@
  */
 
 #include <openssl/objects.h>
-#include "internal/providercommon.h"
+#include "prov/providercommon.h"
 
 /*
  * The FIPS provider has its own version of this in fipsprov.c because it does
diff --git a/providers/common/signature/build.info b/providers/common/signature/build.info
deleted file mode 100644
index 5b64229dfc..0000000000
--- a/providers/common/signature/build.info
+++ /dev/null
@@ -1,7 +0,0 @@
-LIBS=../../../libcrypto
-IF[{- !$disabled{dsa} -}]
-  SOURCE[../../../libcrypto]=\
-          dsa.c
-ENDIF
-
-
diff --git a/providers/default/build.info b/providers/default/build.info
deleted file mode 100644
index ca78cce0a8..0000000000
--- a/providers/default/build.info
+++ /dev/null
@@ -1,6 +0,0 @@
-SUBDIRS=digests macs ciphers
-SUBDIRS=digests kdfs macs ciphers
-LIBS=../../libcrypto
-SOURCE[../../libcrypto]=\
-        defltprov.c
-INCLUDE[../../libcrypto]=include
diff --git a/providers/default/ciphers/build.info b/providers/default/ciphers/build.info
index 5142357c7e..0440789573 100644
--- a/providers/default/ciphers/build.info
+++ b/providers/default/ciphers/build.info
@@ -1,7 +1,7 @@
-LIBS=../../../libcrypto
+$GOAL=../../libimplementations.a
 
 IF[{- !$disabled{des} -}]
-  SOURCE[../../../libcrypto]=\
+  SOURCE[$GOAL]=\
       cipher_tdes_default.c cipher_tdes_default_hw.c \
       cipher_tdes_wrap.c cipher_tdes_wrap_hw.c \
       cipher_desx.c cipher_desx_hw.c \
@@ -9,59 +9,59 @@ IF[{- !$disabled{des} -}]
 ENDIF
 
 IF[{- !$disabled{aria} -}]
-  SOURCE[../../../libcrypto]=\
+  SOURCE[$GOAL]=\
       cipher_aria.c cipher_aria_hw.c \
       cipher_aria_gcm.c cipher_aria_gcm_hw.c \
       cipher_aria_ccm.c cipher_aria_ccm_hw.c
 ENDIF
 
 IF[{- !$disabled{camellia} -}]
-  SOURCE[../../../libcrypto]=\
+  SOURCE[$GOAL]=\
       cipher_camellia.c cipher_camellia_hw.c
 ENDIF
 
 IF[{- !$disabled{bf} -}]
-  SOURCE[../../../libcrypto]=\
+  SOURCE[$GOAL]=\
       cipher_blowfish.c cipher_blowfish_hw.c
 ENDIF
 
 IF[{- !$disabled{idea} -}]
-  SOURCE[../../../libcrypto]=\
+  SOURCE[$GOAL]=\
       cipher_idea.c cipher_idea_hw.c
 ENDIF
 
 IF[{- !$disabled{cast} -}]
-  SOURCE[../../../libcrypto]=\
+  SOURCE[$GOAL]=\
       cipher_cast5.c cipher_cast5_hw.c
 ENDIF
 
 IF[{- !$disabled{seed} -}]
-  SOURCE[../../../libcrypto]=\
+  SOURCE[$GOAL]=\
       cipher_seed.c cipher_seed_hw.c
 ENDIF
 
 IF[{- !$disabled{sm4} -}]
-  SOURCE[../../../libcrypto]=\
+  SOURCE[$GOAL]=\
       cipher_sm4.c cipher_sm4_hw.c
 ENDIF
 
 IF[{- !$disabled{ocb} -}]
-  SOURCE[../../../libcrypto]=\
+  SOURCE[$GOAL]=\
        cipher_aes_ocb.c cipher_aes_ocb_hw.c
 ENDIF
 
 IF[{- !$disabled{rc4} -}]
-  SOURCE[../../../libcrypto]=\
+  SOURCE[$GOAL]=\
       cipher_rc4.c cipher_rc4_hw.c
 ENDIF
 
 IF[{- !$disabled{rc5} -}]
-  SOURCE[../../../libcrypto]=\
+  SOURCE[$GOAL]=\
       cipher_rc5.c cipher_rc5_hw.c
 ENDIF
 
 IF[{- !$disabled{rc2} -}]
-  SOURCE[../../../libcrypto]=\
+  SOURCE[$GOAL]=\
       cipher_rc2.c cipher_rc2_hw.c
 ENDIF
 
diff --git a/providers/default/digests/build.info b/providers/default/digests/build.info
deleted file mode 100644
index 9d61229ae7..0000000000
--- a/providers/default/digests/build.info
+++ /dev/null
@@ -1,15 +0,0 @@
-
-IF[{- !$disabled{blake2} -}]
-  SOURCE[../../../libcrypto]=\
-          blake2_prov.c blake2b_prov.c blake2s_prov.c
-ENDIF
-
-IF[{- !$disabled{sm3} -}]
-  SOURCE[../../../libcrypto]=\
-          sm3_prov.c
-ENDIF
-
-IF[{- !$disabled{md5} -}]
-  SOURCE[../../../libcrypto]=\
-          md5_prov.c md5_sha1_prov.c
-ENDIF
diff --git a/providers/default/kdfs/build.info b/providers/default/kdfs/build.info
deleted file mode 100644
index 27047c5286..0000000000
--- a/providers/default/kdfs/build.info
+++ /dev/null
@@ -1,3 +0,0 @@
-LIBS=../../../libcrypto
-SOURCE[../../../libcrypto]=scrypt.c sshkdf.c x942kdf.c
-INCLUDE[../../../libcrypto]=. ../../../crypto
diff --git a/providers/default/macs/build.info b/providers/default/macs/build.info
deleted file mode 100644
index fa7f5e479a..0000000000
--- a/providers/default/macs/build.info
+++ /dev/null
@@ -1,15 +0,0 @@
-LIBS=../../../libcrypto
-
-IF[{- !$disabled{blake2} -}]
-  SOURCE[../../../libcrypto]=blake2b_mac.c blake2s_mac.c
-ENDIF
-
-IF[{- !$disabled{siphash} -}]
-  SOURCE[../../../libcrypto]=siphash_prov.c
-ENDIF
-
-IF[{- !$disabled{poly1305} -}]
-  SOURCE[../../../libcrypto]=poly1305_prov.c
-ENDIF
-
-INCLUDE[../../../libcrypto]=. ../../../crypto
diff --git a/providers/default/defltprov.c b/providers/defltprov.c
similarity index 99%
rename from providers/default/defltprov.c
rename to providers/defltprov.c
index 7e952921c8..7dd0cf5012 100644
--- a/providers/default/defltprov.c
+++ b/providers/defltprov.c
@@ -14,7 +14,7 @@
 #include <openssl/core_numbers.h>
 #include <openssl/core_names.h>
 #include <openssl/params.h>
-#include "internal/provider_algs.h"
+#include "prov/implementations.h"
 
 /* Functions provided by the core */
 static OSSL_core_gettable_params_fn *c_gettable_params = NULL;
diff --git a/providers/fips/build.info b/providers/fips/build.info
index 9b8effa85c..4dfbb4623a 100644
--- a/providers/fips/build.info
+++ b/providers/fips/build.info
@@ -1,2 +1,3 @@
 
 SOURCE[../fips]=fipsprov.c selftest.c
+INCLUDE[../fips]=../implementations/include ../common/include
diff --git a/providers/fips/fipsprov.c b/providers/fips/fipsprov.c
index 8464fe135c..f0cf4a9bd0 100644
--- a/providers/fips/fipsprov.c
+++ b/providers/fips/fipsprov.c
@@ -26,9 +26,9 @@
 #include "internal/cryptlib.h"
 #include "internal/property.h"
 #include "crypto/evp.h"
-#include "internal/provider_algs.h"
-#include "internal/provider_ctx.h"
-#include "internal/providercommon.h"
+#include "prov/implementations.h"
+#include "prov/provider_ctx.h"
+#include "prov/providercommon.h"
 #include "selftest.h"
 
 extern OSSL_core_thread_start_fn *c_thread_start;
diff --git a/providers/implementations/build.info b/providers/implementations/build.info
new file mode 100644
index 0000000000..0fc0822074
--- /dev/null
+++ b/providers/implementations/build.info
@@ -0,0 +1 @@
+SUBDIRS=digests ciphers macs kdfs exchange keymgmt signature
diff --git a/providers/implementations/ciphers/build.info b/providers/implementations/ciphers/build.info
new file mode 100644
index 0000000000..fb2b53e58a
--- /dev/null
+++ b/providers/implementations/ciphers/build.info
@@ -0,0 +1,102 @@
+# We make separate GOAL variables for each algorithm, to make it easy to
+# switch each to the Legacy provider when needed.
+#
+# $TDES_1_GOAL and $TDES_2_GOAL separate FIPSable and non-FIPSable TDES.
+# The latter may become legacy sooner, so it's comfortable to have two
+# variables already now, to switch the non-FIPSable TDES to legacy if needed.
+
+$AES_GOAL=../../libimplementations.a
+$TDES_1_GOAL=../../libimplementations.a
+$TDES_2_GOAL=../../libimplementations.a
+$DES_GOAL=../../libimplementations.a
+$ARIA_GOAL=../../libimplementations.a
+$CAMELLIA_GOAL=../../libimplementations.a
+$BLOWFISH_GOAL=../../libimplementations.a
+$IDEA_GOAL=../../libimplementations.a
+$CAST5_GOAL=../../libimplementations.a
+$SEED_GOAL=../../libimplementations.a
+$SM4_GOAL=../../libimplementations.a
+$RC4_GOAL=../../libimplementations.a
+$RC5_GOAL=../../libimplementations.a
+$RC2_GOAL=../../libimplementations.a
+
+IF[{- !$disabled{des} -}]
+  SOURCE[$TDES_1_GOAL]=cipher_tdes.c cipher_tdes_hw.c
+ENDIF
+
+SOURCE[$AES_GOAL]=\
+        cipher_aes.c cipher_aes_hw.c \
+        cipher_aes_xts.c cipher_aes_xts_hw.c \
+        cipher_aes_gcm.c cipher_aes_gcm_hw.c \
+        cipher_aes_ccm.c cipher_aes_ccm_hw.c \
+        cipher_aes_wrp.c
+# Extra code to satisfy the FIPS and non-FIPS separation.
+# When the AES-xxx-XTS moves to legacy, this can be removed.
+SOURCE[../../libfips.a]=cipher_aes_xts_fips.c
+SOURCE[../../libnonfips.a]=cipher_aes_xts_fips.c
+
+IF[{- !$disabled{des} -}]
+  SOURCE[$TDES_2_GOAL]=\
+      cipher_tdes_default.c cipher_tdes_default_hw.c \
+      cipher_tdes_wrap.c cipher_tdes_wrap_hw.c
+  SOURCE[$DES_GOAL]=\
+      cipher_desx.c cipher_desx_hw.c \
+      cipher_des.c cipher_des_hw.c
+ENDIF
+
+IF[{- !$disabled{aria} -}]
+  SOURCE[$ARIA_GOAL]=\
+      cipher_aria.c cipher_aria_hw.c \
+      cipher_aria_gcm.c cipher_aria_gcm_hw.c \
+      cipher_aria_ccm.c cipher_aria_ccm_hw.c
+ENDIF
+
+IF[{- !$disabled{camellia} -}]
+  SOURCE[$CAMELLIA_GOAL]=\
+      cipher_camellia.c cipher_camellia_hw.c
+ENDIF
+
+IF[{- !$disabled{bf} -}]
+  SOURCE[$BLOWFISH_GOAL]=\
+      cipher_blowfish.c cipher_blowfish_hw.c
+ENDIF
+
+IF[{- !$disabled{idea} -}]
+  SOURCE[$IDEA_GOAL]=\
+      cipher_idea.c cipher_idea_hw.c
+ENDIF
+
+IF[{- !$disabled{cast} -}]
+  SOURCE[$CAST5_GOAL]=\
+      cipher_cast5.c cipher_cast5_hw.c
+ENDIF
+
+IF[{- !$disabled{seed} -}]
+  SOURCE[$SEED_GOAL]=\
+      cipher_seed.c cipher_seed_hw.c
+ENDIF
+
+IF[{- !$disabled{sm4} -}]
+  SOURCE[$SM4_GOAL]=\
+      cipher_sm4.c cipher_sm4_hw.c
+ENDIF
+
+IF[{- !$disabled{ocb} -}]
+  SOURCE[$AES_GOAL]=\
+       cipher_aes_ocb.c cipher_aes_ocb_hw.c
+ENDIF
+
+IF[{- !$disabled{rc4} -}]
+  SOURCE[$RC4_GOAL]=\
+      cipher_rc4.c cipher_rc4_hw.c
+ENDIF
+
+IF[{- !$disabled{rc5} -}]
+  SOURCE[$RC5_GOAL]=\
+      cipher_rc5.c cipher_rc5_hw.c
+ENDIF
+
+IF[{- !$disabled{rc2} -}]
+  SOURCE[$RC2_GOAL]=\
+      cipher_rc2.c cipher_rc2_hw.c
+ENDIF
diff --git a/providers/common/ciphers/cipher_aes.c b/providers/implementations/ciphers/cipher_aes.c
similarity index 98%
rename from providers/common/ciphers/cipher_aes.c
rename to providers/implementations/ciphers/cipher_aes.c
index 46880e0bf7..c62d2d2c29 100644
--- a/providers/common/ciphers/cipher_aes.c
+++ b/providers/implementations/ciphers/cipher_aes.c
@@ -10,7 +10,7 @@
 /* Dispatch functions for AES cipher modes ecb, cbc, ofb, cfb, ctr */
 
 #include "cipher_aes.h"
-#include "internal/provider_algs.h"
+#include "prov/implementations.h"
 
 static OSSL_OP_cipher_freectx_fn aes_freectx;
 static OSSL_OP_cipher_dupctx_fn aes_dupctx;
diff --git a/providers/common/ciphers/cipher_aes.h b/providers/implementations/ciphers/cipher_aes.h
similarity index 98%
rename from providers/common/ciphers/cipher_aes.h
rename to providers/implementations/ciphers/cipher_aes.h
index 741b20f6e3..d00fab13ef 100644
--- a/providers/common/ciphers/cipher_aes.h
+++ b/providers/implementations/ciphers/cipher_aes.h
@@ -8,7 +8,7 @@
  */
 
 #include <openssl/aes.h>
-#include "internal/ciphers/ciphercommon.h"
+#include "prov/ciphercommon.h"
 
 typedef struct prov_aes_ctx_st {
     PROV_CIPHER_CTX base;      /* Must be first */
diff --git a/providers/common/ciphers/cipher_aes_ccm.c b/providers/implementations/ciphers/cipher_aes_ccm.c
similarity index 91%
rename from providers/common/ciphers/cipher_aes_ccm.c
rename to providers/implementations/ciphers/cipher_aes_ccm.c
index cffca06c80..c1fb51b565 100644
--- a/providers/common/ciphers/cipher_aes_ccm.c
+++ b/providers/implementations/ciphers/cipher_aes_ccm.c
@@ -9,9 +9,9 @@
 
 /* Dispatch functions for AES CCM mode */
 
-#include "cipher_local.h"
-#include "internal/ciphers/cipher_ccm.h"
-#include "internal/provider_algs.h"
+#include "prov/ciphercommon.h"
+#include "prov/cipher_ccm.h"
+#include "prov/implementations.h"
 
 static void *aes_ccm_newctx(void *provctx, size_t keybits)
 {
diff --git a/providers/common/ciphers/cipher_aes_ccm_hw.c b/providers/implementations/ciphers/cipher_aes_ccm_hw.c
similarity index 96%
rename from providers/common/ciphers/cipher_aes_ccm_hw.c
rename to providers/implementations/ciphers/cipher_aes_ccm_hw.c
index ba7ce4dcab..ae200ebada 100644
--- a/providers/common/ciphers/cipher_aes_ccm_hw.c
+++ b/providers/implementations/ciphers/cipher_aes_ccm_hw.c
@@ -9,8 +9,8 @@
 
 /* AES CCM mode */
 
-#include "cipher_local.h"
-#include "internal/ciphers/cipher_ccm.h"
+#include "prov/ciphercommon.h"
+#include "prov/cipher_ccm.h"
 
 #define AES_HW_CCM_SET_KEY_FN(fn_set_enc_key, fn_blk, fn_ccm_enc, fn_ccm_dec)  \
     fn_set_enc_key(key, keylen * 8, &actx->ccm.ks.ks);                         \
diff --git a/providers/common/ciphers/cipher_aes_ccm_hw_aesni.inc b/providers/implementations/ciphers/cipher_aes_ccm_hw_aesni.inc
similarity index 100%
rename from providers/common/ciphers/cipher_aes_ccm_hw_aesni.inc
rename to providers/implementations/ciphers/cipher_aes_ccm_hw_aesni.inc
diff --git a/providers/common/ciphers/cipher_aes_ccm_hw_s390x.inc b/providers/implementations/ciphers/cipher_aes_ccm_hw_s390x.inc
similarity index 100%
rename from providers/common/ciphers/cipher_aes_ccm_hw_s390x.inc
rename to providers/implementations/ciphers/cipher_aes_ccm_hw_s390x.inc
diff --git a/providers/common/ciphers/cipher_aes_ccm_hw_t4.inc b/providers/implementations/ciphers/cipher_aes_ccm_hw_t4.inc
similarity index 100%
rename from providers/common/ciphers/cipher_aes_ccm_hw_t4.inc
rename to providers/implementations/ciphers/cipher_aes_ccm_hw_t4.inc
diff --git a/providers/common/ciphers/cipher_aes_gcm.c b/providers/implementations/ciphers/cipher_aes_gcm.c
similarity index 91%
rename from providers/common/ciphers/cipher_aes_gcm.c
rename to providers/implementations/ciphers/cipher_aes_gcm.c
index ef015bff21..4ebc8140ee 100644
--- a/providers/common/ciphers/cipher_aes_gcm.c
+++ b/providers/implementations/ciphers/cipher_aes_gcm.c
@@ -9,9 +9,9 @@
 
 /* Dispatch functions for AES GCM mode */
 
-#include "cipher_local.h"
-#include "internal/ciphers/cipher_gcm.h"
-#include "internal/provider_algs.h"
+#include "prov/ciphercommon.h"
+#include "prov/cipher_gcm.h"
+#include "prov/implementations.h"
 
 static void *aes_gcm_newctx(void *provctx, size_t keybits)
 {
diff --git a/providers/common/ciphers/cipher_aes_gcm_hw.c b/providers/implementations/ciphers/cipher_aes_gcm_hw.c
similarity index 96%
rename from providers/common/ciphers/cipher_aes_gcm_hw.c
rename to providers/implementations/ciphers/cipher_aes_gcm_hw.c
index 5263bdd6dd..f5dc0c4eed 100644
--- a/providers/common/ciphers/cipher_aes_gcm_hw.c
+++ b/providers/implementations/ciphers/cipher_aes_gcm_hw.c
@@ -9,8 +9,8 @@
 
 /* Dispatch functions for AES GCM mode */
 
-#include "cipher_local.h"
-#include "internal/ciphers/cipher_gcm.h"
+#include "prov/ciphercommon.h"
+#include "prov/cipher_gcm.h"
 
 static int generic_aes_gcm_initkey(PROV_GCM_CTX *ctx, const unsigned char *key,
                                    size_t keylen)
diff --git a/providers/common/ciphers/cipher_aes_gcm_hw_aesni.inc b/providers/implementations/ciphers/cipher_aes_gcm_hw_aesni.inc
similarity index 100%
rename from providers/common/ciphers/cipher_aes_gcm_hw_aesni.inc
rename to providers/implementations/ciphers/cipher_aes_gcm_hw_aesni.inc
diff --git a/providers/common/ciphers/cipher_aes_gcm_hw_s390x.inc b/providers/implementations/ciphers/cipher_aes_gcm_hw_s390x.inc
similarity index 100%
rename from providers/common/ciphers/cipher_aes_gcm_hw_s390x.inc
rename to providers/implementations/ciphers/cipher_aes_gcm_hw_s390x.inc
diff --git a/providers/common/ciphers/cipher_aes_gcm_hw_t4.inc b/providers/implementations/ciphers/cipher_aes_gcm_hw_t4.inc
similarity index 100%
rename from providers/common/ciphers/cipher_aes_gcm_hw_t4.inc
rename to providers/implementations/ciphers/cipher_aes_gcm_hw_t4.inc
diff --git a/providers/common/ciphers/cipher_aes_hw.c b/providers/implementations/ciphers/cipher_aes_hw.c
similarity index 99%
rename from providers/common/ciphers/cipher_aes_hw.c
rename to providers/implementations/ciphers/cipher_aes_hw.c
index e9b6388300..8519662e73 100644
--- a/providers/common/ciphers/cipher_aes_hw.c
+++ b/providers/implementations/ciphers/cipher_aes_hw.c
@@ -8,7 +8,7 @@
  */
 
 #include "cipher_aes.h"
-#include "internal/providercommonerr.h"
+#include "prov/providercommonerr.h"
 
 static int cipher_hw_aes_initkey(PROV_CIPHER_CTX *dat,
                                  const unsigned char *key, size_t keylen)
diff --git a/providers/common/ciphers/cipher_aes_hw_aesni.inc b/providers/implementations/ciphers/cipher_aes_hw_aesni.inc
similarity index 100%
rename from providers/common/ciphers/cipher_aes_hw_aesni.inc
rename to providers/implementations/ciphers/cipher_aes_hw_aesni.inc
diff --git a/providers/common/ciphers/cipher_aes_hw_s390x.inc b/providers/implementations/ciphers/cipher_aes_hw_s390x.inc
similarity index 100%
rename from providers/common/ciphers/cipher_aes_hw_s390x.inc
rename to providers/implementations/ciphers/cipher_aes_hw_s390x.inc
diff --git a/providers/common/ciphers/cipher_aes_hw_t4.inc b/providers/implementations/ciphers/cipher_aes_hw_t4.inc
similarity index 100%
rename from providers/common/ciphers/cipher_aes_hw_t4.inc
rename to providers/implementations/ciphers/cipher_aes_hw_t4.inc
diff --git a/providers/default/ciphers/cipher_aes_ocb.c b/providers/implementations/ciphers/cipher_aes_ocb.c
similarity index 99%
rename from providers/default/ciphers/cipher_aes_ocb.c
rename to providers/implementations/ciphers/cipher_aes_ocb.c
index 95c0658fee..d30a666fc5 100644
--- a/providers/default/ciphers/cipher_aes_ocb.c
+++ b/providers/implementations/ciphers/cipher_aes_ocb.c
@@ -8,9 +8,9 @@
  */
 
 #include "cipher_aes_ocb.h"
-#include "internal/providercommonerr.h"
-#include "internal/ciphers/cipher_aead.h"
-#include "internal/provider_algs.h"
+#include "prov/providercommonerr.h"
+#include "prov/cipher_aead.h"
+#include "prov/implementations.h"
 
 #define AES_OCB_FLAGS AEAD_FLAGS
 
diff --git a/providers/default/ciphers/cipher_aes_ocb.h b/providers/implementations/ciphers/cipher_aes_ocb.h
similarity index 96%
rename from providers/default/ciphers/cipher_aes_ocb.h
rename to providers/implementations/ciphers/cipher_aes_ocb.h
index 7750e97615..ba515241e2 100644
--- a/providers/default/ciphers/cipher_aes_ocb.h
+++ b/providers/implementations/ciphers/cipher_aes_ocb.h
@@ -8,7 +8,7 @@
  */
 
 #include <openssl/aes.h>
-#include "internal/ciphers/ciphercommon.h"
+#include "prov/ciphercommon.h"
 
 #define OCB_MAX_TAG_LEN     AES_BLOCK_SIZE
 #define OCB_MAX_DATA_LEN    AES_BLOCK_SIZE
diff --git a/providers/default/ciphers/cipher_aes_ocb_hw.c b/providers/implementations/ciphers/cipher_aes_ocb_hw.c
similarity index 100%
rename from providers/default/ciphers/cipher_aes_ocb_hw.c
rename to providers/implementations/ciphers/cipher_aes_ocb_hw.c
diff --git a/providers/common/ciphers/cipher_aes_wrp.c b/providers/implementations/ciphers/cipher_aes_wrp.c
similarity index 99%
rename from providers/common/ciphers/cipher_aes_wrp.c
rename to providers/implementations/ciphers/cipher_aes_wrp.c
index 1bf4c1793a..9eaec16318 100644
--- a/providers/common/ciphers/cipher_aes_wrp.c
+++ b/providers/implementations/ciphers/cipher_aes_wrp.c
@@ -8,8 +8,8 @@
  */
 
 #include "cipher_aes.h"
-#include "internal/providercommonerr.h"
-#include "internal/provider_algs.h"
+#include "prov/providercommonerr.h"
+#include "prov/implementations.h"
 
 /* AES wrap with padding has IV length of 4, without padding 8 */
 #define AES_WRAP_PAD_IVLEN   4
diff --git a/providers/common/ciphers/cipher_aes_xts.c b/providers/implementations/ciphers/cipher_aes_xts.c
similarity index 97%
rename from providers/common/ciphers/cipher_aes_xts.c
rename to providers/implementations/ciphers/cipher_aes_xts.c
index fdda733d24..2ad1fbe84a 100644
--- a/providers/common/ciphers/cipher_aes_xts.c
+++ b/providers/implementations/ciphers/cipher_aes_xts.c
@@ -8,8 +8,8 @@
  */
 
 #include "cipher_aes_xts.h"
-#include "internal/provider_algs.h"
-#include "internal/providercommonerr.h"
+#include "prov/implementations.h"
+#include "prov/providercommonerr.h"
 
 /* TODO (3.0) Figure out what flags need to be set */
 #define AES_XTS_FLAGS (EVP_CIPH_CUSTOM_IV          \
@@ -20,12 +20,6 @@
 #define AES_XTS_IV_BITS 128
 #define AES_XTS_BLOCK_BITS 8
 
-#ifdef FIPS_MODE
-static const int allow_insecure_decrypt = 0;
-#else
-static const int allow_insecure_decrypt = 1;
-#endif /* FIPS_MODE */
-
 /* forward declarations */
 static OSSL_OP_cipher_encrypt_init_fn aes_xts_einit;
 static OSSL_OP_cipher_decrypt_init_fn aes_xts_dinit;
diff --git a/providers/common/ciphers/cipher_aes_xts.h b/providers/implementations/ciphers/cipher_aes_xts.h
similarity index 82%
rename from providers/common/ciphers/cipher_aes_xts.h
rename to providers/implementations/ciphers/cipher_aes_xts.h
index 4f8a8f874f..615ee61905 100644
--- a/providers/common/ciphers/cipher_aes_xts.h
+++ b/providers/implementations/ciphers/cipher_aes_xts.h
@@ -8,7 +8,13 @@
  */
 
 #include <openssl/aes.h>
-#include "internal/ciphers/ciphercommon.h"
+#include "prov/ciphercommon.h"
+
+/*
+ * Available in cipher_fips.c, and compiled with different values depending
+ * on we're in the FIPS module or not.
+ */
+extern const int allow_insecure_decrypt;
 
 PROV_CIPHER_FUNC(void, xts_stream,
                  (const unsigned char *in, unsigned char *out, size_t len,
diff --git a/providers/common/include/internal/providercommon.h b/providers/implementations/ciphers/cipher_aes_xts_fips.c
similarity index 68%
rename from providers/common/include/internal/providercommon.h
rename to providers/implementations/ciphers/cipher_aes_xts_fips.c
index 569c08c0b1..c99d6ed2f4 100644
--- a/providers/common/include/internal/providercommon.h
+++ b/providers/implementations/ciphers/cipher_aes_xts_fips.c
@@ -7,9 +7,10 @@
  * https://www.openssl.org/source/license.html
  */
 
-#include <openssl/provider.h>
-
-const OSSL_PROVIDER *FIPS_get_provider(OPENSSL_CTX *ctx);
-
-const char *ossl_prov_util_nid_to_name(int nid);
+#include "cipher_aes_xts.h"
 
+#ifdef FIPS_MODE
+const int allow_insecure_decrypt = 0;
+#else
+const int allow_insecure_decrypt = 1;
+#endif /* FIPS_MODE */
diff --git a/providers/common/ciphers/cipher_aes_xts_hw.c b/providers/implementations/ciphers/cipher_aes_xts_hw.c
similarity index 100%
rename from providers/common/ciphers/cipher_aes_xts_hw.c
rename to providers/implementations/ciphers/cipher_aes_xts_hw.c
diff --git a/providers/default/ciphers/cipher_aria.c b/providers/implementations/ciphers/cipher_aria.c
similarity index 98%
rename from providers/default/ciphers/cipher_aria.c
rename to providers/implementations/ciphers/cipher_aria.c
index 861b28268b..da864015bd 100644
--- a/providers/default/ciphers/cipher_aria.c
+++ b/providers/implementations/ciphers/cipher_aria.c
@@ -10,7 +10,7 @@
 /* Dispatch functions for ARIA cipher modes ecb, cbc, ofb, cfb, ctr */
 
 #include "cipher_aria.h"
-#include "internal/provider_algs.h"
+#include "prov/implementations.h"
 
 static OSSL_OP_cipher_freectx_fn aria_freectx;
 static OSSL_OP_cipher_dupctx_fn aria_dupctx;
diff --git a/providers/default/ciphers/cipher_aria.h b/providers/implementations/ciphers/cipher_aria.h
similarity index 96%
rename from providers/default/ciphers/cipher_aria.h
rename to providers/implementations/ciphers/cipher_aria.h
index e95e4ca93c..282408c58e 100644
--- a/providers/default/ciphers/cipher_aria.h
+++ b/providers/implementations/ciphers/cipher_aria.h
@@ -8,7 +8,7 @@
  */
 
 #include "crypto/aria.h"
-#include "internal/ciphers/ciphercommon.h"
+#include "prov/ciphercommon.h"
 
 typedef struct prov_aria_ctx_st {
     PROV_CIPHER_CTX base;      /* Must be first */
diff --git a/providers/default/ciphers/cipher_aria_ccm.c b/providers/implementations/ciphers/cipher_aria_ccm.c
similarity index 96%
rename from providers/default/ciphers/cipher_aria_ccm.c
rename to providers/implementations/ciphers/cipher_aria_ccm.c
index 97e8137db8..e4cfc6cd8f 100644
--- a/providers/default/ciphers/cipher_aria_ccm.c
+++ b/providers/implementations/ciphers/cipher_aria_ccm.c
@@ -10,7 +10,7 @@
 /* Dispatch functions for ARIA CCM mode */
 
 #include "cipher_aria_ccm.h"
-#include "internal/provider_algs.h"
+#include "prov/implementations.h"
 
 static OSSL_OP_cipher_freectx_fn aria_ccm_freectx;
 
diff --git a/providers/default/ciphers/cipher_aria_ccm.h b/providers/implementations/ciphers/cipher_aria_ccm.h
similarity index 88%
rename from providers/default/ciphers/cipher_aria_ccm.h
rename to providers/implementations/ciphers/cipher_aria_ccm.h
index fe0a3908bc..301ce14306 100644
--- a/providers/default/ciphers/cipher_aria_ccm.h
+++ b/providers/implementations/ciphers/cipher_aria_ccm.h
@@ -8,8 +8,8 @@
  */
 
 #include "crypto/aria.h"
-#include "internal/ciphers/ciphercommon.h"
-#include "internal/ciphers/cipher_ccm.h"
+#include "prov/ciphercommon.h"
+#include "prov/cipher_ccm.h"
 
 typedef struct prov_aria_ccm_ctx_st {
     PROV_CCM_CTX base; /* Must be first */
diff --git a/providers/default/ciphers/cipher_aria_ccm_hw.c b/providers/implementations/ciphers/cipher_aria_ccm_hw.c
similarity index 100%
rename from providers/default/ciphers/cipher_aria_ccm_hw.c
rename to providers/implementations/ciphers/cipher_aria_ccm_hw.c
diff --git a/providers/default/ciphers/cipher_aria_gcm.c b/providers/implementations/ciphers/cipher_aria_gcm.c
similarity index 96%
rename from providers/default/ciphers/cipher_aria_gcm.c
rename to providers/implementations/ciphers/cipher_aria_gcm.c
index 7c9fa3d211..1481fcc2e2 100644
--- a/providers/default/ciphers/cipher_aria_gcm.c
+++ b/providers/implementations/ciphers/cipher_aria_gcm.c
@@ -10,7 +10,7 @@
 /* Dispatch functions for ARIA GCM mode */
 
 #include "cipher_aria_gcm.h"
-#include "internal/provider_algs.h"
+#include "prov/implementations.h"
 
 static void *aria_gcm_newctx(void *provctx, size_t keybits)
 {
diff --git a/providers/default/ciphers/cipher_aria_gcm.h b/providers/implementations/ciphers/cipher_aria_gcm.h
similarity index 87%
rename from providers/default/ciphers/cipher_aria_gcm.h
rename to providers/implementations/ciphers/cipher_aria_gcm.h
index ac5c248201..13fbe175d9 100644
--- a/providers/default/ciphers/cipher_aria_gcm.h
+++ b/providers/implementations/ciphers/cipher_aria_gcm.h
@@ -8,8 +8,8 @@
  */
 
 #include "crypto/aria.h"
-#include "internal/ciphers/ciphercommon.h"
-#include "internal/ciphers/cipher_gcm.h"
+#include "prov/ciphercommon.h"
+#include "prov/cipher_gcm.h"
 
 typedef struct prov_aria_gcm_ctx_st {
     PROV_GCM_CTX base;              /* must be first entry in struct */
diff --git a/providers/default/ciphers/cipher_aria_gcm_hw.c b/providers/implementations/ciphers/cipher_aria_gcm_hw.c
similarity index 100%
rename from providers/default/ciphers/cipher_aria_gcm_hw.c
rename to providers/implementations/ciphers/cipher_aria_gcm_hw.c
diff --git a/providers/default/ciphers/cipher_aria_hw.c b/providers/implementations/ciphers/cipher_aria_hw.c
similarity index 100%
rename from providers/default/ciphers/cipher_aria_hw.c
rename to providers/implementations/ciphers/cipher_aria_hw.c
diff --git a/providers/default/ciphers/cipher_blowfish.c b/providers/implementations/ciphers/cipher_blowfish.c
similarity index 97%
rename from providers/default/ciphers/cipher_blowfish.c
rename to providers/implementations/ciphers/cipher_blowfish.c
index 4730f1fd40..786cc15189 100644
--- a/providers/default/ciphers/cipher_blowfish.c
+++ b/providers/implementations/ciphers/cipher_blowfish.c
@@ -10,7 +10,7 @@
 /* Dispatch functions for Blowfish cipher modes ecb, cbc, ofb, cfb */
 
 #include "cipher_blowfish.h"
-#include "internal/provider_algs.h"
+#include "prov/implementations.h"
 
 #define BF_FLAGS (EVP_CIPH_VARIABLE_LENGTH)
 
diff --git a/providers/default/ciphers/cipher_blowfish.h b/providers/implementations/ciphers/cipher_blowfish.h
similarity index 94%
rename from providers/default/ciphers/cipher_blowfish.h
rename to providers/implementations/ciphers/cipher_blowfish.h
index 819a61f140..2d66d1bc0e 100644
--- a/providers/default/ciphers/cipher_blowfish.h
+++ b/providers/implementations/ciphers/cipher_blowfish.h
@@ -8,7 +8,7 @@
  */
 
 #include <openssl/blowfish.h>
-#include "internal/ciphers/ciphercommon.h"
+#include "prov/ciphercommon.h"
 
 typedef struct prov_blowfish_ctx_st {
     PROV_CIPHER_CTX base;      /* Must be first */
diff --git a/providers/default/ciphers/cipher_blowfish_hw.c b/providers/implementations/ciphers/cipher_blowfish_hw.c
similarity index 100%
rename from providers/default/ciphers/cipher_blowfish_hw.c
rename to providers/implementations/ciphers/cipher_blowfish_hw.c
diff --git a/providers/default/ciphers/cipher_camellia.c b/providers/implementations/ciphers/cipher_camellia.c
similarity index 98%
rename from providers/default/ciphers/cipher_camellia.c
rename to providers/implementations/ciphers/cipher_camellia.c
index 68c0e91355..cf9af3db32 100644
--- a/providers/default/ciphers/cipher_camellia.c
+++ b/providers/implementations/ciphers/cipher_camellia.c
@@ -10,7 +10,7 @@
 /* Dispatch functions for CAMELLIA cipher modes ecb, cbc, ofb, cfb, ctr */
 
 #include "cipher_camellia.h"
-#include "internal/provider_algs.h"
+#include "prov/implementations.h"
 
 static OSSL_OP_cipher_freectx_fn camellia_freectx;
 static OSSL_OP_cipher_dupctx_fn camellia_dupctx;
diff --git a/providers/default/ciphers/cipher_camellia.h b/providers/implementations/ciphers/cipher_camellia.h
similarity index 96%
rename from providers/default/ciphers/cipher_camellia.h
rename to providers/implementations/ciphers/cipher_camellia.h
index 521c03e261..58636f1d32 100644
--- a/providers/default/ciphers/cipher_camellia.h
+++ b/providers/implementations/ciphers/cipher_camellia.h
@@ -8,7 +8,7 @@
  */
 
 #include "openssl/camellia.h"
-#include "internal/ciphers/ciphercommon.h"
+#include "prov/ciphercommon.h"
 
 typedef struct prov_camellia_ctx_st {
     PROV_CIPHER_CTX base;      /* Must be first */
diff --git a/providers/default/ciphers/cipher_camellia_hw.c b/providers/implementations/ciphers/cipher_camellia_hw.c
similarity index 100%
rename from providers/default/ciphers/cipher_camellia_hw.c
rename to providers/implementations/ciphers/cipher_camellia_hw.c
diff --git a/providers/default/ciphers/cipher_camellia_hw_t4.inc b/providers/implementations/ciphers/cipher_camellia_hw_t4.inc
similarity index 100%
rename from providers/default/ciphers/cipher_camellia_hw_t4.inc
rename to providers/implementations/ciphers/cipher_camellia_hw_t4.inc
diff --git a/providers/default/ciphers/cipher_cast.h b/providers/implementations/ciphers/cipher_cast.h
similarity index 94%
rename from providers/default/ciphers/cipher_cast.h
rename to providers/implementations/ciphers/cipher_cast.h
index 279f92216f..218f5c4fb5 100644
--- a/providers/default/ciphers/cipher_cast.h
+++ b/providers/implementations/ciphers/cipher_cast.h
@@ -8,7 +8,7 @@
  */
 
 #include <openssl/cast.h>
-#include "internal/ciphers/ciphercommon.h"
+#include "prov/ciphercommon.h"
 
 typedef struct prov_cast_ctx_st {
     PROV_CIPHER_CTX base;      /* Must be first */
diff --git a/providers/default/ciphers/cipher_cast5.c b/providers/implementations/ciphers/cipher_cast5.c
similarity index 97%
rename from providers/default/ciphers/cipher_cast5.c
rename to providers/implementations/ciphers/cipher_cast5.c
index eb79aad820..d049d836d0 100644
--- a/providers/default/ciphers/cipher_cast5.c
+++ b/providers/implementations/ciphers/cipher_cast5.c
@@ -10,7 +10,7 @@
 /* Dispatch functions for cast cipher modes ecb, cbc, ofb, cfb */
 
 #include "cipher_cast.h"
-#include "internal/provider_algs.h"
+#include "prov/implementations.h"
 
 #define CAST5_FLAGS (EVP_CIPH_VARIABLE_LENGTH)
 
diff --git a/providers/default/ciphers/cipher_cast5_hw.c b/providers/implementations/ciphers/cipher_cast5_hw.c
similarity index 100%
rename from providers/default/ciphers/cipher_cast5_hw.c
rename to providers/implementations/ciphers/cipher_cast5_hw.c
diff --git a/providers/default/ciphers/cipher_des.c b/providers/implementations/ciphers/cipher_des.c
similarity index 98%
rename from providers/default/ciphers/cipher_des.c
rename to providers/implementations/ciphers/cipher_des.c
index 4530114187..200c365282 100644
--- a/providers/default/ciphers/cipher_des.c
+++ b/providers/implementations/ciphers/cipher_des.c
@@ -7,11 +7,11 @@
  * https://www.openssl.org/source/license.html
  */
 
-#include "cipher_local.h"
+#include "prov/ciphercommon.h"
 #include "cipher_des.h"
 #include "crypto/rand.h"
-#include "internal/provider_algs.h"
-#include "internal/providercommonerr.h"
+#include "prov/implementations.h"
+#include "prov/providercommonerr.h"
 
 /* TODO(3.0) Figure out what flags need to be here */
 #define DES_FLAGS (EVP_CIPH_RAND_KEY)
diff --git a/providers/default/ciphers/cipher_des.h b/providers/implementations/ciphers/cipher_des.h
similarity index 100%
rename from providers/default/ciphers/cipher_des.h
rename to providers/implementations/ciphers/cipher_des.h
diff --git a/providers/default/ciphers/cipher_des_hw.c b/providers/implementations/ciphers/cipher_des_hw.c
similarity index 99%
rename from providers/default/ciphers/cipher_des_hw.c
rename to providers/implementations/ciphers/cipher_des_hw.c
index 78107062a5..c3a67080fd 100644
--- a/providers/default/ciphers/cipher_des_hw.c
+++ b/providers/implementations/ciphers/cipher_des_hw.c
@@ -7,7 +7,7 @@
  * https://www.openssl.org/source/license.html
  */
 
-#include "internal/ciphers/ciphercommon.h"
+#include "prov/ciphercommon.h"
 #include "cipher_des.h"
 
 static int cipher_hw_des_initkey(PROV_CIPHER_CTX *ctx,
diff --git a/providers/default/ciphers/cipher_desx.c b/providers/implementations/ciphers/cipher_desx.c
similarity index 92%
rename from providers/default/ciphers/cipher_desx.c
rename to providers/implementations/ciphers/cipher_desx.c
index 4a232cd080..b8447d2c3f 100644
--- a/providers/default/ciphers/cipher_desx.c
+++ b/providers/implementations/ciphers/cipher_desx.c
@@ -8,7 +8,7 @@
  */
 
 #include "cipher_tdes_default.h"
-#include "internal/provider_algs.h"
+#include "prov/implementations.h"
 
 /* desx_cbc_functions */
 IMPLEMENT_tdes_cipher(desx, DESX, cbc, CBC, TDES_FLAGS, 64*3, 64, 64, block);
diff --git a/providers/default/ciphers/cipher_desx_hw.c b/providers/implementations/ciphers/cipher_desx_hw.c
similarity index 100%
rename from providers/default/ciphers/cipher_desx_hw.c
rename to providers/implementations/ciphers/cipher_desx_hw.c
diff --git a/providers/default/ciphers/cipher_idea.c b/providers/implementations/ciphers/cipher_idea.c
similarity index 97%
rename from providers/default/ciphers/cipher_idea.c
rename to providers/implementations/ciphers/cipher_idea.c
index 6bb5419b6d..5602655f76 100644
--- a/providers/default/ciphers/cipher_idea.c
+++ b/providers/implementations/ciphers/cipher_idea.c
@@ -10,7 +10,7 @@
 /* Dispatch functions for Idea cipher modes ecb, cbc, ofb, cfb */
 
 #include "cipher_idea.h"
-#include "internal/provider_algs.h"
+#include "prov/implementations.h"
 
 static OSSL_OP_cipher_freectx_fn idea_freectx;
 static OSSL_OP_cipher_dupctx_fn idea_dupctx;
diff --git a/providers/default/ciphers/cipher_idea.h b/providers/implementations/ciphers/cipher_idea.h
similarity index 94%
rename from providers/default/ciphers/cipher_idea.h
rename to providers/implementations/ciphers/cipher_idea.h
index 8e096bfe9f..ebe590b93c 100644
--- a/providers/default/ciphers/cipher_idea.h
+++ b/providers/implementations/ciphers/cipher_idea.h
@@ -8,7 +8,7 @@
  */
 
 #include <openssl/idea.h>
-#include "internal/ciphers/ciphercommon.h"
+#include "prov/ciphercommon.h"
 
 typedef struct prov_idea_ctx_st {
     PROV_CIPHER_CTX base;      /* Must be first */
diff --git a/providers/default/ciphers/cipher_idea_hw.c b/providers/implementations/ciphers/cipher_idea_hw.c
similarity index 100%
rename from providers/default/ciphers/cipher_idea_hw.c
rename to providers/implementations/ciphers/cipher_idea_hw.c
diff --git a/providers/default/ciphers/cipher_rc2.c b/providers/implementations/ciphers/cipher_rc2.c
similarity index 99%
rename from providers/default/ciphers/cipher_rc2.c
rename to providers/implementations/ciphers/cipher_rc2.c
index f7ee268276..135c6171ec 100644
--- a/providers/default/ciphers/cipher_rc2.c
+++ b/providers/implementations/ciphers/cipher_rc2.c
@@ -10,8 +10,8 @@
 /* Dispatch functions for RC2 cipher modes ecb, cbc, ofb, cfb */
 
 #include "cipher_rc2.h"
-#include "internal/provider_algs.h"
-#include "internal/providercommonerr.h"
+#include "prov/implementations.h"
+#include "prov/providercommonerr.h"
 
 #define RC2_40_MAGIC    0xa0
 #define RC2_64_MAGIC    0x78
diff --git a/providers/default/ciphers/cipher_rc2.h b/providers/implementations/ciphers/cipher_rc2.h
similarity index 95%
rename from providers/default/ciphers/cipher_rc2.h
rename to providers/implementations/ciphers/cipher_rc2.h
index 7a7928925b..82f0f6ca74 100644
--- a/providers/default/ciphers/cipher_rc2.h
+++ b/providers/implementations/ciphers/cipher_rc2.h
@@ -8,7 +8,7 @@
  */
 
 #include <openssl/rc2.h>
-#include "internal/ciphers/ciphercommon.h"
+#include "prov/ciphercommon.h"
 
 typedef struct prov_rc2_ctx_st {
     PROV_CIPHER_CTX base;      /* Must be first */
diff --git a/providers/default/ciphers/cipher_rc2_hw.c b/providers/implementations/ciphers/cipher_rc2_hw.c
similarity index 100%
rename from providers/default/ciphers/cipher_rc2_hw.c
rename to providers/implementations/ciphers/cipher_rc2_hw.c
diff --git a/providers/default/ciphers/cipher_rc4.c b/providers/implementations/ciphers/cipher_rc4.c
similarity index 99%
rename from providers/default/ciphers/cipher_rc4.c
rename to providers/implementations/ciphers/cipher_rc4.c
index d81b776bc2..c3da8b4397 100644
--- a/providers/default/ciphers/cipher_rc4.c
+++ b/providers/implementations/ciphers/cipher_rc4.c
@@ -10,7 +10,7 @@
 /* Dispatch functions for RC4 ciphers */
 
 #include "cipher_rc4.h"
-#include "internal/provider_algs.h"
+#include "prov/implementations.h"
 
 /* TODO (3.0) Figure out what flags are required */
 #define RC4_FLAGS EVP_CIPH_FLAG_DEFAULT_ASN1
diff --git a/providers/default/ciphers/cipher_rc4.h b/providers/implementations/ciphers/cipher_rc4.h
similarity index 93%
rename from providers/default/ciphers/cipher_rc4.h
rename to providers/implementations/ciphers/cipher_rc4.h
index df61f7c265..a2d0a50f21 100644
--- a/providers/default/ciphers/cipher_rc4.h
+++ b/providers/implementations/ciphers/cipher_rc4.h
@@ -8,7 +8,7 @@
  */
 
 #include <openssl/rc4.h>
-#include "internal/ciphers/ciphercommon.h"
+#include "prov/ciphercommon.h"
 
 typedef struct prov_rc4_ctx_st {
     PROV_CIPHER_CTX base;      /* Must be first */
diff --git a/providers/default/ciphers/cipher_rc4_hw.c b/providers/implementations/ciphers/cipher_rc4_hw.c
similarity index 100%
rename from providers/default/ciphers/cipher_rc4_hw.c
rename to providers/implementations/ciphers/cipher_rc4_hw.c
diff --git a/providers/default/ciphers/cipher_rc5.c b/providers/implementations/ciphers/cipher_rc5.c
similarity index 98%
rename from providers/default/ciphers/cipher_rc5.c
rename to providers/implementations/ciphers/cipher_rc5.c
index 645a6b8b64..7f5780f062 100644
--- a/providers/default/ciphers/cipher_rc5.c
+++ b/providers/implementations/ciphers/cipher_rc5.c
@@ -10,8 +10,8 @@
 /* Dispatch functions for RC5 cipher modes ecb, cbc, ofb, cfb */
 
 #include "cipher_rc5.h"
-#include "internal/provider_algs.h"
-#include "internal/providercommonerr.h"
+#include "prov/implementations.h"
+#include "prov/providercommonerr.h"
 
 static OSSL_OP_cipher_freectx_fn rc5_freectx;
 static OSSL_OP_cipher_dupctx_fn rc5_dupctx;
diff --git a/providers/default/ciphers/cipher_rc5.h b/providers/implementations/ciphers/cipher_rc5.h
similarity index 95%
rename from providers/default/ciphers/cipher_rc5.h
rename to providers/implementations/ciphers/cipher_rc5.h
index c415e18c59..fe0d09f710 100644
--- a/providers/default/ciphers/cipher_rc5.h
+++ b/providers/implementations/ciphers/cipher_rc5.h
@@ -8,7 +8,7 @@
  */
 
 #include <openssl/rc5.h>
-#include "internal/ciphers/ciphercommon.h"
+#include "prov/ciphercommon.h"
 
 typedef struct prov_blowfish_ctx_st {
     PROV_CIPHER_CTX base;      /* Must be first */
diff --git a/providers/default/ciphers/cipher_rc5_hw.c b/providers/implementations/ciphers/cipher_rc5_hw.c
similarity index 100%
rename from providers/default/ciphers/cipher_rc5_hw.c
rename to providers/implementations/ciphers/cipher_rc5_hw.c
diff --git a/providers/default/ciphers/cipher_seed.c b/providers/implementations/ciphers/cipher_seed.c
similarity index 97%
rename from providers/default/ciphers/cipher_seed.c
rename to providers/implementations/ciphers/cipher_seed.c
index 397671dd06..ee90669fda 100644
--- a/providers/default/ciphers/cipher_seed.c
+++ b/providers/implementations/ciphers/cipher_seed.c
@@ -10,7 +10,7 @@
 /* Dispatch functions for Seed cipher modes ecb, cbc, ofb, cfb */
 
 #include "cipher_seed.h"
-#include "internal/provider_algs.h"
+#include "prov/implementations.h"
 
 static OSSL_OP_cipher_freectx_fn seed_freectx;
 static OSSL_OP_cipher_dupctx_fn seed_dupctx;
diff --git a/providers/default/ciphers/cipher_seed.h b/providers/implementations/ciphers/cipher_seed.h
similarity index 94%
rename from providers/default/ciphers/cipher_seed.h
rename to providers/implementations/ciphers/cipher_seed.h
index 093cd3bb5d..976af35005 100644
--- a/providers/default/ciphers/cipher_seed.h
+++ b/providers/implementations/ciphers/cipher_seed.h
@@ -8,7 +8,7 @@
  */
 
 #include <openssl/seed.h>
-#include "internal/ciphers/ciphercommon.h"
+#include "prov/ciphercommon.h"
 
 typedef struct prov_seed_ctx_st {
     PROV_CIPHER_CTX base;      /* Must be first */
diff --git a/providers/default/ciphers/cipher_seed_hw.c b/providers/implementations/ciphers/cipher_seed_hw.c
similarity index 100%
rename from providers/default/ciphers/cipher_seed_hw.c
rename to providers/implementations/ciphers/cipher_seed_hw.c
diff --git a/providers/default/ciphers/cipher_sm4.c b/providers/implementations/ciphers/cipher_sm4.c
similarity index 97%
rename from providers/default/ciphers/cipher_sm4.c
rename to providers/implementations/ciphers/cipher_sm4.c
index 2c1e587863..bf9d220923 100644
--- a/providers/default/ciphers/cipher_sm4.c
+++ b/providers/implementations/ciphers/cipher_sm4.c
@@ -10,7 +10,7 @@
 /* Dispatch functions for cast cipher modes ecb, cbc, ofb, cfb */
 
 #include "cipher_sm4.h"
-#include "internal/provider_algs.h"
+#include "prov/implementations.h"
 
 static OSSL_OP_cipher_freectx_fn sm4_freectx;
 static OSSL_OP_cipher_dupctx_fn sm4_dupctx;
diff --git a/providers/default/ciphers/cipher_sm4.h b/providers/implementations/ciphers/cipher_sm4.h
similarity index 95%
rename from providers/default/ciphers/cipher_sm4.h
rename to providers/implementations/ciphers/cipher_sm4.h
index 4740bb3355..d5c9633552 100644
--- a/providers/default/ciphers/cipher_sm4.h
+++ b/providers/implementations/ciphers/cipher_sm4.h
@@ -7,7 +7,7 @@
  * https://www.openssl.org/source/license.html
  */
 
-#include "internal/ciphers/ciphercommon.h"
+#include "prov/ciphercommon.h"
 #include "crypto/sm4.h"
 
 typedef struct prov_cast_ctx_st {
diff --git a/providers/default/ciphers/cipher_sm4_hw.c b/providers/implementations/ciphers/cipher_sm4_hw.c
similarity index 100%
rename from providers/default/ciphers/cipher_sm4_hw.c
rename to providers/implementations/ciphers/cipher_sm4_hw.c
diff --git a/providers/common/ciphers/cipher_tdes.c b/providers/implementations/ciphers/cipher_tdes.c
similarity index 95%
rename from providers/common/ciphers/cipher_tdes.c
rename to providers/implementations/ciphers/cipher_tdes.c
index e5fa16358c..e6dab582ca 100644
--- a/providers/common/ciphers/cipher_tdes.c
+++ b/providers/implementations/ciphers/cipher_tdes.c
@@ -7,11 +7,11 @@
  * https://www.openssl.org/source/license.html
  */
 
-#include "cipher_local.h"
-#include "internal/ciphers/cipher_tdes.h"
+#include "prov/ciphercommon.h"
+#include "cipher_tdes.h"
 #include "crypto/rand.h"
-#include "internal/provider_algs.h"
-#include "internal/providercommonerr.h"
+#include "prov/implementations.h"
+#include "prov/providercommonerr.h"
 
 void *tdes_newctx(void *provctx, int mode, size_t kbits, size_t blkbits,
                   size_t ivbits, uint64_t flags, const PROV_CIPHER_HW *hw)
diff --git a/providers/common/include/internal/ciphers/cipher_tdes.h b/providers/implementations/ciphers/cipher_tdes.h
similarity index 100%
rename from providers/common/include/internal/ciphers/cipher_tdes.h
rename to providers/implementations/ciphers/cipher_tdes.h
diff --git a/providers/default/ciphers/cipher_tdes_default.c b/providers/implementations/ciphers/cipher_tdes_default.c
similarity index 97%
rename from providers/default/ciphers/cipher_tdes_default.c
rename to providers/implementations/ciphers/cipher_tdes_default.c
index 73a78e8089..9aefef26b6 100644
--- a/providers/default/ciphers/cipher_tdes_default.c
+++ b/providers/implementations/ciphers/cipher_tdes_default.c
@@ -8,7 +8,7 @@
  */
 
 #include "cipher_tdes_default.h"
-#include "internal/provider_algs.h"
+#include "prov/implementations.h"
 
 /* tdes_ede3_ofb_functions */
 IMPLEMENT_tdes_cipher(ede3, EDE3,  ofb, OFB, TDES_FLAGS, 64*3,  8, 64, stream);
diff --git a/providers/default/ciphers/cipher_tdes_default.h b/providers/implementations/ciphers/cipher_tdes_default.h
similarity index 91%
rename from providers/default/ciphers/cipher_tdes_default.h
rename to providers/implementations/ciphers/cipher_tdes_default.h
index c809993795..0bc499fc86 100644
--- a/providers/default/ciphers/cipher_tdes_default.h
+++ b/providers/implementations/ciphers/cipher_tdes_default.h
@@ -7,8 +7,8 @@
  * https://www.openssl.org/source/license.html
  */
 
-#include "internal/ciphers/ciphercommon.h"
-#include "internal/ciphers/cipher_tdes.h"
+#include "prov/ciphercommon.h"
+#include "cipher_tdes.h"
 
 const PROV_CIPHER_HW *PROV_CIPHER_HW_tdes_ede3_ofb(void);
 const PROV_CIPHER_HW *PROV_CIPHER_HW_tdes_ede3_cfb(void);
diff --git a/providers/default/ciphers/cipher_tdes_default_hw.c b/providers/implementations/ciphers/cipher_tdes_default_hw.c
similarity index 100%
rename from providers/default/ciphers/cipher_tdes_default_hw.c
rename to providers/implementations/ciphers/cipher_tdes_default_hw.c
diff --git a/providers/common/ciphers/cipher_tdes_hw.c b/providers/implementations/ciphers/cipher_tdes_hw.c
similarity index 97%
rename from providers/common/ciphers/cipher_tdes_hw.c
rename to providers/implementations/ciphers/cipher_tdes_hw.c
index 10ba5a24da..208e83df0f 100644
--- a/providers/common/ciphers/cipher_tdes_hw.c
+++ b/providers/implementations/ciphers/cipher_tdes_hw.c
@@ -7,8 +7,8 @@
  * https://www.openssl.org/source/license.html
  */
 
-#include "cipher_local.h"
-#include "internal/ciphers/cipher_tdes.h"
+#include "prov/ciphercommon.h"
+#include "cipher_tdes.h"
 
 #define ks1 tks.ks[0]
 #define ks2 tks.ks[1]
diff --git a/providers/default/ciphers/cipher_tdes_wrap.c b/providers/implementations/ciphers/cipher_tdes_wrap.c
similarity index 99%
rename from providers/default/ciphers/cipher_tdes_wrap.c
rename to providers/implementations/ciphers/cipher_tdes_wrap.c
index 1ee0044489..75cc25df06 100644
--- a/providers/default/ciphers/cipher_tdes_wrap.c
+++ b/providers/implementations/ciphers/cipher_tdes_wrap.c
@@ -11,8 +11,8 @@
 #include "cipher_tdes_default.h"
 #include "crypto/evp.h"
 #include "crypto/rand.h"
-#include "internal/provider_algs.h"
-#include "internal/providercommonerr.h"
+#include "prov/implementations.h"
+#include "prov/providercommonerr.h"
 
 /* TODO (3.0) Figure out what flags are requred */
 #define TDES_WRAP_FLAGS (EVP_CIPH_WRAP_MODE             \
diff --git a/providers/default/ciphers/cipher_tdes_wrap_hw.c b/providers/implementations/ciphers/cipher_tdes_wrap_hw.c
similarity index 100%
rename from providers/default/ciphers/cipher_tdes_wrap_hw.c
rename to providers/implementations/ciphers/cipher_tdes_wrap_hw.c
diff --git a/providers/default/digests/blake2_impl.h b/providers/implementations/digests/blake2_impl.h
similarity index 100%
rename from providers/default/digests/blake2_impl.h
rename to providers/implementations/digests/blake2_impl.h
diff --git a/providers/default/digests/blake2_prov.c b/providers/implementations/digests/blake2_prov.c
similarity index 92%
rename from providers/default/digests/blake2_prov.c
rename to providers/implementations/digests/blake2_prov.c
index f299fb289d..1fe7cb18fc 100644
--- a/providers/default/digests/blake2_prov.c
+++ b/providers/implementations/digests/blake2_prov.c
@@ -8,9 +8,9 @@
  */
 
 #include <openssl/crypto.h>
-#include "internal/blake2.h"
-#include "internal/digestcommon.h"
-#include "internal/provider_algs.h"
+#include "prov/blake2.h"
+#include "prov/digestcommon.h"
+#include "prov/implementations.h"
 
 OSSL_OP_digest_init_fn blake2s256_init;
 OSSL_OP_digest_init_fn blake2b512_init;
diff --git a/providers/default/digests/blake2b_prov.c b/providers/implementations/digests/blake2b_prov.c
similarity index 99%
rename from providers/default/digests/blake2b_prov.c
rename to providers/implementations/digests/blake2b_prov.c
index 2f8081268e..baa33e922f 100644
--- a/providers/default/digests/blake2b_prov.c
+++ b/providers/implementations/digests/blake2b_prov.c
@@ -18,7 +18,7 @@
 #include <string.h>
 #include <openssl/crypto.h>
 #include "blake2_impl.h"
-#include "internal/blake2.h"
+#include "prov/blake2.h"
 
 static const uint64_t blake2b_IV[8] =
 {
diff --git a/providers/default/digests/blake2s_prov.c b/providers/implementations/digests/blake2s_prov.c
similarity index 99%
rename from providers/default/digests/blake2s_prov.c
rename to providers/implementations/digests/blake2s_prov.c
index a9c757ea62..703d8a8fab 100644
--- a/providers/default/digests/blake2s_prov.c
+++ b/providers/implementations/digests/blake2s_prov.c
@@ -18,7 +18,7 @@
 #include <string.h>
 #include <openssl/crypto.h>
 #include "blake2_impl.h"
-#include "internal/blake2.h"
+#include "prov/blake2.h"
 
 static const uint32_t blake2s_IV[8] =
 {
diff --git a/providers/implementations/digests/build.info b/providers/implementations/digests/build.info
new file mode 100644
index 0000000000..2026de95d7
--- /dev/null
+++ b/providers/implementations/digests/build.info
@@ -0,0 +1,52 @@
+# We make separate GOAL variables for each algorithm, to make it easy to
+# switch each to the Legacy provider when needed.
+
+$SHA1_GOAL=../../libimplementations.a
+$SHA2_GOAL=../../libimplementations.a
+$SHA3_GOAL=../../libimplementations.a
+$BLAKE2_GOAL=../../libimplementations.a
+$SM3_GOAL=../../libimplementations.a
+$MD5_GOAL=../../libimplementations.a
+
+$MD2_GOAL=../../liblegacy.a
+$MD4_GOAL=../../liblegacy.a
+$MDC2_GOAL=../../liblegacy.a
+$WHIRLPOOL_GOAL=../../liblegacy.a
+$RIPEMD_GOAL=../../liblegacy.a
+
+SOURCE[$SHA2_GOAL]=sha2_prov.c
+SOURCE[$SHA3_GOAL]=sha3_prov.c
+
+$GOAL=../../libimplementations.a
+
+IF[{- !$disabled{blake2} -}]
+  SOURCE[$BLAKE2_GOAL]=blake2_prov.c blake2b_prov.c blake2s_prov.c
+ENDIF
+
+IF[{- !$disabled{sm3} -}]
+  SOURCE[$SM3_GOAL]=sm3_prov.c
+ENDIF
+
+IF[{- !$disabled{md5} -}]
+  SOURCE[$MD5_GOAL]=md5_prov.c md5_sha1_prov.c
+ENDIF
+
+IF[{- !$disabled{md2} -}]
+  SOURCE[$MD2_GOAL]=md2_prov.c
+ENDIF
+
+IF[{- !$disabled{md4} -}]
+  SOURCE[$MD4_GOAL]=md4_prov.c
+ENDIF
+
+IF[{- !$disabled{mdc2} -}]
+  SOURCE[$MDC2_GOAL]=mdc2_prov.c
+ENDIF
+
+IF[{- !$disabled{whirlpool} -}]
+  SOURCE[$WHIRLPOOL_GOAL]=wp_prov.c
+ENDIF
+
+IF[{- !$disabled{rmd160} -}]
+  SOURCE[$RIPEMD_GOAL]=ripemd_prov.c
+ENDIF
diff --git a/providers/legacy/digests/md2_prov.c b/providers/implementations/digests/md2_prov.c
similarity index 88%
rename from providers/legacy/digests/md2_prov.c
rename to providers/implementations/digests/md2_prov.c
index 2a4439d26c..6e12e3c172 100644
--- a/providers/legacy/digests/md2_prov.c
+++ b/providers/implementations/digests/md2_prov.c
@@ -9,8 +9,8 @@
 
 #include <openssl/crypto.h>
 #include <openssl/md2.h>
-#include "internal/digestcommon.h"
-#include "internal/provider_algs.h"
+#include "prov/digestcommon.h"
+#include "prov/implementations.h"
 
 /* md2_functions */
 IMPLEMENT_digest_functions(md2, MD2_CTX,
diff --git a/providers/legacy/digests/md4_prov.c b/providers/implementations/digests/md4_prov.c
similarity index 88%
rename from providers/legacy/digests/md4_prov.c
rename to providers/implementations/digests/md4_prov.c
index 8486b7b48d..3ce356a58f 100644
--- a/providers/legacy/digests/md4_prov.c
+++ b/providers/implementations/digests/md4_prov.c
@@ -9,8 +9,8 @@
 
 #include <openssl/crypto.h>
 #include <openssl/md4.h>
-#include "internal/digestcommon.h"
-#include "internal/provider_algs.h"
+#include "prov/digestcommon.h"
+#include "prov/implementations.h"
 
 /* md4_functions */
 IMPLEMENT_digest_functions(md4, MD4_CTX,
diff --git a/providers/default/digests/md5_prov.c b/providers/implementations/digests/md5_prov.c
similarity index 88%
rename from providers/default/digests/md5_prov.c
rename to providers/implementations/digests/md5_prov.c
index c688bebac0..7b92b6139c 100644
--- a/providers/default/digests/md5_prov.c
+++ b/providers/implementations/digests/md5_prov.c
@@ -9,8 +9,8 @@
 
 #include <openssl/crypto.h>
 #include <openssl/md5.h>
-#include "internal/digestcommon.h"
-#include "internal/provider_algs.h"
+#include "prov/digestcommon.h"
+#include "prov/implementations.h"
 
 /* md5_functions */
 IMPLEMENT_digest_functions(md5, MD5_CTX,
diff --git a/providers/default/digests/md5_sha1_prov.c b/providers/implementations/digests/md5_sha1_prov.c
similarity index 94%
rename from providers/default/digests/md5_sha1_prov.c
rename to providers/implementations/digests/md5_sha1_prov.c
index 7f224cba4f..09c502d839 100644
--- a/providers/default/digests/md5_sha1_prov.c
+++ b/providers/implementations/digests/md5_sha1_prov.c
@@ -12,9 +12,9 @@
 #include <openssl/evp.h>
 #include <openssl/params.h>
 #include <openssl/core_names.h>
-#include "internal/md5_sha1.h"
-#include "internal/digestcommon.h"
-#include "internal/provider_algs.h"
+#include "prov/md5_sha1.h"
+#include "prov/digestcommon.h"
+#include "prov/implementations.h"
 
 static OSSL_OP_digest_set_ctx_params_fn md5_sha1_set_ctx_params;
 static OSSL_OP_digest_settable_ctx_params_fn md5_sha1_settable_ctx_params;
diff --git a/providers/legacy/digests/mdc2_prov.c b/providers/implementations/digests/mdc2_prov.c
similarity index 93%
rename from providers/legacy/digests/mdc2_prov.c
rename to providers/implementations/digests/mdc2_prov.c
index cf37b528e7..4a7d3a43ab 100644
--- a/providers/legacy/digests/mdc2_prov.c
+++ b/providers/implementations/digests/mdc2_prov.c
@@ -12,9 +12,9 @@
 #include <openssl/mdc2.h>
 #include <openssl/core_names.h>
 #include <openssl/err.h>
-#include "internal/digestcommon.h"
-#include "internal/provider_algs.h"
-#include "internal/providercommonerr.h"
+#include "prov/digestcommon.h"
+#include "prov/implementations.h"
+#include "prov/providercommonerr.h"
 
 static OSSL_OP_digest_set_ctx_params_fn mdc2_set_ctx_params;
 static OSSL_OP_digest_settable_ctx_params_fn mdc2_settable_ctx_params;
diff --git a/providers/legacy/digests/ripemd_prov.c b/providers/implementations/digests/ripemd_prov.c
similarity index 89%
rename from providers/legacy/digests/ripemd_prov.c
rename to providers/implementations/digests/ripemd_prov.c
index 314b69a3fb..023e46cf83 100644
--- a/providers/legacy/digests/ripemd_prov.c
+++ b/providers/implementations/digests/ripemd_prov.c
@@ -9,8 +9,8 @@
 
 #include <openssl/crypto.h>
 #include <openssl/ripemd.h>
-#include "internal/digestcommon.h"
-#include "internal/provider_algs.h"
+#include "prov/digestcommon.h"
+#include "prov/implementations.h"
 
 /* ripemd160_functions */
 IMPLEMENT_digest_functions(ripemd160, RIPEMD160_CTX,
diff --git a/providers/common/digests/sha2_prov.c b/providers/implementations/digests/sha2_prov.c
similarity index 97%
rename from providers/common/digests/sha2_prov.c
rename to providers/implementations/digests/sha2_prov.c
index d2c7df2ee6..8055ce5ad2 100644
--- a/providers/common/digests/sha2_prov.c
+++ b/providers/implementations/digests/sha2_prov.c
@@ -14,8 +14,8 @@
 #include <openssl/evp.h>
 #include <openssl/params.h>
 #include <openssl/core_names.h>
-#include "internal/digestcommon.h"
-#include "internal/provider_algs.h"
+#include "prov/digestcommon.h"
+#include "prov/implementations.h"
 #include "crypto/sha.h"
 
 static OSSL_OP_digest_set_ctx_params_fn sha1_set_ctx_params;
diff --git a/providers/common/digests/sha3_prov.c b/providers/implementations/digests/sha3_prov.c
similarity index 99%
rename from providers/common/digests/sha3_prov.c
rename to providers/implementations/digests/sha3_prov.c
index 0563d0cfc1..251039e992 100644
--- a/providers/common/digests/sha3_prov.c
+++ b/providers/implementations/digests/sha3_prov.c
@@ -14,9 +14,9 @@
 #include <openssl/params.h>
 #include <openssl/err.h>
 #include "internal/sha3.h"
-#include "internal/digestcommon.h"
-#include "internal/provider_algs.h"
-#include "internal/providercommonerr.h"
+#include "prov/digestcommon.h"
+#include "prov/implementations.h"
+#include "prov/providercommonerr.h"
 
 /*
  * Forward declaration of any unique methods implemented here. This is not strictly
diff --git a/providers/default/digests/sm3_prov.c b/providers/implementations/digests/sm3_prov.c
similarity index 88%
rename from providers/default/digests/sm3_prov.c
rename to providers/implementations/digests/sm3_prov.c
index 512e3cb1c1..88e65d1537 100644
--- a/providers/default/digests/sm3_prov.c
+++ b/providers/implementations/digests/sm3_prov.c
@@ -9,8 +9,8 @@
 
 #include <openssl/crypto.h>
 #include "internal/sm3.h"
-#include "internal/digestcommon.h"
-#include "internal/provider_algs.h"
+#include "prov/digestcommon.h"
+#include "prov/implementations.h"
 
 /* sm3_functions */
 IMPLEMENT_digest_functions(sm3, SM3_CTX,
diff --git a/providers/legacy/digests/wp_prov.c b/providers/implementations/digests/wp_prov.c
similarity index 89%
rename from providers/legacy/digests/wp_prov.c
rename to providers/implementations/digests/wp_prov.c
index eaa41b0af1..75fcc0dffc 100644
--- a/providers/legacy/digests/wp_prov.c
+++ b/providers/implementations/digests/wp_prov.c
@@ -9,8 +9,8 @@
 
 #include <openssl/crypto.h>
 #include <openssl/whrlpool.h>
-#include "internal/digestcommon.h"
-#include "internal/provider_algs.h"
+#include "prov/digestcommon.h"
+#include "prov/implementations.h"
 
 /* wp_functions */
 IMPLEMENT_digest_functions(wp, WHIRLPOOL_CTX,
diff --git a/providers/implementations/exchange/build.info b/providers/implementations/exchange/build.info
new file mode 100644
index 0000000000..fdedb86c03
--- /dev/null
+++ b/providers/implementations/exchange/build.info
@@ -0,0 +1,8 @@
+# We make separate GOAL variables for each algorithm, to make it easy to
+# switch each to the Legacy provider when needed.
+
+$DH_GOAL=../../libimplementations.a
+
+IF[{- !$disabled{dh} -}]
+  SOURCE[$DH_GOAL]=dh_exch.c
+ENDIF
diff --git a/providers/common/exchange/dh_exch.c b/providers/implementations/exchange/dh_exch.c
similarity index 99%
rename from providers/common/exchange/dh_exch.c
rename to providers/implementations/exchange/dh_exch.c
index cfbda43fb8..1b16a83245 100644
--- a/providers/common/exchange/dh_exch.c
+++ b/providers/implementations/exchange/dh_exch.c
@@ -12,7 +12,7 @@
 #include <openssl/core_names.h>
 #include <openssl/dh.h>
 #include <openssl/params.h>
-#include "internal/provider_algs.h"
+#include "prov/implementations.h"
 
 static OSSL_OP_keyexch_newctx_fn dh_newctx;
 static OSSL_OP_keyexch_init_fn dh_init;
diff --git a/providers/default/include/internal/blake2.h b/providers/implementations/include/prov/blake2.h
similarity index 100%
rename from providers/default/include/internal/blake2.h
rename to providers/implementations/include/prov/blake2.h
diff --git a/providers/common/include/internal/provider_algs.h b/providers/implementations/include/prov/implementations.h
similarity index 100%
rename from providers/common/include/internal/provider_algs.h
rename to providers/implementations/include/prov/implementations.h
diff --git a/providers/default/include/internal/md5_sha1.h b/providers/implementations/include/prov/md5_sha1.h
similarity index 100%
rename from providers/default/include/internal/md5_sha1.h
rename to providers/implementations/include/prov/md5_sha1.h
diff --git a/providers/implementations/kdfs/build.info b/providers/implementations/kdfs/build.info
new file mode 100644
index 0000000000..dee8f532fa
--- /dev/null
+++ b/providers/implementations/kdfs/build.info
@@ -0,0 +1,29 @@
+# We make separate GOAL variables for each algorithm, to make it easy to
+# switch each to the Legacy provider when needed.
+
+$TLS1_PRF_GOAL=../../libimplementations.a
+$HKDF_GOAL=../../libimplementations.a
+$KBKDF_GOAL=../../libimplementations.a
+$PBKDF2_GOAL=../../libimplementations.a
+$SSKDF_GOAL=../../libimplementations.a
+$SCRYPT_GOAL=../../libimplementations.a
+$SSHKDF_GOAL=../../libimplementations.a
+$X942KDF_GOAL=../../libimplementations.a
+
+SOURCE[$TLS1_PRF_GOAL]=tls1_prf.c
+
+SOURCE[$HKDF_GOAL]=hkdf.c
+
+SOURCE[$KBKDF_GOAL]=kbkdf.c
+
+SOURCE[$PBKDF2_GOAL]=pbkdf2.c
+# Extra code to satisfy the FIPS and non-FIPS separation.
+# When the PBKDF2 moves to legacy, this can be removed.
+SOURCE[../../libfips.a]=pbkdf2_fips.c
+SOURCE[../../libnonfips.a]=pbkdf2_fips.c
+
+SOURCE[$SSKDF_GOAL]=sskdf.c
+
+SOURCE[$SCRYPT_GOAL]=scrypt.c
+SOURCE[$SSHKDF_GOAL]=sshkdf.c
+SOURCE[$X942KDF_GOAL]=x942kdf.c
diff --git a/providers/common/kdfs/hkdf.c b/providers/implementations/kdfs/hkdf.c
similarity index 98%
rename from providers/common/kdfs/hkdf.c
rename to providers/implementations/kdfs/hkdf.c
index 041811f0e1..66d70635a6 100644
--- a/providers/common/kdfs/hkdf.c
+++ b/providers/implementations/kdfs/hkdf.c
@@ -17,10 +17,10 @@
 #include "internal/cryptlib.h"
 #include "internal/numbers.h"
 #include "crypto/evp.h"
-#include "internal/provider_ctx.h"
-#include "internal/providercommonerr.h"
-#include "internal/provider_algs.h"
-#include "internal/provider_util.h"
+#include "prov/provider_ctx.h"
+#include "prov/providercommonerr.h"
+#include "prov/implementations.h"
+#include "prov/provider_util.h"
 #include "e_os.h"
 
 #define HKDF_MAXBUF 1024
diff --git a/providers/common/kdfs/kbkdf.c b/providers/implementations/kdfs/kbkdf.c
similarity index 98%
rename from providers/common/kdfs/kbkdf.c
rename to providers/implementations/kdfs/kbkdf.c
index ffffef0b17..6faf22e8d2 100644
--- a/providers/common/kdfs/kbkdf.c
+++ b/providers/implementations/kdfs/kbkdf.c
@@ -37,10 +37,10 @@
 #include "internal/cryptlib.h"
 #include "crypto/evp.h"
 #include "internal/numbers.h"
-#include "internal/provider_algs.h"
-#include "internal/provider_ctx.h"
-#include "internal/provider_util.h"
-#include "internal/providercommonerr.h"
+#include "prov/implementations.h"
+#include "prov/provider_ctx.h"
+#include "prov/provider_util.h"
+#include "prov/providercommonerr.h"
 
 #include "e_os.h"
 
diff --git a/providers/common/kdfs/pbkdf2.c b/providers/implementations/kdfs/pbkdf2.c
similarity index 96%
rename from providers/common/kdfs/pbkdf2.c
rename to providers/implementations/kdfs/pbkdf2.c
index b98123b872..f08063fab5 100644
--- a/providers/common/kdfs/pbkdf2.c
+++ b/providers/implementations/kdfs/pbkdf2.c
@@ -17,25 +17,17 @@
 #include "internal/cryptlib.h"
 #include "internal/numbers.h"
 #include "crypto/evp.h"
-#include "internal/provider_ctx.h"
-#include "internal/providercommonerr.h"
-#include "internal/provider_algs.h"
-#include "internal/provider_util.h"
+#include "prov/provider_ctx.h"
+#include "prov/providercommonerr.h"
+#include "prov/implementations.h"
+#include "prov/provider_util.h"
+#include "pbkdf2.h"
 
 /* Constants specified in SP800-132 */
 #define KDF_PBKDF2_MIN_KEY_LEN_BITS  112
 #define KDF_PBKDF2_MAX_KEY_LEN_DIGEST_RATIO 0xFFFFFFFF
 #define KDF_PBKDF2_MIN_ITERATIONS 1000
 #define KDF_PBKDF2_MIN_SALT_LEN   (128 / 8)
-/*
- * For backwards compatibility reasons,
- * Extra checks are done by default in fips mode only.
- */
-#ifdef FIPS_MODE
-# define KDF_PBKDF2_DEFAULT_CHECKS 1
-#else
-# define KDF_PBKDF2_DEFAULT_CHECKS 0
-#endif /* FIPS_MODE */
 
 static OSSL_OP_kdf_newctx_fn kdf_pbkdf2_new;
 static OSSL_OP_kdf_freectx_fn kdf_pbkdf2_free;
@@ -111,7 +103,7 @@ static void kdf_pbkdf2_init(KDF_PBKDF2 *ctx)
         /* This is an error, but there is no way to indicate such directly */
         ossl_prov_digest_reset(&ctx->digest);
     ctx->iter = PKCS5_DEFAULT_ITER;
-    ctx->lower_bound_checks = KDF_PBKDF2_DEFAULT_CHECKS;
+    ctx->lower_bound_checks = kdf_pbkdf2_default_checks;
 }
 
 static int pbkdf2_set_membuf(unsigned char **buffer, size_t *buflen,
diff --git a/providers/common/include/internal/provider_ctx.h b/providers/implementations/kdfs/pbkdf2.h
similarity index 68%
copy from providers/common/include/internal/provider_ctx.h
copy to providers/implementations/kdfs/pbkdf2.h
index 365667d19e..c8c2e5b8a7 100644
--- a/providers/common/include/internal/provider_ctx.h
+++ b/providers/implementations/kdfs/pbkdf2.h
@@ -8,7 +8,7 @@
  */
 
 /*
- * To be used anywhere the library context needs to be passed, such as to
- * fetching functions.
+ * Available in pbkdfe_fips.c, and compiled with different values depending
+ * on we're in the FIPS module or not.
  */
-#define PROV_LIBRARY_CONTEXT_OF(provctx)        (provctx)
+extern const int kdf_pbkdf2_default_checks;
diff --git a/providers/common/include/internal/provider_ctx.h b/providers/implementations/kdfs/pbkdf2_fips.c
similarity index 58%
rename from providers/common/include/internal/provider_ctx.h
rename to providers/implementations/kdfs/pbkdf2_fips.c
index 365667d19e..d33782b24c 100644
--- a/providers/common/include/internal/provider_ctx.h
+++ b/providers/implementations/kdfs/pbkdf2_fips.c
@@ -7,8 +7,14 @@
  * https://www.openssl.org/source/license.html
  */
 
+#include "pbkdf2.h"
+
 /*
- * To be used anywhere the library context needs to be passed, such as to
- * fetching functions.
+ * For backwards compatibility reasons,
+ * Extra checks are done by default in fips mode only.
  */
-#define PROV_LIBRARY_CONTEXT_OF(provctx)        (provctx)
+#ifdef FIPS_MODE
+const int kdf_pbkdf2_default_checks = 1;
+#else
+const int kdf_pbkdf2_default_checks = 0;
+#endif /* FIPS_MODE */
diff --git a/providers/default/kdfs/scrypt.c b/providers/implementations/kdfs/scrypt.c
similarity index 98%
rename from providers/default/kdfs/scrypt.c
rename to providers/implementations/kdfs/scrypt.c
index 505963eec5..a067a9a91c 100644
--- a/providers/default/kdfs/scrypt.c
+++ b/providers/implementations/kdfs/scrypt.c
@@ -16,10 +16,10 @@
 #include <openssl/core_names.h>
 #include "crypto/evp.h"
 #include "internal/numbers.h"
-#include "internal/provider_algs.h"
-#include "internal/provider_ctx.h"
-#include "internal/providercommonerr.h"
-#include "internal/provider_algs.h"
+#include "prov/implementations.h"
+#include "prov/provider_ctx.h"
+#include "prov/providercommonerr.h"
+#include "prov/implementations.h"
 
 #ifndef OPENSSL_NO_SCRYPT
 
diff --git a/providers/default/kdfs/sshkdf.c b/providers/implementations/kdfs/sshkdf.c
similarity index 98%
rename from providers/default/kdfs/sshkdf.c
rename to providers/implementations/kdfs/sshkdf.c
index 7e6445dbdd..d5484f4acb 100644
--- a/providers/default/kdfs/sshkdf.c
+++ b/providers/implementations/kdfs/sshkdf.c
@@ -16,10 +16,10 @@
 #include "internal/cryptlib.h"
 #include "internal/numbers.h"
 #include "crypto/evp.h"
-#include "internal/provider_ctx.h"
-#include "internal/providercommonerr.h"
-#include "internal/provider_algs.h"
-# include "internal/provider_util.h"
+#include "prov/provider_ctx.h"
+#include "prov/providercommonerr.h"
+#include "prov/implementations.h"
+# include "prov/provider_util.h"
 
 /* See RFC 4253, Section 7.2 */
 static OSSL_OP_kdf_newctx_fn kdf_sshkdf_new;
diff --git a/providers/common/kdfs/sskdf.c b/providers/implementations/kdfs/sskdf.c
similarity index 99%
rename from providers/common/kdfs/sskdf.c
rename to providers/implementations/kdfs/sskdf.c
index 1e538a9c0a..4f69eec7f6 100644
--- a/providers/common/kdfs/sskdf.c
+++ b/providers/implementations/kdfs/sskdf.c
@@ -45,10 +45,10 @@
 #include "internal/cryptlib.h"
 #include "internal/numbers.h"
 #include "crypto/evp.h"
-#include "internal/provider_ctx.h"
-#include "internal/providercommonerr.h"
-#include "internal/provider_algs.h"
-#include "internal/provider_util.h"
+#include "prov/provider_ctx.h"
+#include "prov/providercommonerr.h"
+#include "prov/implementations.h"
+#include "prov/provider_util.h"
 
 typedef struct {
     void *provctx;
diff --git a/providers/common/kdfs/tls1_prf.c b/providers/implementations/kdfs/tls1_prf.c
similarity index 98%
rename from providers/common/kdfs/tls1_prf.c
rename to providers/implementations/kdfs/tls1_prf.c
index af49b1b044..0a83753a8a 100644
--- a/providers/common/kdfs/tls1_prf.c
+++ b/providers/implementations/kdfs/tls1_prf.c
@@ -55,10 +55,10 @@
 #include "internal/cryptlib.h"
 #include "internal/numbers.h"
 #include "crypto/evp.h"
-#include "internal/provider_ctx.h"
-#include "internal/providercommonerr.h"
-#include "internal/provider_algs.h"
-#include "internal/provider_util.h"
+#include "prov/provider_ctx.h"
+#include "prov/providercommonerr.h"
+#include "prov/implementations.h"
+#include "prov/provider_util.h"
 #include "e_os.h"
 
 static OSSL_OP_kdf_newctx_fn kdf_tls1_prf_new;
diff --git a/providers/default/kdfs/x942kdf.c b/providers/implementations/kdfs/x942kdf.c
similarity index 98%
rename from providers/default/kdfs/x942kdf.c
rename to providers/implementations/kdfs/x942kdf.c
index 65c586fb99..5a84d50968 100644
--- a/providers/default/kdfs/x942kdf.c
+++ b/providers/implementations/kdfs/x942kdf.c
@@ -25,10 +25,10 @@
 # include "internal/cryptlib.h"
 # include "internal/numbers.h"
 # include "crypto/evp.h"
-# include "internal/provider_ctx.h"
-# include "internal/providercommonerr.h"
-# include "internal/provider_algs.h"
-# include "internal/provider_util.h"
+# include "prov/provider_ctx.h"
+# include "prov/providercommonerr.h"
+# include "prov/implementations.h"
+# include "prov/provider_util.h"
 
 # define X942KDF_MAX_INLEN (1 << 30)
 
diff --git a/providers/implementations/keymgmt/build.info b/providers/implementations/keymgmt/build.info
new file mode 100644
index 0000000000..dc6039b02d
--- /dev/null
+++ b/providers/implementations/keymgmt/build.info
@@ -0,0 +1,12 @@
+# We make separate GOAL variables for each algorithm, to make it easy to
+# switch each to the Legacy provider when needed.
+
+$DH_GOAL=../../libimplementations.a
+$DSA_GOAL=../../libimplementations.a
+
+IF[{- !$disabled{dh} -}]
+  SOURCE[$DH_GOAL]=dh_kmgmt.c
+ENDIF
+IF[{- !$disabled{dsa} -}]
+  SOURCE[$DSA_GOAL]=dsa_kmgmt.c
+ENDIF
diff --git a/providers/common/keymgmt/dh_kmgmt.c b/providers/implementations/keymgmt/dh_kmgmt.c
similarity index 98%
rename from providers/common/keymgmt/dh_kmgmt.c
rename to providers/implementations/keymgmt/dh_kmgmt.c
index c13f07546b..e2999bde18 100644
--- a/providers/common/keymgmt/dh_kmgmt.c
+++ b/providers/implementations/keymgmt/dh_kmgmt.c
@@ -12,7 +12,7 @@
 #include <openssl/bn.h>
 #include <openssl/dh.h>
 #include <openssl/params.h>
-#include "internal/provider_algs.h"
+#include "prov/implementations.h"
 
 static OSSL_OP_keymgmt_importkey_fn dh_importkey;
 
diff --git a/providers/common/keymgmt/dsa_kmgmt.c b/providers/implementations/keymgmt/dsa_kmgmt.c
similarity index 98%
rename from providers/common/keymgmt/dsa_kmgmt.c
rename to providers/implementations/keymgmt/dsa_kmgmt.c
index a53c0b212c..818a451bb9 100644
--- a/providers/common/keymgmt/dsa_kmgmt.c
+++ b/providers/implementations/keymgmt/dsa_kmgmt.c
@@ -12,7 +12,7 @@
 #include <openssl/bn.h>
 #include <openssl/dsa.h>
 #include <openssl/params.h>
-#include "internal/provider_algs.h"
+#include "prov/implementations.h"
 
 static OSSL_OP_keymgmt_importkey_fn dsa_importkey;
 
diff --git a/providers/default/macs/blake2_mac_impl.c b/providers/implementations/macs/blake2_mac_impl.c
similarity index 98%
rename from providers/default/macs/blake2_mac_impl.c
rename to providers/implementations/macs/blake2_mac_impl.c
index a190b91b98..6b6261f31c 100644
--- a/providers/default/macs/blake2_mac_impl.c
+++ b/providers/implementations/macs/blake2_mac_impl.c
@@ -11,10 +11,10 @@
 #include <openssl/core_names.h>
 #include <openssl/params.h>
 
-#include "internal/blake2.h"
+#include "prov/blake2.h"
 #include "internal/cryptlib.h"
-#include "internal/providercommonerr.h"
-#include "internal/provider_algs.h"
+#include "prov/providercommonerr.h"
+#include "prov/implementations.h"
 
 /*
  * Forward declaration of everything implemented here.  This is not strictly
diff --git a/providers/default/macs/blake2b_mac.c b/providers/implementations/macs/blake2b_mac.c
similarity index 100%
rename from providers/default/macs/blake2b_mac.c
rename to providers/implementations/macs/blake2b_mac.c
diff --git a/providers/default/macs/blake2s_mac.c b/providers/implementations/macs/blake2s_mac.c
similarity index 100%
rename from providers/default/macs/blake2s_mac.c
rename to providers/implementations/macs/blake2s_mac.c
diff --git a/providers/implementations/macs/build.info b/providers/implementations/macs/build.info
new file mode 100644
index 0000000000..07c40d354b
--- /dev/null
+++ b/providers/implementations/macs/build.info
@@ -0,0 +1,32 @@
+# We make separate GOAL variables for each algorithm, to make it easy to
+# switch each to the Legacy provider when needed.
+
+$GMAC_GOAL=../../libimplementations.a
+$HMAC_GOAL=../../libimplementations.a
+$KMAC_GOAL=../../libimplementations.a
+$CMAC_GOAL=../../libimplementations.a
+$BLAKE2_GOAL=../../libimplementations.a
+$SIPHASH_GOAL=../../libimplementations.a
+$POLY1305_GOAL=../../libimplementations.a
+
+SOURCE[$GMAC_GOAL]=gmac_prov.c
+SOURCE[$HMAC_GOAL]=hmac_prov.c
+SOURCE[$KMAC_GOAL]=kmac_prov.c
+
+IF[{- !$disabled{cmac} -}]
+  SOURCE[$CMAC_GOAL]=cmac_prov.c
+ENDIF
+
+$GOAL=../../libimplementations.a
+
+IF[{- !$disabled{blake2} -}]
+  SOURCE[$BLAKE2_GOAL]=blake2b_mac.c blake2s_mac.c
+ENDIF
+
+IF[{- !$disabled{siphash} -}]
+  SOURCE[$SIPHASH_GOAL]=siphash_prov.c
+ENDIF
+
+IF[{- !$disabled{poly1305} -}]
+  SOURCE[$POLY1305_GOAL]=poly1305_prov.c
+ENDIF
diff --git a/providers/common/macs/cmac_prov.c b/providers/implementations/macs/cmac_prov.c
similarity index 98%
rename from providers/common/macs/cmac_prov.c
rename to providers/implementations/macs/cmac_prov.c
index c01b2f87ad..f3dbe1f2e7 100644
--- a/providers/common/macs/cmac_prov.c
+++ b/providers/implementations/macs/cmac_prov.c
@@ -14,9 +14,9 @@
 #include <openssl/evp.h>
 #include <openssl/cmac.h>
 
-#include "internal/provider_algs.h"
-#include "internal/provider_ctx.h"
-#include "internal/provider_util.h"
+#include "prov/implementations.h"
+#include "prov/provider_ctx.h"
+#include "prov/provider_util.h"
 
 /*
  * Forward declaration of everything implemented here.  This is not strictly
diff --git a/providers/common/macs/gmac_prov.c b/providers/implementations/macs/gmac_prov.c
similarity index 97%
rename from providers/common/macs/gmac_prov.c
rename to providers/implementations/macs/gmac_prov.c
index 3d81af8766..f9e5a3a17d 100644
--- a/providers/common/macs/gmac_prov.c
+++ b/providers/implementations/macs/gmac_prov.c
@@ -15,10 +15,10 @@
 #include <openssl/evp.h>
 #include <openssl/err.h>
 
-#include "internal/providercommonerr.h"
-#include "internal/provider_algs.h"
-#include "internal/provider_ctx.h"
-#include "internal/provider_util.h"
+#include "prov/providercommonerr.h"
+#include "prov/implementations.h"
+#include "prov/provider_ctx.h"
+#include "prov/provider_util.h"
 
 /*
  * Forward declaration of everything implemented here.  This is not strictly
diff --git a/providers/common/macs/hmac_prov.c b/providers/implementations/macs/hmac_prov.c
similarity index 98%
rename from providers/common/macs/hmac_prov.c
rename to providers/implementations/macs/hmac_prov.c
index e9d7647ce2..3eccc0d2c8 100644
--- a/providers/common/macs/hmac_prov.c
+++ b/providers/implementations/macs/hmac_prov.c
@@ -14,9 +14,9 @@
 #include <openssl/evp.h>
 #include <openssl/hmac.h>
 
-#include "internal/provider_algs.h"
-#include "internal/provider_ctx.h"
-#include "internal/provider_util.h"
+#include "prov/implementations.h"
+#include "prov/provider_ctx.h"
+#include "prov/provider_util.h"
 
 /*
  * Forward declaration of everything implemented here.  This is not strictly
diff --git a/providers/common/macs/kmac_prov.c b/providers/implementations/macs/kmac_prov.c
similarity index 99%
rename from providers/common/macs/kmac_prov.c
rename to providers/implementations/macs/kmac_prov.c
index 99bcbf7da9..6feaba7695 100644
--- a/providers/common/macs/kmac_prov.c
+++ b/providers/implementations/macs/kmac_prov.c
@@ -54,10 +54,10 @@
 #include <openssl/evp.h>
 #include <openssl/err.h>
 
-#include "internal/providercommonerr.h"
-#include "internal/provider_algs.h"
-#include "internal/provider_ctx.h"
-#include "internal/provider_util.h"
+#include "prov/providercommonerr.h"
+#include "prov/implementations.h"
+#include "prov/provider_ctx.h"
+#include "prov/provider_util.h"
 
 /*
  * Forward declaration of everything implemented here.  This is not strictly
diff --git a/providers/default/macs/poly1305_prov.c b/providers/implementations/macs/poly1305_prov.c
similarity index 98%
rename from providers/default/macs/poly1305_prov.c
rename to providers/implementations/macs/poly1305_prov.c
index 88005716e6..f41752a3cf 100644
--- a/providers/default/macs/poly1305_prov.c
+++ b/providers/implementations/macs/poly1305_prov.c
@@ -21,8 +21,8 @@
  */
 #include "../../../crypto/poly1305/poly1305_local.h"
 
-#include "internal/providercommonerr.h"
-#include "internal/provider_algs.h"
+#include "prov/providercommonerr.h"
+#include "prov/implementations.h"
 
 /*
  * Forward declaration of everything implemented here.  This is not strictly
diff --git a/providers/default/macs/siphash_prov.c b/providers/implementations/macs/siphash_prov.c
similarity index 98%
rename from providers/default/macs/siphash_prov.c
rename to providers/implementations/macs/siphash_prov.c
index a9511925f0..d1cb5cf1e7 100644
--- a/providers/default/macs/siphash_prov.c
+++ b/providers/implementations/macs/siphash_prov.c
@@ -22,8 +22,8 @@
  */
 #include "../../../crypto/siphash/siphash_local.h"
 
-#include "internal/providercommonerr.h"
-#include "internal/provider_algs.h"
+#include "prov/providercommonerr.h"
+#include "prov/implementations.h"
 
 /*
  * Forward declaration of everything implemented here.  This is not strictly
diff --git a/providers/implementations/signature/build.info b/providers/implementations/signature/build.info
new file mode 100644
index 0000000000..a9687fc929
--- /dev/null
+++ b/providers/implementations/signature/build.info
@@ -0,0 +1,10 @@
+# We make separate GOAL variables for each algorithm, to make it easy to
+# switch each to the Legacy provider when needed.
+
+$DSA_GOAL=../../libimplementations.a
+
+IF[{- !$disabled{dsa} -}]
+  SOURCE[$DSA_GOAL]=dsa.c
+ENDIF
+
+
diff --git a/providers/common/signature/dsa.c b/providers/implementations/signature/dsa.c
similarity index 99%
rename from providers/common/signature/dsa.c
rename to providers/implementations/signature/dsa.c
index 1d6b565d38..1eef3c9165 100644
--- a/providers/common/signature/dsa.c
+++ b/providers/implementations/signature/dsa.c
@@ -13,8 +13,8 @@
 #include <openssl/dsa.h>
 #include <openssl/params.h>
 #include <openssl/evp.h>
-#include "internal/provider_algs.h"
-#include "internal/provider_ctx.h"
+#include "prov/implementations.h"
+#include "prov/provider_ctx.h"
 
 static OSSL_OP_signature_newctx_fn dsa_newctx;
 static OSSL_OP_signature_sign_init_fn dsa_signature_init;
diff --git a/providers/legacy/build.info b/providers/legacy/build.info
deleted file mode 100644
index 713c48dbe6..0000000000
--- a/providers/legacy/build.info
+++ /dev/null
@@ -1,8 +0,0 @@
-SUBDIRS=digests
-IF[{- $disabled{module} -}]
-  $GOAL=../../libcrypto
-ELSE
-  $GOAL=../legacy
-ENDIF
-
-SOURCE[$GOAL]=legacyprov.c
diff --git a/providers/legacy/digests/build.info b/providers/legacy/digests/build.info
deleted file mode 100644
index 2c85970dde..0000000000
--- a/providers/legacy/digests/build.info
+++ /dev/null
@@ -1,30 +0,0 @@
-IF[{- $disabled{module} -}]
-  $GOAL=../../../libcrypto
-ELSE
-  $GOAL=../../legacy
-ENDIF
-
-IF[{- !$disabled{md2} -}]
-  SOURCE[$GOAL]=\
-          md2_prov.c
-ENDIF
-
-IF[{- !$disabled{md4} -}]
-  SOURCE[$GOAL]=\
-          md4_prov.c
-ENDIF
-
-IF[{- !$disabled{mdc2} -}]
-  SOURCE[$GOAL]=\
-          mdc2_prov.c
-ENDIF
-
-IF[{- !$disabled{whirlpool} -}]
-  SOURCE[$GOAL]=\
-          wp_prov.c
-ENDIF
-
-IF[{- !$disabled{rmd160} -}]
-  SOURCE[$GOAL]=\
-          ripemd_prov.c
-ENDIF
\ No newline at end of file
diff --git a/providers/legacy/legacyprov.c b/providers/legacyprov.c
similarity index 99%
rename from providers/legacy/legacyprov.c
rename to providers/legacyprov.c
index 1e0c315629..11a050e203 100644
--- a/providers/legacy/legacyprov.c
+++ b/providers/legacyprov.c
@@ -13,7 +13,7 @@
 #include <openssl/core_numbers.h>
 #include <openssl/core_names.h>
 #include <openssl/params.h>
-#include "internal/provider_algs.h"
+#include "prov/implementations.h"
 
 #ifdef STATIC_LEGACY
 OSSL_provider_init_fn ossl_legacy_provider_init;


More information about the openssl-commits mailing list