From 46ea86584a9787c8b9dc3983cf23d9b5b93b5841 Mon Sep 17 00:00:00 2001 From: George Hazan Date: Fri, 21 Jun 2024 14:29:17 +0300 Subject: fixes #4477 (libsodium: update to 1.0.20) --- libs/libsodium/docs/AUTHORS | 19 +- libs/libsodium/docs/ChangeLog | 124 ++ libs/libsodium/docs/LICENSE | 2 +- libs/libsodium/libsodium.vcxproj | 309 ++-- libs/libsodium/libsodium.vcxproj.filters | 708 +++++++- libs/libsodium/res/resource.h | 14 + libs/libsodium/res/resource.rc | 65 + .../src/crypto_aead/aegis128l/aead_aegis128l.c | 159 ++ .../src/crypto_aead/aegis128l/aegis128l_aesni.c | 70 + .../src/crypto_aead/aegis128l/aegis128l_aesni.h | 8 + .../crypto_aead/aegis128l/aegis128l_armcrypto.h | 8 + .../src/crypto_aead/aegis128l/aegis128l_common.h | 249 +++ .../src/crypto_aead/aegis128l/aegis128l_soft.c | 59 + .../src/crypto_aead/aegis128l/aegis128l_soft.h | 8 + .../src/crypto_aead/aegis128l/implementations.h | 17 + .../src/crypto_aead/aegis256/aead_aegis256.c | 158 ++ .../src/crypto_aead/aegis256/aegis256_aesni.c | 65 + .../src/crypto_aead/aegis256/aegis256_aesni.h | 8 + .../src/crypto_aead/aegis256/aegis256_armcrypto.h | 8 + .../src/crypto_aead/aegis256/aegis256_common.h | 232 +++ .../src/crypto_aead/aegis256/aegis256_soft.c | 54 + .../src/crypto_aead/aegis256/aegis256_soft.h | 8 + .../src/crypto_aead/aegis256/implementations.h | 17 + .../src/crypto_aead/aes256gcm/aead_aes256gcm.c | 157 ++ .../aes256gcm/aesni/aead_aes256gcm_aesni.c | 1784 ++++++++++---------- .../aes256gcm/armcrypto/aead_aes256gcm_armcrypto.c | 1033 ++++++++++++ .../chacha20poly1305/aead_chacha20poly1305.c | 400 +++++ .../sodium/aead_chacha20poly1305.c | 400 ----- .../xchacha20poly1305/aead_xchacha20poly1305.c | 262 +++ .../sodium/aead_xchacha20poly1305.c | 262 --- libs/libsodium/src/crypto_box/crypto_box_seal.c | 2 +- .../box_seal_curve25519xchacha20poly1305.c | 2 +- .../src/crypto_core/ed25519/core_ed25519.c | 65 +- libs/libsodium/src/crypto_core/ed25519/core_h2c.c | 133 ++ libs/libsodium/src/crypto_core/ed25519/core_h2c.h | 12 + .../src/crypto_core/ed25519/core_ristretto255.c | 215 +++ .../src/crypto_core/ed25519/ref10/ed25519_ref10.c | 1194 +++++++++---- .../crypto_core/ed25519/ref10/fe_25_5/constants.h | 42 +- .../src/crypto_core/ed25519/ref10/fe_25_5/fe.h | 4 +- .../crypto_core/ed25519/ref10/fe_51/constants.h | 42 +- .../src/crypto_core/ed25519/ref10/fe_51/fe.h | 4 +- .../src/crypto_core/salsa/ref/core_salsa_ref.c | 4 +- libs/libsodium/src/crypto_core/softaes/softaes.c | 143 ++ .../src/crypto_generichash/blake2b/ref/blake2.h | 31 +- .../blake2b/ref/blake2b-compress-avx2.c | 15 +- .../blake2b/ref/blake2b-compress-avx2.h | 16 +- .../blake2b/ref/blake2b-compress-ref.c | 22 +- .../blake2b/ref/blake2b-compress-sse41.c | 14 +- .../blake2b/ref/blake2b-compress-sse41.h | 3 + .../blake2b/ref/blake2b-compress-ssse3.c | 13 +- .../blake2b/ref/blake2b-compress-ssse3.h | 3 + .../blake2b/ref/blake2b-load-avx2.h | 126 +- .../src/crypto_hash/sha256/cp/hash_sha256_cp.c | 2 + .../src/crypto_hash/sha512/cp/hash_sha512_cp.c | 2 + .../src/crypto_kdf/hkdf/kdf_hkdf_sha256.c | 123 ++ .../src/crypto_kdf/hkdf/kdf_hkdf_sha512.c | 123 ++ .../poly1305/donna/poly1305_donna32.h | 2 +- .../poly1305/donna/poly1305_donna64.h | 47 +- .../poly1305/sse2/poly1305_sse2.c | 26 +- .../src/crypto_pwhash/argon2/argon2-core.c | 105 +- .../src/crypto_pwhash/argon2/argon2-core.h | 53 +- .../src/crypto_pwhash/argon2/argon2-encoding.c | 11 +- .../src/crypto_pwhash/argon2/argon2-encoding.h | 8 +- .../crypto_pwhash/argon2/argon2-fill-block-avx2.c | 28 +- .../argon2/argon2-fill-block-avx512f.c | 33 +- .../crypto_pwhash/argon2/argon2-fill-block-ref.c | 3 +- .../crypto_pwhash/argon2/argon2-fill-block-ssse3.c | 18 +- libs/libsodium/src/crypto_pwhash/argon2/argon2.c | 32 +- libs/libsodium/src/crypto_pwhash/argon2/argon2.h | 7 +- .../src/crypto_pwhash/argon2/blake2b-long.h | 1 + .../src/crypto_pwhash/argon2/blamka-round-ssse3.h | 4 + .../src/crypto_pwhash/argon2/pwhash_argon2i.c | 24 +- .../src/crypto_pwhash/argon2/pwhash_argon2id.c | 18 +- libs/libsodium/src/crypto_pwhash/crypto_pwhash.c | 14 +- .../scryptsalsa208sha256/crypto_scrypt-common.c | 5 + .../scryptsalsa208sha256/crypto_scrypt.h | 53 +- .../nosse/pwhash_scryptsalsa208sha256_nosse.c | 129 +- .../scryptsalsa208sha256/pbkdf2-sha256.c | 7 +- .../scryptsalsa208sha256/pbkdf2-sha256.h | 7 +- .../pwhash_scryptsalsa208sha256.c | 17 +- .../scryptsalsa208sha256/scrypt_platform.c | 12 +- .../sse/pwhash_scryptsalsa208sha256_sse.c | 64 +- .../curve25519/ref10/x25519_ref10.c | 71 +- .../curve25519/sandy2x/consts_namespace.h | 28 +- .../curve25519/sandy2x/curve25519_sandy2x.c | 117 +- .../src/crypto_scalarmult/curve25519/sandy2x/fe.h | 2 +- .../curve25519/sandy2x/fe51_mul.S | 4 +- .../curve25519/sandy2x/fe51_namespace.h | 18 +- .../curve25519/sandy2x/fe51_nsquare.S | 2 + .../curve25519/sandy2x/fe51_pack.S | 2 + .../curve25519/sandy2x/fe_frombytes_sandy2x.c | 102 +- .../crypto_scalarmult/curve25519/sandy2x/ladder.S | 2 + .../curve25519/sandy2x/ladder_base.S | 1295 -------------- .../curve25519/sandy2x/ladder_base.h | 18 - .../curve25519/sandy2x/ladder_base_namespace.h | 8 - .../curve25519/sandy2x/ladder_namespace.h | 4 +- .../crypto_scalarmult/curve25519/sandy2x/sandy2x.S | 2 - .../curve25519/scalarmult_curve25519.c | 3 +- .../ed25519/ref10/scalarmult_ed25519_ref10.c | 9 +- .../ref10/scalarmult_ristretto255_ref10.c | 63 + .../src/crypto_secretbox/crypto_secretbox_easy.c | 50 +- .../secretbox_xchacha20poly1305.c | 45 +- .../secretstream_xchacha20poly1305.c | 2 + .../src/crypto_sign/ed25519/ref10/keypair.c | 5 +- .../src/crypto_sign/ed25519/ref10/obsolete.c | 116 -- .../libsodium/src/crypto_sign/ed25519/ref10/open.c | 30 +- .../libsodium/src/crypto_sign/ed25519/ref10/sign.c | 31 +- .../crypto_sign/ed25519/ref10/sign_ed25519_ref10.h | 2 + .../chacha20/dolbeau/chacha20_dolbeau-avx2.c | 15 +- .../chacha20/dolbeau/chacha20_dolbeau-ssse3.c | 13 +- .../src/crypto_stream/chacha20/dolbeau/u8.h | 31 - .../src/crypto_stream/salsa20/stream_salsa20.h | 2 + .../crypto_stream/salsa20/xmm6/salsa20_xmm6-asm.S | 6 + .../salsa20/xmm6/salsa20_xmm6-asm_namespace.h | 10 + .../src/crypto_stream/salsa20/xmm6/salsa20_xmm6.h | 1 + .../salsa20/xmm6int/salsa20_xmm6int-avx2.c | 23 +- .../salsa20/xmm6int/salsa20_xmm6int-sse2.c | 10 +- .../src/crypto_stream/salsa20/xmm6int/u0.h | 2 +- .../src/crypto_stream/xchacha20/stream_xchacha20.c | 2 +- libs/libsodium/src/crypto_verify/sodium/verify.c | 98 -- libs/libsodium/src/crypto_verify/verify.c | 96 ++ libs/libsodium/src/crypto_vrf/crypto_vrf.c | 72 + libs/libsodium/src/crypto_vrf/rfc9381/keypair.c | 40 + libs/libsodium/src/crypto_vrf/rfc9381/prove.c | 69 + libs/libsodium/src/crypto_vrf/rfc9381/verify.c | 116 ++ libs/libsodium/src/crypto_vrf/rfc9381/vrf.c | 31 + .../libsodium/src/crypto_vrf/rfc9381/vrf_rfc9381.h | 10 + libs/libsodium/src/include/Makefile.am | 16 +- libs/libsodium/src/include/sodium.h | 13 +- .../src/include/sodium/crypto_aead_aegis128l.h | 92 + .../src/include/sodium/crypto_aead_aegis256.h | 92 + .../src/include/sodium/crypto_aead_aes256gcm.h | 2 +- .../include/sodium/crypto_aead_xchacha20poly1305.h | 2 +- libs/libsodium/src/include/sodium/crypto_auth.h | 4 +- .../src/include/sodium/crypto_auth_hmacsha256.h | 6 +- .../src/include/sodium/crypto_auth_hmacsha512.h | 6 +- .../src/include/sodium/crypto_auth_hmacsha512256.h | 10 +- libs/libsodium/src/include/sodium/crypto_box.h | 22 +- .../crypto_box_curve25519xchacha20poly1305.h | 10 +- .../sodium/crypto_box_curve25519xsalsa20poly1305.h | 11 +- .../src/include/sodium/crypto_core_ed25519.h | 32 + .../src/include/sodium/crypto_core_ristretto255.h | 121 ++ .../src/include/sodium/crypto_generichash.h | 2 +- .../include/sodium/crypto_generichash_blake2b.h | 10 +- libs/libsodium/src/include/sodium/crypto_hash.h | 4 +- .../src/include/sodium/crypto_hash_sha256.h | 6 +- .../src/include/sodium/crypto_hash_sha512.h | 6 +- .../src/include/sodium/crypto_kdf_blake2b.h | 2 +- .../src/include/sodium/crypto_kdf_hkdf_sha256.h | 74 + .../src/include/sodium/crypto_kdf_hkdf_sha512.h | 75 + .../src/include/sodium/crypto_onetimeauth.h | 6 +- .../include/sodium/crypto_onetimeauth_poly1305.h | 20 +- libs/libsodium/src/include/sodium/crypto_pwhash.h | 16 +- .../src/include/sodium/crypto_pwhash_argon2i.h | 14 +- .../src/include/sodium/crypto_pwhash_argon2id.h | 14 +- .../sodium/crypto_pwhash_scryptsalsa208sha256.h | 12 +- .../src/include/sodium/crypto_scalarmult.h | 2 +- .../include/sodium/crypto_scalarmult_curve25519.h | 2 +- .../src/include/sodium/crypto_scalarmult_ed25519.h | 2 +- .../sodium/crypto_scalarmult_ristretto255.h | 43 + .../src/include/sodium/crypto_secretbox.h | 13 +- .../sodium/crypto_secretbox_xchacha20poly1305.h | 4 +- .../sodium/crypto_secretbox_xsalsa20poly1305.h | 38 +- .../src/include/sodium/crypto_shorthash.h | 2 +- .../include/sodium/crypto_shorthash_siphash24.h | 4 +- libs/libsodium/src/include/sodium/crypto_sign.h | 8 +- .../src/include/sodium/crypto_sign_ed25519.h | 10 +- .../sodium/crypto_sign_edwards25519sha512batch.h | 55 - libs/libsodium/src/include/sodium/crypto_vrf.h | 75 + .../src/include/sodium/crypto_vrf_rfc9381.h | 78 + .../libsodium/src/include/sodium/private/asm_cet.h | 11 + .../src/include/sodium/private/chacha20_ietf_ext.h | 2 + libs/libsodium/src/include/sodium/private/common.h | 60 +- .../src/include/sodium/private/ed25519_ref10.h | 45 +- .../include/sodium/private/ed25519_ref10_fe_25_5.h | 154 +- .../include/sodium/private/ed25519_ref10_fe_51.h | 309 ++-- .../src/include/sodium/private/implementations.h | 4 + libs/libsodium/src/include/sodium/private/mutex.h | 2 + libs/libsodium/src/include/sodium/private/quirks.h | 87 + .../libsodium/src/include/sodium/private/softaes.h | 56 + .../src/include/sodium/private/sse2_64_32.h | 4 +- libs/libsodium/src/include/sodium/randombytes.h | 2 +- .../include/sodium/randombytes_internal_random.h | 22 + .../src/include/sodium/randombytes_nativeclient.h | 23 - .../include/sodium/randombytes_salsa20_random.h | 19 - libs/libsodium/src/include/sodium/runtime.h | 3 + libs/libsodium/src/include/sodium/utils.h | 23 +- libs/libsodium/src/include/sodium/version.h | 7 +- libs/libsodium/src/include/sodium/version.h.in | 33 + .../internal/randombytes_internal_random.c | 667 ++++++++ .../nativeclient/randombytes_nativeclient.c | 61 - libs/libsodium/src/randombytes/randombytes.c | 133 +- .../salsa20/randombytes_salsa20_random.c | 569 ------- .../randombytes/sysrandom/randombytes_sysrandom.c | 31 +- libs/libsodium/src/sodium/codecs.c | 2 + libs/libsodium/src/sodium/core.c | 22 +- libs/libsodium/src/sodium/runtime.c | 120 +- libs/libsodium/src/sodium/utils.c | 63 +- 198 files changed, 10245 insertions(+), 5753 deletions(-) create mode 100644 libs/libsodium/res/resource.h create mode 100644 libs/libsodium/res/resource.rc create mode 100644 libs/libsodium/src/crypto_aead/aegis128l/aead_aegis128l.c create mode 100644 libs/libsodium/src/crypto_aead/aegis128l/aegis128l_aesni.c create mode 100644 libs/libsodium/src/crypto_aead/aegis128l/aegis128l_aesni.h create mode 100644 libs/libsodium/src/crypto_aead/aegis128l/aegis128l_armcrypto.h create mode 100644 libs/libsodium/src/crypto_aead/aegis128l/aegis128l_common.h create mode 100644 libs/libsodium/src/crypto_aead/aegis128l/aegis128l_soft.c create mode 100644 libs/libsodium/src/crypto_aead/aegis128l/aegis128l_soft.h create mode 100644 libs/libsodium/src/crypto_aead/aegis128l/implementations.h create mode 100644 libs/libsodium/src/crypto_aead/aegis256/aead_aegis256.c create mode 100644 libs/libsodium/src/crypto_aead/aegis256/aegis256_aesni.c create mode 100644 libs/libsodium/src/crypto_aead/aegis256/aegis256_aesni.h create mode 100644 libs/libsodium/src/crypto_aead/aegis256/aegis256_armcrypto.h create mode 100644 libs/libsodium/src/crypto_aead/aegis256/aegis256_common.h create mode 100644 libs/libsodium/src/crypto_aead/aegis256/aegis256_soft.c create mode 100644 libs/libsodium/src/crypto_aead/aegis256/aegis256_soft.h create mode 100644 libs/libsodium/src/crypto_aead/aegis256/implementations.h create mode 100644 libs/libsodium/src/crypto_aead/aes256gcm/aead_aes256gcm.c create mode 100644 libs/libsodium/src/crypto_aead/aes256gcm/armcrypto/aead_aes256gcm_armcrypto.c create mode 100644 libs/libsodium/src/crypto_aead/chacha20poly1305/aead_chacha20poly1305.c delete mode 100644 libs/libsodium/src/crypto_aead/chacha20poly1305/sodium/aead_chacha20poly1305.c create mode 100644 libs/libsodium/src/crypto_aead/xchacha20poly1305/aead_xchacha20poly1305.c delete mode 100644 libs/libsodium/src/crypto_aead/xchacha20poly1305/sodium/aead_xchacha20poly1305.c create mode 100644 libs/libsodium/src/crypto_core/ed25519/core_h2c.c create mode 100644 libs/libsodium/src/crypto_core/ed25519/core_h2c.h create mode 100644 libs/libsodium/src/crypto_core/ed25519/core_ristretto255.c create mode 100644 libs/libsodium/src/crypto_core/softaes/softaes.c create mode 100644 libs/libsodium/src/crypto_kdf/hkdf/kdf_hkdf_sha256.c create mode 100644 libs/libsodium/src/crypto_kdf/hkdf/kdf_hkdf_sha512.c delete mode 100644 libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/ladder_base.S delete mode 100644 libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/ladder_base.h delete mode 100644 libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/ladder_base_namespace.h create mode 100644 libs/libsodium/src/crypto_scalarmult/ristretto255/ref10/scalarmult_ristretto255_ref10.c delete mode 100644 libs/libsodium/src/crypto_sign/ed25519/ref10/obsolete.c create mode 100644 libs/libsodium/src/crypto_stream/salsa20/xmm6/salsa20_xmm6-asm_namespace.h delete mode 100644 libs/libsodium/src/crypto_verify/sodium/verify.c create mode 100644 libs/libsodium/src/crypto_verify/verify.c create mode 100644 libs/libsodium/src/crypto_vrf/crypto_vrf.c create mode 100644 libs/libsodium/src/crypto_vrf/rfc9381/keypair.c create mode 100644 libs/libsodium/src/crypto_vrf/rfc9381/prove.c create mode 100644 libs/libsodium/src/crypto_vrf/rfc9381/verify.c create mode 100644 libs/libsodium/src/crypto_vrf/rfc9381/vrf.c create mode 100644 libs/libsodium/src/crypto_vrf/rfc9381/vrf_rfc9381.h create mode 100644 libs/libsodium/src/include/sodium/crypto_aead_aegis128l.h create mode 100644 libs/libsodium/src/include/sodium/crypto_aead_aegis256.h create mode 100644 libs/libsodium/src/include/sodium/crypto_core_ristretto255.h create mode 100644 libs/libsodium/src/include/sodium/crypto_kdf_hkdf_sha256.h create mode 100644 libs/libsodium/src/include/sodium/crypto_kdf_hkdf_sha512.h create mode 100644 libs/libsodium/src/include/sodium/crypto_scalarmult_ristretto255.h delete mode 100644 libs/libsodium/src/include/sodium/crypto_sign_edwards25519sha512batch.h create mode 100644 libs/libsodium/src/include/sodium/crypto_vrf.h create mode 100644 libs/libsodium/src/include/sodium/crypto_vrf_rfc9381.h create mode 100644 libs/libsodium/src/include/sodium/private/asm_cet.h create mode 100644 libs/libsodium/src/include/sodium/private/quirks.h create mode 100644 libs/libsodium/src/include/sodium/private/softaes.h create mode 100644 libs/libsodium/src/include/sodium/randombytes_internal_random.h delete mode 100644 libs/libsodium/src/include/sodium/randombytes_nativeclient.h delete mode 100644 libs/libsodium/src/include/sodium/randombytes_salsa20_random.h create mode 100644 libs/libsodium/src/include/sodium/version.h.in create mode 100644 libs/libsodium/src/randombytes/internal/randombytes_internal_random.c delete mode 100644 libs/libsodium/src/randombytes/nativeclient/randombytes_nativeclient.c delete mode 100644 libs/libsodium/src/randombytes/salsa20/randombytes_salsa20_random.c (limited to 'libs') diff --git a/libs/libsodium/docs/AUTHORS b/libs/libsodium/docs/AUTHORS index 6240b1dc37..51893dfc83 100644 --- a/libs/libsodium/docs/AUTHORS +++ b/libs/libsodium/docs/AUTHORS @@ -2,6 +2,9 @@ Designers ========= +aegis Hongjun Wu + Bart Preneel + argon2 Alex Biryukov Daniel Dinu Dmitry Khovratovich @@ -28,6 +31,13 @@ ed25519 Daniel J. Bernstein poly1305 Daniel J. Bernstein +ristretto Mike Hamburg + Henry de Valence + Jack Grigg + George Tankersley + Filippo Valsorda + Isis Lovecruft + salsa20 Daniel J. Bernstein scrypt Colin Percival @@ -38,8 +48,10 @@ siphash Jean-Philippe Aumasson Implementors ============ -crypto_aead/aes256gcm/aesni Romain Dolbeau - Frank Denis +crypto_aead/aegis128l Frank Denis +crypto_aead/aegis256 + +crypto_aead/aes256gcm/aesni Frank Denis crypto_aead/chacha20poly1305 Frank Denis @@ -56,6 +68,7 @@ crypto_box/curve25519xchacha20poly1305 Frank Denis crypto_core/ed25519 Daniel J. Bernstein Adam Langley + Frank Denis crypto_core/hchacha20 Frank Denis @@ -93,6 +106,8 @@ crypto_scalarmult/curve25519/sandy2x Tung Chou crypto_scalarmult/ed25519 Frank Denis +crypto_scalarmult/ristretto255 Frank Denis + crypto_secretbox/xsalsa20poly1305 Daniel J. Bernstein crypto_secretbox/xchacha20poly1305 Frank Denis diff --git a/libs/libsodium/docs/ChangeLog b/libs/libsodium/docs/ChangeLog index 288f58ccab..374063fc05 100644 --- a/libs/libsodium/docs/ChangeLog +++ b/libs/libsodium/docs/ChangeLog @@ -1,3 +1,127 @@ +* Version 1.0.20 + This point release includes all the changes from 1.0.19-stable, +mainly addressing compilation issues and improvements to the .NET +packages. + +* Version 1.0.19-stable + - Building with `zig build` now requires Zig 0.12. + - When using the traditional build system, -O3 is used instead of -Ofast. + - Improved detection of the compiler flags required on aarch64. + - Improved compatibility with custom build systems on aarch64. + - apple-xcframework: VisionOS packages are not built if Xcode doesn't +include that SDK. + - `crypto_kdf_hkdf_sha512_statebytes()` was added. + - When using Visual Studio, runtime CPU feature detection is now enabled +on Windows/aarch64. + - There were issues with C++ guards affecting usage of libsodium +using Swift on Windows. This has been fixed. + - Emscripten: `crypto_aead_aegis*()` functions are now exported in +JavaScript builds + - Emscripten: unsupported `--memory-init-file` option has been removed. + - apple-xcframework: the minimal deployment target can be set to iOS 11+. + - .NET packages now include precompiled libraries for Windows/arm64, +iOS, TvOS and Catalyst. + - .NET precompiled libraries now work on any CPUs, using only runtime +feature detection. + - SYSV assembly should not be used when targeting Windows (reported by +@meiyese, thanks!) + - Compatibility issues with LLVM 18 and AVX512 have been addressed. + - GitHub attestation build provenance are now added to NuGet packages. + - JavaScript tests can now use Bun as an alternative to Node. + +* Version 1.0.19 + This release includes all the changes from 1.0.18-stable, as well as two +additions: + + - New AEADs: AEGIS-128L and AEGIS-256 are now available in the +`crypto_aead_aegis128l_*()` and `crypto_aead_aegis256_*()` namespaces. +AEGIS is a family of authenticated ciphers for high-performance applications, +leveraging hardware AES acceleration on `x86_64` and `aarch64`. In addition +to performance, AEGIS ciphers have unique properties making them easier and +safer to use than AES-GCM. They can also be used as high-performance MACs. + - The HKDF key derivation mechanism, required by many standard protocols, is +now available in the `crypto_kdf_hkdf_*()` namespace. It is implemented for +the SHA-256 and SHA-512 hash functions. + - The `osx.sh` build script was renamed to `macos.sh`. + - Support for android-mips was removed. + +* Version 1.0.18-stable + - Visual Studio: support for Windows/ARM64 builds has been added. + - Visual Studio: AVX512 implementations are enabled on supported CPUs. + - Visual Studio: an MSVC 2022 solution was added. + - Apple XCFramework: support for VisionOS was added. + - Apple XCFramework: support for Catalyst was added. + - Apple XCFramework: building the simulators is now optional. + - iOS: bitcode is not generated any more, as it was deprecated by Apple. + - watchOS: support for arm64 was added. + - The Zig toolchain can now be used as a modern build system to replace +autoconf/automake/libtool/make/ccache and the compiler. This enables faster +compilation times, easier cross compilation, and static libraries optimized +for any CPU. + - The Zig toolchain is now the recommended way to compile `libsodium` +to WebAssembly/WASI(X). + - libsodium can now be added as a dependency to Zig projects. + - Memory fences were added to remove some gadgets that could be used +alongside speculative loads. + - The AES-GCM implementation was completely rewritten. It is now faster, +and also available on aarch64, including Windows/ARM64. + - Compatibility with CET instrumentation / IBT / Shadow Stack was added. + - Emscripten: the `crypto_pwhash_*()` functions have been removed from Sumo +builds, as they reserve a substantial amount of JavaScript memory, even when +not used. + - Benchmarks now use `CLOCK_MONOTONIC` if possible. + - WebAssembly: tests can now run using Bun, WasmEdge, Wazero, wasm3 and +wasmer-js. Support for WAVM and Lucet have been removed, as these projects +have reached EOL. + - .NET: the minimum supported macOS version is now 1.0.15; this matches +Microsoft guidelines. + - .NET: all the packages are now built using Zig, on all platforms. This +allows us to easily match Microsoft's requirements, including supported glibc +versions. However, on x86_64, targets are expected to support at least the +AVX instruction set. + - .NET: packages for ARM64 are now available. + - C23 `memset_explicit()` is now used, when available. + - Compilation now uses `-Ofast` or `-O3` instead of `-O2` by default. + - Portability improvements to help compile libsodium to modern game consoles. + - JavaScript: a default `unhandledRejection` handler is not set any more. + - Slightly faster 25519 operations. + - OpenBSD: leverage `MAP_CONCEAL`. + +* Version 1.0.18 + - Enterprise versions of Visual Studio are now supported. + - Visual Studio 2019 is now supported. + - 32-bit binaries for Visual Studio 2010 are now provided. + - A test designed to trigger an OOM condition didn't work on Linux systems +with memory overcommit turned on. It has been removed in order to fix +Ansible builds. + - Emscripten: `print` and `printErr` functions are overridden to send +errors to the console, if there is one. + - Emscripten: `UTF8ToString()` is now exported since `Pointer_stringify()` +has been deprecated. + - Libsodium version detection has been fixed in the CMake recipe. + - Generic hashing got a 10% speedup on AVX2. + - New target: WebAssembly/WASI (compile with `dist-builds/wasm32-wasi.sh`). + - New functions to map a hash to an edwards25519 point or get a random point: +`core_ed25519_from_hash()` and `core_ed25519_random()`. + - `crypto_core_ed25519_scalar_mul()` has been implemented for +`scalar*scalar (mod L)` multiplication. + - Support for the Ristretto group has been implemented for interoperability +with wasm-crypto. + - Improvements have been made to the test suite. + - Portability improvements have been made. + - `getentropy()` is now used on systems providing this system call. + - `randombytes_salsa20` has been renamed to `randombytes_internal`. + - Support for NativeClient has been removed. + - Most `((nonnull))` attributes have been relaxed to allow 0-length inputs +to be `NULL`. + - The `-ftree-vectorize` and `-ftree-slp-vectorize` compiler switches are +now used, if available, for optimized builds. + +* Version 1.0.17-stable + - AVX512 detection has been improved. + - A compilation option was added to enable retpoline support. + - `-ftls-model=global-dynamic` is now set, if available. + - Portability and documentation improvements. * Version 1.0.17 - Bug fix: `sodium_pad()` didn't properly support block sizes >= 256 bytes. diff --git a/libs/libsodium/docs/LICENSE b/libs/libsodium/docs/LICENSE index 365236e9b7..f69e259131 100644 --- a/libs/libsodium/docs/LICENSE +++ b/libs/libsodium/docs/LICENSE @@ -1,7 +1,7 @@ /* * ISC License * - * Copyright (c) 2013-2019 + * Copyright (c) 2013-2024 * Frank Denis * * Permission to use, copy, modify, and/or distribute this software for any diff --git a/libs/libsodium/libsodium.vcxproj b/libs/libsodium/libsodium.vcxproj index 182ac4184b..0952812c2d 100644 --- a/libs/libsodium/libsodium.vcxproj +++ b/libs/libsodium/libsodium.vcxproj @@ -30,19 +30,43 @@ $(SolutionDir)$(Configuration)\Libs\ $(SolutionDir)$(Configuration)64\Libs\ - + .mir $(OutDir)$(TargetName)$(TargetExt) - SODIUM_DLL_EXPORT;%(PreprocessorDefinitions) + SODIUM_DLL_EXPORT;NO_QUIRKS;%(PreprocessorDefinitions) 4244;4310;4702;%(DisableSpecificWarnings) $(ProjectDir)src\include;$(ProjectDir)src\include\sodium;%(AdditionalIncludeDirectories) - + + + NotUsing + + + NotUsing + + + NotUsing + + + NotUsing + + + NotUsing + + + NotUsing + + + NotUsing + + + NotUsing + NotUsing @@ -76,9 +100,6 @@ NotUsing - - NotUsing - NotUsing @@ -151,9 +172,6 @@ NotUsing - - NotUsing - NotUsing @@ -220,16 +238,13 @@ NotUsing - - NotUsing - - + NotUsing - + NotUsing - + NotUsing @@ -328,15 +343,9 @@ NotUsing - - NotUsing - NotUsing - - NotUsing - NotUsing @@ -360,134 +369,132 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + \ No newline at end of file diff --git a/libs/libsodium/libsodium.vcxproj.filters b/libs/libsodium/libsodium.vcxproj.filters index 6f18071f64..ff8602d49c 100644 --- a/libs/libsodium/libsodium.vcxproj.filters +++ b/libs/libsodium/libsodium.vcxproj.filters @@ -8,11 +8,711 @@ Source Files - - Resource Files - Resource Files + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + + + Resource Files + - + \ No newline at end of file diff --git a/libs/libsodium/res/resource.h b/libs/libsodium/res/resource.h new file mode 100644 index 0000000000..d42b43ecc2 --- /dev/null +++ b/libs/libsodium/res/resource.h @@ -0,0 +1,14 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by Resource.rc + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 101 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1001 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/libs/libsodium/res/resource.rc b/libs/libsodium/res/resource.rc new file mode 100644 index 0000000000..7cd05b6a7c --- /dev/null +++ b/libs/libsodium/res/resource.rc @@ -0,0 +1,65 @@ +// Microsoft Visual C++ generated resource script. +// +#include "resource.h" +#include "windows.h" + +//specify the version numbers for the dll's +#define LIBSODIUM_VERSION_STRING "1.0.21.0" +#define LIBSODIUM_VERSION_BIN 1,0,21,0 + +//specify the product name for the dlls based on the platform we are compiling for +#if defined(x64) + #define LIBSODIUM_PRODUCT_NAME "libsodium (x64)" +#elif defined(Win32) + #define LIBSODIUM_PRODUCT_NAME "libsodium (x86)" +#elif defined(ARM64) + #define LIBSODIUM_PRODUCT_NAME "libsodium (arm64)" +#else + #define LIBSODIUM_PRODUCT_NAME "libsodium" +#endif + +///////////////////////////////////////////////////////////////////////////// +// English (United States) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US + +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +VS_VERSION_INFO VERSIONINFO + FILEVERSION LIBSODIUM_VERSION_BIN + PRODUCTVERSION LIBSODIUM_VERSION_BIN + FILEFLAGSMASK 0x3fL +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x40004L + FILETYPE 0x7L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904b0" + BEGIN + VALUE "FileDescription", "The Sodium crypto library (libsodium)" + VALUE "FileVersion", LIBSODIUM_VERSION_STRING + VALUE "InternalName", "libsodium" + VALUE "LegalCopyright", "Copyright (c) 2013-2024 The libsodium authors." + VALUE "OriginalFilename", "libsodium.dll" + VALUE "ProductName", LIBSODIUM_PRODUCT_NAME + VALUE "ProductVersion", LIBSODIUM_VERSION_STRING + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1200 + END +END + +#endif // English (United States) resources +///////////////////////////////////////////////////////////////////////////// diff --git a/libs/libsodium/src/crypto_aead/aegis128l/aead_aegis128l.c b/libs/libsodium/src/crypto_aead/aegis128l/aead_aegis128l.c new file mode 100644 index 0000000000..ab2596e685 --- /dev/null +++ b/libs/libsodium/src/crypto_aead/aegis128l/aead_aegis128l.c @@ -0,0 +1,159 @@ + +#include +#include + +#include "core.h" +#include "crypto_aead_aegis128l.h" +#include "private/common.h" +#include "private/implementations.h" +#include "randombytes.h" +#include "runtime.h" + +#include "aegis128l_soft.h" + +#if defined(HAVE_ARMCRYPTO) && defined(NATIVE_LITTLE_ENDIAN) +#include "aegis128l_armcrypto.h" +#endif + +#if defined(HAVE_AVXINTRIN_H) && defined(HAVE_WMMINTRIN_H) +#include "aegis128l_aesni.h" +#endif + +static const aegis128l_implementation *implementation = &aegis128l_soft_implementation; + +size_t +crypto_aead_aegis128l_keybytes(void) +{ + return crypto_aead_aegis128l_KEYBYTES; +} + +size_t +crypto_aead_aegis128l_nsecbytes(void) +{ + return crypto_aead_aegis128l_NSECBYTES; +} + +size_t +crypto_aead_aegis128l_npubbytes(void) +{ + return crypto_aead_aegis128l_NPUBBYTES; +} + +size_t +crypto_aead_aegis128l_abytes(void) +{ + return crypto_aead_aegis128l_ABYTES; +} + +size_t +crypto_aead_aegis128l_messagebytes_max(void) +{ + return crypto_aead_aegis128l_MESSAGEBYTES_MAX; +} + +void +crypto_aead_aegis128l_keygen(unsigned char k[crypto_aead_aegis128l_KEYBYTES]) +{ + randombytes_buf(k, crypto_aead_aegis128l_KEYBYTES); +} + +int +crypto_aead_aegis128l_encrypt(unsigned char *c, unsigned long long *clen_p, const unsigned char *m, + unsigned long long mlen, const unsigned char *ad, + unsigned long long adlen, const unsigned char *nsec, + const unsigned char *npub, const unsigned char *k) +{ + unsigned long long clen = 0ULL; + int ret; + + ret = crypto_aead_aegis128l_encrypt_detached(c, c + mlen, NULL, m, mlen, ad, adlen, nsec, npub, + k); + if (clen_p != NULL) { + if (ret == 0) { + clen = mlen + crypto_aead_aegis128l_ABYTES; + } + *clen_p = clen; + } + return ret; +} + +int +crypto_aead_aegis128l_decrypt(unsigned char *m, unsigned long long *mlen_p, unsigned char *nsec, + const unsigned char *c, unsigned long long clen, + const unsigned char *ad, unsigned long long adlen, + const unsigned char *npub, const unsigned char *k) +{ + unsigned long long mlen = 0ULL; + int ret = -1; + + if (clen >= crypto_aead_aegis128l_ABYTES) { + ret = crypto_aead_aegis128l_decrypt_detached( + m, nsec, c, clen - crypto_aead_aegis128l_ABYTES, + c + clen - crypto_aead_aegis128l_ABYTES, ad, adlen, npub, k); + } + if (mlen_p != NULL) { + if (ret == 0) { + mlen = clen - crypto_aead_aegis128l_ABYTES; + } + *mlen_p = mlen; + } + return ret; +} + +int +crypto_aead_aegis128l_encrypt_detached(unsigned char *c, unsigned char *mac, + unsigned long long *maclen_p, const unsigned char *m, + unsigned long long mlen, const unsigned char *ad, + unsigned long long adlen, const unsigned char *nsec, + const unsigned char *npub, const unsigned char *k) +{ + const size_t maclen = crypto_aead_aegis128l_ABYTES; + + if (maclen_p != NULL) { + *maclen_p = maclen; + } + if (mlen > crypto_aead_aegis128l_MESSAGEBYTES_MAX || + adlen > crypto_aead_aegis128l_MESSAGEBYTES_MAX) { + sodium_misuse(); + } + return implementation->encrypt_detached(c, mac, maclen, m, (size_t) mlen, ad, (size_t) adlen, + npub, k); +} + +int +crypto_aead_aegis128l_decrypt_detached(unsigned char *m, unsigned char *nsec, + const unsigned char *c, unsigned long long clen, + const unsigned char *mac, const unsigned char *ad, + unsigned long long adlen, const unsigned char *npub, + const unsigned char *k) +{ + const size_t maclen = crypto_aead_aegis128l_ABYTES; + + if (clen > crypto_aead_aegis128l_MESSAGEBYTES_MAX || + adlen > crypto_aead_aegis128l_MESSAGEBYTES_MAX) { + return -1; + } + return implementation->decrypt_detached(m, c, (size_t) clen, mac, maclen, ad, (size_t) adlen, + npub, k); +} + +int +_crypto_aead_aegis128l_pick_best_implementation(void) +{ + implementation = &aegis128l_soft_implementation; + +#if defined(HAVE_ARMCRYPTO) && defined(NATIVE_LITTLE_ENDIAN) + if (sodium_runtime_has_armcrypto()) { + implementation = &aegis128l_armcrypto_implementation; + return 0; + } +#endif + +#if defined(HAVE_AVXINTRIN_H) && defined(HAVE_WMMINTRIN_H) + if (sodium_runtime_has_aesni() & sodium_runtime_has_avx()) { + implementation = &aegis128l_aesni_implementation; + return 0; + } +#endif + return 0; /* LCOV_EXCL_LINE */ +} diff --git a/libs/libsodium/src/crypto_aead/aegis128l/aegis128l_aesni.c b/libs/libsodium/src/crypto_aead/aegis128l/aegis128l_aesni.c new file mode 100644 index 0000000000..93782ce288 --- /dev/null +++ b/libs/libsodium/src/crypto_aead/aegis128l/aegis128l_aesni.c @@ -0,0 +1,70 @@ +#include +#include +#include +#include +#include + +#include "core.h" +#include "crypto_aead_aegis128l.h" +#include "crypto_verify_16.h" +#include "crypto_verify_32.h" +#include "export.h" +#include "utils.h" + +#include "private/common.h" + +#if defined(HAVE_AVXINTRIN_H) && defined(HAVE_WMMINTRIN_H) + +#include "aegis128l_aesni.h" + +#ifdef __clang__ +#pragma clang attribute push(__attribute__((target("aes,avx"))), apply_to = function) +#elif defined(__GNUC__) +#pragma GCC target("aes,avx") +#endif + +#include "private/sse2_64_32.h" +#include +#include + +#define AES_BLOCK_LENGTH 16 + +typedef __m128i aes_block_t; +#define AES_BLOCK_XOR(A, B) _mm_xor_si128((A), (B)) +#define AES_BLOCK_AND(A, B) _mm_and_si128((A), (B)) +#define AES_BLOCK_LOAD(A) _mm_loadu_si128((const aes_block_t *) (const void *) (A)) +#define AES_BLOCK_LOAD_64x2(A, B) _mm_set_epi64x((long long) (A), (long long) (B)) +#define AES_BLOCK_STORE(A, B) _mm_storeu_si128((aes_block_t *) (void *) (A), (B)) +#define AES_ENC(A, B) _mm_aesenc_si128((A), (B)) + +static inline void +aegis128l_update(aes_block_t *const state, const aes_block_t d1, const aes_block_t d2) +{ + aes_block_t tmp; + + tmp = state[7]; + state[7] = AES_ENC(state[6], state[7]); + state[6] = AES_ENC(state[5], state[6]); + state[5] = AES_ENC(state[4], state[5]); + state[4] = AES_ENC(state[3], state[4]); + state[3] = AES_ENC(state[2], state[3]); + state[2] = AES_ENC(state[1], state[2]); + state[1] = AES_ENC(state[0], state[1]); + state[0] = AES_ENC(tmp, state[0]); + + state[0] = AES_BLOCK_XOR(state[0], d1); + state[4] = AES_BLOCK_XOR(state[4], d2); +} + +#include "aegis128l_common.h" + +struct aegis128l_implementation aegis128l_aesni_implementation = { SODIUM_C99(.encrypt_detached =) + encrypt_detached, + SODIUM_C99(.decrypt_detached =) + decrypt_detached }; + +#ifdef __clang__ +#pragma clang attribute pop +#endif + +#endif diff --git a/libs/libsodium/src/crypto_aead/aegis128l/aegis128l_aesni.h b/libs/libsodium/src/crypto_aead/aegis128l/aegis128l_aesni.h new file mode 100644 index 0000000000..65e52dab1b --- /dev/null +++ b/libs/libsodium/src/crypto_aead/aegis128l/aegis128l_aesni.h @@ -0,0 +1,8 @@ +#ifndef aegis128l_aesni_H +#define aegis128l_aesni_H + +#include "implementations.h" + +extern struct aegis128l_implementation aegis128l_aesni_implementation; + +#endif \ No newline at end of file diff --git a/libs/libsodium/src/crypto_aead/aegis128l/aegis128l_armcrypto.h b/libs/libsodium/src/crypto_aead/aegis128l/aegis128l_armcrypto.h new file mode 100644 index 0000000000..41ad43cba0 --- /dev/null +++ b/libs/libsodium/src/crypto_aead/aegis128l/aegis128l_armcrypto.h @@ -0,0 +1,8 @@ +#ifndef aegis128l_armcrypto_H +#define aegis128l_armcrypto_H + +#include "implementations.h" + +extern struct aegis128l_implementation aegis128l_armcrypto_implementation; + +#endif \ No newline at end of file diff --git a/libs/libsodium/src/crypto_aead/aegis128l/aegis128l_common.h b/libs/libsodium/src/crypto_aead/aegis128l/aegis128l_common.h new file mode 100644 index 0000000000..6e503dc35a --- /dev/null +++ b/libs/libsodium/src/crypto_aead/aegis128l/aegis128l_common.h @@ -0,0 +1,249 @@ +#define RATE 32 + +static void +aegis128l_init(const uint8_t *key, const uint8_t *nonce, aes_block_t *const state) +{ + static CRYPTO_ALIGN(AES_BLOCK_LENGTH) + const uint8_t c0_[AES_BLOCK_LENGTH] = { 0x00, 0x01, 0x01, 0x02, 0x03, 0x05, 0x08, 0x0d, + 0x15, 0x22, 0x37, 0x59, 0x90, 0xe9, 0x79, 0x62 }; + static CRYPTO_ALIGN(AES_BLOCK_LENGTH) + const uint8_t c1_[AES_BLOCK_LENGTH] = { 0xdb, 0x3d, 0x18, 0x55, 0x6d, 0xc2, 0x2f, 0xf1, + 0x20, 0x11, 0x31, 0x42, 0x73, 0xb5, 0x28, 0xdd }; + + const aes_block_t c0 = AES_BLOCK_LOAD(c0_); + const aes_block_t c1 = AES_BLOCK_LOAD(c1_); + aes_block_t k; + aes_block_t n; + int i; + + k = AES_BLOCK_LOAD(key); + n = AES_BLOCK_LOAD(nonce); + + state[0] = AES_BLOCK_XOR(k, n); + state[1] = c1; + state[2] = c0; + state[3] = c1; + state[4] = AES_BLOCK_XOR(k, n); + state[5] = AES_BLOCK_XOR(k, c0); + state[6] = AES_BLOCK_XOR(k, c1); + state[7] = AES_BLOCK_XOR(k, c0); + for (i = 0; i < 10; i++) { + aegis128l_update(state, n, k); + } +} + +static int +aegis128l_mac(uint8_t *mac, size_t maclen, size_t adlen, size_t mlen, aes_block_t *const state) +{ + aes_block_t tmp; + int i; + + tmp = AES_BLOCK_LOAD_64x2(((uint64_t) mlen) << 3, ((uint64_t) adlen) << 3); + tmp = AES_BLOCK_XOR(tmp, state[2]); + + for (i = 0; i < 7; i++) { + aegis128l_update(state, tmp, tmp); + } + + if (maclen == 16) { + tmp = AES_BLOCK_XOR(state[6], AES_BLOCK_XOR(state[5], state[4])); + tmp = AES_BLOCK_XOR(tmp, AES_BLOCK_XOR(state[3], state[2])); + tmp = AES_BLOCK_XOR(tmp, AES_BLOCK_XOR(state[1], state[0])); + AES_BLOCK_STORE(mac, tmp); + } else if (maclen == 32) { + tmp = AES_BLOCK_XOR(state[3], state[2]); + tmp = AES_BLOCK_XOR(tmp, AES_BLOCK_XOR(state[1], state[0])); + AES_BLOCK_STORE(mac, tmp); + tmp = AES_BLOCK_XOR(state[7], state[6]); + tmp = AES_BLOCK_XOR(tmp, AES_BLOCK_XOR(state[5], state[4])); + AES_BLOCK_STORE(mac + 16, tmp); + } else { + memset(mac, 0, maclen); + return -1; + } + return 0; +} + +static inline void +aegis128l_absorb(const uint8_t *const src, aes_block_t *const state) +{ + aes_block_t msg0, msg1; + + msg0 = AES_BLOCK_LOAD(src); + msg1 = AES_BLOCK_LOAD(src + AES_BLOCK_LENGTH); + aegis128l_update(state, msg0, msg1); +} + +static inline void +aegis128l_absorb2(const uint8_t *const src, aes_block_t *const state) +{ + aes_block_t msg0, msg1, msg2, msg3; + + msg0 = AES_BLOCK_LOAD(src + 0 * AES_BLOCK_LENGTH); + msg1 = AES_BLOCK_LOAD(src + 1 * AES_BLOCK_LENGTH); + msg2 = AES_BLOCK_LOAD(src + 2 * AES_BLOCK_LENGTH); + msg3 = AES_BLOCK_LOAD(src + 3 * AES_BLOCK_LENGTH); + aegis128l_update(state, msg0, msg1); + aegis128l_update(state, msg2, msg3); +} + +static void +aegis128l_enc(uint8_t *const dst, const uint8_t *const src, aes_block_t *const state) +{ + aes_block_t msg0, msg1; + aes_block_t tmp0, tmp1; + + msg0 = AES_BLOCK_LOAD(src); + msg1 = AES_BLOCK_LOAD(src + AES_BLOCK_LENGTH); + tmp0 = AES_BLOCK_XOR(msg0, state[6]); + tmp0 = AES_BLOCK_XOR(tmp0, state[1]); + tmp1 = AES_BLOCK_XOR(msg1, state[5]); + tmp1 = AES_BLOCK_XOR(tmp1, state[2]); + tmp0 = AES_BLOCK_XOR(tmp0, AES_BLOCK_AND(state[2], state[3])); + tmp1 = AES_BLOCK_XOR(tmp1, AES_BLOCK_AND(state[6], state[7])); + AES_BLOCK_STORE(dst, tmp0); + AES_BLOCK_STORE(dst + AES_BLOCK_LENGTH, tmp1); + + aegis128l_update(state, msg0, msg1); +} + +static void +aegis128l_dec(uint8_t *const dst, const uint8_t *const src, aes_block_t *const state) +{ + aes_block_t msg0, msg1; + + msg0 = AES_BLOCK_LOAD(src); + msg1 = AES_BLOCK_LOAD(src + AES_BLOCK_LENGTH); + msg0 = AES_BLOCK_XOR(msg0, state[6]); + msg0 = AES_BLOCK_XOR(msg0, state[1]); + msg1 = AES_BLOCK_XOR(msg1, state[5]); + msg1 = AES_BLOCK_XOR(msg1, state[2]); + msg0 = AES_BLOCK_XOR(msg0, AES_BLOCK_AND(state[2], state[3])); + msg1 = AES_BLOCK_XOR(msg1, AES_BLOCK_AND(state[6], state[7])); + AES_BLOCK_STORE(dst, msg0); + AES_BLOCK_STORE(dst + AES_BLOCK_LENGTH, msg1); + + aegis128l_update(state, msg0, msg1); +} + +static void +aegis128l_declast(uint8_t *const dst, const uint8_t *const src, size_t len, + aes_block_t *const state) +{ + uint8_t pad[RATE]; + aes_block_t msg0, msg1; + + memset(pad, 0, sizeof pad); + memcpy(pad, src, len); + + msg0 = AES_BLOCK_LOAD(pad); + msg1 = AES_BLOCK_LOAD(pad + AES_BLOCK_LENGTH); + msg0 = AES_BLOCK_XOR(msg0, state[6]); + msg0 = AES_BLOCK_XOR(msg0, state[1]); + msg1 = AES_BLOCK_XOR(msg1, state[5]); + msg1 = AES_BLOCK_XOR(msg1, state[2]); + msg0 = AES_BLOCK_XOR(msg0, AES_BLOCK_AND(state[2], state[3])); + msg1 = AES_BLOCK_XOR(msg1, AES_BLOCK_AND(state[6], state[7])); + AES_BLOCK_STORE(pad, msg0); + AES_BLOCK_STORE(pad + AES_BLOCK_LENGTH, msg1); + + memset(pad + len, 0, sizeof pad - len); + memcpy(dst, pad, len); + + msg0 = AES_BLOCK_LOAD(pad); + msg1 = AES_BLOCK_LOAD(pad + AES_BLOCK_LENGTH); + + aegis128l_update(state, msg0, msg1); +} + +static int +encrypt_detached(uint8_t *c, uint8_t *mac, size_t maclen, const uint8_t *m, size_t mlen, + const uint8_t *ad, size_t adlen, const uint8_t *npub, const uint8_t *k) +{ + aes_block_t state[8]; + CRYPTO_ALIGN(RATE) uint8_t src[RATE]; + CRYPTO_ALIGN(RATE) uint8_t dst[RATE]; + size_t i; + + aegis128l_init(k, npub, state); + + for (i = 0; i + RATE * 2 <= adlen; i += RATE * 2) { + aegis128l_absorb2(ad + i, state); + } + for (; i + RATE <= adlen; i += RATE) { + aegis128l_absorb(ad + i, state); + } + if (adlen % RATE) { + memset(src, 0, RATE); + memcpy(src, ad + i, adlen % RATE); + aegis128l_absorb(src, state); + } + for (i = 0; i + RATE <= mlen; i += RATE) { + aegis128l_enc(c + i, m + i, state); + } + if (mlen % RATE) { + memset(src, 0, RATE); + memcpy(src, m + i, mlen % RATE); + aegis128l_enc(dst, src, state); + memcpy(c + i, dst, mlen % RATE); + } + + return aegis128l_mac(mac, maclen, adlen, mlen, state); +} + +static int +decrypt_detached(uint8_t *m, const uint8_t *c, size_t clen, const uint8_t *mac, size_t maclen, + const uint8_t *ad, size_t adlen, const uint8_t *npub, const uint8_t *k) +{ + aes_block_t state[8]; + CRYPTO_ALIGN(RATE) uint8_t src[RATE]; + CRYPTO_ALIGN(RATE) uint8_t dst[RATE]; + CRYPTO_ALIGN(16) uint8_t computed_mac[32]; + const size_t mlen = clen; + size_t i; + int ret; + + aegis128l_init(k, npub, state); + + for (i = 0; i + RATE * 2 <= adlen; i += RATE * 2) { + aegis128l_absorb2(ad + i, state); + } + for (; i + RATE <= adlen; i += RATE) { + aegis128l_absorb(ad + i, state); + } + if (adlen % RATE) { + memset(src, 0, RATE); + memcpy(src, ad + i, adlen % RATE); + aegis128l_absorb(src, state); + } + if (m != NULL) { + for (i = 0; i + RATE <= mlen; i += RATE) { + aegis128l_dec(m + i, c + i, state); + } + } else { + for (i = 0; i + RATE <= mlen; i += RATE) { + aegis128l_dec(dst, c + i, state); + } + } + if (mlen % RATE) { + if (m != NULL) { + aegis128l_declast(m + i, c + i, mlen % RATE, state); + } else { + aegis128l_declast(dst, c + i, mlen % RATE, state); + } + } + + COMPILER_ASSERT(sizeof computed_mac >= 32); + ret = -1; + if (aegis128l_mac(computed_mac, maclen, adlen, mlen, state) == 0) { + if (maclen == 16) { + ret = crypto_verify_16(computed_mac, mac); + } else if (maclen == 32) { + ret = crypto_verify_32(computed_mac, mac); + } + } + if (ret != 0 && m != NULL) { + memset(m, 0, mlen); + } + return ret; +} diff --git a/libs/libsodium/src/crypto_aead/aegis128l/aegis128l_soft.c b/libs/libsodium/src/crypto_aead/aegis128l/aegis128l_soft.c new file mode 100644 index 0000000000..e1d60ecb4f --- /dev/null +++ b/libs/libsodium/src/crypto_aead/aegis128l/aegis128l_soft.c @@ -0,0 +1,59 @@ +#include +#include +#include +#include +#include + +#include "core.h" +#include "crypto_aead_aegis128l.h" +#include "crypto_verify_16.h" +#include "crypto_verify_32.h" +#include "export.h" +#include "utils.h" + +#include "private/common.h" + +#include "crypto_aead_aegis128l.h" +#include "private/softaes.h" + +#if 1 + +#include "aegis128l_soft.h" + +#define AES_BLOCK_LENGTH 16 + +typedef SoftAesBlock aes_block_t; +#define AES_BLOCK_XOR(A, B) softaes_block_xor((A), (B)) +#define AES_BLOCK_AND(A, B) softaes_block_and((A), (B)) +#define AES_BLOCK_LOAD(A) softaes_block_load(A) +#define AES_BLOCK_LOAD_64x2(A, B) softaes_block_load64x2((A), (B)) +#define AES_BLOCK_STORE(A, B) softaes_block_store((A), (B)) +#define AES_ENC(A, B) softaes_block_encrypt((A), (B)) + +static inline void +aegis128l_update(aes_block_t *const state, const aes_block_t d1, const aes_block_t d2) +{ + aes_block_t tmp; + + tmp = state[7]; + state[7] = AES_ENC(state[6], state[7]); + state[6] = AES_ENC(state[5], state[6]); + state[5] = AES_ENC(state[4], state[5]); + state[4] = AES_ENC(state[3], state[4]); + state[3] = AES_ENC(state[2], state[3]); + state[2] = AES_ENC(state[1], state[2]); + state[1] = AES_ENC(state[0], state[1]); + state[0] = AES_ENC(tmp, state[0]); + + state[0] = AES_BLOCK_XOR(state[0], d1); + state[4] = AES_BLOCK_XOR(state[4], d2); +} + +#include "aegis128l_common.h" + +struct aegis128l_implementation aegis128l_soft_implementation = { SODIUM_C99(.encrypt_detached =) + encrypt_detached, + SODIUM_C99(.decrypt_detached =) + decrypt_detached }; + +#endif diff --git a/libs/libsodium/src/crypto_aead/aegis128l/aegis128l_soft.h b/libs/libsodium/src/crypto_aead/aegis128l/aegis128l_soft.h new file mode 100644 index 0000000000..df8ddece08 --- /dev/null +++ b/libs/libsodium/src/crypto_aead/aegis128l/aegis128l_soft.h @@ -0,0 +1,8 @@ +#ifndef aegis128l_soft_H +#define aegis128l_soft_H + +#include "implementations.h" + +extern struct aegis128l_implementation aegis128l_soft_implementation; + +#endif \ No newline at end of file diff --git a/libs/libsodium/src/crypto_aead/aegis128l/implementations.h b/libs/libsodium/src/crypto_aead/aegis128l/implementations.h new file mode 100644 index 0000000000..29e7b1cb88 --- /dev/null +++ b/libs/libsodium/src/crypto_aead/aegis128l/implementations.h @@ -0,0 +1,17 @@ +#ifndef aegis128l_implementations_H +#define aegis128l_implementations_H + +#include +#include + +#include "crypto_aead_aegis128l.h" + +typedef struct aegis128l_implementation { + int (*encrypt_detached)(uint8_t *c, uint8_t *mac, size_t maclen, const uint8_t *m, size_t mlen, + const uint8_t *ad, size_t adlen, const uint8_t *npub, const uint8_t *k); + int (*decrypt_detached)(uint8_t *m, const uint8_t *c, size_t clen, const uint8_t *mac, + size_t maclen, const uint8_t *ad, size_t adlen, const uint8_t *npub, + const uint8_t *k); +} aegis128l_implementation; + +#endif diff --git a/libs/libsodium/src/crypto_aead/aegis256/aead_aegis256.c b/libs/libsodium/src/crypto_aead/aegis256/aead_aegis256.c new file mode 100644 index 0000000000..0fd8f966cf --- /dev/null +++ b/libs/libsodium/src/crypto_aead/aegis256/aead_aegis256.c @@ -0,0 +1,158 @@ + +#include +#include + +#include "core.h" +#include "crypto_aead_aegis256.h" +#include "private/common.h" +#include "private/implementations.h" +#include "randombytes.h" +#include "runtime.h" + +#include "aegis256_soft.h" + +#if defined(HAVE_ARMCRYPTO) && defined(NATIVE_LITTLE_ENDIAN) +#include "aegis256_armcrypto.h" +#endif + +#if defined(HAVE_AVXINTRIN_H) && defined(HAVE_WMMINTRIN_H) +#include "aegis256_aesni.h" +#endif + +static const aegis256_implementation *implementation = &aegis256_soft_implementation; + +size_t +crypto_aead_aegis256_keybytes(void) +{ + return crypto_aead_aegis256_KEYBYTES; +} + +size_t +crypto_aead_aegis256_nsecbytes(void) +{ + return crypto_aead_aegis256_NSECBYTES; +} + +size_t +crypto_aead_aegis256_npubbytes(void) +{ + return crypto_aead_aegis256_NPUBBYTES; +} + +size_t +crypto_aead_aegis256_abytes(void) +{ + return crypto_aead_aegis256_ABYTES; +} + +size_t +crypto_aead_aegis256_messagebytes_max(void) +{ + return crypto_aead_aegis256_MESSAGEBYTES_MAX; +} + +void +crypto_aead_aegis256_keygen(unsigned char k[crypto_aead_aegis256_KEYBYTES]) +{ + randombytes_buf(k, crypto_aead_aegis256_KEYBYTES); +} + +int +crypto_aead_aegis256_encrypt(unsigned char *c, unsigned long long *clen_p, const unsigned char *m, + unsigned long long mlen, const unsigned char *ad, + unsigned long long adlen, const unsigned char *nsec, + const unsigned char *npub, const unsigned char *k) +{ + unsigned long long clen = 0ULL; + int ret; + + ret = + crypto_aead_aegis256_encrypt_detached(c, c + mlen, NULL, m, mlen, ad, adlen, nsec, npub, k); + if (clen_p != NULL) { + if (ret == 0) { + clen = mlen + crypto_aead_aegis256_ABYTES; + } + *clen_p = clen; + } + return ret; +} + +int +crypto_aead_aegis256_decrypt(unsigned char *m, unsigned long long *mlen_p, unsigned char *nsec, + const unsigned char *c, unsigned long long clen, + const unsigned char *ad, unsigned long long adlen, + const unsigned char *npub, const unsigned char *k) +{ + unsigned long long mlen = 0ULL; + int ret = -1; + + if (clen >= crypto_aead_aegis256_ABYTES) { + ret = crypto_aead_aegis256_decrypt_detached(m, nsec, c, clen - crypto_aead_aegis256_ABYTES, + c + clen - crypto_aead_aegis256_ABYTES, ad, + adlen, npub, k); + } + if (mlen_p != NULL) { + if (ret == 0) { + mlen = clen - crypto_aead_aegis256_ABYTES; + } + *mlen_p = mlen; + } + return ret; +} + +int +crypto_aead_aegis256_encrypt_detached(unsigned char *c, unsigned char *mac, + unsigned long long *maclen_p, const unsigned char *m, + unsigned long long mlen, const unsigned char *ad, + unsigned long long adlen, const unsigned char *nsec, + const unsigned char *npub, const unsigned char *k) +{ + const size_t maclen = crypto_aead_aegis256_ABYTES; + + if (maclen_p != NULL) { + *maclen_p = maclen; + } + if (mlen > crypto_aead_aegis256_MESSAGEBYTES_MAX || + adlen > crypto_aead_aegis256_MESSAGEBYTES_MAX) { + sodium_misuse(); + } + return implementation->encrypt_detached(c, mac, maclen, m, (size_t) mlen, ad, (size_t) adlen, + npub, k); +} + +int +crypto_aead_aegis256_decrypt_detached(unsigned char *m, unsigned char *nsec, const unsigned char *c, + unsigned long long clen, const unsigned char *mac, + const unsigned char *ad, unsigned long long adlen, + const unsigned char *npub, const unsigned char *k) +{ + const size_t maclen = crypto_aead_aegis256_ABYTES; + + if (clen > crypto_aead_aegis256_MESSAGEBYTES_MAX || + adlen > crypto_aead_aegis256_MESSAGEBYTES_MAX) { + return -1; + } + return implementation->decrypt_detached(m, c, (size_t) clen, mac, maclen, ad, (size_t) adlen, + npub, k); +} + +int +_crypto_aead_aegis256_pick_best_implementation(void) +{ + implementation = &aegis256_soft_implementation; + +#if defined(HAVE_ARMCRYPTO) && defined(NATIVE_LITTLE_ENDIAN) + if (sodium_runtime_has_armcrypto()) { + implementation = &aegis256_armcrypto_implementation; + return 0; + } +#endif + +#if defined(HAVE_AVXINTRIN_H) && defined(HAVE_WMMINTRIN_H) + if (sodium_runtime_has_aesni() & sodium_runtime_has_avx()) { + implementation = &aegis256_aesni_implementation; + return 0; + } +#endif + return 0; /* LCOV_EXCL_LINE */ +} diff --git a/libs/libsodium/src/crypto_aead/aegis256/aegis256_aesni.c b/libs/libsodium/src/crypto_aead/aegis256/aegis256_aesni.c new file mode 100644 index 0000000000..96aa0036ba --- /dev/null +++ b/libs/libsodium/src/crypto_aead/aegis256/aegis256_aesni.c @@ -0,0 +1,65 @@ +#include +#include +#include +#include +#include + +#include "core.h" +#include "crypto_aead_aegis256.h" +#include "crypto_verify_16.h" +#include "crypto_verify_32.h" +#include "export.h" +#include "utils.h" + +#include "private/common.h" + +#if defined(HAVE_AVXINTRIN_H) && defined(HAVE_WMMINTRIN_H) + +#include "aegis256_aesni.h" + +#ifdef __clang__ +#pragma clang attribute push(__attribute__((target("aes,avx"))), apply_to = function) +#elif defined(__GNUC__) +#pragma GCC target("aes,avx") +#endif + +#include "private/sse2_64_32.h" +#include +#include + +#define AES_BLOCK_LENGTH 16 + +typedef __m128i aes_block_t; +#define AES_BLOCK_XOR(A, B) _mm_xor_si128((A), (B)) +#define AES_BLOCK_AND(A, B) _mm_and_si128((A), (B)) +#define AES_BLOCK_LOAD(A) _mm_loadu_si128((const aes_block_t *) (const void *) (A)) +#define AES_BLOCK_LOAD_64x2(A, B) _mm_set_epi64x((long long) (A), (long long) (B)) +#define AES_BLOCK_STORE(A, B) _mm_storeu_si128((aes_block_t *) (void *) (A), (B)) +#define AES_ENC(A, B) _mm_aesenc_si128((A), (B)) + +static inline void +aegis256_update(aes_block_t *const state, const aes_block_t d) +{ + aes_block_t tmp; + + tmp = state[5]; + state[5] = AES_ENC(state[4], state[5]); + state[4] = AES_ENC(state[3], state[4]); + state[3] = AES_ENC(state[2], state[3]); + state[2] = AES_ENC(state[1], state[2]); + state[1] = AES_ENC(state[0], state[1]); + state[0] = AES_BLOCK_XOR(AES_ENC(tmp, state[0]), d); +} + +#include "aegis256_common.h" + +struct aegis256_implementation aegis256_aesni_implementation = { SODIUM_C99(.encrypt_detached =) + encrypt_detached, + SODIUM_C99(.decrypt_detached =) + decrypt_detached }; + +#ifdef __clang__ +#pragma clang attribute pop +#endif + +#endif diff --git a/libs/libsodium/src/crypto_aead/aegis256/aegis256_aesni.h b/libs/libsodium/src/crypto_aead/aegis256/aegis256_aesni.h new file mode 100644 index 0000000000..21f4d819b9 --- /dev/null +++ b/libs/libsodium/src/crypto_aead/aegis256/aegis256_aesni.h @@ -0,0 +1,8 @@ +#ifndef aegis256_aesni_H +#define aegis256_aesni_H + +#include "implementations.h" + +extern struct aegis256_implementation aegis256_aesni_implementation; + +#endif \ No newline at end of file diff --git a/libs/libsodium/src/crypto_aead/aegis256/aegis256_armcrypto.h b/libs/libsodium/src/crypto_aead/aegis256/aegis256_armcrypto.h new file mode 100644 index 0000000000..a9bd4ad392 --- /dev/null +++ b/libs/libsodium/src/crypto_aead/aegis256/aegis256_armcrypto.h @@ -0,0 +1,8 @@ +#ifndef aegis256_armcrypto_H +#define aegis256_armcrypto_H + +#include "implementations.h" + +extern struct aegis256_implementation aegis256_armcrypto_implementation; + +#endif \ No newline at end of file diff --git a/libs/libsodium/src/crypto_aead/aegis256/aegis256_common.h b/libs/libsodium/src/crypto_aead/aegis256/aegis256_common.h new file mode 100644 index 0000000000..adf837a922 --- /dev/null +++ b/libs/libsodium/src/crypto_aead/aegis256/aegis256_common.h @@ -0,0 +1,232 @@ +#define RATE 16 + +static void +aegis256_init(const uint8_t *key, const uint8_t *nonce, aes_block_t *const state) +{ + static CRYPTO_ALIGN(AES_BLOCK_LENGTH) + const uint8_t c0_[AES_BLOCK_LENGTH] = { 0x00, 0x01, 0x01, 0x02, 0x03, 0x05, 0x08, 0x0d, + 0x15, 0x22, 0x37, 0x59, 0x90, 0xe9, 0x79, 0x62 }; + static CRYPTO_ALIGN(AES_BLOCK_LENGTH) + const uint8_t c1_[AES_BLOCK_LENGTH] = { 0xdb, 0x3d, 0x18, 0x55, 0x6d, 0xc2, 0x2f, 0xf1, + 0x20, 0x11, 0x31, 0x42, 0x73, 0xb5, 0x28, 0xdd }; + + const aes_block_t c0 = AES_BLOCK_LOAD(c0_); + const aes_block_t c1 = AES_BLOCK_LOAD(c1_); + const aes_block_t k0 = AES_BLOCK_LOAD(key); + const aes_block_t k1 = AES_BLOCK_LOAD(key + AES_BLOCK_LENGTH); + const aes_block_t n0 = AES_BLOCK_LOAD(nonce); + const aes_block_t n1 = AES_BLOCK_LOAD(nonce + AES_BLOCK_LENGTH); + const aes_block_t k0_n0 = AES_BLOCK_XOR(k0, n0); + const aes_block_t k1_n1 = AES_BLOCK_XOR(k1, n1); + int i; + + state[0] = k0_n0; + state[1] = k1_n1; + state[2] = c1; + state[3] = c0; + state[4] = AES_BLOCK_XOR(k0, c0); + state[5] = AES_BLOCK_XOR(k1, c1); + for (i = 0; i < 4; i++) { + aegis256_update(state, k0); + aegis256_update(state, k1); + aegis256_update(state, k0_n0); + aegis256_update(state, k1_n1); + } +} + +static int +aegis256_mac(uint8_t *mac, size_t maclen, size_t adlen, size_t mlen, aes_block_t *const state) +{ + aes_block_t tmp; + int i; + + tmp = AES_BLOCK_LOAD_64x2(((uint64_t) mlen) << 3, ((uint64_t) adlen) << 3); + tmp = AES_BLOCK_XOR(tmp, state[3]); + + for (i = 0; i < 7; i++) { + aegis256_update(state, tmp); + } + + if (maclen == 16) { + tmp = AES_BLOCK_XOR(state[5], state[4]); + tmp = AES_BLOCK_XOR(tmp, AES_BLOCK_XOR(state[3], state[2])); + tmp = AES_BLOCK_XOR(tmp, AES_BLOCK_XOR(state[1], state[0])); + AES_BLOCK_STORE(mac, tmp); + } else if (maclen == 32) { + tmp = AES_BLOCK_XOR(AES_BLOCK_XOR(state[2], state[1]), state[0]); + AES_BLOCK_STORE(mac, tmp); + tmp = AES_BLOCK_XOR(AES_BLOCK_XOR(state[5], state[4]), state[3]); + AES_BLOCK_STORE(mac + 16, tmp); + } else { + memset(mac, 0, maclen); + return -1; + } + return 0; +} + +static inline void +aegis256_absorb(const uint8_t *const src, aes_block_t *const state) +{ + aes_block_t msg; + + msg = AES_BLOCK_LOAD(src); + aegis256_update(state, msg); +} + +static inline void +aegis256_absorb2(const uint8_t *const src, aes_block_t *const state) +{ + aes_block_t msg, msg2; + + msg = AES_BLOCK_LOAD(src + 0 * AES_BLOCK_LENGTH); + msg2 = AES_BLOCK_LOAD(src + 1 * AES_BLOCK_LENGTH); + aegis256_update(state, msg); + aegis256_update(state, msg2); +} + +static void +aegis256_enc(uint8_t *const dst, const uint8_t *const src, aes_block_t *const state) +{ + aes_block_t msg; + aes_block_t tmp; + + msg = AES_BLOCK_LOAD(src); + tmp = AES_BLOCK_XOR(msg, state[5]); + tmp = AES_BLOCK_XOR(tmp, state[4]); + tmp = AES_BLOCK_XOR(tmp, state[1]); + tmp = AES_BLOCK_XOR(tmp, AES_BLOCK_AND(state[2], state[3])); + AES_BLOCK_STORE(dst, tmp); + + aegis256_update(state, msg); +} + +static void +aegis256_dec(uint8_t *const dst, const uint8_t *const src, aes_block_t *const state) +{ + aes_block_t msg; + + msg = AES_BLOCK_LOAD(src); + msg = AES_BLOCK_XOR(msg, state[5]); + msg = AES_BLOCK_XOR(msg, state[4]); + msg = AES_BLOCK_XOR(msg, state[1]); + msg = AES_BLOCK_XOR(msg, AES_BLOCK_AND(state[2], state[3])); + AES_BLOCK_STORE(dst, msg); + + aegis256_update(state, msg); +} + +static void +aegis256_declast(uint8_t *const dst, const uint8_t *const src, size_t len, aes_block_t *const state) +{ + uint8_t pad[RATE]; + aes_block_t msg; + + memset(pad, 0, sizeof pad); + memcpy(pad, src, len); + + msg = AES_BLOCK_LOAD(pad); + msg = AES_BLOCK_XOR(msg, state[5]); + msg = AES_BLOCK_XOR(msg, state[4]); + msg = AES_BLOCK_XOR(msg, state[1]); + msg = AES_BLOCK_XOR(msg, AES_BLOCK_AND(state[2], state[3])); + AES_BLOCK_STORE(pad, msg); + + memset(pad + len, 0, sizeof pad - len); + memcpy(dst, pad, len); + + msg = AES_BLOCK_LOAD(pad); + + aegis256_update(state, msg); +} + +static int +encrypt_detached(uint8_t *c, uint8_t *mac, size_t maclen, const uint8_t *m, size_t mlen, + const uint8_t *ad, size_t adlen, const uint8_t *npub, const uint8_t *k) +{ + aes_block_t state[6]; + CRYPTO_ALIGN(RATE) uint8_t src[RATE]; + CRYPTO_ALIGN(RATE) uint8_t dst[RATE]; + size_t i; + + aegis256_init(k, npub, state); + + for (i = 0; i + 2 * RATE <= adlen; i += 2 * RATE) { + aegis256_absorb2(ad + i, state); + } + for (; i + RATE <= adlen; i += RATE) { + aegis256_absorb(ad + i, state); + } + if (adlen % RATE) { + memset(src, 0, RATE); + memcpy(src, ad + i, adlen % RATE); + aegis256_absorb(src, state); + } + for (i = 0; i + RATE <= mlen; i += RATE) { + aegis256_enc(c + i, m + i, state); + } + if (mlen % RATE) { + memset(src, 0, RATE); + memcpy(src, m + i, mlen % RATE); + aegis256_enc(dst, src, state); + memcpy(c + i, dst, mlen % RATE); + } + + return aegis256_mac(mac, maclen, adlen, mlen, state); +} + +static int +decrypt_detached(uint8_t *m, const uint8_t *c, size_t clen, const uint8_t *mac, size_t maclen, + const uint8_t *ad, size_t adlen, const uint8_t *npub, const uint8_t *k) +{ + aes_block_t state[6]; + CRYPTO_ALIGN(RATE) uint8_t src[RATE]; + CRYPTO_ALIGN(RATE) uint8_t dst[RATE]; + CRYPTO_ALIGN(16) uint8_t computed_mac[32]; + const size_t mlen = clen; + size_t i; + int ret; + + aegis256_init(k, npub, state); + + for (i = 0; i + 2 * RATE <= adlen; i += 2 * RATE) { + aegis256_absorb2(ad + i, state); + } + for (; i + RATE <= adlen; i += RATE) { + aegis256_absorb(ad + i, state); + } + if (adlen % RATE) { + memset(src, 0, RATE); + memcpy(src, ad + i, adlen % RATE); + aegis256_absorb(src, state); + } + if (m != NULL) { + for (i = 0; i + RATE <= mlen; i += RATE) { + aegis256_dec(m + i, c + i, state); + } + } else { + for (i = 0; i + RATE <= mlen; i += RATE) { + aegis256_dec(dst, c + i, state); + } + } + if (mlen % RATE) { + if (m != NULL) { + aegis256_declast(m + i, c + i, mlen % RATE, state); + } else { + aegis256_declast(dst, c + i, mlen % RATE, state); + } + } + + COMPILER_ASSERT(sizeof computed_mac >= 32); + ret = -1; + if (aegis256_mac(computed_mac, maclen, adlen, mlen, state) == 0) { + if (maclen == 16) { + ret = crypto_verify_16(computed_mac, mac); + } else if (maclen == 32) { + ret = crypto_verify_32(computed_mac, mac); + } + } + if (ret != 0 && m != NULL) { + memset(m, 0, mlen); + } + return ret; +} diff --git a/libs/libsodium/src/crypto_aead/aegis256/aegis256_soft.c b/libs/libsodium/src/crypto_aead/aegis256/aegis256_soft.c new file mode 100644 index 0000000000..38024d17ad --- /dev/null +++ b/libs/libsodium/src/crypto_aead/aegis256/aegis256_soft.c @@ -0,0 +1,54 @@ +#include +#include +#include +#include +#include + +#include "core.h" +#include "crypto_aead_aegis256.h" +#include "crypto_verify_16.h" +#include "crypto_verify_32.h" +#include "export.h" +#include "utils.h" + +#include "private/common.h" + +#include "crypto_aead_aegis256.h" +#include "private/softaes.h" + +#if 1 + +#include "aegis256_soft.h" + +#define AES_BLOCK_LENGTH 16 + +typedef SoftAesBlock aes_block_t; +#define AES_BLOCK_XOR(A, B) softaes_block_xor((A), (B)) +#define AES_BLOCK_AND(A, B) softaes_block_and((A), (B)) +#define AES_BLOCK_LOAD(A) softaes_block_load(A) +#define AES_BLOCK_LOAD_64x2(A, B) softaes_block_load64x2((A), (B)) +#define AES_BLOCK_STORE(A, B) softaes_block_store((A), (B)) +#define AES_ENC(A, B) softaes_block_encrypt((A), (B)) + +static inline void +aegis256_update(aes_block_t *const state, const aes_block_t d) +{ + aes_block_t tmp; + + tmp = state[5]; + state[5] = AES_ENC(state[4], state[5]); + state[4] = AES_ENC(state[3], state[4]); + state[3] = AES_ENC(state[2], state[3]); + state[2] = AES_ENC(state[1], state[2]); + state[1] = AES_ENC(state[0], state[1]); + state[0] = AES_BLOCK_XOR(AES_ENC(tmp, state[0]), d); +} + +#include "aegis256_common.h" + +struct aegis256_implementation aegis256_soft_implementation = { SODIUM_C99(.encrypt_detached =) + encrypt_detached, + SODIUM_C99(.decrypt_detached =) + decrypt_detached }; + +#endif \ No newline at end of file diff --git a/libs/libsodium/src/crypto_aead/aegis256/aegis256_soft.h b/libs/libsodium/src/crypto_aead/aegis256/aegis256_soft.h new file mode 100644 index 0000000000..c20198de3f --- /dev/null +++ b/libs/libsodium/src/crypto_aead/aegis256/aegis256_soft.h @@ -0,0 +1,8 @@ +#ifndef aegis256_soft_H +#define aegis256_soft_H + +#include "implementations.h" + +extern struct aegis256_implementation aegis256_soft_implementation; + +#endif \ No newline at end of file diff --git a/libs/libsodium/src/crypto_aead/aegis256/implementations.h b/libs/libsodium/src/crypto_aead/aegis256/implementations.h new file mode 100644 index 0000000000..9efbf38763 --- /dev/null +++ b/libs/libsodium/src/crypto_aead/aegis256/implementations.h @@ -0,0 +1,17 @@ +#ifndef aegis256_implementations_H +#define aegis256_implementations_H + +#include +#include + +#include "crypto_aead_aegis256.h" + +typedef struct aegis256_implementation { + int (*encrypt_detached)(uint8_t *c, uint8_t *mac, size_t maclen, const uint8_t *m, size_t mlen, + const uint8_t *ad, size_t adlen, const uint8_t *npub, const uint8_t *k); + int (*decrypt_detached)(uint8_t *m, const uint8_t *c, size_t clen, const uint8_t *mac, + size_t maclen, const uint8_t *ad, size_t adlen, const uint8_t *npub, + const uint8_t *k); +} aegis256_implementation; + +#endif diff --git a/libs/libsodium/src/crypto_aead/aes256gcm/aead_aes256gcm.c b/libs/libsodium/src/crypto_aead/aes256gcm/aead_aes256gcm.c new file mode 100644 index 0000000000..2946ba873b --- /dev/null +++ b/libs/libsodium/src/crypto_aead/aes256gcm/aead_aes256gcm.c @@ -0,0 +1,157 @@ +#include +#include + +#include "crypto_aead_aes256gcm.h" +#include "private/common.h" +#include "randombytes.h" + +size_t +crypto_aead_aes256gcm_keybytes(void) +{ + return crypto_aead_aes256gcm_KEYBYTES; +} + +size_t +crypto_aead_aes256gcm_nsecbytes(void) +{ + return crypto_aead_aes256gcm_NSECBYTES; +} + +size_t +crypto_aead_aes256gcm_npubbytes(void) +{ + return crypto_aead_aes256gcm_NPUBBYTES; +} + +size_t +crypto_aead_aes256gcm_abytes(void) +{ + return crypto_aead_aes256gcm_ABYTES; +} + +size_t +crypto_aead_aes256gcm_statebytes(void) +{ + return (sizeof(crypto_aead_aes256gcm_state) + (size_t) 15U) & ~(size_t) 15U; +} + +size_t +crypto_aead_aes256gcm_messagebytes_max(void) +{ + return crypto_aead_aes256gcm_MESSAGEBYTES_MAX; +} + +void +crypto_aead_aes256gcm_keygen(unsigned char k[crypto_aead_aes256gcm_KEYBYTES]) +{ + randombytes_buf(k, crypto_aead_aes256gcm_KEYBYTES); +} + +#if !((defined(HAVE_ARMCRYPTO) && defined(__clang__) && defined(NATIVE_LITTLE_ENDIAN)) || \ + (defined(HAVE_TMMINTRIN_H) && defined(HAVE_WMMINTRIN_H))) + +#ifndef ENOSYS +#define ENOSYS ENXIO +#endif + +int +crypto_aead_aes256gcm_encrypt_detached(unsigned char *c, unsigned char *mac, + unsigned long long *maclen_p, const unsigned char *m, + unsigned long long mlen, const unsigned char *ad, + unsigned long long adlen, const unsigned char *nsec, + const unsigned char *npub, const unsigned char *k) +{ + errno = ENOSYS; + return -1; +} + +int +crypto_aead_aes256gcm_encrypt(unsigned char *c, unsigned long long *clen_p, const unsigned char *m, + unsigned long long mlen, const unsigned char *ad, + unsigned long long adlen, const unsigned char *nsec, + const unsigned char *npub, const unsigned char *k) +{ + errno = ENOSYS; + return -1; +} + +int +crypto_aead_aes256gcm_decrypt_detached(unsigned char *m, unsigned char *nsec, + const unsigned char *c, unsigned long long clen, + const unsigned char *mac, const unsigned char *ad, + unsigned long long adlen, const unsigned char *npub, + const unsigned char *k) +{ + errno = ENOSYS; + return -1; +} + +int +crypto_aead_aes256gcm_decrypt(unsigned char *m, unsigned long long *mlen_p, unsigned char *nsec, + const unsigned char *c, unsigned long long clen, + const unsigned char *ad, unsigned long long adlen, + const unsigned char *npub, const unsigned char *k) +{ + errno = ENOSYS; + return -1; +} + +int +crypto_aead_aes256gcm_beforenm(crypto_aead_aes256gcm_state *st_, const unsigned char *k) +{ + errno = ENOSYS; + return -1; +} + +int +crypto_aead_aes256gcm_encrypt_detached_afternm(unsigned char *c, unsigned char *mac, + unsigned long long *maclen_p, const unsigned char *m, + unsigned long long mlen, const unsigned char *ad, + unsigned long long adlen, const unsigned char *nsec, + const unsigned char *npub, + const crypto_aead_aes256gcm_state *st_) +{ + errno = ENOSYS; + return -1; +} + +int +crypto_aead_aes256gcm_encrypt_afternm(unsigned char *c, unsigned long long *clen_p, + const unsigned char *m, unsigned long long mlen, + const unsigned char *ad, unsigned long long adlen, + const unsigned char *nsec, const unsigned char *npub, + const crypto_aead_aes256gcm_state *st_) +{ + errno = ENOSYS; + return -1; +} + +int +crypto_aead_aes256gcm_decrypt_detached_afternm(unsigned char *m, unsigned char *nsec, + const unsigned char *c, unsigned long long clen, + const unsigned char *mac, const unsigned char *ad, + unsigned long long adlen, const unsigned char *npub, + const crypto_aead_aes256gcm_state *st_) +{ + errno = ENOSYS; + return -1; +} + +int +crypto_aead_aes256gcm_decrypt_afternm(unsigned char *m, unsigned long long *mlen_p, + unsigned char *nsec, const unsigned char *c, + unsigned long long clen, const unsigned char *ad, + unsigned long long adlen, const unsigned char *npub, + const crypto_aead_aes256gcm_state *st_) +{ + errno = ENOSYS; + return -1; +} + +int +crypto_aead_aes256gcm_is_available(void) +{ + return 0; +} + +#endif \ No newline at end of file diff --git a/libs/libsodium/src/crypto_aead/aes256gcm/aesni/aead_aes256gcm_aesni.c b/libs/libsodium/src/crypto_aead/aes256gcm/aesni/aead_aes256gcm_aesni.c index c0d8674af6..7d9cfd12e9 100644 --- a/libs/libsodium/src/crypto_aead/aes256gcm/aesni/aead_aes256gcm_aesni.c +++ b/libs/libsodium/src/crypto_aead/aes256gcm/aesni/aead_aes256gcm_aesni.c @@ -1,17 +1,12 @@ - -/* - * AES256-GCM, based on the "Intel Carry-Less Multiplication Instruction and its Usage for Computing - * the GCM Mode" paper and reference code, using the aggregated reduction method. - * Originally adapted by Romain Dolbeau. - */ - #include +#include #include #include #include #include "core.h" #include "crypto_aead_aes256gcm.h" +#include "crypto_verify_16.h" #include "export.h" #include "private/common.h" #include "private/sse2_64_32.h" @@ -21,976 +16,803 @@ #if defined(HAVE_TMMINTRIN_H) && defined(HAVE_WMMINTRIN_H) -# ifdef __GNUC__ -# pragma GCC target("ssse3") -# pragma GCC target("aes") -# pragma GCC target("pclmul") +# ifdef __clang__ +# pragma clang attribute push(__attribute__((target("aes,avx,pclmul"))), apply_to = function) +# elif defined(__GNUC__) +# pragma GCC target("aes,avx,pclmul") # endif +#if !defined(_MSC_VER) || _MSC_VER < 1800 +#define __vectorcall +#endif + #include #include -#ifndef ENOSYS -# define ENOSYS ENXIO -#endif - -#if defined(__INTEL_COMPILER) || defined(_bswap64) -#elif defined(_MSC_VER) -# define _bswap64(a) _byteswap_uint64(a) -#elif defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 2)) -# define _bswap64(a) __builtin_bswap64(a) -#else -static inline uint64_t -_bswap64(const uint64_t x) -{ - return - ((x << 56) & 0xFF00000000000000UL) | ((x << 40) & 0x00FF000000000000UL) | - ((x << 24) & 0x0000FF0000000000UL) | ((x << 8) & 0x000000FF00000000UL) | - ((x >> 8) & 0x00000000FF000000UL) | ((x >> 24) & 0x0000000000FF0000UL) | - ((x >> 40) & 0x000000000000FF00UL) | ((x >> 56) & 0x00000000000000FFUL); +#define ABYTES crypto_aead_aes256gcm_ABYTES +#define NPUBBYTES crypto_aead_aes256gcm_NPUBBYTES +#define KEYBYTES crypto_aead_aes256gcm_KEYBYTES + +#define PARALLEL_BLOCKS 7 +#undef USE_KARATSUBA_MULTIPLICATION + +typedef __m128i BlockVec; + +#define LOAD128(a) _mm_loadu_si128((const BlockVec *) (a)) +#define STORE128(a, b) _mm_storeu_si128((BlockVec *) (a), (b)) +#define AES_ENCRYPT(block_vec, rkey) _mm_aesenc_si128((block_vec), (rkey)) +#define AES_ENCRYPTLAST(block_vec, rkey) _mm_aesenclast_si128((block_vec), (rkey)) +#define AES_KEYGEN(block_vec, rc) _mm_aeskeygenassist_si128((block_vec), (rc)) +#define XOR128(a, b) _mm_xor_si128((a), (b)) +#define AND128(a, b) _mm_and_si128((a), (b)) +#define OR128(a, b) _mm_or_si128((a), (b)) +#define SET64x2(a, b) _mm_set_epi64x((uint64_t) (a), (uint64_t) (b)) +#define ZERO128 _mm_setzero_si128() +#define ONE128 SET64x2(0, 1) +#define ADD64x2(a, b) _mm_add_epi64((a), (b)) +#define SUB64x2(a, b) _mm_sub_epi64((a), (b)) +#define SHL64x2(a, b) _mm_slli_epi64((a), (b)) +#define SHR64x2(a, b) _mm_srli_epi64((a), (b)) +#define REV128(x) \ + _mm_shuffle_epi8((x), _mm_set_epi8(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15)) +#define SHUFFLE32x4(x, a, b, c, d) _mm_shuffle_epi32((x), _MM_SHUFFLE((d), (c), (b), (a))) +#define BYTESHL128(a, b) _mm_slli_si128(a, b) +#define BYTESHR128(a, b) _mm_srli_si128(a, b) +#define SHL128(a, b) OR128(SHL64x2((a), (b)), SHR64x2(BYTESHL128((a), 8), 64 - (b))) +#define CLMULLO128(a, b) _mm_clmulepi64_si128((a), (b), 0x00) +#define CLMULHI128(a, b) _mm_clmulepi64_si128((a), (b), 0x11) +#define CLMULLOHI128(a, b) _mm_clmulepi64_si128((a), (b), 0x10) +#define CLMULHILO128(a, b) _mm_clmulepi64_si128((a), (b), 0x01) +#define PREFETCH_READ(x) _mm_prefetch((x), _MM_HINT_T1) +#define PREFETCH_WRITE(x) _mm_prefetch((x), _MM_HINT_T1) + +#define ROUNDS 14 + +#define PC_COUNT (2 * PARALLEL_BLOCKS) + +typedef struct I256 { + BlockVec hi; + BlockVec lo; + BlockVec mid; +} I256; + +typedef BlockVec Precomp; + +typedef struct GHash { + BlockVec acc; +} GHash; + +typedef struct State { + BlockVec rkeys[ROUNDS + 1]; + Precomp hx[PC_COUNT]; +} State; + +static void __vectorcall expand256(const unsigned char key[KEYBYTES], BlockVec rkeys[1 + ROUNDS]) +{ + BlockVec t1, t2, s; + size_t i = 0; + +#define EXPAND_KEY_1(RC) \ + rkeys[i++] = t2; \ + s = AES_KEYGEN(t2, RC); \ + t1 = XOR128(t1, BYTESHL128(t1, 4)); \ + t1 = XOR128(t1, BYTESHL128(t1, 8)); \ + t1 = XOR128(t1, SHUFFLE32x4(s, 3, 3, 3, 3)); + +#define EXPAND_KEY_2(RC) \ + rkeys[i++] = t1; \ + s = AES_KEYGEN(t1, RC); \ + t2 = XOR128(t2, BYTESHL128(t2, 4)); \ + t2 = XOR128(t2, BYTESHL128(t2, 8)); \ + t2 = XOR128(t2, SHUFFLE32x4(s, 2, 2, 2, 2)); + + t1 = LOAD128(&key[0]); + t2 = LOAD128(&key[16]); + + rkeys[i++] = t1; + EXPAND_KEY_1(0x01); + EXPAND_KEY_2(0x01); + EXPAND_KEY_1(0x02); + EXPAND_KEY_2(0x02); + EXPAND_KEY_1(0x04); + EXPAND_KEY_2(0x04); + EXPAND_KEY_1(0x08); + EXPAND_KEY_2(0x08); + EXPAND_KEY_1(0x10); + EXPAND_KEY_2(0x10); + EXPAND_KEY_1(0x20); + EXPAND_KEY_2(0x20); + EXPAND_KEY_1(0x40); + rkeys[i++] = t1; } -#endif -typedef struct aes256gcm_state { - __m128i rkeys[16]; - unsigned char H[16]; -} aes256gcm_state; +/* Encrypt a single AES block */ static inline void -aesni_key256_expand(const unsigned char *key, __m128i * const rkeys) +encrypt(const State *st, unsigned char dst[16], const unsigned char src[16]) { - __m128i X0, X1, X2, X3; - int i = 0; - - X0 = _mm_loadu_si128((const __m128i *) &key[0]); - rkeys[i++] = X0; - - X2 = _mm_loadu_si128((const __m128i *) &key[16]); - rkeys[i++] = X2; - -#define EXPAND_KEY_1(S) do { \ - X1 = _mm_shuffle_epi32(_mm_aeskeygenassist_si128(X2, (S)), 0xff); \ - X3 = _mm_castps_si128(_mm_shuffle_ps(_mm_castsi128_ps(X3), _mm_castsi128_ps(X0), 0x10)); \ - X0 = _mm_xor_si128(X0, X3); \ - X3 = _mm_castps_si128(_mm_shuffle_ps(_mm_castsi128_ps(X3), _mm_castsi128_ps(X0), 0x8c)); \ - X0 = _mm_xor_si128(_mm_xor_si128(X0, X3), X1); \ - rkeys[i++] = X0; \ -} while (0) - -#define EXPAND_KEY_2(S) do { \ - X1 = _mm_shuffle_epi32(_mm_aeskeygenassist_si128(X0, (S)), 0xaa); \ - X3 = _mm_castps_si128(_mm_shuffle_ps(_mm_castsi128_ps(X3), _mm_castsi128_ps(X2), 0x10)); \ - X2 = _mm_xor_si128(X2, X3); \ - X3 = _mm_castps_si128(_mm_shuffle_ps(_mm_castsi128_ps(X3), _mm_castsi128_ps(X2), 0x8c)); \ - X2 = _mm_xor_si128(_mm_xor_si128(X2, X3), X1); \ - rkeys[i++] = X2; \ -} while (0) - - X3 = _mm_setzero_si128(); - EXPAND_KEY_1(0x01); EXPAND_KEY_2(0x01); - EXPAND_KEY_1(0x02); EXPAND_KEY_2(0x02); - EXPAND_KEY_1(0x04); EXPAND_KEY_2(0x04); - EXPAND_KEY_1(0x08); EXPAND_KEY_2(0x08); - EXPAND_KEY_1(0x10); EXPAND_KEY_2(0x10); - EXPAND_KEY_1(0x20); EXPAND_KEY_2(0x20); - EXPAND_KEY_1(0x40); + BlockVec t; + + size_t i; + + t = XOR128(LOAD128(src), st->rkeys[0]); + for (i = 1; i < ROUNDS; i++) { + t = AES_ENCRYPT(t, st->rkeys[i]); + } + t = AES_ENCRYPTLAST(t, st->rkeys[ROUNDS]); + STORE128(dst, t); } -/** single, by-the-book AES encryption with AES-NI */ -static inline void -aesni_encrypt1(unsigned char *out, __m128i nv, const __m128i *rkeys) +/* Encrypt and add a single AES block */ + +static inline void __vectorcall encrypt_xor_block(const State *st, unsigned char dst[16], + const unsigned char src[16], + const BlockVec counter) { - __m128i temp = _mm_xor_si128(nv, rkeys[0]); - - temp = _mm_aesenc_si128(temp, rkeys[1]); - temp = _mm_aesenc_si128(temp, rkeys[2]); - temp = _mm_aesenc_si128(temp, rkeys[3]); - temp = _mm_aesenc_si128(temp, rkeys[4]); - temp = _mm_aesenc_si128(temp, rkeys[5]); - temp = _mm_aesenc_si128(temp, rkeys[6]); - temp = _mm_aesenc_si128(temp, rkeys[7]); - temp = _mm_aesenc_si128(temp, rkeys[8]); - temp = _mm_aesenc_si128(temp, rkeys[9]); - temp = _mm_aesenc_si128(temp, rkeys[10]); - temp = _mm_aesenc_si128(temp, rkeys[11]); - temp = _mm_aesenc_si128(temp, rkeys[12]); - temp = _mm_aesenc_si128(temp, rkeys[13]); - - temp = _mm_aesenclast_si128(temp, rkeys[14]); - _mm_storeu_si128((__m128i *) out, temp); -} + BlockVec ts; + size_t i; -/** multiple-blocks-at-once AES encryption with AES-NI ; - on Haswell, aesenc has a latency of 7 and a throughput of 1 - so the sequence of aesenc should be bubble-free if you - have at least 8 blocks. Let's build an arbitratry-sized - function */ -/* Step 1 : loading the nonce */ -/* load & increment the n vector (non-vectorized, unused for now) */ -#define NVDECLx(a) \ - __m128i nv##a - -#define NVx(a) \ - nv##a = _mm_shuffle_epi8(_mm_load_si128((const __m128i *) n), pt); \ - n[3]++ - -/* Step 2 : define value in round one (xor with subkey #0, aka key) */ -#define TEMPDECLx(a) \ - __m128i temp##a - -#define TEMPx(a) \ - temp##a = _mm_xor_si128(nv##a, rkeys[0]) - -/* Step 3: one round of AES */ -#define AESENCx(a) \ - temp##a = _mm_aesenc_si128(temp##a, rkeys[roundctr]) - -/* Step 4: last round of AES */ -#define AESENCLASTx(a) \ - temp##a = _mm_aesenclast_si128(temp##a, rkeys[14]) - -/* Step 5: store result */ -#define STOREx(a) \ - _mm_storeu_si128((__m128i *) (out + (a * 16)), temp##a) - -/* all the MAKE* macros are for automatic explicit unrolling */ -#define MAKE4(X) \ - X(0); \ - X(1); \ - X(2); \ - X(3) - -#define MAKE8(X) \ - X(0); \ - X(1); \ - X(2); \ - X(3); \ - X(4); \ - X(5); \ - X(6); \ - X(7) - -#define COUNTER_INC2(N) (N)[3] += 2 - -/* create a function of unrolling N ; the MAKEN is the unrolling - macro, defined above. The N in MAKEN must match N, obviously. */ -#define FUNC(N, MAKEN) \ - static inline void aesni_encrypt##N(unsigned char *out, uint32_t *n, const __m128i *rkeys) \ - { \ - const __m128i pt = _mm_set_epi8(12, 13, 14, 15, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \ - int roundctr; \ - MAKEN(NVDECLx); \ - MAKEN(TEMPDECLx); \ - \ - MAKEN(NVx); \ - MAKEN(TEMPx); \ - for (roundctr = 1; roundctr < 14; roundctr++) { \ - MAKEN(AESENCx); \ - } \ - MAKEN(AESENCLASTx); \ - MAKEN(STOREx); \ + ts = XOR128(counter, st->rkeys[0]); + for (i = 1; i < ROUNDS; i++) { + ts = AES_ENCRYPT(ts, st->rkeys[i]); } + ts = AES_ENCRYPTLAST(ts, st->rkeys[i]); + ts = XOR128(ts, LOAD128(src)); + STORE128(dst, ts); +} -FUNC(8, MAKE8) - -/* all GF(2^128) fnctions are by the book, meaning this one: - -*/ +/* Encrypt and add PARALLEL_BLOCKS AES blocks */ -static inline void -addmul(unsigned char *c, const unsigned char *a, unsigned int xlen, const unsigned char *b) +static inline void __vectorcall encrypt_xor_wide(const State *st, + unsigned char dst[16 * PARALLEL_BLOCKS], + const unsigned char src[16 * PARALLEL_BLOCKS], + const BlockVec counters[PARALLEL_BLOCKS]) { - const __m128i rev = _mm_set_epi8(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); - __m128i A, B, C; - __m128i tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8, tmp9; - __m128i tmp10, tmp11, tmp12, tmp13, tmp14, tmp15, tmp16, tmp17, tmp18; - __m128i tmp19, tmp20, tmp21, tmp22, tmp23, tmp24, tmp25, tmp26, tmp27; - __m128i tmp28, tmp29, tmp30, tmp31, tmp32, tmp33, tmp34, tmp35, tmp36; - - if (xlen >= 16) { - A = _mm_loadu_si128((const __m128i *) a); - } else { - CRYPTO_ALIGN(16) unsigned char padded[16]; - unsigned int i; + BlockVec ts[PARALLEL_BLOCKS]; + size_t i, j; - memset(padded, 0, 16); - for (i = 0; i < xlen; i++) { - padded[i] = a[i]; + for (j = 0; j < PARALLEL_BLOCKS; j++) { + ts[j] = XOR128(counters[j], st->rkeys[0]); + } + for (i = 1; i < ROUNDS; i++) { + for (j = 0; j < PARALLEL_BLOCKS; j++) { + ts[j] = AES_ENCRYPT(ts[j], st->rkeys[i]); } - A = _mm_load_si128((const __m128i *) padded); } - A = _mm_shuffle_epi8(A, rev); - B = _mm_loadu_si128((const __m128i *) b); - C = _mm_loadu_si128((const __m128i *) c); - A = _mm_xor_si128(A, C); - tmp3 = _mm_clmulepi64_si128(A, B, 0x00); - tmp4 = _mm_clmulepi64_si128(A, B, 0x10); - tmp5 = _mm_clmulepi64_si128(A, B, 0x01); - tmp6 = _mm_clmulepi64_si128(A, B, 0x11); - tmp10 = _mm_xor_si128(tmp4, tmp5); - tmp13 = _mm_slli_si128(tmp10, 8); - tmp11 = _mm_srli_si128(tmp10, 8); - tmp15 = _mm_xor_si128(tmp3, tmp13); - tmp17 = _mm_xor_si128(tmp6, tmp11); - tmp7 = _mm_srli_epi32(tmp15, 31); - tmp8 = _mm_srli_epi32(tmp17, 31); - tmp16 = _mm_slli_epi32(tmp15, 1); - tmp18 = _mm_slli_epi32(tmp17, 1); - tmp9 = _mm_srli_si128(tmp7, 12); - tmp22 = _mm_slli_si128(tmp8, 4); - tmp25 = _mm_slli_si128(tmp7, 4); - tmp29 = _mm_or_si128(tmp16, tmp25); - tmp19 = _mm_or_si128(tmp18, tmp22); - tmp20 = _mm_or_si128(tmp19, tmp9); - tmp26 = _mm_slli_epi32(tmp29, 31); - tmp23 = _mm_slli_epi32(tmp29, 30); - tmp32 = _mm_slli_epi32(tmp29, 25); - tmp27 = _mm_xor_si128(tmp26, tmp23); - tmp28 = _mm_xor_si128(tmp27, tmp32); - tmp24 = _mm_srli_si128(tmp28, 4); - tmp33 = _mm_slli_si128(tmp28, 12); - tmp30 = _mm_xor_si128(tmp29, tmp33); - tmp2 = _mm_srli_epi32(tmp30, 1); - tmp12 = _mm_srli_epi32(tmp30, 2); - tmp14 = _mm_srli_epi32(tmp30, 7); - tmp34 = _mm_xor_si128(tmp2, tmp12); - tmp35 = _mm_xor_si128(tmp34, tmp14); - tmp36 = _mm_xor_si128(tmp35, tmp24); - tmp31 = _mm_xor_si128(tmp30, tmp36); - tmp21 = _mm_xor_si128(tmp20, tmp31); - _mm_storeu_si128((__m128i *) c, tmp21); + for (j = 0; j < PARALLEL_BLOCKS; j++) { + ts[j] = AES_ENCRYPTLAST(ts[j], st->rkeys[i]); + ts[j] = XOR128(ts[j], LOAD128(&src[16 * j])); + } + for (j = 0; j < PARALLEL_BLOCKS; j++) { + STORE128(&dst[16 * j], ts[j]); + } } -/* pure multiplication, for pre-computing powers of H */ -static inline __m128i -mulv(__m128i A, __m128i B) +/* Square a field element */ + +static inline I256 __vectorcall clsq128(const BlockVec x) { - __m128i tmp3 = _mm_clmulepi64_si128(A, B, 0x00); - __m128i tmp4 = _mm_clmulepi64_si128(A, B, 0x10); - __m128i tmp5 = _mm_clmulepi64_si128(A, B, 0x01); - __m128i tmp6 = _mm_clmulepi64_si128(A, B, 0x11); - __m128i tmp10 = _mm_xor_si128(tmp4, tmp5); - __m128i tmp13 = _mm_slli_si128(tmp10, 8); - __m128i tmp11 = _mm_srli_si128(tmp10, 8); - __m128i tmp15 = _mm_xor_si128(tmp3, tmp13); - __m128i tmp17 = _mm_xor_si128(tmp6, tmp11); - __m128i tmp7 = _mm_srli_epi32(tmp15, 31); - __m128i tmp8 = _mm_srli_epi32(tmp17, 31); - __m128i tmp16 = _mm_slli_epi32(tmp15, 1); - __m128i tmp18 = _mm_slli_epi32(tmp17, 1); - __m128i tmp9 = _mm_srli_si128(tmp7, 12); - __m128i tmp22 = _mm_slli_si128(tmp8, 4); - __m128i tmp25 = _mm_slli_si128(tmp7, 4); - __m128i tmp29 = _mm_or_si128(tmp16, tmp25); - __m128i tmp19 = _mm_or_si128(tmp18, tmp22); - __m128i tmp20 = _mm_or_si128(tmp19, tmp9); - __m128i tmp26 = _mm_slli_epi32(tmp29, 31); - __m128i tmp23 = _mm_slli_epi32(tmp29, 30); - __m128i tmp32 = _mm_slli_epi32(tmp29, 25); - __m128i tmp27 = _mm_xor_si128(tmp26, tmp23); - __m128i tmp28 = _mm_xor_si128(tmp27, tmp32); - __m128i tmp24 = _mm_srli_si128(tmp28, 4); - __m128i tmp33 = _mm_slli_si128(tmp28, 12); - __m128i tmp30 = _mm_xor_si128(tmp29, tmp33); - __m128i tmp2 = _mm_srli_epi32(tmp30, 1); - __m128i tmp12 = _mm_srli_epi32(tmp30, 2); - __m128i tmp14 = _mm_srli_epi32(tmp30, 7); - __m128i tmp34 = _mm_xor_si128(tmp2, tmp12); - __m128i tmp35 = _mm_xor_si128(tmp34, tmp14); - __m128i tmp36 = _mm_xor_si128(tmp35, tmp24); - __m128i tmp31 = _mm_xor_si128(tmp30, tmp36); - __m128i C = _mm_xor_si128(tmp20, tmp31); - - return C; + const BlockVec r_lo = CLMULLO128(x, x); + const BlockVec r_hi = CLMULHI128(x, x); + + return (I256) { + SODIUM_C99(.hi =) r_hi, + SODIUM_C99(.lo =) r_lo, + SODIUM_C99(.mid =) ZERO128, + }; } -/* 4 multiply-accumulate at once; again - - for the Aggregated Reduction Method & sample code. - Algorithm by Krzysztof Jankowski, Pierre Laurent - Intel */ - -#define RED_DECL(a) __m128i H##a##_X##a##_lo, H##a##_X##a##_hi, tmp##a, tmp##a##B -#define RED_SHUFFLE(a) X##a = _mm_shuffle_epi8(X##a, rev) -#define RED_MUL_LOW(a) H##a##_X##a##_lo = _mm_clmulepi64_si128(H##a, X##a, 0x00) -#define RED_MUL_HIGH(a) H##a##_X##a##_hi = _mm_clmulepi64_si128(H##a, X##a, 0x11) -#define RED_MUL_MID(a) \ - tmp##a = _mm_shuffle_epi32(H##a, 0x4e); \ - tmp##a##B = _mm_shuffle_epi32(X##a, 0x4e); \ - tmp##a = _mm_xor_si128(tmp##a, H##a); \ - tmp##a##B = _mm_xor_si128(tmp##a##B, X##a); \ - tmp##a = _mm_clmulepi64_si128(tmp##a, tmp##a##B, 0x00) - -#define MULREDUCE4(rev, H0_, H1_, H2_, H3_, X0_, X1_, X2_, X3_, accv) \ -do { \ - MAKE4(RED_DECL); \ - __m128i lo, hi; \ - __m128i tmp8, tmp9; \ - __m128i H0 = H0_; \ - __m128i H1 = H1_; \ - __m128i H2 = H2_; \ - __m128i H3 = H3_; \ - __m128i X0 = X0_; \ - __m128i X1 = X1_; \ - __m128i X2 = X2_; \ - __m128i X3 = X3_; \ -\ -/* byte-revert the inputs & xor the first one into the accumulator */ \ -\ - MAKE4(RED_SHUFFLE); \ - X3 = _mm_xor_si128(X3, accv); \ -\ -/* 4 low H*X (x0*h0) */ \ -\ - MAKE4(RED_MUL_LOW); \ - lo = _mm_xor_si128(H0_X0_lo, H1_X1_lo); \ - lo = _mm_xor_si128(lo, H2_X2_lo); \ - lo = _mm_xor_si128(lo, H3_X3_lo); \ -\ -/* 4 high H*X (x1*h1) */ \ -\ - MAKE4(RED_MUL_HIGH); \ - hi = _mm_xor_si128(H0_X0_hi, H1_X1_hi); \ - hi = _mm_xor_si128(hi, H2_X2_hi); \ - hi = _mm_xor_si128(hi, H3_X3_hi); \ -\ -/* 4 middle H*X, using Karatsuba, i.e. \ - x1*h0+x0*h1 =(x1+x0)*(h1+h0)-x1*h1-x0*h0 \ - we already have all x1y1 & x0y0 (accumulated in hi & lo) \ - (0 is low half and 1 is high half) \ - */ \ -/* permute the high and low 64 bits in H1 & X1, \ - so create (h0,h1) from (h1,h0) and (x0,x1) from (x1,x0), \ - then compute (h0+h1,h1+h0) and (x0+x1,x1+x0), \ - and finally multiply \ - */ \ - MAKE4(RED_MUL_MID); \ -\ -/* substracts x1*h1 and x0*h0 */ \ - tmp0 = _mm_xor_si128(tmp0, lo); \ - tmp0 = _mm_xor_si128(tmp0, hi); \ - tmp0 = _mm_xor_si128(tmp1, tmp0); \ - tmp0 = _mm_xor_si128(tmp2, tmp0); \ - tmp0 = _mm_xor_si128(tmp3, tmp0);\ -\ - /* reduction */ \ - tmp0B = _mm_slli_si128(tmp0, 8); \ - tmp0 = _mm_srli_si128(tmp0, 8); \ - lo = _mm_xor_si128(tmp0B, lo); \ - hi = _mm_xor_si128(tmp0, hi); \ - tmp3 = lo; \ - tmp2B = hi; \ - tmp3B = _mm_srli_epi32(tmp3, 31); \ - tmp8 = _mm_srli_epi32(tmp2B, 31); \ - tmp3 = _mm_slli_epi32(tmp3, 1); \ - tmp2B = _mm_slli_epi32(tmp2B, 1); \ - tmp9 = _mm_srli_si128(tmp3B, 12); \ - tmp8 = _mm_slli_si128(tmp8, 4); \ - tmp3B = _mm_slli_si128(tmp3B, 4); \ - tmp3 = _mm_or_si128(tmp3, tmp3B); \ - tmp2B = _mm_or_si128(tmp2B, tmp8); \ - tmp2B = _mm_or_si128(tmp2B, tmp9); \ - tmp3B = _mm_slli_epi32(tmp3, 31); \ - tmp8 = _mm_slli_epi32(tmp3, 30); \ - tmp9 = _mm_slli_epi32(tmp3, 25); \ - tmp3B = _mm_xor_si128(tmp3B, tmp8); \ - tmp3B = _mm_xor_si128(tmp3B, tmp9); \ - tmp8 = _mm_srli_si128(tmp3B, 4); \ - tmp3B = _mm_slli_si128(tmp3B, 12); \ - tmp3 = _mm_xor_si128(tmp3, tmp3B); \ - tmp2 = _mm_srli_epi32(tmp3, 1); \ - tmp0B = _mm_srli_epi32(tmp3, 2); \ - tmp1B = _mm_srli_epi32(tmp3, 7); \ - tmp2 = _mm_xor_si128(tmp2, tmp0B); \ - tmp2 = _mm_xor_si128(tmp2, tmp1B); \ - tmp2 = _mm_xor_si128(tmp2, tmp8); \ - tmp3 = _mm_xor_si128(tmp3, tmp2); \ - tmp2B = _mm_xor_si128(tmp2B, tmp3); \ -\ - accv = tmp2B; \ -} while(0) - -#define XORx(a) \ - temp##a = _mm_xor_si128(temp##a, \ - _mm_loadu_si128((const __m128i *) (in + a * 16))) - -#define LOADx(a) \ - __m128i in##a = _mm_loadu_si128((const __m128i *) (in + a * 16)) - -/* full encrypt & checksum 8 blocks at once */ -#define aesni_encrypt8full(out_, n_, rkeys, in_, accum, hv_, h2v_, h3v_, h4v_, rev) \ -do { \ - unsigned char *out = out_; \ - uint32_t *n = n_; \ - const unsigned char *in = in_; \ - const __m128i hv = hv_; \ - const __m128i h2v = h2v_; \ - const __m128i h3v = h3v_; \ - const __m128i h4v = h4v_; \ - const __m128i pt = _mm_set_epi8(12, 13, 14, 15, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \ - __m128i accv_; \ - int roundctr; \ - \ - MAKE8(NVDECLx); \ - MAKE8(TEMPDECLx); \ - MAKE8(NVx); \ - MAKE8(TEMPx); \ - for (roundctr = 1; roundctr < 14; roundctr++) { \ - MAKE8(AESENCx); \ - } \ - MAKE8(AESENCLASTx); \ - MAKE8(XORx); \ - MAKE8(STOREx); \ - accv_ = _mm_load_si128((const __m128i *) accum); \ - MULREDUCE4(rev, hv, h2v, h3v, h4v, temp3, temp2, temp1, temp0, accv_); \ - MULREDUCE4(rev, hv, h2v, h3v, h4v, temp7, temp6, temp5, temp4, accv_); \ - _mm_store_si128((__m128i *) accum, accv_); \ -} while(0) - -/* checksum 8 blocks at once */ -#define aesni_addmul8full(in_, accum, hv_, h2v_, h3v_, h4v_, rev) \ -do { \ - const unsigned char *in = in_; \ - const __m128i hv = hv_; \ - const __m128i h2v = h2v_; \ - const __m128i h3v = h3v_; \ - const __m128i h4v = h4v_; \ - __m128i accv_; \ - \ - MAKE8(LOADx); \ - accv_ = _mm_load_si128((const __m128i *) accum); \ - MULREDUCE4(rev, hv, h2v, h3v, h4v, in3, in2, in1, in0, accv_); \ - MULREDUCE4(rev, hv, h2v, h3v, h4v, in7, in6, in5, in4, accv_); \ - _mm_store_si128((__m128i *) accum, accv_); \ -} while(0) - -/* decrypt 8 blocks at once */ -#define aesni_decrypt8full(out_, n_, rkeys, in_) \ -do { \ - unsigned char *out = out_; \ - uint32_t *n = n_; \ - const unsigned char *in = in_; \ - const __m128i pt = _mm_set_epi8(12, 13, 14, 15, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); \ - int roundctr; \ -\ - MAKE8(NVDECLx); \ - MAKE8(TEMPDECLx); \ - MAKE8(NVx); \ - MAKE8(TEMPx); \ - for (roundctr = 1; roundctr < 14; roundctr++) { \ - MAKE8(AESENCx); \ - } \ - MAKE8(AESENCLASTx); \ - MAKE8(XORx); \ - MAKE8(STOREx); \ -} while(0) +/* Multiply two field elements -- Textbook multiplication is faster than Karatsuba on some recent + * CPUs */ -int -crypto_aead_aes256gcm_beforenm(crypto_aead_aes256gcm_state *ctx_, - const unsigned char *k) +static inline I256 __vectorcall clmul128(const BlockVec x, const BlockVec y) +{ +#ifdef USE_KARATSUBA_MULTIPLICATION + const BlockVec x_hi = BYTESHR128(x, 8); + const BlockVec y_hi = BYTESHR128(y, 8); + const BlockVec r_lo = CLMULLO128(x, y); + const BlockVec r_hi = CLMULHI128(x, y); + const BlockVec r_mid = XOR128(CLMULLO128(XOR128(x, x_hi), XOR128(y, y_hi)), XOR128(r_lo, r_hi)); + + return (I256) { + SODIUM_C99(.hi =) r_hi, + SODIUM_C99(.lo =) r_lo, + SODIUM_C99(.mid =) r_mid, + }; +#else + const BlockVec r_hi = CLMULHI128(x, y); + const BlockVec r_lo = CLMULLO128(x, y); + const BlockVec r_mid = XOR128(CLMULHILO128(x, y), CLMULLOHI128(x, y)); + + return (I256) { + SODIUM_C99(.hi =) r_hi, + SODIUM_C99(.lo =) r_lo, + SODIUM_C99(.mid =) r_mid, + }; +#endif +} + +/* Merge the middle word and reduce a field element */ + +static inline BlockVec __vectorcall gcm_reduce(const I256 x) { - aes256gcm_state *ctx = (aes256gcm_state *) (void *) ctx_; - unsigned char *H = ctx->H; - __m128i *rkeys = ctx->rkeys; - __m128i zero = _mm_setzero_si128(); + const BlockVec hi = XOR128(x.hi, BYTESHR128(x.mid, 8)); + const BlockVec lo = XOR128(x.lo, BYTESHL128(x.mid, 8)); - COMPILER_ASSERT((sizeof *ctx_) >= (sizeof *ctx)); - aesni_key256_expand(k, rkeys); - aesni_encrypt1(H, zero, rkeys); + const BlockVec p64 = SET64x2(0, 0xc200000000000000); + const BlockVec a = CLMULLO128(lo, p64); + const BlockVec b = XOR128(SHUFFLE32x4(lo, 2, 3, 0, 1), a); + const BlockVec c = CLMULLO128(b, p64); + const BlockVec d = XOR128(SHUFFLE32x4(b, 2, 3, 0, 1), c); - return 0; + return XOR128(d, hi); } -int -crypto_aead_aes256gcm_encrypt_detached_afternm(unsigned char *c, - unsigned char *mac, unsigned long long *maclen_p, - const unsigned char *m, unsigned long long mlen, - const unsigned char *ad, unsigned long long adlen, - const unsigned char *nsec, - const unsigned char *npub, - const crypto_aead_aes256gcm_state *ctx_) +/* Precompute powers of H from `from` to `to` */ + +static inline void __vectorcall precomp(Precomp hx[PC_COUNT], const size_t from, const size_t to) { - const __m128i rev = _mm_set_epi8(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); - const aes256gcm_state *ctx = (const aes256gcm_state *) (const void *) ctx_; - const __m128i *rkeys = ctx->rkeys; - __m128i Hv, H2v, H3v, H4v, accv; - unsigned long long i, j; - unsigned long long adlen_rnd64 = adlen & ~63ULL; - unsigned long long mlen_rnd128 = mlen & ~127ULL; - CRYPTO_ALIGN(16) uint32_t n2[4]; - CRYPTO_ALIGN(16) unsigned char H[16]; - CRYPTO_ALIGN(16) unsigned char T[16]; - CRYPTO_ALIGN(16) unsigned char accum[16]; - CRYPTO_ALIGN(16) unsigned char fb[16]; + const Precomp h = hx[0]; + size_t i; - (void) nsec; - memcpy(H, ctx->H, sizeof H); - if (mlen > crypto_aead_aes256gcm_MESSAGEBYTES_MAX) { - sodium_misuse(); /* LCOV_EXCL_LINE */ + for (i = from & ~1U; i < to; i += 2) { + hx[i] = gcm_reduce(clmul128(hx[i - 1], h)); + hx[i + 1] = gcm_reduce(clsq128(hx[i / 2])); } - memcpy(&n2[0], npub, 3 * 4); - n2[3] = 0x01000000; - aesni_encrypt1(T, _mm_load_si128((const __m128i *) n2), rkeys); - { - uint64_t x; - x = _bswap64((uint64_t) (8 * adlen)); - memcpy(&fb[0], &x, sizeof x); - x = _bswap64((uint64_t) (8 * mlen)); - memcpy(&fb[8], &x, sizeof x); +} + +/* Precompute powers of H given a key and a block count */ + +static void __vectorcall precomp_for_block_count(Precomp hx[PC_COUNT], + const unsigned char gh_key[16], + const size_t block_count) +{ + const BlockVec h0 = REV128(LOAD128(gh_key)); + BlockVec carry = SET64x2(0xc200000000000000, 1); + BlockVec mask = SUB64x2(ZERO128, SHR64x2(h0, 63)); + BlockVec h0_shifted; + BlockVec h; + + mask = SHUFFLE32x4(mask, 3, 3, 3, 3); + carry = AND128(carry, mask); + h0_shifted = SHL128(h0, 1); + h = XOR128(h0_shifted, carry); + + hx[0] = h; + hx[1] = gcm_reduce(clsq128(hx[0])); + + if (block_count >= PC_COUNT) { + precomp(hx, 2, PC_COUNT); + } else { + precomp(hx, 2, block_count); } - /* we store H (and it's power) byte-reverted once and for all */ - Hv = _mm_shuffle_epi8(_mm_load_si128((const __m128i *) H), rev); - _mm_store_si128((__m128i *) H, Hv); - H2v = mulv(Hv, Hv); - H3v = mulv(H2v, Hv); - H4v = mulv(H3v, Hv); - - accv = _mm_setzero_si128(); - /* unrolled by 4 GCM (by 8 doesn't improve using MULREDUCE4) */ - for (i = 0; i < adlen_rnd64; i += 64) { - __m128i X4_ = _mm_loadu_si128((const __m128i *) (ad + i + 0)); - __m128i X3_ = _mm_loadu_si128((const __m128i *) (ad + i + 16)); - __m128i X2_ = _mm_loadu_si128((const __m128i *) (ad + i + 32)); - __m128i X1_ = _mm_loadu_si128((const __m128i *) (ad + i + 48)); - MULREDUCE4(rev, Hv, H2v, H3v, H4v, X1_, X2_, X3_, X4_, accv); +} + +/* Initialize a GHash */ + +static inline void +gh_init(GHash *sth) +{ + sth->acc = ZERO128; +} + +static inline I256 __vectorcall gh_update0(const GHash *const sth, const unsigned char *const p, + const Precomp hn) +{ + const BlockVec m = REV128(LOAD128(p)); + return clmul128(XOR128(sth->acc, m), hn); +} + +static inline void __vectorcall gh_update(I256 *const u, const unsigned char *p, const Precomp hn) +{ + const BlockVec m = REV128(LOAD128(p)); + const I256 t = clmul128(m, hn); + *u = (I256) { SODIUM_C99(.hi =) XOR128(u->hi, t.hi), SODIUM_C99(.lo =) XOR128(u->lo, t.lo), + SODIUM_C99(.mid =) XOR128(u->mid, t.mid) }; +} + +/* Absorb ad_len bytes of associated data. There has to be no partial block. */ + +static inline void +gh_ad_blocks(const State *st, GHash *sth, const unsigned char *ad, size_t ad_len) +{ + size_t i; + + i = (size_t) 0U; + for (; i + PC_COUNT * 16 <= ad_len; i += PC_COUNT * 16) { + I256 u = gh_update0(sth, ad + i, st->hx[PC_COUNT - 1 - 0]); + size_t j; + + for (j = 1; j < PC_COUNT; j += 1) { + gh_update(&u, ad + i + j * 16, st->hx[PC_COUNT - 1 - j]); + } + sth->acc = gcm_reduce(u); } - _mm_store_si128((__m128i *) accum, accv); + for (; i + PC_COUNT * 16 / 2 <= ad_len; i += PC_COUNT * 16 / 2) { + I256 u = gh_update0(sth, ad + i, st->hx[PC_COUNT / 2 - 1 - 0]); + size_t j; - /* GCM remainder loop */ - for (i = adlen_rnd64; i < adlen; i += 16) { - unsigned int blocklen = 16; + for (j = 1; j < PC_COUNT / 2; j += 1) { + gh_update(&u, ad + i + j * 16, st->hx[PC_COUNT / 2 - 1 - j]); + } + sth->acc = gcm_reduce(u); + } + for (; i + 4 * 16 <= ad_len; i += 4 * 16) { + size_t j; + I256 u = gh_update0(sth, ad + i, st->hx[4 - 1 - 0]); - if (i + (unsigned long long) blocklen > adlen) { - blocklen = (unsigned int) (adlen - i); + for (j = 1; j < 4; j += 1) { + gh_update(&u, ad + i + j * 16, st->hx[4 - 1 - j]); } - addmul(accum, ad + i, blocklen, H); + sth->acc = gcm_reduce(u); } + for (; i + 2 * 16 <= ad_len; i += 2 * 16) { + size_t j; + I256 u = gh_update0(sth, ad + i, st->hx[2 - 1 - 0]); -/* this only does 8 full blocks, so no fancy bounds checking is necessary*/ -#define LOOPRND128 \ - do { \ - const int iter = 8; \ - const int lb = iter * 16; \ - \ - for (i = 0; i < mlen_rnd128; i += lb) { \ - aesni_encrypt8full(c + i, n2, rkeys, m + i, accum, Hv, H2v, H3v, H4v, rev); \ - } \ - } while(0) - -/* remainder loop, with the slower GCM update to accommodate partial blocks */ -#define LOOPRMD128 \ - do { \ - const int iter = 8; \ - const int lb = iter * 16; \ - \ - for (i = mlen_rnd128; i < mlen; i += lb) { \ - CRYPTO_ALIGN(16) unsigned char outni[8 * 16]; \ - unsigned long long mj = lb; \ - \ - aesni_encrypt8(outni, n2, rkeys); \ - if ((i + mj) >= mlen) { \ - mj = mlen - i; \ - } \ - for (j = 0; j < mj; j++) { \ - c[i + j] = m[i + j] ^ outni[j]; \ - } \ - for (j = 0; j < mj; j += 16) { \ - unsigned int bl = 16; \ - \ - if (j + (unsigned long long) bl >= mj) { \ - bl = (unsigned int) (mj - j); \ - } \ - addmul(accum, c + i + j, bl, H); \ - } \ - } \ - } while(0) - - n2[3] &= 0x00ffffff; - COUNTER_INC2(n2); - LOOPRND128; - LOOPRMD128; - - addmul(accum, fb, 16, H); - - for (i = 0; i < 16; ++i) { - mac[i] = T[i] ^ accum[15 - i]; + for (j = 1; j < 2; j += 1) { + gh_update(&u, ad + i + j * 16, st->hx[2 - 1 - j]); + } + sth->acc = gcm_reduce(u); } - if (maclen_p != NULL) { - *maclen_p = 16; + if (i < ad_len) { + I256 u = gh_update0(sth, ad + i, st->hx[0]); + sth->acc = gcm_reduce(u); } - return 0; } -int -crypto_aead_aes256gcm_encrypt_afternm(unsigned char *c, unsigned long long *clen_p, - const unsigned char *m, unsigned long long mlen, - const unsigned char *ad, unsigned long long adlen, - const unsigned char *nsec, - const unsigned char *npub, - const crypto_aead_aes256gcm_state *ctx_) +/* Increment counters */ + +static inline BlockVec __vectorcall incr_counters(BlockVec rev_counters[], BlockVec counter, + const size_t n) { - int ret = crypto_aead_aes256gcm_encrypt_detached_afternm(c, - c + mlen, NULL, - m, mlen, - ad, adlen, - nsec, npub, ctx_); - if (clen_p != NULL) { - *clen_p = mlen + crypto_aead_aes256gcm_ABYTES; + size_t i; + + const BlockVec one = ONE128; + for (i = 0; i < n; i++) { + rev_counters[i] = REV128(counter); + counter = ADD64x2(counter, one); } - return ret; + return counter; } -int -crypto_aead_aes256gcm_decrypt_detached_afternm(unsigned char *m, unsigned char *nsec, - const unsigned char *c, unsigned long long clen, - const unsigned char *mac, - const unsigned char *ad, unsigned long long adlen, - const unsigned char *npub, - const crypto_aead_aes256gcm_state *ctx_) +/* Compute the number of required blocks to encrypt and authenticate `ad_len` of associated data, + * and `m_len` of encrypted bytes. Return `0` if limits would be exceeded.*/ + +static inline size_t +required_blocks(const size_t ad_len, const size_t m_len) { - const __m128i rev = _mm_set_epi8(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15); - const aes256gcm_state *ctx = (const aes256gcm_state *) (const void *) ctx_; - const __m128i *rkeys = ctx->rkeys; - __m128i Hv, H2v, H3v, H4v, accv; - unsigned long long i, j; - unsigned long long adlen_rnd64 = adlen & ~63ULL; - unsigned long long mlen; - unsigned long long mlen_rnd128; - CRYPTO_ALIGN(16) uint32_t n2[4]; - CRYPTO_ALIGN(16) unsigned char H[16]; - CRYPTO_ALIGN(16) unsigned char T[16]; - CRYPTO_ALIGN(16) unsigned char accum[16]; - CRYPTO_ALIGN(16) unsigned char fb[16]; + const size_t ad_blocks = (ad_len + 15) / 16; + const size_t m_blocks = (m_len + 15) / 16; - (void) nsec; - if (clen > crypto_aead_aes256gcm_MESSAGEBYTES_MAX) { - sodium_misuse(); /* LCOV_EXCL_LINE */ + if (ad_len > SIZE_MAX - 2 * PARALLEL_BLOCKS * 16 || + m_len > SIZE_MAX - 2 * PARALLEL_BLOCKS * 16 || ad_len < ad_blocks || m_len < m_blocks || + m_blocks >= (1ULL << 32) - 2) { + return 0; } - mlen = clen; - - memcpy(&n2[0], npub, 3 * 4); - n2[3] = 0x01000000; - aesni_encrypt1(T, _mm_load_si128((const __m128i *) n2), rkeys); - - { - uint64_t x; - x = _bswap64((uint64_t)(8 * adlen)); - memcpy(&fb[0], &x, sizeof x); - x = _bswap64((uint64_t)(8 * mlen)); - memcpy(&fb[8], &x, sizeof x); + return ad_blocks + m_blocks + 1; +} + +/* Generic AES-GCM encryption. "Generic" as it can handle arbitrary input sizes, +unlike a length-limited version that would precompute all the required powers of H */ + +static void +aes_gcm_encrypt_generic(const State *st, GHash *sth, unsigned char mac[ABYTES], unsigned char *dst, + const unsigned char *src, size_t src_len, const unsigned char *ad, + size_t ad_len, unsigned char counter_[16]) +{ + CRYPTO_ALIGN(32) I256 u; + CRYPTO_ALIGN(16) unsigned char last_blocks[2 * 16]; + const BlockVec one = ONE128; + BlockVec final_block; + BlockVec rev_counters[PARALLEL_BLOCKS]; + BlockVec counter; + size_t i; + size_t j; + size_t left; + size_t pi; + + COMPILER_ASSERT(PC_COUNT % PARALLEL_BLOCKS == 0); + + /* Associated data */ + + if (ad != NULL && ad_len != 0) { + gh_ad_blocks(st, sth, ad, ad_len & ~15); + left = ad_len & 15; + if (left != 0) { + unsigned char pad[16]; + + memset(pad, 0, sizeof pad); + memcpy(pad, ad + ad_len - left, left); + gh_ad_blocks(st, sth, pad, sizeof pad); + } } - memcpy(H, ctx->H, sizeof H); - Hv = _mm_shuffle_epi8(_mm_load_si128((const __m128i *) H), rev); - _mm_store_si128((__m128i *) H, Hv); - H2v = mulv(Hv, Hv); - H3v = mulv(H2v, Hv); - H4v = mulv(H3v, Hv); - - accv = _mm_setzero_si128(); - for (i = 0; i < adlen_rnd64; i += 64) { - __m128i X4_ = _mm_loadu_si128((const __m128i *) (ad + i + 0)); - __m128i X3_ = _mm_loadu_si128((const __m128i *) (ad + i + 16)); - __m128i X2_ = _mm_loadu_si128((const __m128i *) (ad + i + 32)); - __m128i X1_ = _mm_loadu_si128((const __m128i *) (ad + i + 48)); - MULREDUCE4(rev, Hv, H2v, H3v, H4v, X1_, X2_, X3_, X4_, accv); + /* Encrypted data */ + + counter = REV128(LOAD128(counter_)); + i = 0; + + /* 2*PARALLEL_BLOCKS aggregation */ + + if (src_len - i >= 2 * PARALLEL_BLOCKS * 16) { + counter = incr_counters(rev_counters, counter, PARALLEL_BLOCKS); + encrypt_xor_wide(st, dst + i, src + i, rev_counters); + i += PARALLEL_BLOCKS * 16; + + for (; i + 2 * PARALLEL_BLOCKS * 16 <= src_len; i += 2 * PARALLEL_BLOCKS * 16) { + counter = incr_counters(rev_counters, counter, PARALLEL_BLOCKS); + encrypt_xor_wide(st, dst + i, src + i, rev_counters); + + PREFETCH_READ(src + i + PARALLEL_BLOCKS * 16); +#if PARALLEL_BLOCKS >= 64 / 16 + PREFETCH_READ(src + i + PARALLEL_BLOCKS * 16 + 64); +#endif + + pi = i - PARALLEL_BLOCKS * 16; + u = gh_update0(sth, dst + pi, st->hx[2 * PARALLEL_BLOCKS - 1 - 0]); + for (j = 1; j < PARALLEL_BLOCKS; j += 1) { + gh_update(&u, dst + pi + j * 16, st->hx[2 * PARALLEL_BLOCKS - 1 - j]); + } + + counter = incr_counters(rev_counters, counter, PARALLEL_BLOCKS); + encrypt_xor_wide(st, dst + i + PARALLEL_BLOCKS * 16, src + i + PARALLEL_BLOCKS * 16, + rev_counters); + + PREFETCH_READ(src + i + 2 * PARALLEL_BLOCKS * 16); +#if PARALLEL_BLOCKS >= 64 / 16 + PREFETCH_READ(src + i + 2 * PARALLEL_BLOCKS * 16 + 64); +#endif + pi = i; + for (j = 0; j < PARALLEL_BLOCKS; j += 1) { + gh_update(&u, dst + pi + j * 16, st->hx[PARALLEL_BLOCKS - 1 - j]); + } + sth->acc = gcm_reduce(u); + } + + pi = i - PARALLEL_BLOCKS * 16; + u = gh_update0(sth, dst + pi, st->hx[PARALLEL_BLOCKS - 1 - 0]); + for (j = 1; j < PARALLEL_BLOCKS; j += 1) { + gh_update(&u, dst + pi + j * 16, st->hx[PARALLEL_BLOCKS - 1 - j]); + } + sth->acc = gcm_reduce(u); } - _mm_store_si128((__m128i *) accum, accv); - for (i = adlen_rnd64; i < adlen; i += 16) { - unsigned int blocklen = 16; - if (i + (unsigned long long) blocklen > adlen) { - blocklen = (unsigned int) (adlen - i); + /* PARALLEL_BLOCKS aggregation */ + + if (src_len - i >= PARALLEL_BLOCKS * 16) { + counter = incr_counters(rev_counters, counter, PARALLEL_BLOCKS); + encrypt_xor_wide(st, dst + i, src + i, rev_counters); + i += PARALLEL_BLOCKS * 16; + + for (; i + PARALLEL_BLOCKS * 16 <= src_len; i += PARALLEL_BLOCKS * 16) { + counter = incr_counters(rev_counters, counter, PARALLEL_BLOCKS); + encrypt_xor_wide(st, dst + i, src + i, rev_counters); + + pi = i - PARALLEL_BLOCKS * 16; + u = gh_update0(sth, dst + pi, st->hx[PARALLEL_BLOCKS - 1 - 0]); + for (j = 1; j < PARALLEL_BLOCKS; j += 1) { + gh_update(&u, dst + pi + j * 16, st->hx[PARALLEL_BLOCKS - 1 - j]); + } + sth->acc = gcm_reduce(u); + } + + pi = i - PARALLEL_BLOCKS * 16; + u = gh_update0(sth, dst + pi, st->hx[PARALLEL_BLOCKS - 1 - 0]); + for (j = 1; j < PARALLEL_BLOCKS; j += 1) { + gh_update(&u, dst + pi + j * 16, st->hx[PARALLEL_BLOCKS - 1 - j]); } - addmul(accum, ad + i, blocklen, H); + sth->acc = gcm_reduce(u); } - mlen_rnd128 = mlen & ~127ULL; - -#define LOOPACCUMDRND128 \ - do { \ - const int iter = 8; \ - const int lb = iter * 16; \ - for (i = 0; i < mlen_rnd128; i += lb) { \ - aesni_addmul8full(c + i, accum, Hv, H2v, H3v, H4v, rev); \ - } \ - } while(0) - -#define LOOPDRND128 \ - do { \ - const int iter = 8; \ - const int lb = iter * 16; \ - \ - for (i = 0; i < mlen_rnd128; i += lb) { \ - aesni_decrypt8full(m + i, n2, rkeys, c + i); \ - } \ - } while(0) - -#define LOOPACCUMDRMD128 \ - do { \ - const int iter = 8; \ - const int lb = iter * 16; \ - \ - for (i = mlen_rnd128; i < mlen; i += lb) { \ - unsigned long long mj = lb; \ - \ - if ((i + mj) >= mlen) { \ - mj = mlen - i; \ - } \ - for (j = 0; j < mj; j += 16) { \ - unsigned int bl = 16; \ - \ - if (j + (unsigned long long) bl >= mj) { \ - bl = (unsigned int) (mj - j); \ - } \ - addmul(accum, c + i + j, bl, H); \ - } \ - } \ - } while(0) - -#define LOOPDRMD128 \ - do { \ - const int iter = 8; \ - const int lb = iter * 16; \ - \ - for (i = mlen_rnd128; i < mlen; i += lb) { \ - CRYPTO_ALIGN(16) unsigned char outni[8 * 16]; \ - unsigned long long mj = lb; \ - \ - if ((i + mj) >= mlen) { \ - mj = mlen - i; \ - } \ - aesni_encrypt8(outni, n2, rkeys); \ - for (j = 0; j < mj; j++) { \ - m[i + j] = c[i + j] ^ outni[j]; \ - } \ - } \ - } while(0) - - n2[3] &= 0x00ffffff; - - COUNTER_INC2(n2); - LOOPACCUMDRND128; - LOOPACCUMDRMD128; - addmul(accum, fb, 16, H); - { - unsigned char d = 0; - - for (i = 0; i < 16; i++) { - d |= (mac[i] ^ (T[i] ^ accum[15 - i])); + /* 4-blocks aggregation */ + + for (; i + 4 * 16 <= src_len; i += 4 * 16) { + counter = incr_counters(rev_counters, counter, 4); + for (j = 0; j < 4; j++) { + encrypt_xor_block(st, dst + i + j * 16, src + i + j * 16, rev_counters[j]); } - if (d != 0) { - if (m != NULL) { - memset(m, 0, mlen); - } - return -1; + + u = gh_update0(sth, dst + i, st->hx[4 - 1 - 0]); + for (j = 1; j < 4; j += 1) { + gh_update(&u, dst + i + j * 16, st->hx[4 - 1 - j]); + } + sth->acc = gcm_reduce(u); + } + + /* 2-blocks aggregation */ + + for (; i + 2 * 16 <= src_len; i += 2 * 16) { + counter = incr_counters(rev_counters, counter, 2); + for (j = 0; j < 2; j++) { + encrypt_xor_block(st, dst + i + j * 16, src + i + j * 16, rev_counters[j]); } - if (m == NULL) { - return 0; + + u = gh_update0(sth, dst + i, st->hx[2 - 1 - 0]); + for (j = 1; j < 2; j += 1) { + gh_update(&u, dst + i + j * 16, st->hx[2 - 1 - j]); } + sth->acc = gcm_reduce(u); } - n2[3] = 0U; - COUNTER_INC2(n2); - LOOPDRND128; - LOOPDRMD128; - return 0; + /* Remaining *partial* blocks; if we have 16 bytes left, we want to keep the + full block authenticated along with the final block, hence < and not <= */ + + for (; i + 16 < src_len; i += 16) { + encrypt_xor_block(st, dst + i, src + i, REV128(counter)); + u = gh_update0(sth, dst + i, st->hx[1 - 1 - 0]); + sth->acc = gcm_reduce(u); + counter = ADD64x2(counter, one); + } + + /* Authenticate both the last block of the message and the final block */ + + final_block = REV128(SET64x2(ad_len * 8, src_len * 8)); + STORE32_BE(counter_ + NPUBBYTES, 1); + encrypt(st, mac, counter_); + left = src_len - i; + if (left != 0) { + for (j = 0; j < left; j++) { + last_blocks[j] = src[i + j]; + } + STORE128(last_blocks + 16, final_block); + encrypt_xor_block(st, last_blocks, last_blocks, REV128(counter)); + for (; j < 16; j++) { + last_blocks[j] = 0; + } + for (j = 0; j < left; j++) { + dst[i + j] = last_blocks[j]; + } + gh_ad_blocks(st, sth, last_blocks, 32); + } else { + STORE128(last_blocks, final_block); + gh_ad_blocks(st, sth, last_blocks, 16); + } + STORE128(mac, XOR128(LOAD128(mac), REV128(sth->acc))); } -int -crypto_aead_aes256gcm_decrypt_afternm(unsigned char *m, unsigned long long *mlen_p, - unsigned char *nsec, - const unsigned char *c, unsigned long long clen, - const unsigned char *ad, unsigned long long adlen, - const unsigned char *npub, - const crypto_aead_aes256gcm_state *ctx_) +/* Generic AES-GCM decryption. "Generic" as it can handle arbitrary input sizes, +unlike a length-limited version that would precompute all the required powers of H */ + +static void +aes_gcm_decrypt_generic(const State *st, GHash *sth, unsigned char mac[ABYTES], unsigned char *dst, + const unsigned char *src, size_t src_len, const unsigned char *ad, + size_t ad_len, unsigned char counter_[16]) { - unsigned long long mlen = 0ULL; - int ret = -1; + CRYPTO_ALIGN(32) I256 u; + CRYPTO_ALIGN(16) unsigned char last_blocks[2 * 16]; + const BlockVec one = ONE128; + BlockVec final_block; + BlockVec rev_counters[PARALLEL_BLOCKS]; + BlockVec counter; + size_t i; + size_t j; + size_t left; + + COMPILER_ASSERT(PC_COUNT % PARALLEL_BLOCKS == 0); - if (clen >= crypto_aead_aes256gcm_ABYTES) { - ret = crypto_aead_aes256gcm_decrypt_detached_afternm - (m, nsec, c, clen - crypto_aead_aes256gcm_ABYTES, - c + clen - crypto_aead_aes256gcm_ABYTES, - ad, adlen, npub, ctx_); + /* Associated data */ + + if (ad != NULL && ad_len != 0) { + gh_ad_blocks(st, sth, ad, ad_len & ~15); + left = ad_len & 15; + if (left != 0) { + unsigned char pad[16]; + + memset(pad, 0, sizeof pad); + memcpy(pad, ad + ad_len - left, left); + gh_ad_blocks(st, sth, pad, sizeof pad); + } } - if (mlen_p != NULL) { - if (ret == 0) { - mlen = clen - crypto_aead_aes256gcm_ABYTES; + + /* Encrypted data */ + + counter = REV128(LOAD128(counter_)); + i = 0; + + /* 2*PARALLEL_BLOCKS aggregation */ + + while (i + 2 * PARALLEL_BLOCKS * 16 <= src_len) { + counter = incr_counters(rev_counters, counter, PARALLEL_BLOCKS); + + u = gh_update0(sth, src + i, st->hx[2 * PARALLEL_BLOCKS - 1 - 0]); + for (j = 1; j < PARALLEL_BLOCKS; j += 1) { + gh_update(&u, src + i + j * 16, st->hx[2 * PARALLEL_BLOCKS - 1 - j]); } - *mlen_p = mlen; + + encrypt_xor_wide(st, dst + i, src + i, rev_counters); + + counter = incr_counters(rev_counters, counter, PARALLEL_BLOCKS); + + i += PARALLEL_BLOCKS * 16; + for (j = 0; j < PARALLEL_BLOCKS; j += 1) { + gh_update(&u, src + i + j * 16, st->hx[PARALLEL_BLOCKS - 1 - j]); + } + sth->acc = gcm_reduce(u); + + encrypt_xor_wide(st, dst + i, src + i, rev_counters); + i += PARALLEL_BLOCKS * 16; } - return ret; -} -int -crypto_aead_aes256gcm_encrypt_detached(unsigned char *c, - unsigned char *mac, - unsigned long long *maclen_p, - const unsigned char *m, - unsigned long long mlen, - const unsigned char *ad, - unsigned long long adlen, - const unsigned char *nsec, - const unsigned char *npub, - const unsigned char *k) -{ - CRYPTO_ALIGN(16) crypto_aead_aes256gcm_state ctx; + /* PARALLEL_BLOCKS aggregation */ - crypto_aead_aes256gcm_beforenm(&ctx, k); + for (; i + PARALLEL_BLOCKS * 16 <= src_len; i += PARALLEL_BLOCKS * 16) { + counter = incr_counters(rev_counters, counter, PARALLEL_BLOCKS); - return crypto_aead_aes256gcm_encrypt_detached_afternm - (c, mac, maclen_p, m, mlen, ad, adlen, nsec, npub, - (const crypto_aead_aes256gcm_state *) &ctx); -} + u = gh_update0(sth, src + i, st->hx[PARALLEL_BLOCKS - 1 - 0]); + for (j = 1; j < PARALLEL_BLOCKS; j += 1) { + gh_update(&u, src + i + j * 16, st->hx[PARALLEL_BLOCKS - 1 - j]); + } + sth->acc = gcm_reduce(u); -int -crypto_aead_aes256gcm_encrypt(unsigned char *c, - unsigned long long *clen_p, - const unsigned char *m, - unsigned long long mlen, - const unsigned char *ad, - unsigned long long adlen, - const unsigned char *nsec, - const unsigned char *npub, - const unsigned char *k) -{ - CRYPTO_ALIGN(16) crypto_aead_aes256gcm_state ctx; - int ret; + encrypt_xor_wide(st, dst + i, src + i, rev_counters); + } - crypto_aead_aes256gcm_beforenm(&ctx, k); + /* 4-blocks aggregation */ - ret = crypto_aead_aes256gcm_encrypt_afternm - (c, clen_p, m, mlen, ad, adlen, nsec, npub, - (const crypto_aead_aes256gcm_state *) &ctx); - sodium_memzero(&ctx, sizeof ctx); + for (; i + 4 * 16 <= src_len; i += 4 * 16) { + counter = incr_counters(rev_counters, counter, 4); - return ret; -} + u = gh_update0(sth, src + i, st->hx[4 - 1 - 0]); + for (j = 1; j < 4; j += 1) { + gh_update(&u, src + i + j * 16, st->hx[4 - 1 - j]); + } + sth->acc = gcm_reduce(u); -int -crypto_aead_aes256gcm_decrypt_detached(unsigned char *m, - unsigned char *nsec, - const unsigned char *c, - unsigned long long clen, - const unsigned char *mac, - const unsigned char *ad, - unsigned long long adlen, - const unsigned char *npub, - const unsigned char *k) -{ - CRYPTO_ALIGN(16) crypto_aead_aes256gcm_state ctx; + for (j = 0; j < 4; j++) { + encrypt_xor_block(st, dst + i + j * 16, src + i + j * 16, rev_counters[j]); + } + } - crypto_aead_aes256gcm_beforenm(&ctx, k); + /* 2-blocks aggregation */ - return crypto_aead_aes256gcm_decrypt_detached_afternm - (m, nsec, c, clen, mac, ad, adlen, npub, - (const crypto_aead_aes256gcm_state *) &ctx); -} + for (; i + 2 * 16 <= src_len; i += 2 * 16) { + counter = incr_counters(rev_counters, counter, 2); -int -crypto_aead_aes256gcm_decrypt(unsigned char *m, - unsigned long long *mlen_p, - unsigned char *nsec, - const unsigned char *c, - unsigned long long clen, - const unsigned char *ad, - unsigned long long adlen, - const unsigned char *npub, - const unsigned char *k) -{ - CRYPTO_ALIGN(16) crypto_aead_aes256gcm_state ctx; - int ret; + u = gh_update0(sth, src + i, st->hx[2 - 1 - 0]); + for (j = 1; j < 2; j += 1) { + gh_update(&u, src + i + j * 16, st->hx[2 - 1 - j]); + } + sth->acc = gcm_reduce(u); - crypto_aead_aes256gcm_beforenm(&ctx, k); + for (j = 0; j < 2; j++) { + encrypt_xor_block(st, dst + i + j * 16, src + i + j * 16, rev_counters[j]); + } + } - ret = crypto_aead_aes256gcm_decrypt_afternm - (m, mlen_p, nsec, c, clen, ad, adlen, npub, - (const crypto_aead_aes256gcm_state *) &ctx); - sodium_memzero(&ctx, sizeof ctx); + /* Remaining *partial* blocks; if we have 16 bytes left, we want to keep the + full block authenticated along with the final block, hence < and not <= */ - return ret; + for (; i + 16 < src_len; i += 16) { + u = gh_update0(sth, src + i, st->hx[1 - 1 - 0]); + sth->acc = gcm_reduce(u); + encrypt_xor_block(st, dst + i, src + i, REV128(counter)); + counter = ADD64x2(counter, one); + } + + /* Authenticate both the last block of the message and the final block */ + + final_block = REV128(SET64x2(ad_len * 8, src_len * 8)); + STORE32_BE(counter_ + NPUBBYTES, 1); + encrypt(st, mac, counter_); + left = src_len - i; + if (left != 0) { + for (j = 0; j < left; j++) { + last_blocks[j] = src[i + j]; + } + for (; j < 16; j++) { + last_blocks[j] = 0; + } + STORE128(last_blocks + 16, final_block); + gh_ad_blocks(st, sth, last_blocks, 32); + encrypt_xor_block(st, last_blocks, last_blocks, REV128(counter)); + for (j = 0; j < left; j++) { + dst[i + j] = last_blocks[j]; + } + } else { + STORE128(last_blocks, final_block); + gh_ad_blocks(st, sth, last_blocks, 16); + } + STORE128(mac, XOR128(LOAD128(mac), REV128(sth->acc))); } int -crypto_aead_aes256gcm_is_available(void) +crypto_aead_aes256gcm_beforenm(crypto_aead_aes256gcm_state *st_, const unsigned char *k) { - return sodium_runtime_has_pclmul() & sodium_runtime_has_aesni(); -} + State *st = (State *) (void *) st_; + CRYPTO_ALIGN(16) unsigned char h[16]; -#else + COMPILER_ASSERT(sizeof *st_ >= sizeof *st); -int -crypto_aead_aes256gcm_encrypt_detached(unsigned char *c, - unsigned char *mac, - unsigned long long *maclen_p, - const unsigned char *m, - unsigned long long mlen, - const unsigned char *ad, - unsigned long long adlen, - const unsigned char *nsec, - const unsigned char *npub, - const unsigned char *k) -{ - errno = ENOSYS; - return -1; -} + expand256(k, st->rkeys); + memset(h, 0, sizeof h); + encrypt(st, h, h); -int -crypto_aead_aes256gcm_encrypt(unsigned char *c, unsigned long long *clen_p, - const unsigned char *m, unsigned long long mlen, - const unsigned char *ad, unsigned long long adlen, - const unsigned char *nsec, const unsigned char *npub, - const unsigned char *k) -{ - errno = ENOSYS; - return -1; -} + precomp_for_block_count(st->hx, h, PC_COUNT); -int -crypto_aead_aes256gcm_decrypt_detached(unsigned char *m, - unsigned char *nsec, - const unsigned char *c, - unsigned long long clen, - const unsigned char *mac, - const unsigned char *ad, - unsigned long long adlen, - const unsigned char *npub, - const unsigned char *k) -{ - errno = ENOSYS; - return -1; + return 0; } int -crypto_aead_aes256gcm_decrypt(unsigned char *m, unsigned long long *mlen_p, - unsigned char *nsec, const unsigned char *c, - unsigned long long clen, const unsigned char *ad, - unsigned long long adlen, const unsigned char *npub, - const unsigned char *k) -{ - errno = ENOSYS; - return -1; +crypto_aead_aes256gcm_encrypt_detached_afternm(unsigned char *c, unsigned char *mac, + unsigned long long *maclen_p, const unsigned char *m, + unsigned long long m_len_, const unsigned char *ad, + unsigned long long ad_len_, + const unsigned char *nsec, const unsigned char *npub, + const crypto_aead_aes256gcm_state *st_) +{ + const State *st = (const State *) (const void *) st_; + GHash sth; + CRYPTO_ALIGN(16) unsigned char j[16]; + size_t gh_required_blocks; + const size_t ad_len = (size_t) ad_len_; + const size_t m_len = (size_t) m_len_; + + (void) nsec; + if (maclen_p != NULL) { + *maclen_p = 0; + } + if (ad_len_ > SODIUM_SIZE_MAX || m_len_ > SODIUM_SIZE_MAX) { + sodium_misuse(); + } + gh_required_blocks = required_blocks(ad_len, m_len); + if (gh_required_blocks == 0) { + memset(mac, 0xd0, ABYTES); + memset(c, 0, m_len); + return -1; + } + + gh_init(&sth); + + memcpy(j, npub, NPUBBYTES); + STORE32_BE(j + NPUBBYTES, 2); + + aes_gcm_encrypt_generic(st, &sth, mac, c, m, m_len, ad, ad_len, j); + + if (maclen_p != NULL) { + *maclen_p = ABYTES; + } + return 0; } int -crypto_aead_aes256gcm_beforenm(crypto_aead_aes256gcm_state *ctx_, - const unsigned char *k) +crypto_aead_aes256gcm_encrypt(unsigned char *c, unsigned long long *clen_p, const unsigned char *m, + unsigned long long m_len, const unsigned char *ad, + unsigned long long ad_len, const unsigned char *nsec, + const unsigned char *npub, const unsigned char *k) { - errno = ENOSYS; - return -1; + const int ret = crypto_aead_aes256gcm_encrypt_detached(c, c + m_len, NULL, m, m_len, ad, ad_len, + nsec, npub, k); + if (clen_p != NULL) { + if (ret == 0) { + *clen_p = m_len + crypto_aead_aes256gcm_ABYTES; + } else { + *clen_p = 0; + } + } + return ret; } int -crypto_aead_aes256gcm_encrypt_detached_afternm(unsigned char *c, - unsigned char *mac, unsigned long long *maclen_p, - const unsigned char *m, unsigned long long mlen, - const unsigned char *ad, unsigned long long adlen, - const unsigned char *nsec, - const unsigned char *npub, - const crypto_aead_aes256gcm_state *ctx_) +crypto_aead_aes256gcm_encrypt_detached(unsigned char *c, unsigned char *mac, + unsigned long long *maclen_p, const unsigned char *m, + unsigned long long m_len, const unsigned char *ad, + unsigned long long ad_len, const unsigned char *nsec, + const unsigned char *npub, const unsigned char *k) { - errno = ENOSYS; - return -1; + CRYPTO_ALIGN(16) crypto_aead_aes256gcm_state st; + int ret; + + PREFETCH_WRITE(c); + PREFETCH_READ(m); + PREFETCH_READ(ad); + + crypto_aead_aes256gcm_beforenm(&st, k); + ret = crypto_aead_aes256gcm_encrypt_detached_afternm(c, mac, maclen_p, m, m_len, ad, ad_len, + nsec, npub, &st); + sodium_memzero(&st, sizeof st); + + return ret; } int @@ -998,82 +820,196 @@ crypto_aead_aes256gcm_encrypt_afternm(unsigned char *c, unsigned long long *clen const unsigned char *m, unsigned long long mlen, const unsigned char *ad, unsigned long long adlen, const unsigned char *nsec, const unsigned char *npub, - const crypto_aead_aes256gcm_state *ctx_) + const crypto_aead_aes256gcm_state *st_) { - errno = ENOSYS; - return -1; + int ret = crypto_aead_aes256gcm_encrypt_detached_afternm(c, c + mlen, NULL, m, mlen, ad, adlen, + nsec, npub, st_); + if (clen_p != NULL) { + *clen_p = mlen + crypto_aead_aes256gcm_ABYTES; + } + return ret; +} + +static int +crypto_aead_aes256gcm_verify_mac(unsigned char *nsec, const unsigned char *c, + unsigned long long c_len_, const unsigned char *mac, + const unsigned char *ad, unsigned long long ad_len_, + const unsigned char *npub, const crypto_aead_aes256gcm_state *st_) +{ + const State *st = (const State *) (const void *) st_; + GHash sth; + BlockVec final_block; + CRYPTO_ALIGN(16) unsigned char j[16]; + CRYPTO_ALIGN(16) unsigned char computed_mac[16]; + CRYPTO_ALIGN(16) unsigned char last_block[16]; + size_t gh_required_blocks; + size_t left; + const size_t ad_len = (size_t) ad_len_; + const size_t c_len = (size_t) c_len_; + int ret; + + (void) nsec; + if (ad_len_ > SODIUM_SIZE_MAX || c_len_ > SODIUM_SIZE_MAX) { + sodium_misuse(); + } + gh_required_blocks = required_blocks(ad_len, c_len); + if (gh_required_blocks == 0) { + return -1; + } + + gh_init(&sth); + + memcpy(j, npub, NPUBBYTES); + STORE32_BE(j + NPUBBYTES, 2); + + gh_ad_blocks(st, &sth, ad, ad_len & ~15); + left = ad_len & 15; + if (left != 0) { + unsigned char pad[16]; + + memset(pad, 0, sizeof pad); + memcpy(pad, ad + ad_len - left, left); + gh_ad_blocks(st, &sth, pad, sizeof pad); + } + + gh_ad_blocks(st, &sth, c, c_len & ~15); + left = c_len & 15; + if (left != 0) { + unsigned char pad[16]; + + memset(pad, 0, sizeof pad); + memcpy(pad, c + c_len - left, left); + gh_ad_blocks(st, &sth, pad, sizeof pad); + } + final_block = REV128(SET64x2(ad_len * 8, c_len * 8)); + STORE32_BE(j + NPUBBYTES, 1); + encrypt(st, computed_mac, j); + STORE128(last_block, final_block); + gh_ad_blocks(st, &sth, last_block, 16); + STORE128(computed_mac, XOR128(LOAD128(computed_mac), REV128(sth.acc))); + + ret = crypto_verify_16(mac, computed_mac); + sodium_memzero(computed_mac, sizeof computed_mac); + + return ret; } int crypto_aead_aes256gcm_decrypt_detached_afternm(unsigned char *m, unsigned char *nsec, - const unsigned char *c, unsigned long long clen, - const unsigned char *mac, - const unsigned char *ad, unsigned long long adlen, - const unsigned char *npub, - const crypto_aead_aes256gcm_state *ctx_) -{ - errno = ENOSYS; - return -1; + const unsigned char *c, unsigned long long c_len_, + const unsigned char *mac, const unsigned char *ad, + unsigned long long ad_len_, + const unsigned char *npub, + const crypto_aead_aes256gcm_state *st_) +{ + const State *st = (const State *) (const void *) st_; + GHash sth; + CRYPTO_ALIGN(16) unsigned char j[16]; + unsigned char computed_mac[16]; + size_t gh_required_blocks; + const size_t ad_len = (size_t) ad_len_; + const size_t c_len = (size_t) c_len_; + const size_t m_len = c_len; + + (void) nsec; + if (ad_len_ > SODIUM_SIZE_MAX || c_len_ > SODIUM_SIZE_MAX) { + sodium_misuse(); + } + if (m == NULL) { + return crypto_aead_aes256gcm_verify_mac(nsec, c, c_len, mac, ad, ad_len, npub, st_); + } + gh_required_blocks = required_blocks(ad_len, m_len); + if (gh_required_blocks == 0) { + return -1; + } + + gh_init(&sth); + + memcpy(j, npub, NPUBBYTES); + STORE32_BE(j + NPUBBYTES, 2); + + aes_gcm_decrypt_generic(st, &sth, computed_mac, m, c, m_len, ad, ad_len, j); + + if (crypto_verify_16(mac, computed_mac) != 0) { + sodium_memzero(computed_mac, sizeof computed_mac); + memset(m, 0xd0, m_len); + return -1; + } + return 0; } int crypto_aead_aes256gcm_decrypt_afternm(unsigned char *m, unsigned long long *mlen_p, - unsigned char *nsec, - const unsigned char *c, unsigned long long clen, - const unsigned char *ad, unsigned long long adlen, - const unsigned char *npub, - const crypto_aead_aes256gcm_state *ctx_) + unsigned char *nsec, const unsigned char *c, + unsigned long long clen, const unsigned char *ad, + unsigned long long adlen, const unsigned char *npub, + const crypto_aead_aes256gcm_state *st_) { - errno = ENOSYS; - return -1; + unsigned long long mlen = 0ULL; + int ret = -1; + + if (clen >= ABYTES) { + ret = crypto_aead_aes256gcm_decrypt_detached_afternm( + m, nsec, c, clen - ABYTES, c + clen - ABYTES, ad, adlen, npub, st_); + } + if (mlen_p != NULL) { + if (ret == 0) { + mlen = clen - ABYTES; + } + *mlen_p = mlen; + } + return ret; } int -crypto_aead_aes256gcm_is_available(void) +crypto_aead_aes256gcm_decrypt_detached(unsigned char *m, unsigned char *nsec, + const unsigned char *c, unsigned long long clen, + const unsigned char *mac, const unsigned char *ad, + unsigned long long adlen, const unsigned char *npub, + const unsigned char *k) { - return 0; -} + CRYPTO_ALIGN(16) crypto_aead_aes256gcm_state st; -#endif + PREFETCH_WRITE(m); + PREFETCH_READ(c); + PREFETCH_READ(ad); -size_t -crypto_aead_aes256gcm_keybytes(void) -{ - return crypto_aead_aes256gcm_KEYBYTES; -} + crypto_aead_aes256gcm_beforenm(&st, k); -size_t -crypto_aead_aes256gcm_nsecbytes(void) -{ - return crypto_aead_aes256gcm_NSECBYTES; + return crypto_aead_aes256gcm_decrypt_detached_afternm( + m, nsec, c, clen, mac, ad, adlen, npub, (const crypto_aead_aes256gcm_state *) &st); } -size_t -crypto_aead_aes256gcm_npubbytes(void) +int +crypto_aead_aes256gcm_decrypt(unsigned char *m, unsigned long long *mlen_p, unsigned char *nsec, + const unsigned char *c, unsigned long long clen, + const unsigned char *ad, unsigned long long adlen, + const unsigned char *npub, const unsigned char *k) { - return crypto_aead_aes256gcm_NPUBBYTES; -} + CRYPTO_ALIGN(16) crypto_aead_aes256gcm_state st; + int ret; -size_t -crypto_aead_aes256gcm_abytes(void) -{ - return crypto_aead_aes256gcm_ABYTES; -} + PREFETCH_WRITE(m); + PREFETCH_READ(c); + PREFETCH_READ(ad); -size_t -crypto_aead_aes256gcm_statebytes(void) -{ - return (sizeof(crypto_aead_aes256gcm_state) + (size_t) 15U) & ~(size_t) 15U; -} + crypto_aead_aes256gcm_beforenm(&st, k); -size_t -crypto_aead_aes256gcm_messagebytes_max(void) -{ - return crypto_aead_aes256gcm_MESSAGEBYTES_MAX; + ret = crypto_aead_aes256gcm_decrypt_afternm(m, mlen_p, nsec, c, clen, ad, adlen, npub, + (const crypto_aead_aes256gcm_state *) &st); + sodium_memzero(&st, sizeof st); + + return ret; } -void -crypto_aead_aes256gcm_keygen(unsigned char k[crypto_aead_aes256gcm_KEYBYTES]) +int +crypto_aead_aes256gcm_is_available(void) { - randombytes_buf(k, crypto_aead_aes256gcm_KEYBYTES); + return sodium_runtime_has_pclmul() & sodium_runtime_has_aesni() & sodium_runtime_has_avx(); } + +#ifdef __clang__ +# pragma clang attribute pop +#endif + +#endif diff --git a/libs/libsodium/src/crypto_aead/aes256gcm/armcrypto/aead_aes256gcm_armcrypto.c b/libs/libsodium/src/crypto_aead/aes256gcm/armcrypto/aead_aes256gcm_armcrypto.c new file mode 100644 index 0000000000..8f9bba6d74 --- /dev/null +++ b/libs/libsodium/src/crypto_aead/aes256gcm/armcrypto/aead_aes256gcm_armcrypto.c @@ -0,0 +1,1033 @@ +#include +#include +#include +#include +#include + +#include "core.h" +#include "crypto_aead_aes256gcm.h" +#include "crypto_verify_16.h" +#include "export.h" +#include "private/common.h" +#include "randombytes.h" +#include "runtime.h" +#include "utils.h" + +#if defined(HAVE_ARMCRYPTO) && defined(__clang__) && defined(NATIVE_LITTLE_ENDIAN) + +#if !defined(MSC_VER) || _MSC_VER < 1800 +#define __vectorcall +#endif + +#ifndef __ARM_FEATURE_CRYPTO +#define __ARM_FEATURE_CRYPTO 1 +#endif +#ifndef __ARM_FEATURE_AES +#define __ARM_FEATURE_AES 1 +#endif + +#include + +#ifdef __clang__ +#pragma clang attribute push(__attribute__((target("neon,crypto,aes"))), apply_to = function) +#elif defined(__GNUC__) +#pragma GCC target("+simd+crypto") +#endif + +#define ABYTES crypto_aead_aes256gcm_ABYTES +#define NPUBBYTES crypto_aead_aes256gcm_NPUBBYTES +#define KEYBYTES crypto_aead_aes256gcm_KEYBYTES + +#define PARALLEL_BLOCKS 6 +#undef USE_KARATSUBA_MULTIPLICATION + +typedef uint64x2_t BlockVec; + +#define LOAD128(a) vld1q_u64((const uint64_t *) (const void *) (a)) +#define STORE128(a, b) vst1q_u64((uint64_t *) (void *) (a), (b)) +#define AES_XENCRYPT(block_vec, rkey) \ + vreinterpretq_u64_u8( \ + vaesmcq_u8(vaeseq_u8(vreinterpretq_u8_u64(block_vec), rkey))) +#define AES_XENCRYPTLAST(block_vec, rkey) \ + vreinterpretq_u64_u8(vaeseq_u8(vreinterpretq_u8_u64(block_vec), rkey)) +#define XOR128(a, b) veorq_u64((a), (b)) +#define AND128(a, b) vandq_u64((a), (b)) +#define OR128(a, b) vorrq_u64((a), (b)) +#define SET64x2(a, b) vsetq_lane_u64((uint64_t) (a), vmovq_n_u64((uint64_t) (b)), 1) +#define ZERO128 vmovq_n_u8(0) +#define ONE128 SET64x2(0, 1) +#define ADD64x2(a, b) vaddq_u64((a), (b)) +#define SUB64x2(a, b) vsubq_u64((a), (b)) +#define SHL64x2(a, b) vshlq_n_u64((a), (b)) +#define SHR64x2(a, b) vshrq_n_u64((a), (b)) +#define REV128(x) \ + vreinterpretq_u64_u8(__builtin_shufflevector(vreinterpretq_u8_u64(x), vreinterpretq_u8_u64(x), \ + 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, \ + 1, 0)) +#define SHUFFLE32x4(x, a, b, c, d) \ + vreinterpretq_u64_u32(__builtin_shufflevector(vreinterpretq_u32_u64(x), \ + vreinterpretq_u32_u64(x), (a), (b), (c), (d))) +#define BYTESHL128(a, b) vreinterpretq_u64_u8(vextq_s8(vdupq_n_s8(0), (int8x16_t) a, 16 - (b))) +#define BYTESHR128(a, b) vreinterpretq_u64_u8(vextq_s8((int8x16_t) a, vdupq_n_s8(0), (b))) + +#define SHL128(a, b) OR128(SHL64x2((a), (b)), SHR64x2(BYTESHL128((a), 8), 64 - (b))) +#define CLMULLO128(a, b) \ + vreinterpretq_u64_p128(vmull_p64((poly64_t) vget_low_u64(a), (poly64_t) vget_low_u64(b))) +#define CLMULHI128(a, b) \ + vreinterpretq_u64_p128(vmull_high_p64(vreinterpretq_p64_s64(a), vreinterpretq_p64_s64(b))) +#define CLMULLOHI128(a, b) \ + vreinterpretq_u64_p128(vmull_p64((poly64_t) vget_low_u64(a), (poly64_t) vget_high_u64(b))) +#define CLMULHILO128(a, b) \ + vreinterpretq_u64_p128(vmull_p64((poly64_t) vget_high_u64(a), (poly64_t) vget_low_u64(b))) +#define PREFETCH_READ(x) __builtin_prefetch((x), 0, 2) +#define PREFETCH_WRITE(x) __builtin_prefetch((x), 1, 2); + +static inline BlockVec +AES_KEYGEN(BlockVec block_vec, const int rc) +{ + uint8x16_t a = vaeseq_u8(vreinterpretq_u8_u64(block_vec), vmovq_n_u8(0)); + const uint8x16_t b = + __builtin_shufflevector(a, a, 4, 1, 14, 11, 1, 14, 11, 4, 12, 9, 6, 3, 9, 6, 3, 12); + const uint64x2_t c = SET64x2((uint64_t) rc << 32, (uint64_t) rc << 32); + return XOR128(b, c); +} + +#define ROUNDS 14 + +#define PC_COUNT (2 * PARALLEL_BLOCKS) + +typedef struct I256 { + BlockVec hi; + BlockVec lo; + BlockVec mid; +} I256; + +typedef BlockVec Precomp; + +typedef struct GHash { + BlockVec acc; +} GHash; + +typedef struct State { + BlockVec rkeys[ROUNDS + 1]; + Precomp hx[PC_COUNT]; +} State; + +static void __vectorcall expand256(const unsigned char key[KEYBYTES], BlockVec rkeys[1 + ROUNDS]) +{ + BlockVec t1, t2, s; + size_t i = 0; + +#define EXPAND_KEY_1(RC) \ + rkeys[i++] = t2; \ + s = AES_KEYGEN(t2, RC); \ + t1 = XOR128(t1, BYTESHL128(t1, 4)); \ + t1 = XOR128(t1, BYTESHL128(t1, 8)); \ + t1 = XOR128(t1, SHUFFLE32x4(s, 3, 3, 3, 3)); + +#define EXPAND_KEY_2(RC) \ + rkeys[i++] = t1; \ + s = AES_KEYGEN(t1, RC); \ + t2 = XOR128(t2, BYTESHL128(t2, 4)); \ + t2 = XOR128(t2, BYTESHL128(t2, 8)); \ + t2 = XOR128(t2, SHUFFLE32x4(s, 2, 2, 2, 2)); + + t1 = LOAD128(&key[0]); + t2 = LOAD128(&key[16]); + + rkeys[i++] = t1; + EXPAND_KEY_1(0x01); + EXPAND_KEY_2(0x01); + EXPAND_KEY_1(0x02); + EXPAND_KEY_2(0x02); + EXPAND_KEY_1(0x04); + EXPAND_KEY_2(0x04); + EXPAND_KEY_1(0x08); + EXPAND_KEY_2(0x08); + EXPAND_KEY_1(0x10); + EXPAND_KEY_2(0x10); + EXPAND_KEY_1(0x20); + EXPAND_KEY_2(0x20); + EXPAND_KEY_1(0x40); + rkeys[i++] = t1; +} + +/* Encrypt a single AES block */ + +static inline void +encrypt(const State *st, unsigned char dst[16], const unsigned char src[16]) +{ + BlockVec t; + + size_t i; + + t = AES_XENCRYPT(LOAD128(src), st->rkeys[0]); + for (i = 1; i < ROUNDS - 1; i++) { + t = AES_XENCRYPT(t, st->rkeys[i]); + } + t = AES_XENCRYPTLAST(t, st->rkeys[i]); + t = XOR128(t, st->rkeys[ROUNDS]); + STORE128(dst, t); +} + +/* Encrypt and add a single AES block */ + +static inline void __vectorcall encrypt_xor_block(const State *st, unsigned char dst[16], + const unsigned char src[16], + const BlockVec counter) +{ + BlockVec ts; + size_t i; + + ts = AES_XENCRYPT(counter, st->rkeys[0]); + for (i = 1; i < ROUNDS - 1; i++) { + ts = AES_XENCRYPT(ts, st->rkeys[i]); + } + ts = AES_XENCRYPTLAST(ts, st->rkeys[i]); + ts = XOR128(ts, XOR128(st->rkeys[ROUNDS], LOAD128(src))); + STORE128(dst, ts); +} + +/* Encrypt and add PARALLEL_BLOCKS AES blocks */ + +static inline void __vectorcall encrypt_xor_wide(const State *st, + unsigned char dst[16 * PARALLEL_BLOCKS], + const unsigned char src[16 * PARALLEL_BLOCKS], + const BlockVec counters[PARALLEL_BLOCKS]) +{ + BlockVec ts[PARALLEL_BLOCKS]; + size_t i, j; + + for (j = 0; j < PARALLEL_BLOCKS; j++) { + ts[j] = AES_XENCRYPT(counters[j], st->rkeys[0]); + } + for (i = 1; i < ROUNDS - 1; i++) { + for (j = 0; j < PARALLEL_BLOCKS; j++) { + ts[j] = AES_XENCRYPT(ts[j], st->rkeys[i]); + } + } + for (j = 0; j < PARALLEL_BLOCKS; j++) { + ts[j] = AES_XENCRYPTLAST(ts[j], st->rkeys[i]); + ts[j] = XOR128(ts[j], XOR128(st->rkeys[ROUNDS], LOAD128(&src[16 * j]))); + } + for (j = 0; j < PARALLEL_BLOCKS; j++) { + STORE128(&dst[16 * j], ts[j]); + } +} + +/* Square a field element */ + +static inline I256 __vectorcall clsq128(const BlockVec x) +{ + const BlockVec r_lo = CLMULLO128(x, x); + const BlockVec r_hi = CLMULHI128(x, x); + + return (I256) { + SODIUM_C99(.hi =) r_hi, + SODIUM_C99(.lo =) r_lo, + SODIUM_C99(.mid =) ZERO128, + }; +} + +/* Multiply two field elements -- Textbook multiplication is faster than Karatsuba on some recent + * CPUs */ + +static inline I256 __vectorcall clmul128(const BlockVec x, const BlockVec y) +{ +#ifdef USE_KARATSUBA_MULTIPLICATION + const BlockVec x_hi = BYTESHR128(x, 8); + const BlockVec y_hi = BYTESHR128(y, 8); + const BlockVec r_lo = CLMULLO128(x, y); + const BlockVec r_hi = CLMULHI128(x, y); + const BlockVec r_mid = XOR128(CLMULLO128(XOR128(x, x_hi), XOR128(y, y_hi)), XOR128(r_lo, r_hi)); + + return (I256) { + SODIUM_C99(.hi =) r_hi, + SODIUM_C99(.lo =) r_lo, + SODIUM_C99(.mid =) r_mid, + }; +#else + const BlockVec r_hi = CLMULHI128(x, y); + const BlockVec r_lo = CLMULLO128(x, y); + const BlockVec r_mid = XOR128(CLMULHILO128(x, y), CLMULLOHI128(x, y)); + + return (I256) { + SODIUM_C99(.hi =) r_hi, + SODIUM_C99(.lo =) r_lo, + SODIUM_C99(.mid =) r_mid, + }; +#endif +} + +/* Merge the middle word and reduce a field element */ + +static inline BlockVec __vectorcall gcm_reduce(const I256 x) +{ + const BlockVec hi = XOR128(x.hi, BYTESHR128(x.mid, 8)); + const BlockVec lo = XOR128(x.lo, BYTESHL128(x.mid, 8)); + + const BlockVec p64 = SET64x2(0, 0xc200000000000000); + const BlockVec a = CLMULLO128(lo, p64); + const BlockVec b = XOR128(SHUFFLE32x4(lo, 2, 3, 0, 1), a); + const BlockVec c = CLMULLO128(b, p64); + const BlockVec d = XOR128(SHUFFLE32x4(b, 2, 3, 0, 1), c); + + return XOR128(d, hi); +} + +/* Precompute powers of H from `from` to `to` */ + +static inline void __vectorcall precomp(Precomp hx[PC_COUNT], const size_t from, const size_t to) +{ + const Precomp h = hx[0]; + size_t i; + + for (i = from & ~1U; i < to; i += 2) { + hx[i] = gcm_reduce(clmul128(hx[i - 1], h)); + hx[i + 1] = gcm_reduce(clsq128(hx[i / 2])); + } +} + +/* Precompute powers of H given a key and a block count */ + +static void __vectorcall precomp_for_block_count(Precomp hx[PC_COUNT], + const unsigned char gh_key[16], + const size_t block_count) +{ + const BlockVec h0 = REV128(LOAD128(gh_key)); + BlockVec carry = SET64x2(0xc200000000000000, 1); + BlockVec mask = SUB64x2(ZERO128, SHR64x2(h0, 63)); + BlockVec h0_shifted; + BlockVec h; + + mask = SHUFFLE32x4(mask, 3, 3, 3, 3); + carry = AND128(carry, mask); + h0_shifted = SHL128(h0, 1); + h = XOR128(h0_shifted, carry); + + hx[0] = h; + hx[1] = gcm_reduce(clsq128(hx[0])); + + if (block_count >= PC_COUNT) { + precomp(hx, 2, PC_COUNT); + } else { + precomp(hx, 2, block_count); + } +} + +/* Initialize a GHash */ + +static inline void +gh_init(GHash *sth) +{ + sth->acc = ZERO128; +} + +static inline I256 __vectorcall gh_update0(const GHash *const sth, const unsigned char *const p, + const Precomp hn) +{ + const BlockVec m = REV128(LOAD128(p)); + return clmul128(XOR128(sth->acc, m), hn); +} + +static inline void __vectorcall gh_update(I256 *const u, const unsigned char *p, const Precomp hn) +{ + const BlockVec m = REV128(LOAD128(p)); + const I256 t = clmul128(m, hn); + *u = (I256) { SODIUM_C99(.hi =) XOR128(u->hi, t.hi), SODIUM_C99(.lo =) XOR128(u->lo, t.lo), + SODIUM_C99(.mid =) XOR128(u->mid, t.mid) }; +} + +/* Absorb ad_len bytes of associated data. There has to be no partial block. */ + +static inline void +gh_ad_blocks(const State *st, GHash *sth, const unsigned char *ad, size_t ad_len) +{ + size_t i; + + i = (size_t) 0U; + for (; i + PC_COUNT * 16 <= ad_len; i += PC_COUNT * 16) { + I256 u = gh_update0(sth, ad + i, st->hx[PC_COUNT - 1 - 0]); + size_t j; + + for (j = 1; j < PC_COUNT; j += 1) { + gh_update(&u, ad + i + j * 16, st->hx[PC_COUNT - 1 - j]); + } + sth->acc = gcm_reduce(u); + } + for (; i + PC_COUNT * 16 / 2 <= ad_len; i += PC_COUNT * 16 / 2) { + I256 u = gh_update0(sth, ad + i, st->hx[PC_COUNT / 2 - 1 - 0]); + size_t j; + + for (j = 1; j < PC_COUNT / 2; j += 1) { + gh_update(&u, ad + i + j * 16, st->hx[PC_COUNT / 2 - 1 - j]); + } + sth->acc = gcm_reduce(u); + } + for (; i + 4 * 16 <= ad_len; i += 4 * 16) { + size_t j; + I256 u = gh_update0(sth, ad + i, st->hx[4 - 1 - 0]); + + for (j = 1; j < 4; j += 1) { + gh_update(&u, ad + i + j * 16, st->hx[4 - 1 - j]); + } + sth->acc = gcm_reduce(u); + } + for (; i + 2 * 16 <= ad_len; i += 2 * 16) { + size_t j; + I256 u = gh_update0(sth, ad + i, st->hx[2 - 1 - 0]); + + for (j = 1; j < 2; j += 1) { + gh_update(&u, ad + i + j * 16, st->hx[2 - 1 - j]); + } + sth->acc = gcm_reduce(u); + } + if (i < ad_len) { + I256 u = gh_update0(sth, ad + i, st->hx[0]); + sth->acc = gcm_reduce(u); + } +} + +/* Increment counters */ + +static inline BlockVec __vectorcall incr_counters(BlockVec rev_counters[], BlockVec counter, + const size_t n) +{ + size_t i; + + const BlockVec one = ONE128; + for (i = 0; i < n; i++) { + rev_counters[i] = REV128(counter); + counter = ADD64x2(counter, one); + } + return counter; +} + +/* Compute the number of required blocks to encrypt and authenticate `ad_len` of associated data, + * and `m_len` of encrypted bytes. Return `0` if limits would be exceeded.*/ + +static inline size_t +required_blocks(const size_t ad_len, const size_t m_len) +{ + const size_t ad_blocks = (ad_len + 15) / 16; + const size_t m_blocks = (m_len + 15) / 16; + + if (ad_len > SIZE_MAX - 2 * PARALLEL_BLOCKS * 16 || + m_len > SIZE_MAX - 2 * PARALLEL_BLOCKS * 16 || ad_len < ad_blocks || m_len < m_blocks || + m_blocks >= (1ULL << 32) - 2) { + return 0; + } + return ad_blocks + m_blocks + 1; +} + +/* Generic AES-GCM encryption. "Generic" as it can handle arbitrary input sizes, +unlike a length-limited version that would precompute all the required powers of H */ + +static void +aes_gcm_encrypt_generic(const State *st, GHash *sth, unsigned char mac[ABYTES], unsigned char *dst, + const unsigned char *src, size_t src_len, const unsigned char *ad, + size_t ad_len, unsigned char counter_[16]) +{ + CRYPTO_ALIGN(32) I256 u; + CRYPTO_ALIGN(16) unsigned char last_blocks[2 * 16]; + const BlockVec one = ONE128; + BlockVec final_block; + BlockVec rev_counters[PARALLEL_BLOCKS]; + BlockVec counter; + size_t i; + size_t j; + size_t left; + size_t pi; + + COMPILER_ASSERT(PC_COUNT % PARALLEL_BLOCKS == 0); + + /* Associated data */ + + if (ad != NULL && ad_len != 0) { + gh_ad_blocks(st, sth, ad, ad_len & ~15); + left = ad_len & 15; + if (left != 0) { + unsigned char pad[16]; + + memset(pad, 0, sizeof pad); + memcpy(pad, ad + ad_len - left, left); + gh_ad_blocks(st, sth, pad, sizeof pad); + } + } + + /* Encrypted data */ + + counter = REV128(LOAD128(counter_)); + i = 0; + + /* 2*PARALLEL_BLOCKS aggregation */ + + if (src_len - i >= 2 * PARALLEL_BLOCKS * 16) { + counter = incr_counters(rev_counters, counter, PARALLEL_BLOCKS); + encrypt_xor_wide(st, dst + i, src + i, rev_counters); + i += PARALLEL_BLOCKS * 16; + + for (; i + 2 * PARALLEL_BLOCKS * 16 <= src_len; i += 2 * PARALLEL_BLOCKS * 16) { + counter = incr_counters(rev_counters, counter, PARALLEL_BLOCKS); + encrypt_xor_wide(st, dst + i, src + i, rev_counters); + + pi = i - PARALLEL_BLOCKS * 16; + u = gh_update0(sth, dst + pi, st->hx[2 * PARALLEL_BLOCKS - 1 - 0]); + for (j = 1; j < PARALLEL_BLOCKS; j += 1) { + gh_update(&u, dst + pi + j * 16, st->hx[2 * PARALLEL_BLOCKS - 1 - j]); + } + + counter = incr_counters(rev_counters, counter, PARALLEL_BLOCKS); + encrypt_xor_wide(st, dst + i + PARALLEL_BLOCKS * 16, src + i + PARALLEL_BLOCKS * 16, + rev_counters); + + pi = i; + for (j = 0; j < PARALLEL_BLOCKS; j += 1) { + gh_update(&u, dst + pi + j * 16, st->hx[PARALLEL_BLOCKS - 1 - j]); + } + sth->acc = gcm_reduce(u); + } + + pi = i - PARALLEL_BLOCKS * 16; + u = gh_update0(sth, dst + pi, st->hx[PARALLEL_BLOCKS - 1 - 0]); + for (j = 1; j < PARALLEL_BLOCKS; j += 1) { + gh_update(&u, dst + pi + j * 16, st->hx[PARALLEL_BLOCKS - 1 - j]); + } + sth->acc = gcm_reduce(u); + } + + /* PARALLEL_BLOCKS aggregation */ + + if (src_len - i >= PARALLEL_BLOCKS * 16) { + counter = incr_counters(rev_counters, counter, PARALLEL_BLOCKS); + encrypt_xor_wide(st, dst + i, src + i, rev_counters); + i += PARALLEL_BLOCKS * 16; + + for (; i + PARALLEL_BLOCKS * 16 <= src_len; i += PARALLEL_BLOCKS * 16) { + counter = incr_counters(rev_counters, counter, PARALLEL_BLOCKS); + encrypt_xor_wide(st, dst + i, src + i, rev_counters); + + pi = i - PARALLEL_BLOCKS * 16; + u = gh_update0(sth, dst + pi, st->hx[PARALLEL_BLOCKS - 1 - 0]); + for (j = 1; j < PARALLEL_BLOCKS; j += 1) { + gh_update(&u, dst + pi + j * 16, st->hx[PARALLEL_BLOCKS - 1 - j]); + } + sth->acc = gcm_reduce(u); + } + + pi = i - PARALLEL_BLOCKS * 16; + u = gh_update0(sth, dst + pi, st->hx[PARALLEL_BLOCKS - 1 - 0]); + for (j = 1; j < PARALLEL_BLOCKS; j += 1) { + gh_update(&u, dst + pi + j * 16, st->hx[PARALLEL_BLOCKS - 1 - j]); + } + sth->acc = gcm_reduce(u); + } + + /* 4-blocks aggregation */ + + for (; i + 4 * 16 <= src_len; i += 4 * 16) { + counter = incr_counters(rev_counters, counter, 4); + for (j = 0; j < 4; j++) { + encrypt_xor_block(st, dst + i + j * 16, src + i + j * 16, rev_counters[j]); + } + + u = gh_update0(sth, dst + i, st->hx[4 - 1 - 0]); + for (j = 1; j < 4; j += 1) { + gh_update(&u, dst + i + j * 16, st->hx[4 - 1 - j]); + } + sth->acc = gcm_reduce(u); + } + + /* 2-blocks aggregation */ + + for (; i + 2 * 16 <= src_len; i += 2 * 16) { + counter = incr_counters(rev_counters, counter, 2); + for (j = 0; j < 2; j++) { + encrypt_xor_block(st, dst + i + j * 16, src + i + j * 16, rev_counters[j]); + } + + u = gh_update0(sth, dst + i, st->hx[2 - 1 - 0]); + for (j = 1; j < 2; j += 1) { + gh_update(&u, dst + i + j * 16, st->hx[2 - 1 - j]); + } + sth->acc = gcm_reduce(u); + } + + /* Remaining *partial* blocks; if we have 16 bytes left, we want to keep the + full block authenticated along with the final block, hence < and not <= */ + + for (; i + 16 < src_len; i += 16) { + encrypt_xor_block(st, dst + i, src + i, REV128(counter)); + u = gh_update0(sth, dst + i, st->hx[1 - 1 - 0]); + sth->acc = gcm_reduce(u); + counter = ADD64x2(counter, one); + } + + /* Authenticate both the last block of the message and the final block */ + + final_block = REV128(SET64x2(ad_len * 8, src_len * 8)); + STORE32_BE(counter_ + NPUBBYTES, 1); + encrypt(st, mac, counter_); + left = src_len - i; + if (left != 0) { + for (j = 0; j < left; j++) { + last_blocks[j] = src[i + j]; + } + STORE128(last_blocks + 16, final_block); + encrypt_xor_block(st, last_blocks, last_blocks, REV128(counter)); + for (; j < 16; j++) { + last_blocks[j] = 0; + } + for (j = 0; j < left; j++) { + dst[i + j] = last_blocks[j]; + } + gh_ad_blocks(st, sth, last_blocks, 32); + } else { + STORE128(last_blocks, final_block); + gh_ad_blocks(st, sth, last_blocks, 16); + } + STORE128(mac, XOR128(LOAD128(mac), REV128(sth->acc))); +} + +/* Generic AES-GCM decryption. "Generic" as it can handle arbitrary input sizes, +unlike a length-limited version that would precompute all the required powers of H */ + +static void +aes_gcm_decrypt_generic(const State *st, GHash *sth, unsigned char mac[ABYTES], unsigned char *dst, + const unsigned char *src, size_t src_len, const unsigned char *ad, + size_t ad_len, unsigned char counter_[16]) +{ + CRYPTO_ALIGN(32) I256 u; + CRYPTO_ALIGN(16) unsigned char last_blocks[2 * 16]; + const BlockVec one = ONE128; + BlockVec final_block; + BlockVec rev_counters[PARALLEL_BLOCKS]; + BlockVec counter; + size_t i; + size_t j; + size_t left; + + COMPILER_ASSERT(PC_COUNT % PARALLEL_BLOCKS == 0); + + /* Associated data */ + + if (ad != NULL && ad_len != 0) { + gh_ad_blocks(st, sth, ad, ad_len & ~15); + left = ad_len & 15; + if (left != 0) { + unsigned char pad[16]; + + memset(pad, 0, sizeof pad); + memcpy(pad, ad + ad_len - left, left); + gh_ad_blocks(st, sth, pad, sizeof pad); + } + } + + /* Encrypted data */ + + counter = REV128(LOAD128(counter_)); + i = 0; + + /* 2*PARALLEL_BLOCKS aggregation */ + + while (i + 2 * PARALLEL_BLOCKS * 16 <= src_len) { + counter = incr_counters(rev_counters, counter, PARALLEL_BLOCKS); + + u = gh_update0(sth, src + i, st->hx[2 * PARALLEL_BLOCKS - 1 - 0]); + for (j = 1; j < PARALLEL_BLOCKS; j += 1) { + gh_update(&u, src + i + j * 16, st->hx[2 * PARALLEL_BLOCKS - 1 - j]); + } + + encrypt_xor_wide(st, dst + i, src + i, rev_counters); + + counter = incr_counters(rev_counters, counter, PARALLEL_BLOCKS); + + i += PARALLEL_BLOCKS * 16; + for (j = 0; j < PARALLEL_BLOCKS; j += 1) { + gh_update(&u, src + i + j * 16, st->hx[PARALLEL_BLOCKS - 1 - j]); + } + sth->acc = gcm_reduce(u); + + encrypt_xor_wide(st, dst + i, src + i, rev_counters); + i += PARALLEL_BLOCKS * 16; + } + + /* PARALLEL_BLOCKS aggregation */ + + for (; i + PARALLEL_BLOCKS * 16 <= src_len; i += PARALLEL_BLOCKS * 16) { + counter = incr_counters(rev_counters, counter, PARALLEL_BLOCKS); + + u = gh_update0(sth, src + i, st->hx[PARALLEL_BLOCKS - 1 - 0]); + for (j = 1; j < PARALLEL_BLOCKS; j += 1) { + gh_update(&u, src + i + j * 16, st->hx[PARALLEL_BLOCKS - 1 - j]); + } + sth->acc = gcm_reduce(u); + + encrypt_xor_wide(st, dst + i, src + i, rev_counters); + } + + /* 4-blocks aggregation */ + + for (; i + 4 * 16 <= src_len; i += 4 * 16) { + counter = incr_counters(rev_counters, counter, 4); + + u = gh_update0(sth, src + i, st->hx[4 - 1 - 0]); + for (j = 1; j < 4; j += 1) { + gh_update(&u, src + i + j * 16, st->hx[4 - 1 - j]); + } + sth->acc = gcm_reduce(u); + + for (j = 0; j < 4; j++) { + encrypt_xor_block(st, dst + i + j * 16, src + i + j * 16, rev_counters[j]); + } + } + + /* 2-blocks aggregation */ + + for (; i + 2 * 16 <= src_len; i += 2 * 16) { + counter = incr_counters(rev_counters, counter, 2); + + u = gh_update0(sth, src + i, st->hx[2 - 1 - 0]); + for (j = 1; j < 2; j += 1) { + gh_update(&u, src + i + j * 16, st->hx[2 - 1 - j]); + } + sth->acc = gcm_reduce(u); + + for (j = 0; j < 2; j++) { + encrypt_xor_block(st, dst + i + j * 16, src + i + j * 16, rev_counters[j]); + } + } + + /* Remaining *partial* blocks; if we have 16 bytes left, we want to keep the + full block authenticated along with the final block, hence < and not <= */ + + for (; i + 16 < src_len; i += 16) { + u = gh_update0(sth, src + i, st->hx[1 - 1 - 0]); + sth->acc = gcm_reduce(u); + encrypt_xor_block(st, dst + i, src + i, REV128(counter)); + counter = ADD64x2(counter, one); + } + + /* Authenticate both the last block of the message and the final block */ + + final_block = REV128(SET64x2(ad_len * 8, src_len * 8)); + STORE32_BE(counter_ + NPUBBYTES, 1); + encrypt(st, mac, counter_); + left = src_len - i; + if (left != 0) { + for (j = 0; j < left; j++) { + last_blocks[j] = src[i + j]; + } + for (; j < 16; j++) { + last_blocks[j] = 0; + } + STORE128(last_blocks + 16, final_block); + gh_ad_blocks(st, sth, last_blocks, 32); + encrypt_xor_block(st, last_blocks, last_blocks, REV128(counter)); + for (j = 0; j < left; j++) { + dst[i + j] = last_blocks[j]; + } + } else { + STORE128(last_blocks, final_block); + gh_ad_blocks(st, sth, last_blocks, 16); + } + STORE128(mac, XOR128(LOAD128(mac), REV128(sth->acc))); +} + +int +crypto_aead_aes256gcm_beforenm(crypto_aead_aes256gcm_state *st_, const unsigned char *k) +{ + State *st = (State *) (void *) st_; + CRYPTO_ALIGN(16) unsigned char h[16]; + + COMPILER_ASSERT(sizeof *st_ >= sizeof *st); + + expand256(k, st->rkeys); + memset(h, 0, sizeof h); + encrypt(st, h, h); + + precomp_for_block_count(st->hx, h, PC_COUNT); + + return 0; +} + +int +crypto_aead_aes256gcm_encrypt_detached_afternm(unsigned char *c, unsigned char *mac, + unsigned long long *maclen_p, const unsigned char *m, + unsigned long long m_len_, const unsigned char *ad, + unsigned long long ad_len_, + const unsigned char *nsec, const unsigned char *npub, + const crypto_aead_aes256gcm_state *st_) +{ + const State *st = (const State *) (const void *) st_; + GHash sth; + CRYPTO_ALIGN(16) unsigned char j[16]; + size_t gh_required_blocks; + const size_t ad_len = (size_t) ad_len_; + const size_t m_len = (size_t) m_len_; + + (void) nsec; + if (maclen_p != NULL) { + *maclen_p = 0; + } + if (ad_len_ > SODIUM_SIZE_MAX || m_len_ > SODIUM_SIZE_MAX) { + sodium_misuse(); + } + gh_required_blocks = required_blocks(ad_len, m_len); + if (gh_required_blocks == 0) { + memset(mac, 0xd0, ABYTES); + memset(c, 0, m_len); + return -1; + } + + gh_init(&sth); + + memcpy(j, npub, NPUBBYTES); + STORE32_BE(j + NPUBBYTES, 2); + + aes_gcm_encrypt_generic(st, &sth, mac, c, m, m_len, ad, ad_len, j); + + if (maclen_p != NULL) { + *maclen_p = ABYTES; + } + return 0; +} + +int +crypto_aead_aes256gcm_encrypt(unsigned char *c, unsigned long long *clen_p, const unsigned char *m, + unsigned long long m_len, const unsigned char *ad, + unsigned long long ad_len, const unsigned char *nsec, + const unsigned char *npub, const unsigned char *k) +{ + const int ret = crypto_aead_aes256gcm_encrypt_detached(c, c + m_len, NULL, m, m_len, ad, ad_len, + nsec, npub, k); + if (clen_p != NULL) { + if (ret == 0) { + *clen_p = m_len + crypto_aead_aes256gcm_ABYTES; + } else { + *clen_p = 0; + } + } + return ret; +} + +int +crypto_aead_aes256gcm_encrypt_detached(unsigned char *c, unsigned char *mac, + unsigned long long *maclen_p, const unsigned char *m, + unsigned long long m_len, const unsigned char *ad, + unsigned long long ad_len, const unsigned char *nsec, + const unsigned char *npub, const unsigned char *k) +{ + CRYPTO_ALIGN(16) crypto_aead_aes256gcm_state st; + int ret; + + PREFETCH_WRITE(c); + PREFETCH_READ(m); + PREFETCH_READ(ad); + + crypto_aead_aes256gcm_beforenm(&st, k); + ret = crypto_aead_aes256gcm_encrypt_detached_afternm(c, mac, maclen_p, m, m_len, ad, ad_len, + nsec, npub, &st); + sodium_memzero(&st, sizeof st); + + return ret; +} + +int +crypto_aead_aes256gcm_encrypt_afternm(unsigned char *c, unsigned long long *clen_p, + const unsigned char *m, unsigned long long mlen, + const unsigned char *ad, unsigned long long adlen, + const unsigned char *nsec, const unsigned char *npub, + const crypto_aead_aes256gcm_state *st_) +{ + int ret = crypto_aead_aes256gcm_encrypt_detached_afternm(c, c + mlen, NULL, m, mlen, ad, adlen, + nsec, npub, st_); + if (clen_p != NULL) { + *clen_p = mlen + crypto_aead_aes256gcm_ABYTES; + } + return ret; +} + +static int +crypto_aead_aes256gcm_verify_mac(unsigned char *nsec, const unsigned char *c, + unsigned long long c_len_, const unsigned char *mac, + const unsigned char *ad, unsigned long long ad_len_, + const unsigned char *npub, const crypto_aead_aes256gcm_state *st_) +{ + const State *st = (const State *) (const void *) st_; + GHash sth; + BlockVec final_block; + CRYPTO_ALIGN(16) unsigned char j[16]; + CRYPTO_ALIGN(16) unsigned char computed_mac[16]; + CRYPTO_ALIGN(16) unsigned char last_block[16]; + size_t gh_required_blocks; + size_t left; + const size_t ad_len = (size_t) ad_len_; + const size_t c_len = (size_t) c_len_; + int ret; + + (void) nsec; + if (ad_len_ > SODIUM_SIZE_MAX || c_len_ > SODIUM_SIZE_MAX) { + sodium_misuse(); + } + gh_required_blocks = required_blocks(ad_len, c_len); + if (gh_required_blocks == 0) { + return -1; + } + + gh_init(&sth); + + memcpy(j, npub, NPUBBYTES); + STORE32_BE(j + NPUBBYTES, 2); + + gh_ad_blocks(st, &sth, ad, ad_len & ~15); + left = ad_len & 15; + if (left != 0) { + unsigned char pad[16]; + + memset(pad, 0, sizeof pad); + memcpy(pad, ad + ad_len - left, left); + gh_ad_blocks(st, &sth, pad, sizeof pad); + } + + gh_ad_blocks(st, &sth, c, c_len & ~15); + left = c_len & 15; + if (left != 0) { + unsigned char pad[16]; + + memset(pad, 0, sizeof pad); + memcpy(pad, c + c_len - left, left); + gh_ad_blocks(st, &sth, pad, sizeof pad); + } + final_block = REV128(SET64x2(ad_len * 8, c_len * 8)); + STORE32_BE(j + NPUBBYTES, 1); + encrypt(st, computed_mac, j); + STORE128(last_block, final_block); + gh_ad_blocks(st, &sth, last_block, 16); + STORE128(computed_mac, XOR128(LOAD128(computed_mac), REV128(sth.acc))); + + ret = crypto_verify_16(mac, computed_mac); + sodium_memzero(computed_mac, sizeof computed_mac); + + return ret; +} + +int +crypto_aead_aes256gcm_decrypt_detached_afternm(unsigned char *m, unsigned char *nsec, + const unsigned char *c, unsigned long long c_len_, + const unsigned char *mac, const unsigned char *ad, + unsigned long long ad_len_, + const unsigned char *npub, + const crypto_aead_aes256gcm_state *st_) +{ + const State *st = (const State *) (const void *) st_; + GHash sth; + CRYPTO_ALIGN(16) unsigned char j[16]; + unsigned char computed_mac[16]; + size_t gh_required_blocks; + const size_t ad_len = (size_t) ad_len_; + const size_t c_len = (size_t) c_len_; + const size_t m_len = c_len; + + (void) nsec; + if (ad_len_ > SODIUM_SIZE_MAX || c_len_ > SODIUM_SIZE_MAX) { + sodium_misuse(); + } + if (m == NULL) { + return crypto_aead_aes256gcm_verify_mac(nsec, c, c_len, mac, ad, ad_len, npub, st_); + } + gh_required_blocks = required_blocks(ad_len, m_len); + if (gh_required_blocks == 0) { + return -1; + } + + gh_init(&sth); + + memcpy(j, npub, NPUBBYTES); + STORE32_BE(j + NPUBBYTES, 2); + + aes_gcm_decrypt_generic(st, &sth, computed_mac, m, c, m_len, ad, ad_len, j); + + if (crypto_verify_16(mac, computed_mac) != 0) { + sodium_memzero(computed_mac, sizeof computed_mac); + memset(m, 0xd0, m_len); + return -1; + } + return 0; +} + +int +crypto_aead_aes256gcm_decrypt_afternm(unsigned char *m, unsigned long long *mlen_p, + unsigned char *nsec, const unsigned char *c, + unsigned long long clen, const unsigned char *ad, + unsigned long long adlen, const unsigned char *npub, + const crypto_aead_aes256gcm_state *st_) +{ + unsigned long long mlen = 0ULL; + int ret = -1; + + if (clen >= ABYTES) { + ret = crypto_aead_aes256gcm_decrypt_detached_afternm( + m, nsec, c, clen - ABYTES, c + clen - ABYTES, ad, adlen, npub, st_); + } + if (mlen_p != NULL) { + if (ret == 0) { + mlen = clen - ABYTES; + } + *mlen_p = mlen; + } + return ret; +} + +int +crypto_aead_aes256gcm_decrypt_detached(unsigned char *m, unsigned char *nsec, + const unsigned char *c, unsigned long long clen, + const unsigned char *mac, const unsigned char *ad, + unsigned long long adlen, const unsigned char *npub, + const unsigned char *k) +{ + CRYPTO_ALIGN(16) crypto_aead_aes256gcm_state st; + + PREFETCH_WRITE(m); + PREFETCH_READ(c); + PREFETCH_READ(ad); + + crypto_aead_aes256gcm_beforenm(&st, k); + + return crypto_aead_aes256gcm_decrypt_detached_afternm( + m, nsec, c, clen, mac, ad, adlen, npub, (const crypto_aead_aes256gcm_state *) &st); +} + +int +crypto_aead_aes256gcm_decrypt(unsigned char *m, unsigned long long *mlen_p, unsigned char *nsec, + const unsigned char *c, unsigned long long clen, + const unsigned char *ad, unsigned long long adlen, + const unsigned char *npub, const unsigned char *k) +{ + CRYPTO_ALIGN(16) crypto_aead_aes256gcm_state st; + int ret; + + PREFETCH_WRITE(m); + PREFETCH_READ(c); + PREFETCH_READ(ad); + + crypto_aead_aes256gcm_beforenm(&st, k); + + ret = crypto_aead_aes256gcm_decrypt_afternm(m, mlen_p, nsec, c, clen, ad, adlen, npub, + (const crypto_aead_aes256gcm_state *) &st); + sodium_memzero(&st, sizeof st); + + return ret; +} + +int +crypto_aead_aes256gcm_is_available(void) +{ + return sodium_runtime_has_armcrypto(); +} + +#ifdef __clang__ +#pragma clang attribute pop +#endif + +#endif diff --git a/libs/libsodium/src/crypto_aead/chacha20poly1305/aead_chacha20poly1305.c b/libs/libsodium/src/crypto_aead/chacha20poly1305/aead_chacha20poly1305.c new file mode 100644 index 0000000000..c354087975 --- /dev/null +++ b/libs/libsodium/src/crypto_aead/chacha20poly1305/aead_chacha20poly1305.c @@ -0,0 +1,400 @@ + +#include +#include +#include +#include + +#include "core.h" +#include "crypto_aead_chacha20poly1305.h" +#include "crypto_onetimeauth_poly1305.h" +#include "crypto_stream_chacha20.h" +#include "crypto_verify_16.h" +#include "randombytes.h" +#include "utils.h" + +#include "private/chacha20_ietf_ext.h" +#include "private/common.h" + +static const unsigned char _pad0[16] = { 0 }; + +int +crypto_aead_chacha20poly1305_encrypt_detached(unsigned char *c, + unsigned char *mac, + unsigned long long *maclen_p, + const unsigned char *m, + unsigned long long mlen, + const unsigned char *ad, + unsigned long long adlen, + const unsigned char *nsec, + const unsigned char *npub, + const unsigned char *k) +{ + crypto_onetimeauth_poly1305_state state; + unsigned char block0[64U]; + unsigned char slen[8U]; + + (void) nsec; + crypto_stream_chacha20(block0, sizeof block0, npub, k); + crypto_onetimeauth_poly1305_init(&state, block0); + sodium_memzero(block0, sizeof block0); + + crypto_onetimeauth_poly1305_update(&state, ad, adlen); + STORE64_LE(slen, (uint64_t) adlen); + crypto_onetimeauth_poly1305_update(&state, slen, sizeof slen); + + crypto_stream_chacha20_xor_ic(c, m, mlen, npub, 1U, k); + + crypto_onetimeauth_poly1305_update(&state, c, mlen); + STORE64_LE(slen, (uint64_t) mlen); + crypto_onetimeauth_poly1305_update(&state, slen, sizeof slen); + + crypto_onetimeauth_poly1305_final(&state, mac); + sodium_memzero(&state, sizeof state); + + if (maclen_p != NULL) { + *maclen_p = crypto_aead_chacha20poly1305_ABYTES; + } + return 0; +} + +int +crypto_aead_chacha20poly1305_encrypt(unsigned char *c, + unsigned long long *clen_p, + const unsigned char *m, + unsigned long long mlen, + const unsigned char *ad, + unsigned long long adlen, + const unsigned char *nsec, + const unsigned char *npub, + const unsigned char *k) +{ + unsigned long long clen = 0ULL; + int ret; + + if (mlen > crypto_aead_chacha20poly1305_MESSAGEBYTES_MAX) { + sodium_misuse(); + } + ret = crypto_aead_chacha20poly1305_encrypt_detached(c, + c + mlen, NULL, + m, mlen, + ad, adlen, + nsec, npub, k); + if (clen_p != NULL) { + if (ret == 0) { + clen = mlen + crypto_aead_chacha20poly1305_ABYTES; + } + *clen_p = clen; + } + return ret; +} + +int +crypto_aead_chacha20poly1305_ietf_encrypt_detached(unsigned char *c, + unsigned char *mac, + unsigned long long *maclen_p, + const unsigned char *m, + unsigned long long mlen, + const unsigned char *ad, + unsigned long long adlen, + const unsigned char *nsec, + const unsigned char *npub, + const unsigned char *k) +{ + crypto_onetimeauth_poly1305_state state; + unsigned char block0[64U]; + unsigned char slen[8U]; + + (void) nsec; + crypto_stream_chacha20_ietf(block0, sizeof block0, npub, k); + crypto_onetimeauth_poly1305_init(&state, block0); + sodium_memzero(block0, sizeof block0); + + crypto_onetimeauth_poly1305_update(&state, ad, adlen); + crypto_onetimeauth_poly1305_update(&state, _pad0, (0x10 - adlen) & 0xf); + + crypto_stream_chacha20_ietf_xor_ic(c, m, mlen, npub, 1U, k); + + crypto_onetimeauth_poly1305_update(&state, c, mlen); + crypto_onetimeauth_poly1305_update(&state, _pad0, (0x10 - mlen) & 0xf); + + STORE64_LE(slen, (uint64_t) adlen); + crypto_onetimeauth_poly1305_update(&state, slen, sizeof slen); + + STORE64_LE(slen, (uint64_t) mlen); + crypto_onetimeauth_poly1305_update(&state, slen, sizeof slen); + + crypto_onetimeauth_poly1305_final(&state, mac); + sodium_memzero(&state, sizeof state); + + if (maclen_p != NULL) { + *maclen_p = crypto_aead_chacha20poly1305_ietf_ABYTES; + } + return 0; +} + +int +crypto_aead_chacha20poly1305_ietf_encrypt(unsigned char *c, + unsigned long long *clen_p, + const unsigned char *m, + unsigned long long mlen, + const unsigned char *ad, + unsigned long long adlen, + const unsigned char *nsec, + const unsigned char *npub, + const unsigned char *k) +{ + unsigned long long clen = 0ULL; + int ret; + + if (mlen > crypto_aead_chacha20poly1305_ietf_MESSAGEBYTES_MAX) { + sodium_misuse(); + } + ret = crypto_aead_chacha20poly1305_ietf_encrypt_detached(c, + c + mlen, NULL, + m, mlen, + ad, adlen, + nsec, npub, k); + if (clen_p != NULL) { + if (ret == 0) { + clen = mlen + crypto_aead_chacha20poly1305_ietf_ABYTES; + } + *clen_p = clen; + } + return ret; +} + +int +crypto_aead_chacha20poly1305_decrypt_detached(unsigned char *m, + unsigned char *nsec, + const unsigned char *c, + unsigned long long clen, + const unsigned char *mac, + const unsigned char *ad, + unsigned long long adlen, + const unsigned char *npub, + const unsigned char *k) +{ + crypto_onetimeauth_poly1305_state state; + unsigned char block0[64U]; + unsigned char slen[8U]; + unsigned char computed_mac[crypto_aead_chacha20poly1305_ABYTES]; + unsigned long long mlen; + int ret; + + (void) nsec; + crypto_stream_chacha20(block0, sizeof block0, npub, k); + crypto_onetimeauth_poly1305_init(&state, block0); + sodium_memzero(block0, sizeof block0); + + crypto_onetimeauth_poly1305_update(&state, ad, adlen); + STORE64_LE(slen, (uint64_t) adlen); + crypto_onetimeauth_poly1305_update(&state, slen, sizeof slen); + + mlen = clen; + crypto_onetimeauth_poly1305_update(&state, c, mlen); + STORE64_LE(slen, (uint64_t) mlen); + crypto_onetimeauth_poly1305_update(&state, slen, sizeof slen); + + crypto_onetimeauth_poly1305_final(&state, computed_mac); + sodium_memzero(&state, sizeof state); + + COMPILER_ASSERT(sizeof computed_mac == 16U); + ret = crypto_verify_16(computed_mac, mac); + sodium_memzero(computed_mac, sizeof computed_mac); + if (m == NULL) { + return ret; + } + if (ret != 0) { + memset(m, 0, mlen); + return -1; + } + crypto_stream_chacha20_xor_ic(m, c, mlen, npub, 1U, k); + + return 0; +} + +int +crypto_aead_chacha20poly1305_decrypt(unsigned char *m, + unsigned long long *mlen_p, + unsigned char *nsec, + const unsigned char *c, + unsigned long long clen, + const unsigned char *ad, + unsigned long long adlen, + const unsigned char *npub, + const unsigned char *k) +{ + unsigned long long mlen = 0ULL; + int ret = -1; + + if (clen >= crypto_aead_chacha20poly1305_ABYTES) { + ret = crypto_aead_chacha20poly1305_decrypt_detached + (m, nsec, + c, clen - crypto_aead_chacha20poly1305_ABYTES, + c + clen - crypto_aead_chacha20poly1305_ABYTES, + ad, adlen, npub, k); + } + if (mlen_p != NULL) { + if (ret == 0) { + mlen = clen - crypto_aead_chacha20poly1305_ABYTES; + } + *mlen_p = mlen; + } + return ret; +} + +int +crypto_aead_chacha20poly1305_ietf_decrypt_detached(unsigned char *m, + unsigned char *nsec, + const unsigned char *c, + unsigned long long clen, + const unsigned char *mac, + const unsigned char *ad, + unsigned long long adlen, + const unsigned char *npub, + const unsigned char *k) +{ + crypto_onetimeauth_poly1305_state state; + unsigned char block0[64U]; + unsigned char slen[8U]; + unsigned char computed_mac[crypto_aead_chacha20poly1305_ietf_ABYTES]; + unsigned long long mlen; + int ret; + + (void) nsec; + crypto_stream_chacha20_ietf(block0, sizeof block0, npub, k); + crypto_onetimeauth_poly1305_init(&state, block0); + sodium_memzero(block0, sizeof block0); + + crypto_onetimeauth_poly1305_update(&state, ad, adlen); + crypto_onetimeauth_poly1305_update(&state, _pad0, (0x10 - adlen) & 0xf); + + mlen = clen; + crypto_onetimeauth_poly1305_update(&state, c, mlen); + crypto_onetimeauth_poly1305_update(&state, _pad0, (0x10 - mlen) & 0xf); + + STORE64_LE(slen, (uint64_t) adlen); + crypto_onetimeauth_poly1305_update(&state, slen, sizeof slen); + + STORE64_LE(slen, (uint64_t) mlen); + crypto_onetimeauth_poly1305_update(&state, slen, sizeof slen); + + crypto_onetimeauth_poly1305_final(&state, computed_mac); + sodium_memzero(&state, sizeof state); + + COMPILER_ASSERT(sizeof computed_mac == 16U); + ret = crypto_verify_16(computed_mac, mac); + sodium_memzero(computed_mac, sizeof computed_mac); + if (m == NULL) { + return ret; + } + if (ret != 0) { + memset(m, 0, mlen); + return -1; + } + crypto_stream_chacha20_ietf_xor_ic(m, c, mlen, npub, 1U, k); + + return 0; +} + +int +crypto_aead_chacha20poly1305_ietf_decrypt(unsigned char *m, + unsigned long long *mlen_p, + unsigned char *nsec, + const unsigned char *c, + unsigned long long clen, + const unsigned char *ad, + unsigned long long adlen, + const unsigned char *npub, + const unsigned char *k) +{ + unsigned long long mlen = 0ULL; + int ret = -1; + + if (clen >= crypto_aead_chacha20poly1305_ietf_ABYTES) { + ret = crypto_aead_chacha20poly1305_ietf_decrypt_detached + (m, nsec, + c, clen - crypto_aead_chacha20poly1305_ietf_ABYTES, + c + clen - crypto_aead_chacha20poly1305_ietf_ABYTES, + ad, adlen, npub, k); + } + if (mlen_p != NULL) { + if (ret == 0) { + mlen = clen - crypto_aead_chacha20poly1305_ietf_ABYTES; + } + *mlen_p = mlen; + } + return ret; +} + +size_t +crypto_aead_chacha20poly1305_ietf_keybytes(void) +{ + return crypto_aead_chacha20poly1305_ietf_KEYBYTES; +} + +size_t +crypto_aead_chacha20poly1305_ietf_npubbytes(void) +{ + return crypto_aead_chacha20poly1305_ietf_NPUBBYTES; +} + +size_t +crypto_aead_chacha20poly1305_ietf_nsecbytes(void) +{ + return crypto_aead_chacha20poly1305_ietf_NSECBYTES; +} + +size_t +crypto_aead_chacha20poly1305_ietf_abytes(void) +{ + return crypto_aead_chacha20poly1305_ietf_ABYTES; +} + +size_t +crypto_aead_chacha20poly1305_ietf_messagebytes_max(void) +{ + return crypto_aead_chacha20poly1305_ietf_MESSAGEBYTES_MAX; +} + +void +crypto_aead_chacha20poly1305_ietf_keygen(unsigned char k[crypto_aead_chacha20poly1305_ietf_KEYBYTES]) +{ + randombytes_buf(k, crypto_aead_chacha20poly1305_ietf_KEYBYTES); +} + +size_t +crypto_aead_chacha20poly1305_keybytes(void) +{ + return crypto_aead_chacha20poly1305_KEYBYTES; +} + +size_t +crypto_aead_chacha20poly1305_npubbytes(void) +{ + return crypto_aead_chacha20poly1305_NPUBBYTES; +} + +size_t +crypto_aead_chacha20poly1305_nsecbytes(void) +{ + return crypto_aead_chacha20poly1305_NSECBYTES; +} + +size_t +crypto_aead_chacha20poly1305_abytes(void) +{ + return crypto_aead_chacha20poly1305_ABYTES; +} + +size_t +crypto_aead_chacha20poly1305_messagebytes_max(void) +{ + return crypto_aead_chacha20poly1305_MESSAGEBYTES_MAX; +} + +void +crypto_aead_chacha20poly1305_keygen(unsigned char k[crypto_aead_chacha20poly1305_KEYBYTES]) +{ + randombytes_buf(k, crypto_aead_chacha20poly1305_KEYBYTES); +} diff --git a/libs/libsodium/src/crypto_aead/chacha20poly1305/sodium/aead_chacha20poly1305.c b/libs/libsodium/src/crypto_aead/chacha20poly1305/sodium/aead_chacha20poly1305.c deleted file mode 100644 index ce51546200..0000000000 --- a/libs/libsodium/src/crypto_aead/chacha20poly1305/sodium/aead_chacha20poly1305.c +++ /dev/null @@ -1,400 +0,0 @@ - -#include -#include -#include -#include - -#include "core.h" -#include "crypto_aead_chacha20poly1305.h" -#include "crypto_onetimeauth_poly1305.h" -#include "crypto_stream_chacha20.h" -#include "crypto_verify_16.h" -#include "randombytes.h" -#include "utils.h" - -#include "private/chacha20_ietf_ext.h" -#include "private/common.h" - -static const unsigned char _pad0[16] = { 0 }; - -int -crypto_aead_chacha20poly1305_encrypt_detached(unsigned char *c, - unsigned char *mac, - unsigned long long *maclen_p, - const unsigned char *m, - unsigned long long mlen, - const unsigned char *ad, - unsigned long long adlen, - const unsigned char *nsec, - const unsigned char *npub, - const unsigned char *k) -{ - crypto_onetimeauth_poly1305_state state; - unsigned char block0[64U]; - unsigned char slen[8U]; - - (void) nsec; - crypto_stream_chacha20(block0, sizeof block0, npub, k); - crypto_onetimeauth_poly1305_init(&state, block0); - sodium_memzero(block0, sizeof block0); - - crypto_onetimeauth_poly1305_update(&state, ad, adlen); - STORE64_LE(slen, (uint64_t) adlen); - crypto_onetimeauth_poly1305_update(&state, slen, sizeof slen); - - crypto_stream_chacha20_xor_ic(c, m, mlen, npub, 1U, k); - - crypto_onetimeauth_poly1305_update(&state, c, mlen); - STORE64_LE(slen, (uint64_t) mlen); - crypto_onetimeauth_poly1305_update(&state, slen, sizeof slen); - - crypto_onetimeauth_poly1305_final(&state, mac); - sodium_memzero(&state, sizeof state); - - if (maclen_p != NULL) { - *maclen_p = crypto_aead_chacha20poly1305_ABYTES; - } - return 0; -} - -int -crypto_aead_chacha20poly1305_encrypt(unsigned char *c, - unsigned long long *clen_p, - const unsigned char *m, - unsigned long long mlen, - const unsigned char *ad, - unsigned long long adlen, - const unsigned char *nsec, - const unsigned char *npub, - const unsigned char *k) -{ - unsigned long long clen = 0ULL; - int ret; - - if (mlen > crypto_aead_chacha20poly1305_MESSAGEBYTES_MAX) { - sodium_misuse(); - } - ret = crypto_aead_chacha20poly1305_encrypt_detached(c, - c + mlen, NULL, - m, mlen, - ad, adlen, - nsec, npub, k); - if (clen_p != NULL) { - if (ret == 0) { - clen = mlen + crypto_aead_chacha20poly1305_ABYTES; - } - *clen_p = clen; - } - return ret; -} - -int -crypto_aead_chacha20poly1305_ietf_encrypt_detached(unsigned char *c, - unsigned char *mac, - unsigned long long *maclen_p, - const unsigned char *m, - unsigned long long mlen, - const unsigned char *ad, - unsigned long long adlen, - const unsigned char *nsec, - const unsigned char *npub, - const unsigned char *k) -{ - crypto_onetimeauth_poly1305_state state; - unsigned char block0[64U]; - unsigned char slen[8U]; - - (void) nsec; - crypto_stream_chacha20_ietf(block0, sizeof block0, npub, k); - crypto_onetimeauth_poly1305_init(&state, block0); - sodium_memzero(block0, sizeof block0); - - crypto_onetimeauth_poly1305_update(&state, ad, adlen); - crypto_onetimeauth_poly1305_update(&state, _pad0, (0x10 - adlen) & 0xf); - - crypto_stream_chacha20_ietf_xor_ic(c, m, mlen, npub, 1U, k); - - crypto_onetimeauth_poly1305_update(&state, c, mlen); - crypto_onetimeauth_poly1305_update(&state, _pad0, (0x10 - mlen) & 0xf); - - STORE64_LE(slen, (uint64_t) adlen); - crypto_onetimeauth_poly1305_update(&state, slen, sizeof slen); - - STORE64_LE(slen, (uint64_t) mlen); - crypto_onetimeauth_poly1305_update(&state, slen, sizeof slen); - - crypto_onetimeauth_poly1305_final(&state, mac); - sodium_memzero(&state, sizeof state); - - if (maclen_p != NULL) { - *maclen_p = crypto_aead_chacha20poly1305_ietf_ABYTES; - } - return 0; -} - -int -crypto_aead_chacha20poly1305_ietf_encrypt(unsigned char *c, - unsigned long long *clen_p, - const unsigned char *m, - unsigned long long mlen, - const unsigned char *ad, - unsigned long long adlen, - const unsigned char *nsec, - const unsigned char *npub, - const unsigned char *k) -{ - unsigned long long clen = 0ULL; - int ret; - - if (mlen > crypto_aead_chacha20poly1305_ietf_MESSAGEBYTES_MAX) { - sodium_misuse(); - } - ret = crypto_aead_chacha20poly1305_ietf_encrypt_detached(c, - c + mlen, NULL, - m, mlen, - ad, adlen, - nsec, npub, k); - if (clen_p != NULL) { - if (ret == 0) { - clen = mlen + crypto_aead_chacha20poly1305_ietf_ABYTES; - } - *clen_p = clen; - } - return ret; -} - -int -crypto_aead_chacha20poly1305_decrypt_detached(unsigned char *m, - unsigned char *nsec, - const unsigned char *c, - unsigned long long clen, - const unsigned char *mac, - const unsigned char *ad, - unsigned long long adlen, - const unsigned char *npub, - const unsigned char *k) -{ - crypto_onetimeauth_poly1305_state state; - unsigned char block0[64U]; - unsigned char slen[8U]; - unsigned char computed_mac[crypto_aead_chacha20poly1305_ABYTES]; - unsigned long long mlen; - int ret; - - (void) nsec; - crypto_stream_chacha20(block0, sizeof block0, npub, k); - crypto_onetimeauth_poly1305_init(&state, block0); - sodium_memzero(block0, sizeof block0); - - crypto_onetimeauth_poly1305_update(&state, ad, adlen); - STORE64_LE(slen, (uint64_t) adlen); - crypto_onetimeauth_poly1305_update(&state, slen, sizeof slen); - - mlen = clen; - crypto_onetimeauth_poly1305_update(&state, c, mlen); - STORE64_LE(slen, (uint64_t) mlen); - crypto_onetimeauth_poly1305_update(&state, slen, sizeof slen); - - crypto_onetimeauth_poly1305_final(&state, computed_mac); - sodium_memzero(&state, sizeof state); - - COMPILER_ASSERT(sizeof computed_mac == 16U); - ret = crypto_verify_16(computed_mac, mac); - sodium_memzero(computed_mac, sizeof computed_mac); - if (m == NULL) { - return ret; - } - if (ret != 0) { - memset(m, 0, mlen); - return -1; - } - crypto_stream_chacha20_xor_ic(m, c, mlen, npub, 1U, k); - - return 0; -} - -int -crypto_aead_chacha20poly1305_decrypt(unsigned char *m, - unsigned long long *mlen_p, - unsigned char *nsec, - const unsigned char *c, - unsigned long long clen, - const unsigned char *ad, - unsigned long long adlen, - const unsigned char *npub, - const unsigned char *k) -{ - unsigned long long mlen = 0ULL; - int ret = -1; - - if (clen >= crypto_aead_chacha20poly1305_ABYTES) { - ret = crypto_aead_chacha20poly1305_decrypt_detached - (m, nsec, - c, clen - crypto_aead_chacha20poly1305_ABYTES, - c + clen - crypto_aead_chacha20poly1305_ABYTES, - ad, adlen, npub, k); - } - if (mlen_p != NULL) { - if (ret == 0) { - mlen = clen - crypto_aead_chacha20poly1305_ABYTES; - } - *mlen_p = mlen; - } - return ret; -} - -int -crypto_aead_chacha20poly1305_ietf_decrypt_detached(unsigned char *m, - unsigned char *nsec, - const unsigned char *c, - unsigned long long clen, - const unsigned char *mac, - const unsigned char *ad, - unsigned long long adlen, - const unsigned char *npub, - const unsigned char *k) -{ - crypto_onetimeauth_poly1305_state state; - unsigned char block0[64U]; - unsigned char slen[8U]; - unsigned char computed_mac[crypto_aead_chacha20poly1305_ietf_ABYTES]; - unsigned long long mlen; - int ret; - - (void) nsec; - crypto_stream_chacha20_ietf(block0, sizeof block0, npub, k); - crypto_onetimeauth_poly1305_init(&state, block0); - sodium_memzero(block0, sizeof block0); - - crypto_onetimeauth_poly1305_update(&state, ad, adlen); - crypto_onetimeauth_poly1305_update(&state, _pad0, (0x10 - adlen) & 0xf); - - mlen = clen; - crypto_onetimeauth_poly1305_update(&state, c, mlen); - crypto_onetimeauth_poly1305_update(&state, _pad0, (0x10 - mlen) & 0xf); - - STORE64_LE(slen, (uint64_t) adlen); - crypto_onetimeauth_poly1305_update(&state, slen, sizeof slen); - - STORE64_LE(slen, (uint64_t) mlen); - crypto_onetimeauth_poly1305_update(&state, slen, sizeof slen); - - crypto_onetimeauth_poly1305_final(&state, computed_mac); - sodium_memzero(&state, sizeof state); - - COMPILER_ASSERT(sizeof computed_mac == 16U); - ret = crypto_verify_16(computed_mac, mac); - sodium_memzero(computed_mac, sizeof computed_mac); - if (m == NULL) { - return ret; - } - if (ret != 0) { - memset(m, 0, mlen); - return -1; - } - crypto_stream_chacha20_ietf_xor_ic(m, c, mlen, npub, 1U, k); - - return 0; -} - -int -crypto_aead_chacha20poly1305_ietf_decrypt(unsigned char *m, - unsigned long long *mlen_p, - unsigned char *nsec, - const unsigned char *c, - unsigned long long clen, - const unsigned char *ad, - unsigned long long adlen, - const unsigned char *npub, - const unsigned char *k) -{ - unsigned long long mlen = 0ULL; - int ret = -1; - - if (clen >= crypto_aead_chacha20poly1305_ietf_ABYTES) { - ret = crypto_aead_chacha20poly1305_ietf_decrypt_detached - (m, nsec, - c, clen - crypto_aead_chacha20poly1305_ietf_ABYTES, - c + clen - crypto_aead_chacha20poly1305_ietf_ABYTES, - ad, adlen, npub, k); - } - if (mlen_p != NULL) { - if (ret == 0) { - mlen = clen - crypto_aead_chacha20poly1305_ietf_ABYTES; - } - *mlen_p = mlen; - } - return ret; -} - -size_t -crypto_aead_chacha20poly1305_ietf_keybytes(void) -{ - return crypto_aead_chacha20poly1305_ietf_KEYBYTES; -} - -size_t -crypto_aead_chacha20poly1305_ietf_npubbytes(void) -{ - return crypto_aead_chacha20poly1305_ietf_NPUBBYTES; -} - -size_t -crypto_aead_chacha20poly1305_ietf_nsecbytes(void) -{ - return crypto_aead_chacha20poly1305_ietf_NSECBYTES; -} - -size_t -crypto_aead_chacha20poly1305_ietf_abytes(void) -{ - return crypto_aead_chacha20poly1305_ietf_ABYTES; -} - -size_t -crypto_aead_chacha20poly1305_ietf_messagebytes_max(void) -{ - return crypto_aead_chacha20poly1305_ietf_MESSAGEBYTES_MAX; -} - -void -crypto_aead_chacha20poly1305_ietf_keygen(unsigned char k[crypto_aead_chacha20poly1305_ietf_KEYBYTES]) -{ - randombytes_buf(k, crypto_aead_chacha20poly1305_ietf_KEYBYTES); -} - -size_t -crypto_aead_chacha20poly1305_keybytes(void) -{ - return crypto_aead_chacha20poly1305_KEYBYTES; -} - -size_t -crypto_aead_chacha20poly1305_npubbytes(void) -{ - return crypto_aead_chacha20poly1305_NPUBBYTES; -} - -size_t -crypto_aead_chacha20poly1305_nsecbytes(void) -{ - return crypto_aead_chacha20poly1305_NSECBYTES; -} - -size_t -crypto_aead_chacha20poly1305_abytes(void) -{ - return crypto_aead_chacha20poly1305_ABYTES; -} - -size_t -crypto_aead_chacha20poly1305_messagebytes_max(void) -{ - return crypto_aead_chacha20poly1305_MESSAGEBYTES_MAX; -} - -void -crypto_aead_chacha20poly1305_keygen(unsigned char k[crypto_aead_chacha20poly1305_KEYBYTES]) -{ - randombytes_buf(k, crypto_aead_chacha20poly1305_KEYBYTES); -} diff --git a/libs/libsodium/src/crypto_aead/xchacha20poly1305/aead_xchacha20poly1305.c b/libs/libsodium/src/crypto_aead/xchacha20poly1305/aead_xchacha20poly1305.c new file mode 100644 index 0000000000..07e3655731 --- /dev/null +++ b/libs/libsodium/src/crypto_aead/xchacha20poly1305/aead_xchacha20poly1305.c @@ -0,0 +1,262 @@ + +#include +#include +#include +#include + +#include "core.h" +#include "crypto_aead_chacha20poly1305.h" +#include "crypto_aead_xchacha20poly1305.h" +#include "crypto_core_hchacha20.h" +#include "crypto_onetimeauth_poly1305.h" +#include "crypto_stream_chacha20.h" +#include "crypto_verify_16.h" +#include "randombytes.h" +#include "utils.h" + +#include "private/chacha20_ietf_ext.h" +#include "private/common.h" + +static const unsigned char _pad0[16] = { 0 }; + +static int +_encrypt_detached(unsigned char *c, + unsigned char *mac, + unsigned long long *maclen_p, + const unsigned char *m, + unsigned long long mlen, + const unsigned char *ad, + unsigned long long adlen, + const unsigned char *nsec, + const unsigned char *npub, + const unsigned char *k) +{ + crypto_onetimeauth_poly1305_state state; + unsigned char block0[64U]; + unsigned char slen[8U]; + + (void) nsec; + crypto_stream_chacha20_ietf_ext(block0, sizeof block0, npub, k); + crypto_onetimeauth_poly1305_init(&state, block0); + sodium_memzero(block0, sizeof block0); + + crypto_onetimeauth_poly1305_update(&state, ad, adlen); + crypto_onetimeauth_poly1305_update(&state, _pad0, (0x10 - adlen) & 0xf); + + crypto_stream_chacha20_ietf_ext_xor_ic(c, m, mlen, npub, 1U, k); + + crypto_onetimeauth_poly1305_update(&state, c, mlen); + crypto_onetimeauth_poly1305_update(&state, _pad0, (0x10 - mlen) & 0xf); + + STORE64_LE(slen, (uint64_t) adlen); + crypto_onetimeauth_poly1305_update(&state, slen, sizeof slen); + + STORE64_LE(slen, (uint64_t) mlen); + crypto_onetimeauth_poly1305_update(&state, slen, sizeof slen); + + crypto_onetimeauth_poly1305_final(&state, mac); + sodium_memzero(&state, sizeof state); + + if (maclen_p != NULL) { + *maclen_p = crypto_aead_chacha20poly1305_ietf_ABYTES; + } + return 0; +} + +static int +_decrypt_detached(unsigned char *m, + unsigned char *nsec, + const unsigned char *c, + unsigned long long clen, + const unsigned char *mac, + const unsigned char *ad, + unsigned long long adlen, + const unsigned char *npub, + const unsigned char *k) +{ + crypto_onetimeauth_poly1305_state state; + unsigned char block0[64U]; + unsigned char slen[8U]; + unsigned char computed_mac[crypto_aead_chacha20poly1305_ietf_ABYTES]; + unsigned long long mlen; + int ret; + + (void) nsec; + crypto_stream_chacha20_ietf_ext(block0, sizeof block0, npub, k); + crypto_onetimeauth_poly1305_init(&state, block0); + sodium_memzero(block0, sizeof block0); + + crypto_onetimeauth_poly1305_update(&state, ad, adlen); + crypto_onetimeauth_poly1305_update(&state, _pad0, (0x10 - adlen) & 0xf); + + mlen = clen; + crypto_onetimeauth_poly1305_update(&state, c, mlen); + crypto_onetimeauth_poly1305_update(&state, _pad0, (0x10 - mlen) & 0xf); + + STORE64_LE(slen, (uint64_t) adlen); + crypto_onetimeauth_poly1305_update(&state, slen, sizeof slen); + + STORE64_LE(slen, (uint64_t) mlen); + crypto_onetimeauth_poly1305_update(&state, slen, sizeof slen); + + crypto_onetimeauth_poly1305_final(&state, computed_mac); + sodium_memzero(&state, sizeof state); + + COMPILER_ASSERT(sizeof computed_mac == 16U); + ret = crypto_verify_16(computed_mac, mac); + sodium_memzero(computed_mac, sizeof computed_mac); + if (m == NULL) { + return ret; + } + if (ret != 0) { + memset(m, 0, mlen); + return -1; + } + crypto_stream_chacha20_ietf_ext_xor_ic(m, c, mlen, npub, 1U, k); + + return 0; +} + +int +crypto_aead_xchacha20poly1305_ietf_encrypt_detached(unsigned char *c, + unsigned char *mac, + unsigned long long *maclen_p, + const unsigned char *m, + unsigned long long mlen, + const unsigned char *ad, + unsigned long long adlen, + const unsigned char *nsec, + const unsigned char *npub, + const unsigned char *k) +{ + unsigned char k2[crypto_core_hchacha20_OUTPUTBYTES]; + unsigned char npub2[crypto_aead_chacha20poly1305_ietf_NPUBBYTES] = { 0 }; + int ret; + + crypto_core_hchacha20(k2, npub, k, NULL); + memcpy(npub2 + 4, npub + crypto_core_hchacha20_INPUTBYTES, + crypto_aead_chacha20poly1305_ietf_NPUBBYTES - 4); + ret = _encrypt_detached(c, mac, maclen_p, m, mlen, ad, adlen, + nsec, npub2, k2); + sodium_memzero(k2, crypto_core_hchacha20_OUTPUTBYTES); + + return ret; +} + +int +crypto_aead_xchacha20poly1305_ietf_encrypt(unsigned char *c, + unsigned long long *clen_p, + const unsigned char *m, + unsigned long long mlen, + const unsigned char *ad, + unsigned long long adlen, + const unsigned char *nsec, + const unsigned char *npub, + const unsigned char *k) +{ + unsigned long long clen = 0ULL; + int ret; + + if (mlen > crypto_aead_xchacha20poly1305_ietf_MESSAGEBYTES_MAX) { + sodium_misuse(); + } + ret = crypto_aead_xchacha20poly1305_ietf_encrypt_detached + (c, c + mlen, NULL, m, mlen, ad, adlen, nsec, npub, k); + if (clen_p != NULL) { + if (ret == 0) { + clen = mlen + crypto_aead_xchacha20poly1305_ietf_ABYTES; + } + *clen_p = clen; + } + return ret; +} + +int +crypto_aead_xchacha20poly1305_ietf_decrypt_detached(unsigned char *m, + unsigned char *nsec, + const unsigned char *c, + unsigned long long clen, + const unsigned char *mac, + const unsigned char *ad, + unsigned long long adlen, + const unsigned char *npub, + const unsigned char *k) +{ + unsigned char k2[crypto_core_hchacha20_OUTPUTBYTES]; + unsigned char npub2[crypto_aead_chacha20poly1305_ietf_NPUBBYTES] = { 0 }; + int ret; + + crypto_core_hchacha20(k2, npub, k, NULL); + memcpy(npub2 + 4, npub + crypto_core_hchacha20_INPUTBYTES, + crypto_aead_chacha20poly1305_ietf_NPUBBYTES - 4); + ret = _decrypt_detached(m, nsec, c, clen, mac, ad, adlen, npub2, k2); + sodium_memzero(k2, crypto_core_hchacha20_OUTPUTBYTES); + + return ret; +} + +int +crypto_aead_xchacha20poly1305_ietf_decrypt(unsigned char *m, + unsigned long long *mlen_p, + unsigned char *nsec, + const unsigned char *c, + unsigned long long clen, + const unsigned char *ad, + unsigned long long adlen, + const unsigned char *npub, + const unsigned char *k) +{ + unsigned long long mlen = 0ULL; + int ret = -1; + + if (clen >= crypto_aead_xchacha20poly1305_ietf_ABYTES) { + ret = crypto_aead_xchacha20poly1305_ietf_decrypt_detached + (m, nsec, + c, clen - crypto_aead_xchacha20poly1305_ietf_ABYTES, + c + clen - crypto_aead_xchacha20poly1305_ietf_ABYTES, + ad, adlen, npub, k); + } + if (mlen_p != NULL) { + if (ret == 0) { + mlen = clen - crypto_aead_xchacha20poly1305_ietf_ABYTES; + } + *mlen_p = mlen; + } + return ret; +} + +size_t +crypto_aead_xchacha20poly1305_ietf_keybytes(void) +{ + return crypto_aead_xchacha20poly1305_ietf_KEYBYTES; +} + +size_t +crypto_aead_xchacha20poly1305_ietf_npubbytes(void) +{ + return crypto_aead_xchacha20poly1305_ietf_NPUBBYTES; +} + +size_t +crypto_aead_xchacha20poly1305_ietf_nsecbytes(void) +{ + return crypto_aead_xchacha20poly1305_ietf_NSECBYTES; +} + +size_t +crypto_aead_xchacha20poly1305_ietf_abytes(void) +{ + return crypto_aead_xchacha20poly1305_ietf_ABYTES; +} + +size_t +crypto_aead_xchacha20poly1305_ietf_messagebytes_max(void) +{ + return crypto_aead_xchacha20poly1305_ietf_MESSAGEBYTES_MAX; +} + +void +crypto_aead_xchacha20poly1305_ietf_keygen(unsigned char k[crypto_aead_xchacha20poly1305_ietf_KEYBYTES]) +{ + randombytes_buf(k, crypto_aead_xchacha20poly1305_ietf_KEYBYTES); +} diff --git a/libs/libsodium/src/crypto_aead/xchacha20poly1305/sodium/aead_xchacha20poly1305.c b/libs/libsodium/src/crypto_aead/xchacha20poly1305/sodium/aead_xchacha20poly1305.c deleted file mode 100644 index 61ccc84c8c..0000000000 --- a/libs/libsodium/src/crypto_aead/xchacha20poly1305/sodium/aead_xchacha20poly1305.c +++ /dev/null @@ -1,262 +0,0 @@ - -#include -#include -#include -#include - -#include "core.h" -#include "crypto_aead_chacha20poly1305.h" -#include "crypto_aead_xchacha20poly1305.h" -#include "crypto_core_hchacha20.h" -#include "crypto_onetimeauth_poly1305.h" -#include "crypto_stream_chacha20.h" -#include "crypto_verify_16.h" -#include "randombytes.h" -#include "utils.h" - -#include "private/chacha20_ietf_ext.h" -#include "private/common.h" - -static const unsigned char _pad0[16] = { 0 }; - -static int -_encrypt_detached(unsigned char *c, - unsigned char *mac, - unsigned long long *maclen_p, - const unsigned char *m, - unsigned long long mlen, - const unsigned char *ad, - unsigned long long adlen, - const unsigned char *nsec, - const unsigned char *npub, - const unsigned char *k) -{ - crypto_onetimeauth_poly1305_state state; - unsigned char block0[64U]; - unsigned char slen[8U]; - - (void) nsec; - crypto_stream_chacha20_ietf_ext(block0, sizeof block0, npub, k); - crypto_onetimeauth_poly1305_init(&state, block0); - sodium_memzero(block0, sizeof block0); - - crypto_onetimeauth_poly1305_update(&state, ad, adlen); - crypto_onetimeauth_poly1305_update(&state, _pad0, (0x10 - adlen) & 0xf); - - crypto_stream_chacha20_ietf_ext_xor_ic(c, m, mlen, npub, 1U, k); - - crypto_onetimeauth_poly1305_update(&state, c, mlen); - crypto_onetimeauth_poly1305_update(&state, _pad0, (0x10 - mlen) & 0xf); - - STORE64_LE(slen, (uint64_t) adlen); - crypto_onetimeauth_poly1305_update(&state, slen, sizeof slen); - - STORE64_LE(slen, (uint64_t) mlen); - crypto_onetimeauth_poly1305_update(&state, slen, sizeof slen); - - crypto_onetimeauth_poly1305_final(&state, mac); - sodium_memzero(&state, sizeof state); - - if (maclen_p != NULL) { - *maclen_p = crypto_aead_chacha20poly1305_ietf_ABYTES; - } - return 0; -} - -static int -_decrypt_detached(unsigned char *m, - unsigned char *nsec, - const unsigned char *c, - unsigned long long clen, - const unsigned char *mac, - const unsigned char *ad, - unsigned long long adlen, - const unsigned char *npub, - const unsigned char *k) -{ - crypto_onetimeauth_poly1305_state state; - unsigned char block0[64U]; - unsigned char slen[8U]; - unsigned char computed_mac[crypto_aead_chacha20poly1305_ietf_ABYTES]; - unsigned long long mlen; - int ret; - - (void) nsec; - crypto_stream_chacha20_ietf_ext(block0, sizeof block0, npub, k); - crypto_onetimeauth_poly1305_init(&state, block0); - sodium_memzero(block0, sizeof block0); - - crypto_onetimeauth_poly1305_update(&state, ad, adlen); - crypto_onetimeauth_poly1305_update(&state, _pad0, (0x10 - adlen) & 0xf); - - mlen = clen; - crypto_onetimeauth_poly1305_update(&state, c, mlen); - crypto_onetimeauth_poly1305_update(&state, _pad0, (0x10 - mlen) & 0xf); - - STORE64_LE(slen, (uint64_t) adlen); - crypto_onetimeauth_poly1305_update(&state, slen, sizeof slen); - - STORE64_LE(slen, (uint64_t) mlen); - crypto_onetimeauth_poly1305_update(&state, slen, sizeof slen); - - crypto_onetimeauth_poly1305_final(&state, computed_mac); - sodium_memzero(&state, sizeof state); - - COMPILER_ASSERT(sizeof computed_mac == 16U); - ret = crypto_verify_16(computed_mac, mac); - sodium_memzero(computed_mac, sizeof computed_mac); - if (m == NULL) { - return ret; - } - if (ret != 0) { - memset(m, 0, mlen); - return -1; - } - crypto_stream_chacha20_ietf_ext_xor_ic(m, c, mlen, npub, 1U, k); - - return 0; -} - -int -crypto_aead_xchacha20poly1305_ietf_encrypt_detached(unsigned char *c, - unsigned char *mac, - unsigned long long *maclen_p, - const unsigned char *m, - unsigned long long mlen, - const unsigned char *ad, - unsigned long long adlen, - const unsigned char *nsec, - const unsigned char *npub, - const unsigned char *k) -{ - unsigned char k2[crypto_core_hchacha20_OUTPUTBYTES]; - unsigned char npub2[crypto_aead_chacha20poly1305_ietf_NPUBBYTES] = { 0 }; - int ret; - - crypto_core_hchacha20(k2, npub, k, NULL); - memcpy(npub2 + 4, npub + crypto_core_hchacha20_INPUTBYTES, - crypto_aead_chacha20poly1305_ietf_NPUBBYTES - 4); - ret = _encrypt_detached(c, mac, maclen_p, m, mlen, ad, adlen, - nsec, npub2, k2); - sodium_memzero(k2, crypto_core_hchacha20_OUTPUTBYTES); - - return ret; -} - -int -crypto_aead_xchacha20poly1305_ietf_encrypt(unsigned char *c, - unsigned long long *clen_p, - const unsigned char *m, - unsigned long long mlen, - const unsigned char *ad, - unsigned long long adlen, - const unsigned char *nsec, - const unsigned char *npub, - const unsigned char *k) -{ - unsigned long long clen = 0ULL; - int ret; - - if (mlen > crypto_aead_xchacha20poly1305_ietf_MESSAGEBYTES_MAX) { - sodium_misuse(); - } - ret = crypto_aead_xchacha20poly1305_ietf_encrypt_detached - (c, c + mlen, NULL, m, mlen, ad, adlen, nsec, npub, k); - if (clen_p != NULL) { - if (ret == 0) { - clen = mlen + crypto_aead_xchacha20poly1305_ietf_ABYTES; - } - *clen_p = clen; - } - return ret; -} - -int -crypto_aead_xchacha20poly1305_ietf_decrypt_detached(unsigned char *m, - unsigned char *nsec, - const unsigned char *c, - unsigned long long clen, - const unsigned char *mac, - const unsigned char *ad, - unsigned long long adlen, - const unsigned char *npub, - const unsigned char *k) -{ - unsigned char k2[crypto_core_hchacha20_OUTPUTBYTES]; - unsigned char npub2[crypto_aead_chacha20poly1305_ietf_NPUBBYTES] = { 0 }; - int ret; - - crypto_core_hchacha20(k2, npub, k, NULL); - memcpy(npub2 + 4, npub + crypto_core_hchacha20_INPUTBYTES, - crypto_aead_chacha20poly1305_ietf_NPUBBYTES - 4); - ret = _decrypt_detached(m, nsec, c, clen, mac, ad, adlen, npub2, k2); - sodium_memzero(k2, crypto_core_hchacha20_OUTPUTBYTES); - - return ret; -} - -int -crypto_aead_xchacha20poly1305_ietf_decrypt(unsigned char *m, - unsigned long long *mlen_p, - unsigned char *nsec, - const unsigned char *c, - unsigned long long clen, - const unsigned char *ad, - unsigned long long adlen, - const unsigned char *npub, - const unsigned char *k) -{ - unsigned long long mlen = 0ULL; - int ret = -1; - - if (clen >= crypto_aead_xchacha20poly1305_ietf_ABYTES) { - ret = crypto_aead_xchacha20poly1305_ietf_decrypt_detached - (m, nsec, - c, clen - crypto_aead_xchacha20poly1305_ietf_ABYTES, - c + clen - crypto_aead_xchacha20poly1305_ietf_ABYTES, - ad, adlen, npub, k); - } - if (mlen_p != NULL) { - if (ret == 0) { - mlen = clen - crypto_aead_xchacha20poly1305_ietf_ABYTES; - } - *mlen_p = mlen; - } - return ret; -} - -size_t -crypto_aead_xchacha20poly1305_ietf_keybytes(void) -{ - return crypto_aead_xchacha20poly1305_ietf_KEYBYTES; -} - -size_t -crypto_aead_xchacha20poly1305_ietf_npubbytes(void) -{ - return crypto_aead_xchacha20poly1305_ietf_NPUBBYTES; -} - -size_t -crypto_aead_xchacha20poly1305_ietf_nsecbytes(void) -{ - return crypto_aead_xchacha20poly1305_ietf_NSECBYTES; -} - -size_t -crypto_aead_xchacha20poly1305_ietf_abytes(void) -{ - return crypto_aead_xchacha20poly1305_ietf_ABYTES; -} - -size_t -crypto_aead_xchacha20poly1305_ietf_messagebytes_max(void) -{ - return crypto_aead_xchacha20poly1305_ietf_MESSAGEBYTES_MAX; -} - -void -crypto_aead_xchacha20poly1305_ietf_keygen(unsigned char k[crypto_aead_xchacha20poly1305_ietf_KEYBYTES]) -{ - randombytes_buf(k, crypto_aead_xchacha20poly1305_ietf_KEYBYTES); -} diff --git a/libs/libsodium/src/crypto_box/crypto_box_seal.c b/libs/libsodium/src/crypto_box/crypto_box_seal.c index 59c686c4cc..f01845c47a 100644 --- a/libs/libsodium/src/crypto_box/crypto_box_seal.c +++ b/libs/libsodium/src/crypto_box/crypto_box_seal.c @@ -32,10 +32,10 @@ crypto_box_seal(unsigned char *c, const unsigned char *m, if (crypto_box_keypair(epk, esk) != 0) { return -1; /* LCOV_EXCL_LINE */ } - memcpy(c, epk, crypto_box_PUBLICKEYBYTES); _crypto_box_seal_nonce(nonce, epk, pk); ret = crypto_box_easy(c + crypto_box_PUBLICKEYBYTES, m, mlen, nonce, pk, esk); + memcpy(c, epk, crypto_box_PUBLICKEYBYTES); sodium_memzero(esk, sizeof esk); sodium_memzero(epk, sizeof epk); sodium_memzero(nonce, sizeof nonce); diff --git a/libs/libsodium/src/crypto_box/curve25519xchacha20poly1305/box_seal_curve25519xchacha20poly1305.c b/libs/libsodium/src/crypto_box/curve25519xchacha20poly1305/box_seal_curve25519xchacha20poly1305.c index 9ed3e809aa..d6c7c9d5d0 100644 --- a/libs/libsodium/src/crypto_box/curve25519xchacha20poly1305/box_seal_curve25519xchacha20poly1305.c +++ b/libs/libsodium/src/crypto_box/curve25519xchacha20poly1305/box_seal_curve25519xchacha20poly1305.c @@ -38,11 +38,11 @@ crypto_box_curve25519xchacha20poly1305_seal(unsigned char *c, const unsigned cha if (crypto_box_curve25519xchacha20poly1305_keypair(epk, esk) != 0) { return -1; /* LCOV_EXCL_LINE */ } - memcpy(c, epk, crypto_box_curve25519xchacha20poly1305_PUBLICKEYBYTES); _crypto_box_curve25519xchacha20poly1305_seal_nonce(nonce, epk, pk); ret = crypto_box_curve25519xchacha20poly1305_easy( c + crypto_box_curve25519xchacha20poly1305_PUBLICKEYBYTES, m, mlen, nonce, pk, esk); + memcpy(c, epk, crypto_box_curve25519xchacha20poly1305_PUBLICKEYBYTES); sodium_memzero(esk, sizeof esk); sodium_memzero(epk, sizeof epk); sodium_memzero(nonce, sizeof nonce); diff --git a/libs/libsodium/src/crypto_core/ed25519/core_ed25519.c b/libs/libsodium/src/crypto_core/ed25519/core_ed25519.c index 007db4656e..99d5fd8780 100644 --- a/libs/libsodium/src/crypto_core/ed25519/core_ed25519.c +++ b/libs/libsodium/src/crypto_core/ed25519/core_ed25519.c @@ -1,7 +1,10 @@ - #include +#include +#include +#include "core_h2c.h" #include "crypto_core_ed25519.h" +#include "crypto_hash_sha512.h" #include "private/common.h" #include "private/ed25519_ref10.h" #include "randombytes.h" @@ -13,9 +16,9 @@ crypto_core_ed25519_is_valid_point(const unsigned char *p) ge25519_p3 p_p3; if (ge25519_is_canonical(p) == 0 || - ge25519_has_small_order(p) != 0 || ge25519_frombytes(&p_p3, p) != 0 || ge25519_is_on_curve(&p_p3) == 0 || + ge25519_has_small_order(&p_p3) != 0 || ge25519_is_on_main_subgroup(&p_p3) == 0) { return 0; } @@ -27,16 +30,12 @@ crypto_core_ed25519_add(unsigned char *r, const unsigned char *p, const unsigned char *q) { ge25519_p3 p_p3, q_p3, r_p3; - ge25519_p1p1 r_p1p1; - ge25519_cached q_cached; if (ge25519_frombytes(&p_p3, p) != 0 || ge25519_is_on_curve(&p_p3) == 0 || ge25519_frombytes(&q_p3, q) != 0 || ge25519_is_on_curve(&q_p3) == 0) { return -1; } - ge25519_p3_to_cached(&q_cached, &q_p3); - ge25519_add(&r_p1p1, &p_p3, &q_cached); - ge25519_p1p1_to_p3(&r_p3, &r_p1p1); + ge25519_p3_add(&r_p3, &p_p3, &q_p3); ge25519_p3_tobytes(r, &r_p3); return 0; @@ -47,16 +46,12 @@ crypto_core_ed25519_sub(unsigned char *r, const unsigned char *p, const unsigned char *q) { ge25519_p3 p_p3, q_p3, r_p3; - ge25519_p1p1 r_p1p1; - ge25519_cached q_cached; if (ge25519_frombytes(&p_p3, p) != 0 || ge25519_is_on_curve(&p_p3) == 0 || ge25519_frombytes(&q_p3, q) != 0 || ge25519_is_on_curve(&q_p3) == 0) { return -1; } - ge25519_p3_to_cached(&q_cached, &q_p3); - ge25519_sub(&r_p1p1, &p_p3, &q_cached); - ge25519_p1p1_to_p3(&r_p3, &r_p1p1); + ge25519_p3_sub(&r_p3, &p_p3, &q_p3); ge25519_p3_tobytes(r, &r_p3); return 0; @@ -67,7 +62,32 @@ crypto_core_ed25519_from_uniform(unsigned char *p, const unsigned char *r) { ge25519_from_uniform(p, r); - return - ge25519_has_small_order(p); + return 0; +} + +int +crypto_core_ed25519_from_string(unsigned char p[crypto_core_ed25519_BYTES], + const char *ctx, const unsigned char *msg, + size_t msg_len, int hash_alg) +{ + return ge25519_from_string(p, ctx, msg, msg_len, hash_alg); +} + +int +crypto_core_ed25519_from_string_ro(unsigned char p[crypto_core_ed25519_BYTES], + const char *ctx, const unsigned char *msg, + size_t msg_len, int hash_alg) +{ + return ge25519_from_string_ro(p, ctx, msg, msg_len, hash_alg); +} + +void +crypto_core_ed25519_random(unsigned char *p) +{ + unsigned char h[crypto_core_ed25519_UNIFORMBYTES]; + + randombytes_buf(h, sizeof h); + (void) crypto_core_ed25519_from_uniform(p, h); } void @@ -158,6 +178,13 @@ crypto_core_ed25519_scalar_sub(unsigned char *z, const unsigned char *x, crypto_core_ed25519_scalar_add(z, x, yn); } +void +crypto_core_ed25519_scalar_mul(unsigned char *z, const unsigned char *x, + const unsigned char *y) +{ + sc25519_mul(z, x, y); +} + void crypto_core_ed25519_scalar_reduce(unsigned char *r, const unsigned char *s) @@ -170,6 +197,12 @@ crypto_core_ed25519_scalar_reduce(unsigned char *r, sodium_memzero(t, sizeof t); } +int +crypto_core_ed25519_scalar_is_canonical(const unsigned char *s) +{ + return sc25519_is_canonical(s); +} + size_t crypto_core_ed25519_bytes(void) { @@ -188,6 +221,12 @@ crypto_core_ed25519_uniformbytes(void) return crypto_core_ed25519_UNIFORMBYTES; } +size_t +crypto_core_ed25519_hashbytes(void) +{ + return crypto_core_ed25519_HASHBYTES; +} + size_t crypto_core_ed25519_scalarbytes(void) { diff --git a/libs/libsodium/src/crypto_core/ed25519/core_h2c.c b/libs/libsodium/src/crypto_core/ed25519/core_h2c.c new file mode 100644 index 0000000000..37f3ed59fb --- /dev/null +++ b/libs/libsodium/src/crypto_core/ed25519/core_h2c.c @@ -0,0 +1,133 @@ +#include +#include +#include +#include + +#include "core_h2c.h" +#include "crypto_hash_sha256.h" +#include "crypto_hash_sha512.h" +#include "private/common.h" + +#define HASH_BYTES crypto_hash_sha256_BYTES +#define HASH_BLOCKBYTES 64U + +static int +core_h2c_string_to_hash_sha256(unsigned char *h, const size_t h_len, const char *ctx, + const unsigned char *msg, size_t msg_len) +{ + crypto_hash_sha256_state st; + const unsigned char empty_block[HASH_BLOCKBYTES] = { 0 }; + unsigned char u0[HASH_BYTES]; + unsigned char ux[HASH_BYTES] = { 0 }; + unsigned char t[3] = { 0U, (unsigned char) h_len, 0U}; + unsigned char ctx_len_u8; + size_t ctx_len = ctx != NULL ? strlen(ctx) : 0U; + size_t i, j; + + assert(h_len <= 0xff); + if (ctx_len > (size_t) 0xff) { + crypto_hash_sha256_init(&st); + crypto_hash_sha256_update(&st, + (const unsigned char *) "H2C-OVERSIZE-DST-", + sizeof "H2C-OVERSIZE-DST-" - 1U); + crypto_hash_sha256_update(&st, (const unsigned char *) ctx, ctx_len); + crypto_hash_sha256_final(&st, u0); + ctx = (const char *) u0; + ctx_len = HASH_BYTES; + COMPILER_ASSERT(HASH_BYTES <= (size_t) 0xff); + } + ctx_len_u8 = (unsigned char) ctx_len; + crypto_hash_sha256_init(&st); + crypto_hash_sha256_update(&st, empty_block, sizeof empty_block); + crypto_hash_sha256_update(&st, msg, msg_len); + crypto_hash_sha256_update(&st, t, 3U); + crypto_hash_sha256_update(&st, (const unsigned char *) ctx, ctx_len); + crypto_hash_sha256_update(&st, &ctx_len_u8, 1U); + crypto_hash_sha256_final(&st, u0); + + for (i = 0U; i < h_len; i += HASH_BYTES) { + for (j = 0U; j < HASH_BYTES; j++) { + ux[j] ^= u0[j]; + } + t[2]++; + crypto_hash_sha256_init(&st); + crypto_hash_sha256_update(&st, ux, HASH_BYTES); + crypto_hash_sha256_update(&st, &t[2], 1U); + crypto_hash_sha256_update(&st, (const unsigned char *) ctx, ctx_len); + crypto_hash_sha256_update(&st, &ctx_len_u8, 1U); + crypto_hash_sha256_final(&st, ux); + memcpy(&h[i], ux, h_len - i >= (sizeof ux) ? (sizeof ux) : h_len - i); + } + return 0; +} + +#undef HASH_BYTES +#undef HASH_BLOCKBYTES + +#define HASH_BYTES crypto_hash_sha512_BYTES +#define HASH_BLOCKBYTES 128U + +static int +core_h2c_string_to_hash_sha512(unsigned char *h, const size_t h_len, const char *ctx, + const unsigned char *msg, size_t msg_len) +{ + crypto_hash_sha512_state st; + const unsigned char empty_block[HASH_BLOCKBYTES] = { 0 }; + unsigned char u0[HASH_BYTES]; + unsigned char ux[HASH_BYTES] = { 0 }; + unsigned char t[3] = { 0U, (unsigned char) h_len, 0U}; + unsigned char ctx_len_u8; + size_t ctx_len = ctx != NULL ? strlen(ctx) : 0U; + size_t i, j; + + assert(h_len <= 0xff); + if (ctx_len > (size_t) 0xff) { + crypto_hash_sha512_init(&st); + crypto_hash_sha512_update(&st, + (const unsigned char *) "H2C-OVERSIZE-DST-", + sizeof "H2C-OVERSIZE-DST-" - 1U); + crypto_hash_sha512_update(&st, (const unsigned char *) ctx, ctx_len); + crypto_hash_sha512_final(&st, u0); + ctx = (const char *) u0; + ctx_len = HASH_BYTES; + COMPILER_ASSERT(HASH_BYTES <= (size_t) 0xff); + } + ctx_len_u8 = (unsigned char) ctx_len; + crypto_hash_sha512_init(&st); + crypto_hash_sha512_update(&st, empty_block, sizeof empty_block); + crypto_hash_sha512_update(&st, msg, msg_len); + crypto_hash_sha512_update(&st, t, 3U); + crypto_hash_sha512_update(&st, (const unsigned char *) ctx, ctx_len); + crypto_hash_sha512_update(&st, &ctx_len_u8, 1U); + crypto_hash_sha512_final(&st, u0); + + for (i = 0U; i < h_len; i += HASH_BYTES) { + for (j = 0U; j < HASH_BYTES; j++) { + ux[j] ^= u0[j]; + } + t[2]++; + crypto_hash_sha512_init(&st); + crypto_hash_sha512_update(&st, ux, HASH_BYTES); + crypto_hash_sha512_update(&st, &t[2], 1U); + crypto_hash_sha512_update(&st, (const unsigned char *) ctx, ctx_len); + crypto_hash_sha512_update(&st, &ctx_len_u8, 1U); + crypto_hash_sha512_final(&st, ux); + memcpy(&h[i], ux, h_len - i >= (sizeof ux) ? (sizeof ux) : h_len - i); + } + return 0; +} + +int +core_h2c_string_to_hash(unsigned char *h, const size_t h_len, const char *ctx, + const unsigned char *msg, size_t msg_len, int hash_alg) +{ + switch (hash_alg) { + case CORE_H2C_SHA256: + return core_h2c_string_to_hash_sha256(h, h_len, ctx, msg, msg_len); + case CORE_H2C_SHA512: + return core_h2c_string_to_hash_sha512(h, h_len, ctx, msg, msg_len); + default: + errno = EINVAL; + return -1; + } +} diff --git a/libs/libsodium/src/crypto_core/ed25519/core_h2c.h b/libs/libsodium/src/crypto_core/ed25519/core_h2c.h new file mode 100644 index 0000000000..e595b80c4c --- /dev/null +++ b/libs/libsodium/src/crypto_core/ed25519/core_h2c.h @@ -0,0 +1,12 @@ +#ifndef core_h2c_H +#define core_h2c_H + +#include "private/quirks.h" + +#define CORE_H2C_SHA256 1 +#define CORE_H2C_SHA512 2 + +int core_h2c_string_to_hash(unsigned char *h, const size_t h_len, const char *ctx, + const unsigned char *msg, size_t msg_len, + int hash_alg); +#endif diff --git a/libs/libsodium/src/crypto_core/ed25519/core_ristretto255.c b/libs/libsodium/src/crypto_core/ed25519/core_ristretto255.c new file mode 100644 index 0000000000..6d3a85cd08 --- /dev/null +++ b/libs/libsodium/src/crypto_core/ed25519/core_ristretto255.c @@ -0,0 +1,215 @@ + +#include +#include +#include + +#include "core_h2c.h" +#include "crypto_core_ed25519.h" +#include "crypto_core_ristretto255.h" +#include "crypto_hash_sha256.h" +#include "private/common.h" +#include "private/ed25519_ref10.h" +#include "randombytes.h" +#include "utils.h" + +int +crypto_core_ristretto255_is_valid_point(const unsigned char *p) +{ + ge25519_p3 p_p3; + + if (ristretto255_frombytes(&p_p3, p) != 0) { + return 0; + } + return 1; +} + +int +crypto_core_ristretto255_add(unsigned char *r, + const unsigned char *p, const unsigned char *q) +{ + ge25519_p3 p_p3, q_p3, r_p3; + + if (ristretto255_frombytes(&p_p3, p) != 0 || + ristretto255_frombytes(&q_p3, q) != 0) { + return -1; + } + ge25519_p3_add(&r_p3, &p_p3, &q_p3); + ristretto255_p3_tobytes(r, &r_p3); + + return 0; +} + +int +crypto_core_ristretto255_sub(unsigned char *r, + const unsigned char *p, const unsigned char *q) +{ + ge25519_p3 p_p3, q_p3, r_p3; + + if (ristretto255_frombytes(&p_p3, p) != 0 || + ristretto255_frombytes(&q_p3, q) != 0) { + return -1; + } + ge25519_p3_sub(&r_p3, &p_p3, &q_p3); + ristretto255_p3_tobytes(r, &r_p3); + + return 0; +} + +int +crypto_core_ristretto255_from_hash(unsigned char *p, const unsigned char *r) +{ + ristretto255_from_hash(p, r); + + return 0; +} + +static int +_string_to_element(unsigned char *p, + const char *ctx, const unsigned char *msg, size_t msg_len, + int hash_alg) +{ + unsigned char h[crypto_core_ristretto255_HASHBYTES]; + + if (core_h2c_string_to_hash(h, sizeof h, ctx, msg, msg_len, + hash_alg) != 0) { + return -1; + } + ristretto255_from_hash(p, h); + + return 0; +} + +int +crypto_core_ristretto255_from_string(unsigned char p[crypto_core_ristretto255_BYTES], + const char *ctx, const unsigned char *msg, + size_t msg_len, int hash_alg) +{ + return _string_to_element(p, ctx, msg, msg_len, hash_alg); +} + +int +crypto_core_ristretto255_from_string_ro(unsigned char p[crypto_core_ristretto255_BYTES], + const char *ctx, const unsigned char *msg, + size_t msg_len, int hash_alg) +{ + return crypto_core_ristretto255_from_string(p, ctx, msg, msg_len, hash_alg); +} + +void +crypto_core_ristretto255_random(unsigned char *p) +{ + unsigned char h[crypto_core_ristretto255_HASHBYTES]; + + randombytes_buf(h, sizeof h); + (void) crypto_core_ristretto255_from_hash(p, h); +} + +void +crypto_core_ristretto255_scalar_random(unsigned char *r) +{ + crypto_core_ed25519_scalar_random(r); +} + +int +crypto_core_ristretto255_scalar_invert(unsigned char *recip, + const unsigned char *s) +{ + return crypto_core_ed25519_scalar_invert(recip, s); +} + +void +crypto_core_ristretto255_scalar_negate(unsigned char *neg, + const unsigned char *s) +{ + crypto_core_ed25519_scalar_negate(neg, s); +} + +void +crypto_core_ristretto255_scalar_complement(unsigned char *comp, + const unsigned char *s) +{ + crypto_core_ed25519_scalar_complement(comp, s); +} + +void +crypto_core_ristretto255_scalar_add(unsigned char *z, const unsigned char *x, + const unsigned char *y) +{ + crypto_core_ed25519_scalar_add(z, x, y); +} + +void +crypto_core_ristretto255_scalar_sub(unsigned char *z, const unsigned char *x, + const unsigned char *y) +{ + crypto_core_ed25519_scalar_sub(z, x, y); +} + +void +crypto_core_ristretto255_scalar_mul(unsigned char *z, const unsigned char *x, + const unsigned char *y) +{ + sc25519_mul(z, x, y); +} + +void +crypto_core_ristretto255_scalar_reduce(unsigned char *r, + const unsigned char *s) +{ + crypto_core_ed25519_scalar_reduce(r, s); +} + +int +crypto_core_ristretto255_scalar_is_canonical(const unsigned char *s) +{ + return sc25519_is_canonical(s); +} + +#define HASH_SC_L 48U + +int +crypto_core_ristretto255_scalar_from_string(unsigned char *s, + const char *ctx, const unsigned char *msg, + size_t msg_len, int hash_alg) +{ + unsigned char h[crypto_core_ristretto255_NONREDUCEDSCALARBYTES]; + unsigned char h_be[HASH_SC_L]; + size_t i; + + if (core_h2c_string_to_hash(h_be, sizeof h_be, ctx, msg, msg_len, + hash_alg) != 0) { + return -1; + } + COMPILER_ASSERT(sizeof h >= sizeof h_be); + for (i = 0U; i < HASH_SC_L; i++) { + h[i] = h_be[HASH_SC_L - 1U - i]; + } + memset(&h[i], 0, (sizeof h) - i); + crypto_core_ristretto255_scalar_reduce(s, h); + + return 0; +} + +size_t +crypto_core_ristretto255_bytes(void) +{ + return crypto_core_ristretto255_BYTES; +} + +size_t +crypto_core_ristretto255_nonreducedscalarbytes(void) +{ + return crypto_core_ristretto255_NONREDUCEDSCALARBYTES; +} + +size_t +crypto_core_ristretto255_hashbytes(void) +{ + return crypto_core_ristretto255_HASHBYTES; +} + +size_t +crypto_core_ristretto255_scalarbytes(void) +{ + return crypto_core_ristretto255_SCALARBYTES; +} diff --git a/libs/libsodium/src/crypto_core/ed25519/ref10/ed25519_ref10.c b/libs/libsodium/src/crypto_core/ed25519/ref10/ed25519_ref10.c index fdff8eeb90..27ab377609 100644 --- a/libs/libsodium/src/crypto_core/ed25519/ref10/ed25519_ref10.c +++ b/libs/libsodium/src/crypto_core/ed25519/ref10/ed25519_ref10.c @@ -4,6 +4,7 @@ #include #include "crypto_verify_32.h" +#include "../core_h2c.h" #include "private/common.h" #include "private/ed25519_ref10.h" #include "utils.h" @@ -50,13 +51,24 @@ load_4(const unsigned char *in) # include "fe_25_5/fe.h" #endif +static inline void +fe25519_sqmul(fe25519 s, const int n, const fe25519 a) +{ + int i; + + for (i = 0; i < n; i++) { + fe25519_sq(s, s); + } + fe25519_mul(s, s, a); +} + +/* + * Inversion - returns 0 if z=0 + */ void fe25519_invert(fe25519 out, const fe25519 z) { - fe25519 t0; - fe25519 t1; - fe25519 t2; - fe25519 t3; + fe25519 t0, t1, t2, t3; int i; fe25519_sq(t0, z); @@ -81,8 +93,7 @@ fe25519_invert(fe25519 out, const fe25519 z) fe25519_sq(t3, t3); } fe25519_mul(t2, t3, t2); - fe25519_sq(t2, t2); - for (i = 1; i < 10; ++i) { + for (i = 1; i < 11; ++i) { fe25519_sq(t2, t2); } fe25519_mul(t1, t2, t1); @@ -96,24 +107,24 @@ fe25519_invert(fe25519 out, const fe25519 z) fe25519_sq(t3, t3); } fe25519_mul(t2, t3, t2); - fe25519_sq(t2, t2); - for (i = 1; i < 50; ++i) { + for (i = 1; i < 51; ++i) { fe25519_sq(t2, t2); } fe25519_mul(t1, t2, t1); - fe25519_sq(t1, t1); - for (i = 1; i < 5; ++i) { + for (i = 1; i < 6; ++i) { fe25519_sq(t1, t1); } fe25519_mul(out, t1, t0); } +/* + * returns z^((p-5)/8) = z^(2^252-3) + * used to compute square roots since we have p=5 (mod 8); see Cohen and Frey. + */ static void fe25519_pow22523(fe25519 out, const fe25519 z) { - fe25519 t0; - fe25519 t1; - fe25519 t2; + fe25519 t0, t1, t2; int i; fe25519_sq(t0, z); @@ -138,8 +149,7 @@ fe25519_pow22523(fe25519 out, const fe25519 z) fe25519_sq(t2, t2); } fe25519_mul(t1, t2, t1); - fe25519_sq(t1, t1); - for (i = 1; i < 10; ++i) { + for (i = 1; i < 11; ++i) { fe25519_sq(t1, t1); } fe25519_mul(t0, t1, t0); @@ -153,8 +163,7 @@ fe25519_pow22523(fe25519 out, const fe25519 z) fe25519_sq(t2, t2); } fe25519_mul(t1, t2, t1); - fe25519_sq(t1, t1); - for (i = 1; i < 50; ++i) { + for (i = 1; i < 51; ++i) { fe25519_sq(t1, t1); } fe25519_mul(t0, t1, t0); @@ -163,12 +172,96 @@ fe25519_pow22523(fe25519 out, const fe25519 z) fe25519_mul(out, t0, z); } +static inline void +fe25519_cneg(fe25519 h, unsigned int b) +{ + fe25519 negf; + + fe25519_neg(negf, h); + fe25519_cmov(h, negf, b); +} + +static inline void +fe25519_abs(fe25519 h) +{ + fe25519_cneg(h, fe25519_isnegative(h)); +} + +static void +fe25519_unchecked_sqrt(fe25519 x, const fe25519 x2) +{ + fe25519 p_root; + fe25519 m_root; + fe25519 m_root2; + fe25519 e; + + fe25519_pow22523(e, x2); + fe25519_mul(p_root, e, x2); + fe25519_mul(m_root, p_root, fe25519_sqrtm1); + fe25519_sq(m_root2, m_root); + fe25519_sub(e, x2, m_root2); + fe25519_copy(x, p_root); + fe25519_cmov(x, m_root, fe25519_iszero(e)); +} + +static int +fe25519_sqrt(fe25519 x, const fe25519 x2) +{ + fe25519 check; + fe25519 x2_copy; + + fe25519_copy(x2_copy, x2); + fe25519_unchecked_sqrt(x, x2); + fe25519_sq(check, x); + fe25519_sub(check, check, x2_copy); + + return fe25519_iszero(check) - 1; +} + +static int +fe25519_notsquare(const fe25519 x) +{ + fe25519 _10, _11, _1100, _1111, _11110000, _11111111; + fe25519 t, u, v; + unsigned char s[32]; + + /* Jacobi symbol - x^((p-1)/2) */ + fe25519_mul(_10, x, x); + fe25519_mul(_11, x, _10); + fe25519_sq(_1100, _11); + fe25519_sq(_1100, _1100); + fe25519_mul(_1111, _11, _1100); + fe25519_sq(_11110000, _1111); + fe25519_sq(_11110000, _11110000); + fe25519_sq(_11110000, _11110000); + fe25519_sq(_11110000, _11110000); + fe25519_mul(_11111111, _1111, _11110000); + fe25519_copy(t, _11111111); + fe25519_sqmul(t, 2, _11); + fe25519_copy(u, t); + fe25519_sqmul(t, 10, u); + fe25519_sqmul(t, 10, u); + fe25519_copy(v, t); + fe25519_sqmul(t, 30, v); + fe25519_copy(v, t); + fe25519_sqmul(t, 60, v); + fe25519_copy(v, t); + fe25519_sqmul(t, 120, v); + fe25519_sqmul(t, 10, u); + fe25519_sqmul(t, 3, _11); + fe25519_sq(t, t); + + fe25519_tobytes(s, t); + + return s[1] & 1; +} + /* r = p + q */ -void -ge25519_add(ge25519_p1p1 *r, const ge25519_p3 *p, const ge25519_cached *q) +static void +ge25519_add_cached(ge25519_p1p1 *r, const ge25519_p3 *p, const ge25519_cached *q) { fe25519 t0; @@ -233,7 +326,6 @@ ge25519_frombytes(ge25519_p3 *h, const unsigned char *s) { fe25519 u; fe25519 v; - fe25519 v3; fe25519 vxx; fe25519 m_root_check, p_root_check; fe25519 negx; @@ -243,19 +335,13 @@ ge25519_frombytes(ge25519_p3 *h, const unsigned char *s) fe25519_frombytes(h->Y, s); fe25519_1(h->Z); fe25519_sq(u, h->Y); - fe25519_mul(v, u, d); + fe25519_mul(v, u, ed25519_d); fe25519_sub(u, u, h->Z); /* u = y^2-1 */ fe25519_add(v, v, h->Z); /* v = dy^2+1 */ - fe25519_sq(v3, v); - fe25519_mul(v3, v3, v); /* v3 = v^3 */ - fe25519_sq(h->X, v3); - fe25519_mul(h->X, h->X, v); - fe25519_mul(h->X, h->X, u); /* x = uv^7 */ - - fe25519_pow22523(h->X, h->X); /* x = (uv^7)^((q-5)/8) */ - fe25519_mul(h->X, h->X, v3); - fe25519_mul(h->X, h->X, u); /* x = uv^3(uv^7)^((q-5)/8) */ + fe25519_mul(h->X, u, v); + fe25519_pow22523(h->X, h->X); + fe25519_mul(h->X, u, h->X); /* u((uv)^((q-5)/8)) */ fe25519_sq(vxx, h->X); fe25519_mul(vxx, vxx, v); @@ -263,7 +349,7 @@ ge25519_frombytes(ge25519_p3 *h, const unsigned char *s) fe25519_add(p_root_check, vxx, u); /* vx^2+u */ has_m_root = fe25519_iszero(m_root_check); has_p_root = fe25519_iszero(p_root_check); - fe25519_mul(x_sqrtm1, h->X, sqrtm1); /* x*sqrt(-1) */ + fe25519_mul(x_sqrtm1, h->X, fe25519_sqrtm1); /* x*sqrt(-1) */ fe25519_cmov(h->X, x_sqrtm1, 1 - has_m_root); fe25519_neg(negx, h->X); @@ -285,7 +371,7 @@ ge25519_frombytes_negate_vartime(ge25519_p3 *h, const unsigned char *s) fe25519_frombytes(h->Y, s); fe25519_1(h->Z); fe25519_sq(u, h->Y); - fe25519_mul(v, u, d); + fe25519_mul(v, u, ed25519_d); fe25519_sub(u, u, h->Z); /* u = y^2-1 */ fe25519_add(v, v, h->Z); /* v = dy^2+1 */ @@ -307,7 +393,7 @@ ge25519_frombytes_negate_vartime(ge25519_p3 *h, const unsigned char *s) if (fe25519_iszero(p_root_check) == 0) { return -1; } - fe25519_mul(h->X, h->X, sqrtm1); + fe25519_mul(h->X, h->X, fe25519_sqrtm1); } if (fe25519_isnegative(h->X) == (s[31] >> 7)) { @@ -323,7 +409,7 @@ ge25519_frombytes_negate_vartime(ge25519_p3 *h, const unsigned char *s) */ static void -ge25519_madd(ge25519_p1p1 *r, const ge25519_p3 *p, const ge25519_precomp *q) +ge25519_add_precomp(ge25519_p1p1 *r, const ge25519_p3 *p, const ge25519_precomp *q) { fe25519 t0; @@ -344,7 +430,7 @@ ge25519_madd(ge25519_p1p1 *r, const ge25519_p3 *p, const ge25519_precomp *q) */ static void -ge25519_msub(ge25519_p1p1 *r, const ge25519_p3 *p, const ge25519_precomp *q) +ge25519_sub_precomp(ge25519_p1p1 *r, const ge25519_p3 *p, const ge25519_precomp *q) { fe25519 t0; @@ -385,6 +471,18 @@ ge25519_p1p1_to_p3(ge25519_p3 *r, const ge25519_p1p1 *p) fe25519_mul(r->T, p->X, p->Y); } +/* + r = p + */ +void +ge25519_p2_to_p3(ge25519_p3 *r, const ge25519_p2 *p) +{ + fe25519_copy(r->X, p->X); + fe25519_copy(r->Y, p->Y); + fe25519_copy(r->Z, p->Z); + fe25519_mul(r->T, p->X, p->Y); +} + static void ge25519_p2_0(ge25519_p2 *h) { @@ -435,13 +533,13 @@ ge25519_cached_0(ge25519_cached *h) r = p */ -void +static void ge25519_p3_to_cached(ge25519_cached *r, const ge25519_p3 *p) { fe25519_add(r->YplusX, p->Y, p->X); fe25519_sub(r->YminusX, p->Y, p->X); fe25519_copy(r->Z, p->Z); - fe25519_mul(r->T2d, p->T, d2); + fe25519_mul(r->T2d, p->T, ed25519_d2); } static void @@ -458,7 +556,7 @@ ge25519_p3_to_precomp(ge25519_precomp *pi, const ge25519_p3 *p) fe25519_add(pi->yplusx, y, x); fe25519_sub(pi->yminusx, y, x); fe25519_mul(xy, x, y); - fe25519_mul(pi->xy2d, xy, d2); + fe25519_mul(pi->xy2d, xy, ed25519_d2); } /* @@ -513,7 +611,7 @@ equal(signed char b, signed char c) unsigned char ub = b; unsigned char uc = c; unsigned char x = ub ^ uc; /* 0: yes; 1..255: no */ - uint32_t y = x; /* 0: yes; 1..255: no */ + uint32_t y = (uint32_t) x; /* 0: yes; 1..255: no */ y -= 1; /* 4294967295: yes; 0..254: no */ y >>= 31; /* 1: yes; 0: no */ @@ -550,7 +648,7 @@ ge25519_cmov_cached(ge25519_cached *t, const ge25519_cached *u, unsigned char b) } static void -ge25519_select(ge25519_precomp *t, const ge25519_precomp precomp[8], const signed char b) +ge25519_cmov8(ge25519_precomp *t, const ge25519_precomp precomp[8], const signed char b) { ge25519_precomp minust; const unsigned char bnegative = negative(b); @@ -572,7 +670,7 @@ ge25519_select(ge25519_precomp *t, const ge25519_precomp precomp[8], const signe } static void -ge25519_select_base(ge25519_precomp *t, const int pos, const signed char b) +ge25519_cmov8_base(ge25519_precomp *t, const int pos, const signed char b) { static const ge25519_precomp base[32][8] = { /* base[i][j] = (j+1)*256^i*B */ #ifdef HAVE_TI_MODE @@ -581,11 +679,11 @@ ge25519_select_base(ge25519_precomp *t, const int pos, const signed char b) # include "fe_25_5/base.h" #endif }; - ge25519_select(t, base[pos], b); + ge25519_cmov8(t, base[pos], b); } static void -ge25519_select_cached(ge25519_cached *t, const ge25519_cached cached[8], const signed char b) +ge25519_cmov8_cached(ge25519_cached *t, const ge25519_cached cached[8], const signed char b) { ge25519_cached minust; const unsigned char bnegative = negative(b); @@ -611,8 +709,8 @@ ge25519_select_cached(ge25519_cached *t, const ge25519_cached cached[8], const s r = p - q */ -void -ge25519_sub(ge25519_p1p1 *r, const ge25519_p3 *p, const ge25519_cached *q) +static void +ge25519_sub_cached(ge25519_p1p1 *r, const ge25519_p3 *p, const ge25519_cached *q) { fe25519 t0; @@ -644,68 +742,76 @@ ge25519_tobytes(unsigned char *s, const ge25519_p2 *h) } /* - r = a * A + b * B - where a = a[0]+256*a[1]+...+256^31 a[31]. - and b = b[0]+256*b[1]+...+256^31 b[31]. - B is the Ed25519 base point (x,4/5) with x positive. - - Only used for signatures verification. + * Precomputation of a base point, to use in multiscalar multiplication algorithm A,3A,5A,7A,9A,11A,13A,15A */ - -void -ge25519_double_scalarmult_vartime(ge25519_p2 *r, const unsigned char *a, - const ge25519_p3 *A, const unsigned char *b) -{ - static const ge25519_precomp Bi[8] = { -#ifdef HAVE_TI_MODE -# include "fe_51/base2.h" -#else -# include "fe_25_5/base2.h" -#endif - }; - signed char aslide[256]; - signed char bslide[256]; - ge25519_cached Ai[8]; /* A,3A,5A,7A,9A,11A,13A,15A */ +static void point_precomputation(ge25519_cached cached[8], const ge25519_p3 *base) { ge25519_p1p1 t; ge25519_p3 u; - ge25519_p3 A2; - int i; + ge25519_p3 A; - slide_vartime(aslide, a); - slide_vartime(bslide, b); - - ge25519_p3_to_cached(&Ai[0], A); + // Precomputation of values of A + ge25519_p3_to_cached(&cached[0], base); - ge25519_p3_dbl(&t, A); - ge25519_p1p1_to_p3(&A2, &t); + ge25519_p3_dbl(&t, base); + ge25519_p1p1_to_p3(&A, &t); - ge25519_add(&t, &A2, &Ai[0]); + ge25519_add_cached(&t, &A, &cached[0]); ge25519_p1p1_to_p3(&u, &t); - ge25519_p3_to_cached(&Ai[1], &u); + ge25519_p3_to_cached(&cached[1], &u); - ge25519_add(&t, &A2, &Ai[1]); + ge25519_add_cached(&t, &A, &cached[1]); ge25519_p1p1_to_p3(&u, &t); - ge25519_p3_to_cached(&Ai[2], &u); + ge25519_p3_to_cached(&cached[2], &u); - ge25519_add(&t, &A2, &Ai[2]); + ge25519_add_cached(&t, &A, &cached[2]); ge25519_p1p1_to_p3(&u, &t); - ge25519_p3_to_cached(&Ai[3], &u); + ge25519_p3_to_cached(&cached[3], &u); - ge25519_add(&t, &A2, &Ai[3]); + ge25519_add_cached(&t, &A, &cached[3]); ge25519_p1p1_to_p3(&u, &t); - ge25519_p3_to_cached(&Ai[4], &u); + ge25519_p3_to_cached(&cached[4], &u); - ge25519_add(&t, &A2, &Ai[4]); + ge25519_add_cached(&t, &A, &cached[4]); ge25519_p1p1_to_p3(&u, &t); - ge25519_p3_to_cached(&Ai[5], &u); + ge25519_p3_to_cached(&cached[5], &u); - ge25519_add(&t, &A2, &Ai[5]); + ge25519_add_cached(&t, &A, &cached[5]); ge25519_p1p1_to_p3(&u, &t); - ge25519_p3_to_cached(&Ai[6], &u); + ge25519_p3_to_cached(&cached[6], &u); - ge25519_add(&t, &A2, &Ai[6]); + ge25519_add_cached(&t, &A, &cached[6]); ge25519_p1p1_to_p3(&u, &t); - ge25519_p3_to_cached(&Ai[7], &u); + ge25519_p3_to_cached(&cached[7], &u); +} + +/* + Variable time double scalar multiplication with variable bases + r = a * A + b * B + where a = a[0]+256*a[1]+...+256^31 a[31]. + and b = b[0]+256*b[1]+...+256^31 b[31]. + + If a null pointer is passed as an argument for B, the function uses + the precomputed values of the base point for the scalar multiplication. + + Only used for ed25519 and VRF verification. + */ + +void +ge25519_double_scalarmult_vartime(ge25519_p2 *r, const unsigned char *a, + const ge25519_p3 *A, const unsigned char *b, + const ge25519_p3 *B) +{ + signed char aslide[256]; + signed char bslide[256]; + ge25519_cached Ai[8]; + ge25519_p1p1 t; + ge25519_p3 u; + int i; + + slide_vartime(aslide, a); + slide_vartime(bslide, b); + + point_precomputation(Ai, A); ge25519_p2_0(r); @@ -720,18 +826,37 @@ ge25519_double_scalarmult_vartime(ge25519_p2 *r, const unsigned char *a, if (aslide[i] > 0) { ge25519_p1p1_to_p3(&u, &t); - ge25519_add(&t, &u, &Ai[aslide[i] / 2]); + ge25519_add_cached(&t, &u, &Ai[aslide[i] / 2]); } else if (aslide[i] < 0) { ge25519_p1p1_to_p3(&u, &t); - ge25519_sub(&t, &u, &Ai[(-aslide[i]) / 2]); + ge25519_sub_cached(&t, &u, &Ai[(-aslide[i]) / 2]); } - if (bslide[i] > 0) { - ge25519_p1p1_to_p3(&u, &t); - ge25519_madd(&t, &u, &Bi[bslide[i] / 2]); - } else if (bslide[i] < 0) { - ge25519_p1p1_to_p3(&u, &t); - ge25519_msub(&t, &u, &Bi[(-bslide[i]) / 2]); + if (B == NULL) { + static const ge25519_precomp Bi[8] = { +#ifdef HAVE_TI_MODE +# include "fe_51/base2.h" +#else +# include "fe_25_5/base2.h" +#endif + }; + if (bslide[i] > 0) { + ge25519_p1p1_to_p3(&u, &t); + ge25519_add_precomp(&t, &u, &Bi[bslide[i] / 2]); + } else if (bslide[i] < 0) { + ge25519_p1p1_to_p3(&u, &t); + ge25519_sub_precomp(&t, &u, &Bi[(-bslide[i]) / 2]); + } + } else { + ge25519_cached Bi[8]; + point_precomputation(Bi, B); + if (bslide[i] > 0) { + ge25519_p1p1_to_p3(&u, &t); + ge25519_add_cached(&t, &u, &Bi[bslide[i] / 2]); + } else if (bslide[i] < 0) { + ge25519_p1p1_to_p3(&u, &t); + ge25519_sub_cached(&t, &u, &Bi[(-bslide[i]) / 2]); + } } ge25519_p1p1_to_p2(r, &t); @@ -767,7 +892,7 @@ ge25519_scalarmult(ge25519_p3 *h, const unsigned char *a, const ge25519_p3 *p) ge25519_p1p1_to_p3(&p2, &t2); ge25519_p3_to_cached(&pi[2 - 1], &p2); /* 2p = 2*p */ - ge25519_add(&t3, p, &pi[2 - 1]); + ge25519_add_cached(&t3, p, &pi[2 - 1]); ge25519_p1p1_to_p3(&p3, &t3); ge25519_p3_to_cached(&pi[3 - 1], &p3); /* 3p = 2p+p */ @@ -775,7 +900,7 @@ ge25519_scalarmult(ge25519_p3 *h, const unsigned char *a, const ge25519_p3 *p) ge25519_p1p1_to_p3(&p4, &t4); ge25519_p3_to_cached(&pi[4 - 1], &p4); /* 4p = 2*2p */ - ge25519_add(&t5, p, &pi[4 - 1]); + ge25519_add_cached(&t5, p, &pi[4 - 1]); ge25519_p1p1_to_p3(&p5, &t5); ge25519_p3_to_cached(&pi[5 - 1], &p5); /* 5p = 4p+p */ @@ -783,7 +908,7 @@ ge25519_scalarmult(ge25519_p3 *h, const unsigned char *a, const ge25519_p3 *p) ge25519_p1p1_to_p3(&p6, &t6); ge25519_p3_to_cached(&pi[6 - 1], &p6); /* 6p = 2*3p */ - ge25519_add(&t7, p, &pi[6 - 1]); + ge25519_add_cached(&t7, p, &pi[6 - 1]); ge25519_p1p1_to_p3(&p7, &t7); ge25519_p3_to_cached(&pi[7 - 1], &p7); /* 7p = 6p+p */ @@ -811,8 +936,8 @@ ge25519_scalarmult(ge25519_p3 *h, const unsigned char *a, const ge25519_p3 *p) ge25519_p3_0(h); for (i = 63; i != 0; i--) { - ge25519_select_cached(&t, pi, e[i]); - ge25519_add(&r, h, &t); + ge25519_cmov8_cached(&t, pi, e[i]); + ge25519_add_cached(&r, h, &t); ge25519_p1p1_to_p2(&s, &r); ge25519_p2_dbl(&r, &s); @@ -825,8 +950,8 @@ ge25519_scalarmult(ge25519_p3 *h, const unsigned char *a, const ge25519_p3 *p) ge25519_p1p1_to_p3(h, &r); /* *16 */ } - ge25519_select_cached(&t, pi, e[i]); - ge25519_add(&r, h, &t); + ge25519_cmov8_cached(&t, pi, e[i]); + ge25519_add_cached(&r, h, &t); ge25519_p1p1_to_p3(h, &r); } @@ -871,8 +996,8 @@ ge25519_scalarmult_base(ge25519_p3 *h, const unsigned char *a) ge25519_p3_0(h); for (i = 1; i < 64; i += 2) { - ge25519_select_base(&t, i / 2, e[i]); - ge25519_madd(&r, h, &t); + ge25519_cmov8_base(&t, i / 2, e[i]); + ge25519_add_precomp(&r, h, &t); ge25519_p1p1_to_p3(h, &r); } @@ -886,65 +1011,118 @@ ge25519_scalarmult_base(ge25519_p3 *h, const unsigned char *a) ge25519_p1p1_to_p3(h, &r); for (i = 0; i < 64; i += 2) { - ge25519_select_base(&t, i / 2, e[i]); - ge25519_madd(&r, h, &t); + ge25519_cmov8_base(&t, i / 2, e[i]); + ge25519_add_precomp(&r, h, &t); ge25519_p1p1_to_p3(h, &r); } } -/* multiply by the order of the main subgroup l = 2^252+27742317777372353535851937790883648493 */ +/* r = 2p */ static void -ge25519_mul_l(ge25519_p3 *r, const ge25519_p3 *A) +ge25519_p3p3_dbl(ge25519_p3 *r, const ge25519_p3 *p) { - static const signed char aslide[253] = { - 13, 0, 0, 0, 0, -1, 0, 0, 0, 0, -11, 0, 0, 0, 0, 0, 0, -5, 0, 0, 0, 0, 0, 0, -3, 0, 0, 0, 0, -13, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, -13, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, 0, 11, 0, 0, 0, 0, -13, 0, 0, 0, 0, 0, 0, -3, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 3, 0, 0, 0, 0, -11, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, -1, 0, 0, 0, 0, 7, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 - }; - ge25519_cached Ai[8]; - ge25519_p1p1 t; - ge25519_p3 u; - ge25519_p3 A2; - int i; + ge25519_p1p1 p1p1; - ge25519_p3_to_cached(&Ai[0], A); - ge25519_p3_dbl(&t, A); - ge25519_p1p1_to_p3(&A2, &t); - ge25519_add(&t, &A2, &Ai[0]); - ge25519_p1p1_to_p3(&u, &t); - ge25519_p3_to_cached(&Ai[1], &u); - ge25519_add(&t, &A2, &Ai[1]); - ge25519_p1p1_to_p3(&u, &t); - ge25519_p3_to_cached(&Ai[2], &u); - ge25519_add(&t, &A2, &Ai[2]); - ge25519_p1p1_to_p3(&u, &t); - ge25519_p3_to_cached(&Ai[3], &u); - ge25519_add(&t, &A2, &Ai[3]); - ge25519_p1p1_to_p3(&u, &t); - ge25519_p3_to_cached(&Ai[4], &u); - ge25519_add(&t, &A2, &Ai[4]); - ge25519_p1p1_to_p3(&u, &t); - ge25519_p3_to_cached(&Ai[5], &u); - ge25519_add(&t, &A2, &Ai[5]); - ge25519_p1p1_to_p3(&u, &t); - ge25519_p3_to_cached(&Ai[6], &u); - ge25519_add(&t, &A2, &Ai[6]); - ge25519_p1p1_to_p3(&u, &t); - ge25519_p3_to_cached(&Ai[7], &u); + ge25519_p3_dbl(&p1p1, p); + ge25519_p1p1_to_p3(r, &p1p1); +} - ge25519_p3_0(r); +/* r = -p */ +static void +ge25519_p3_neg(ge25519_p3 *r, const ge25519_p3 *p) +{ + fe25519_neg(r->X, p->X); + fe25519_copy(r->Y, p->Y); + fe25519_copy(r->Z, p->Z); + fe25519_neg(r->T, p->T); +} - for (i = 252; i >= 0; --i) { - ge25519_p3_dbl(&t, r); +/* r = p+q */ +void +ge25519_p3_add(ge25519_p3 *r, const ge25519_p3 *p, const ge25519_p3 *q) +{ + ge25519_cached q_cached; + ge25519_p1p1 p1p1; - if (aslide[i] > 0) { - ge25519_p1p1_to_p3(&u, &t); - ge25519_add(&t, &u, &Ai[aslide[i] / 2]); - } else if (aslide[i] < 0) { - ge25519_p1p1_to_p3(&u, &t); - ge25519_sub(&t, &u, &Ai[(-aslide[i]) / 2]); - } + ge25519_p3_to_cached(&q_cached, q); + ge25519_add_cached(&p1p1, p, &q_cached); + ge25519_p1p1_to_p3(r, &p1p1); +} - ge25519_p1p1_to_p3(r, &t); +/* r = p-q */ +void +ge25519_p3_sub(ge25519_p3 *r, const ge25519_p3 *p, const ge25519_p3 *q) +{ + ge25519_p3 q_neg; + + ge25519_p3_neg(&q_neg, q); + ge25519_p3_add(r, p, &q_neg); +} + +/* r = r*(2^n)+q */ +static void +ge25519_p3_dbladd(ge25519_p3 *r, const int n, const ge25519_p3 *q) +{ + ge25519_p2 p2; + ge25519_p1p1 p1p1; + int i; + + ge25519_p3_to_p2(&p2, r); + for (i = 0; i < n; i++) { + ge25519_p2_dbl(&p1p1, &p2); + ge25519_p1p1_to_p2(&p2, &p1p1); } + ge25519_p1p1_to_p3(r, &p1p1); + ge25519_p3_add(r, r, q); +} + +/* multiply by the order of the main subgroup l = 2^252+27742317777372353535851937790883648493 */ +static void +ge25519_mul_l(ge25519_p3 *r, const ge25519_p3 *p) +{ + ge25519_p3 _10, _11, _100, _110, _1000, _1011, _10000, _100000, _100110, + _1000000, _1010000, _1010011, _1100011, _1100111, _1101011, _10010011, + _10010111, _10111101, _11010011, _11100111, _11101101, _11110101; + + ge25519_p3p3_dbl(&_10, p); + ge25519_p3_add(&_11, p, &_10); + ge25519_p3_add(&_100, p, &_11); + ge25519_p3_add(&_110, &_10, &_100); + ge25519_p3_add(&_1000, &_10, &_110); + ge25519_p3_add(&_1011, &_11, &_1000); + ge25519_p3p3_dbl(&_10000, &_1000); + ge25519_p3p3_dbl(&_100000, &_10000); + ge25519_p3_add(&_100110, &_110, &_100000); + ge25519_p3p3_dbl(&_1000000, &_100000); + ge25519_p3_add(&_1010000, &_10000, &_1000000); + ge25519_p3_add(&_1010011, &_11, &_1010000); + ge25519_p3_add(&_1100011, &_10000, &_1010011); + ge25519_p3_add(&_1100111, &_100, &_1100011); + ge25519_p3_add(&_1101011, &_100, &_1100111); + ge25519_p3_add(&_10010011, &_1000000, &_1010011); + ge25519_p3_add(&_10010111, &_100, &_10010011); + ge25519_p3_add(&_10111101, &_100110, &_10010111); + ge25519_p3_add(&_11010011, &_1000000, &_10010011); + ge25519_p3_add(&_11100111, &_1010000, &_10010111); + ge25519_p3_add(&_11101101, &_110, &_11100111); + ge25519_p3_add(&_11110101, &_1000, &_11101101); + + ge25519_p3_add(r, &_1011, &_11110101); + ge25519_p3_dbladd(r, 126, &_1010011); + ge25519_p3_dbladd(r, 9, &_10); + ge25519_p3_add(r, r, &_11110101); + ge25519_p3_dbladd(r, 7, &_1100111); + ge25519_p3_dbladd(r, 9, &_11110101); + ge25519_p3_dbladd(r, 11, &_10111101); + ge25519_p3_dbladd(r, 8, &_11100111); + ge25519_p3_dbladd(r, 9, &_1101011); + ge25519_p3_dbladd(r, 6, &_1011); + ge25519_p3_dbladd(r, 14, &_10010011); + ge25519_p3_dbladd(r, 10, &_1100011); + ge25519_p3_dbladd(r, 9, &_10010111); + ge25519_p3_dbladd(r, 10, &_11110101); + ge25519_p3_dbladd(r, 8, &_11010011); + ge25519_p3_dbladd(r, 8, &_11101101); } int @@ -964,7 +1142,7 @@ ge25519_is_on_curve(const ge25519_p3 *p) fe25519_mul(t0, t0, z2); fe25519_mul(t1, x2, y2); - fe25519_mul(t1, t1, d); + fe25519_mul(t1, t1, ed25519_d); fe25519_sq(z4, z2); fe25519_add(t1, t1, z4); fe25519_sub(t0, t0, t1); @@ -1000,59 +1178,29 @@ ge25519_is_canonical(const unsigned char *s) } int -ge25519_has_small_order(const unsigned char s[32]) -{ - CRYPTO_ALIGN(16) - static const unsigned char blacklist[][32] = { - /* 0 (order 4) */ - { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - /* 1 (order 1) */ - { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, - /* 2707385501144840649318225287225658788936804267575313519463743609750303402022 - (order 8) */ - { 0x26, 0xe8, 0x95, 0x8f, 0xc2, 0xb2, 0x27, 0xb0, 0x45, 0xc3, 0xf4, - 0x89, 0xf2, 0xef, 0x98, 0xf0, 0xd5, 0xdf, 0xac, 0x05, 0xd3, 0xc6, - 0x33, 0x39, 0xb1, 0x38, 0x02, 0x88, 0x6d, 0x53, 0xfc, 0x05 }, - /* 55188659117513257062467267217118295137698188065244968500265048394206261417927 - (order 8) */ - { 0xc7, 0x17, 0x6a, 0x70, 0x3d, 0x4d, 0xd8, 0x4f, 0xba, 0x3c, 0x0b, - 0x76, 0x0d, 0x10, 0x67, 0x0f, 0x2a, 0x20, 0x53, 0xfa, 0x2c, 0x39, - 0xcc, 0xc6, 0x4e, 0xc7, 0xfd, 0x77, 0x92, 0xac, 0x03, 0x7a }, - /* p-1 (order 2) */ - { 0xec, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f }, - /* p (=0, order 4) */ - { 0xed, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f }, - /* p+1 (=1, order 1) */ - { 0xee, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f } - }; - unsigned char c[7] = { 0 }; - unsigned int k; - size_t i, j; +ge25519_has_small_order(const ge25519_p3 *p) +{ + fe25519 recip; + fe25519 x; + fe25519 x_neg; + fe25519 y; + fe25519 y_sqrtm1; + fe25519 c; + int ret = 0; - COMPILER_ASSERT(7 == sizeof blacklist / sizeof blacklist[0]); - for (j = 0; j < 31; j++) { - for (i = 0; i < sizeof blacklist / sizeof blacklist[0]; i++) { - c[i] |= s[j] ^ blacklist[i][j]; - } - } - for (i = 0; i < sizeof blacklist / sizeof blacklist[0]; i++) { - c[i] |= (s[j] & 0x7f) ^ blacklist[i][j]; - } - k = 0; - for (i = 0; i < sizeof blacklist / sizeof blacklist[0]; i++) { - k |= (c[i] - 1); - } - return (int) ((k >> 8) & 1); + fe25519_invert(recip, p->Z); + fe25519_mul(x, p->X, recip); + ret |= fe25519_iszero(x); + fe25519_mul(y, p->Y, recip); + ret |= fe25519_iszero(y); + fe25519_neg(x_neg, p->X); + fe25519_mul(y_sqrtm1, y, fe25519_sqrtm1); + fe25519_sub(c, y_sqrtm1, x); + ret |= fe25519_iszero(c); + fe25519_sub(c, y_sqrtm1, x_neg); + ret |= fe25519_iszero(c); + + return ret; } /* @@ -1065,7 +1213,7 @@ ge25519_has_small_order(const unsigned char s[32]) where l = 2^252 + 27742317777372353535851937790883648493. */ -static void +void sc25519_mul(unsigned char s[32], const unsigned char a[32], const unsigned char b[32]) { int64_t a0 = 2097151 & load_3(a); @@ -2055,46 +2203,75 @@ sc25519_sqmul(unsigned char s[32], const int n, const unsigned char a[32]) void sc25519_invert(unsigned char recip[32], const unsigned char s[32]) { - unsigned char _10[32], _100[32], _11[32], _101[32], _111[32], - _1001[32], _1011[32], _1111[32]; + unsigned char _10[32], _100[32], _1000[32], _10000[32], _100000[32], + _1000000[32], _10010011[32], _10010111[32], _100110[32], _1010[32], + _1010000[32], _1010011[32], _1011[32], _10110[32], _10111101[32], + _11[32], _1100011[32], _1100111[32], _11010011[32], _1101011[32], + _11100111[32], _11101011[32], _11110101[32]; sc25519_sq(_10, s); - sc25519_sq(_100, _10); - sc25519_mul(_11, _10, s); - sc25519_mul(_101, _10, _11); - sc25519_mul(_111, _10, _101); - sc25519_mul(_1001, _10, _111); - sc25519_mul(_1011, _10, _1001); - sc25519_mul(_1111, _100, _1011); - sc25519_mul(recip, _1111, s); - - sc25519_sqmul(recip, 123 + 3, _101); - sc25519_sqmul(recip, 2 + 2, _11); - sc25519_sqmul(recip, 1 + 4, _1111); - sc25519_sqmul(recip, 1 + 4, _1111); - sc25519_sqmul(recip, 4, _1001); - sc25519_sqmul(recip, 2, _11); - sc25519_sqmul(recip, 1 + 4, _1111); - sc25519_sqmul(recip, 1 + 3, _101); - sc25519_sqmul(recip, 3 + 3, _101); - sc25519_sqmul(recip, 3, _111); - sc25519_sqmul(recip, 1 + 4, _1111); - sc25519_sqmul(recip, 2 + 3, _111); - sc25519_sqmul(recip, 2 + 2, _11); - sc25519_sqmul(recip, 1 + 4, _1011); - sc25519_sqmul(recip, 2 + 4, _1011); - sc25519_sqmul(recip, 6 + 4, _1001); - sc25519_sqmul(recip, 2 + 2, _11); - sc25519_sqmul(recip, 3 + 2, _11); - sc25519_sqmul(recip, 3 + 2, _11); - sc25519_sqmul(recip, 1 + 4, _1001); - sc25519_sqmul(recip, 1 + 3, _111); - sc25519_sqmul(recip, 2 + 4, _1111); - sc25519_sqmul(recip, 1 + 4, _1011); - sc25519_sqmul(recip, 3, _101); - sc25519_sqmul(recip, 2 + 4, _1111); - sc25519_sqmul(recip, 3, _101); - sc25519_sqmul(recip, 1 + 2, _11); + sc25519_mul(_11, s, _10); + sc25519_mul(_100, s, _11); + sc25519_sq(_1000, _100); + sc25519_mul(_1010, _10, _1000); + sc25519_mul(_1011, s, _1010); + sc25519_sq(_10000, _1000); + sc25519_sq(_10110, _1011); + sc25519_mul(_100000, _1010, _10110); + sc25519_mul(_100110, _10000, _10110); + sc25519_sq(_1000000, _100000); + sc25519_mul(_1010000, _10000, _1000000); + sc25519_mul(_1010011, _11, _1010000); + sc25519_mul(_1100011, _10000, _1010011); + sc25519_mul(_1100111, _100, _1100011); + sc25519_mul(_1101011, _100, _1100111); + sc25519_mul(_10010011, _1000000, _1010011); + sc25519_mul(_10010111, _100, _10010011); + sc25519_mul(_10111101, _100110, _10010111); + sc25519_mul(_11010011, _10110, _10111101); + sc25519_mul(_11100111, _1010000, _10010111); + sc25519_mul(_11101011, _100, _11100111); + sc25519_mul(_11110101, _1010, _11101011); + + sc25519_mul(recip, _1011, _11110101); + sc25519_sqmul(recip, 126, _1010011); + sc25519_sqmul(recip, 9, _10); + sc25519_mul(recip, recip, _11110101); + sc25519_sqmul(recip, 7, _1100111); + sc25519_sqmul(recip, 9, _11110101); + sc25519_sqmul(recip, 11, _10111101); + sc25519_sqmul(recip, 8, _11100111); + sc25519_sqmul(recip, 9, _1101011); + sc25519_sqmul(recip, 6, _1011); + sc25519_sqmul(recip, 14, _10010011); + sc25519_sqmul(recip, 10, _1100011); + sc25519_sqmul(recip, 9, _10010111); + sc25519_sqmul(recip, 10, _11110101); + sc25519_sqmul(recip, 8, _11010011); + sc25519_sqmul(recip, 8, _11101011); +} + +/* 2^252+27742317777372353535851937790883648493 */ +static const unsigned char L[] = { + 0xed, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58, 0xd6, 0x9c, 0xf7, + 0xa2, 0xde, 0xf9, 0xde, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10 +}; + +void +sc25519_negate(unsigned char neg[32], const unsigned char s[32]) +{ + unsigned char t_[64]; + unsigned char s_[64]; + + memset(t_, 0, sizeof t_); + memset(s_, 0, sizeof s_); + memcpy(t_ + 32, L, + 32); + memcpy(s_, s, 32); + sodium_sub(t_, s_, sizeof t_); + sc25519_reduce(t_); + memcpy(neg, t_, 32); } /* @@ -2453,133 +2630,460 @@ sc25519_is_canonical(const unsigned char s[32]) return (c != 0); } +/* montgomery to edwards */ static void -chi25519(fe25519 out, const fe25519 z) +ge25519_mont_to_ed(fe25519 xed, fe25519 yed, const fe25519 x, const fe25519 y) { - fe25519 t0, t1, t2, t3; - int i; + fe25519 one; + fe25519 x_plus_one; + fe25519 x_minus_one; + fe25519 x_plus_one_y_inv; + + fe25519_1(one); + fe25519_add(x_plus_one, x, one); + fe25519_sub(x_minus_one, x, one); + + /* xed = sqrt(-A-2)*x/y */ + fe25519_mul(x_plus_one_y_inv, x_plus_one, y); + fe25519_invert(x_plus_one_y_inv, x_plus_one_y_inv); /* 1/((x+1)*y) */ + fe25519_mul(xed, x, ed25519_sqrtam2); + fe25519_mul(xed, xed, x_plus_one_y_inv); /* sqrt(-A-2)*x/((x+1)*y) */ + fe25519_mul(xed, xed, x_plus_one); - fe25519_sq(t0, z); - fe25519_mul(t1, t0, z); - fe25519_sq(t0, t1); - fe25519_sq(t2, t0); - fe25519_sq(t2, t2); - fe25519_mul(t2, t2, t0); - fe25519_mul(t1, t2, z); - fe25519_sq(t2, t1); + /* yed = (x-1)/(x+1) */ + fe25519_mul(yed, x_plus_one_y_inv, y); /* 1/(x+1) */ + fe25519_mul(yed, yed, x_minus_one); + fe25519_cmov(yed, one, fe25519_iszero(x_plus_one_y_inv)); +} - for (i = 1; i < 5; i++) { - fe25519_sq(t2, t2); - } - fe25519_mul(t1, t2, t1); - fe25519_sq(t2, t1); - for (i = 1; i < 10; i++) { - fe25519_sq(t2, t2); - } - fe25519_mul(t2, t2, t1); - fe25519_sq(t3, t2); - for (i = 1; i < 20; i++) { - fe25519_sq(t3, t3); - } - fe25519_mul(t2, t3, t2); - fe25519_sq(t2, t2); - for (i = 1; i < 10; i++) { - fe25519_sq(t2, t2); - } - fe25519_mul(t1, t2, t1); - fe25519_sq(t2, t1); - for (i = 1; i < 50; i++) { - fe25519_sq(t2, t2); - } - fe25519_mul(t2, t2, t1); - fe25519_sq(t3, t2); - for (i = 1; i < 100; i++) { - fe25519_sq(t3, t3); - } - fe25519_mul(t2, t3, t2); - fe25519_sq(t2, t2); - for (i = 1; i < 50; i++) { - fe25519_sq(t2, t2); - } - fe25519_mul(t1, t2, t1); - fe25519_sq(t1, t1); - for (i = 1; i < 4; i++) { - fe25519_sq(t1, t1); - } - fe25519_mul(out, t1, t0); +/* montgomery -- recover y = sqrt(x^3 + A*x^2 + x) */ +static int +ge25519_xmont_to_ymont(fe25519 y, const fe25519 x) +{ + fe25519 x2; + fe25519 x3; + + fe25519_sq(x2, x); + fe25519_mul(x3, x, x2); + fe25519_mul32(x2, x2, ed25519_A_32); + fe25519_add(y, x3, x); + fe25519_add(y, y, x2); + + return fe25519_sqrt(y, y); } +/* multiply by the cofactor */ void -ge25519_from_uniform(unsigned char s[32], const unsigned char r[32]) +ge25519_clear_cofactor(ge25519_p3 *p3) { - fe25519 e; - fe25519 negx; - fe25519 rr2; - fe25519 x, x2, x3; - ge25519_p3 p3; - ge25519_p1p1 p1; - ge25519_p2 p2; - unsigned int e_is_minus_1; - unsigned char x_sign; + ge25519_p1p1 p1; + ge25519_p2 p2; - memcpy(s, r, 32); - x_sign = s[31] & 0x80; - s[31] &= 0x7f; + ge25519_p3_dbl(&p1, p3); + ge25519_p1p1_to_p2(&p2, &p1); + ge25519_p2_dbl(&p1, &p2); + ge25519_p1p1_to_p2(&p2, &p1); + ge25519_p2_dbl(&p1, &p2); + ge25519_p1p1_to_p3(p3, &p1); +} - fe25519_frombytes(rr2, s); +static void +ge25519_elligator2(fe25519 x, fe25519 y, const fe25519 r, int *notsquare_p) +{ + fe25519 gx1; + fe25519 rr2; + fe25519 x2, x3, negx; + int notsquare; - /* elligator */ - fe25519_sq2(rr2, rr2); + fe25519_sq2(rr2, r); rr2[0]++; fe25519_invert(rr2, rr2); - fe25519_mul(x, curve25519_A, rr2); - fe25519_neg(x, x); + fe25519_mul32(x, rr2, ed25519_A_32); + fe25519_neg(x, x); /* x=x1 */ fe25519_sq(x2, x); fe25519_mul(x3, x, x2); - fe25519_add(e, x3, x); - fe25519_mul(x2, x2, curve25519_A); - fe25519_add(e, x2, e); + fe25519_mul32(x2, x2, ed25519_A_32); /* x2 = A*x1^2 */ + fe25519_add(gx1, x3, x); + fe25519_add(gx1, gx1, x2); /* gx1 = x1^3 + A*x1^2 + x1 */ - chi25519(e, e); + notsquare = fe25519_notsquare(gx1); - fe25519_tobytes(s, e); - e_is_minus_1 = s[1] & 1; + /* gx1 not a square => x = -x1-A */ fe25519_neg(negx, x); - fe25519_cmov(x, negx, e_is_minus_1); + fe25519_cmov(x, negx, notsquare); fe25519_0(x2); - fe25519_cmov(x2, curve25519_A, e_is_minus_1); + fe25519_cmov(x2, ed25519_A, notsquare); fe25519_sub(x, x, x2); - /* yed = (x-1)/(x+1) */ - { - fe25519 one; - fe25519 x_plus_one; - fe25519 x_plus_one_inv; - fe25519 x_minus_one; - fe25519 yed; - - fe25519_1(one); - fe25519_add(x_plus_one, x, one); - fe25519_sub(x_minus_one, x, one); - fe25519_invert(x_plus_one_inv, x_plus_one); - fe25519_mul(yed, x_minus_one, x_plus_one_inv); - fe25519_tobytes(s, yed); + /* y = sqrt(gx1) or sqrt(gx2) with gx2 = gx1 * (A+x1) / -x1 */ + /* but it is about as fast to just recompute from the curve equation. */ + if (ge25519_xmont_to_ymont(y, x) != 0) { + abort(); } + *notsquare_p = notsquare; +} - /* recover x */ - s[31] |= x_sign; - if (ge25519_frombytes(&p3, s) != 0) { - abort(); /* LCOV_EXCL_LINE */ +void +ge25519_from_uniform(unsigned char s[32], const unsigned char r[32]) +{ + ge25519_p3 p3; + fe25519 x, y, negxed; + fe25519 r_fe; + int notsquare; + unsigned char x_sign; + + memcpy(s, r, 32); + x_sign = s[31] >> 7; + s[31] &= 0x7f; + fe25519_frombytes(r_fe, s); + + ge25519_elligator2(x, y, r_fe, ¬square); + + ge25519_mont_to_ed(p3.X, p3.Y, x, y); + fe25519_neg(negxed, p3.X); + fe25519_cmov(p3.X, negxed, fe25519_isnegative(p3.X) ^ x_sign); + + fe25519_1(p3.Z); + fe25519_mul(p3.T, p3.X, p3.Y); + ge25519_clear_cofactor(&p3); + ge25519_p3_tobytes(s, &p3); +} + +#define HASH_GE_L 48U + +static int +_string_to_points(unsigned char * const px, const size_t n, + const char *ctx, const unsigned char *msg, size_t msg_len, + int hash_alg) +{ + unsigned char h[64]; + unsigned char h_be[2U * HASH_GE_L]; + size_t i, j; + + if (n > 2U) { + abort(); /* LCOV_EXCL_LINE */; + } + if (core_h2c_string_to_hash(h_be, n * HASH_GE_L, ctx, msg, msg_len, + hash_alg) != 0) { + return -1; } + COMPILER_ASSERT(sizeof h >= HASH_GE_L); + for (i = 0U; i < n; i++) { + for (j = 0U; j < HASH_GE_L; j++) { + h[j] = h_be[i * HASH_GE_L + HASH_GE_L - 1U - j]; + } + memset(&h[j], 0, (sizeof h) - j); + ge25519_from_hash(&px[i * 32], h); + } + return 0; +} - /* multiply by the cofactor */ - ge25519_p3_dbl(&p1, &p3); - ge25519_p1p1_to_p2(&p2, &p1); - ge25519_p2_dbl(&p1, &p2); - ge25519_p1p1_to_p2(&p2, &p1); - ge25519_p2_dbl(&p1, &p2); - ge25519_p1p1_to_p3(&p3, &p1); +int +ge25519_from_string(unsigned char p[32], + const char *ctx, const unsigned char *msg, + size_t msg_len, int hash_alg) +{ + return _string_to_points(p, 1, ctx, msg, msg_len, hash_alg); + + +} + +int +ge25519_from_string_ro(unsigned char p[32], + const char *ctx, const unsigned char *msg, + size_t msg_len, int hash_alg) +{ + unsigned char px[64]; + ge25519_p3 p_p3, q_p3, r_p3; + + if (_string_to_points(px, 2, ctx, msg, msg_len, hash_alg) != 0) { + return -1; + } + + if (ge25519_frombytes(&p_p3, &px[0]) != 0 || ge25519_is_on_curve(&p_p3) == 0 || + ge25519_frombytes(&q_p3, &px[32]) != 0 || ge25519_is_on_curve(&q_p3) == 0) { + return -1; + } + ge25519_p3_add(&r_p3, &p_p3, &q_p3); + ge25519_p3_tobytes(p, &r_p3); + + return 0; +} + + +static void +fe25519_reduce64(fe25519 fe_f, const unsigned char h[64]) +{ + unsigned char fl[32]; + unsigned char gl[32]; + fe25519 fe_g; + size_t i; + + memcpy(fl, h, 32); + memcpy(gl, h + 32, 32); + fl[31] &= 0x7f; + gl[31] &= 0x7f; + fe25519_frombytes(fe_f, fl); + fe25519_frombytes(fe_g, gl); + fe_f[0] += (h[31] >> 7) * 19 + (h[63] >> 7) * 722; + for (i = 0; i < sizeof (fe25519) / sizeof fe_f[0]; i++) { + fe_f[i] += 38 * fe_g[i]; + } + fe25519_reduce(fe_f, fe_f); +} +void +ge25519_from_hash(unsigned char s[32], const unsigned char h[64]) +{ + ge25519_p3 p3; + fe25519 fe_f; + fe25519 x, y, negy; + int notsquare; + unsigned char y_sign; + + fe25519_reduce64(fe_f, h); + ge25519_elligator2(x, y, fe_f, ¬square); + + y_sign = notsquare ^ 1; + fe25519_neg(negy, y); + fe25519_cmov(y, negy, fe25519_isnegative(y) ^ y_sign); + + ge25519_mont_to_ed(p3.X, p3.Y, x, y); + + fe25519_1(p3.Z); + fe25519_mul(p3.T, p3.X, p3.Y); + ge25519_clear_cofactor(&p3); ge25519_p3_tobytes(s, &p3); } + +/* Ristretto group */ + +static int +ristretto255_sqrt_ratio_m1(fe25519 x, const fe25519 u, const fe25519 v) +{ + fe25519 v3; + fe25519 vxx; + fe25519 m_root_check, p_root_check, f_root_check; + fe25519 x_sqrtm1; + int has_m_root, has_p_root, has_f_root; + + fe25519_sq(v3, v); + fe25519_mul(v3, v3, v); /* v3 = v^3 */ + fe25519_sq(x, v3); + fe25519_mul(x, x, u); + fe25519_mul(x, x, v); /* x = uv^7 */ + + fe25519_pow22523(x, x); /* x = (uv^7)^((q-5)/8) */ + fe25519_mul(x, x, v3); + fe25519_mul(x, x, u); /* x = uv^3(uv^7)^((q-5)/8) */ + + fe25519_sq(vxx, x); + fe25519_mul(vxx, vxx, v); /* vx^2 */ + fe25519_sub(m_root_check, vxx, u); /* vx^2-u */ + fe25519_add(p_root_check, vxx, u); /* vx^2+u */ + fe25519_mul(f_root_check, u, fe25519_sqrtm1); /* u*sqrt(-1) */ + fe25519_add(f_root_check, vxx, f_root_check); /* vx^2+u*sqrt(-1) */ + has_m_root = fe25519_iszero(m_root_check); + has_p_root = fe25519_iszero(p_root_check); + has_f_root = fe25519_iszero(f_root_check); + fe25519_mul(x_sqrtm1, x, fe25519_sqrtm1); /* x*sqrt(-1) */ + + fe25519_cmov(x, x_sqrtm1, has_p_root | has_f_root); + fe25519_abs(x); + + return has_m_root | has_p_root; +} + +static int +ristretto255_is_canonical(const unsigned char *s) +{ + unsigned char c; + unsigned char d; + unsigned char e; + unsigned int i; + + c = (s[31] & 0x7f) ^ 0x7f; + for (i = 30; i > 0; i--) { + c |= s[i] ^ 0xff; + } + c = (((unsigned int) c) - 1U) >> 8; + d = (0xed - 1U - (unsigned int) s[0]) >> 8; + e = s[31] >> 7; + + return 1 - (((c & d) | e | s[0]) & 1); +} + +int +ristretto255_frombytes(ge25519_p3 *h, const unsigned char *s) +{ + fe25519 inv_sqrt; + fe25519 one; + fe25519 s_; + fe25519 ss; + fe25519 u1, u2; + fe25519 u1u1, u2u2; + fe25519 v; + fe25519 v_u2u2; + int notsquare; + + if (ristretto255_is_canonical(s) == 0) { + return -1; + } + fe25519_frombytes(s_, s); + fe25519_sq(ss, s_); /* ss = s^2 */ + + fe25519_1(u1); + fe25519_sub(u1, u1, ss); /* u1 = 1-ss */ + fe25519_sq(u1u1, u1); /* u1u1 = u1^2 */ + + fe25519_1(u2); + fe25519_add(u2, u2, ss); /* u2 = 1+ss */ + fe25519_sq(u2u2, u2); /* u2u2 = u2^2 */ + + fe25519_mul(v, ed25519_d, u1u1); /* v = d*u1^2 */ + fe25519_neg(v, v); /* v = -d*u1^2 */ + fe25519_sub(v, v, u2u2); /* v = -(d*u1^2)-u2^2 */ + + fe25519_mul(v_u2u2, v, u2u2); /* v_u2u2 = v*u2^2 */ + + fe25519_1(one); + notsquare = ristretto255_sqrt_ratio_m1(inv_sqrt, one, v_u2u2); + fe25519_mul(h->X, inv_sqrt, u2); + fe25519_mul(h->Y, inv_sqrt, h->X); + fe25519_mul(h->Y, h->Y, v); + + fe25519_mul(h->X, h->X, s_); + fe25519_add(h->X, h->X, h->X); + fe25519_abs(h->X); + fe25519_mul(h->Y, u1, h->Y); + fe25519_1(h->Z); + fe25519_mul(h->T, h->X, h->Y); + + return - ((1 - notsquare) | + fe25519_isnegative(h->T) | fe25519_iszero(h->Y)); +} + +void +ristretto255_p3_tobytes(unsigned char *s, const ge25519_p3 *h) +{ + fe25519 den1, den2; + fe25519 den_inv; + fe25519 eden; + fe25519 inv_sqrt; + fe25519 ix, iy; + fe25519 one; + fe25519 s_; + fe25519 t_z_inv; + fe25519 u1, u2; + fe25519 u1_u2u2; + fe25519 x_, y_; + fe25519 x_z_inv; + fe25519 z_inv; + fe25519 zmy; + int rotate; + + fe25519_add(u1, h->Z, h->Y); /* u1 = Z+Y */ + fe25519_sub(zmy, h->Z, h->Y); /* zmy = Z-Y */ + fe25519_mul(u1, u1, zmy); /* u1 = (Z+Y)*(Z-Y) */ + fe25519_mul(u2, h->X, h->Y); /* u2 = X*Y */ + + fe25519_sq(u1_u2u2, u2); /* u1_u2u2 = u2^2 */ + fe25519_mul(u1_u2u2, u1, u1_u2u2); /* u1_u2u2 = u1*u2^2 */ + + fe25519_1(one); + (void) ristretto255_sqrt_ratio_m1(inv_sqrt, one, u1_u2u2); + fe25519_mul(den1, inv_sqrt, u1); /* den1 = inv_sqrt*u1 */ + fe25519_mul(den2, inv_sqrt, u2); /* den2 = inv_sqrt*u2 */ + fe25519_mul(z_inv, den1, den2); /* z_inv = den1*den2 */ + fe25519_mul(z_inv, z_inv, h->T); /* z_inv = den1*den2*T */ + + fe25519_mul(ix, h->X, fe25519_sqrtm1); /* ix = X*sqrt(-1) */ + fe25519_mul(iy, h->Y, fe25519_sqrtm1); /* iy = Y*sqrt(-1) */ + fe25519_mul(eden, den1, ed25519_invsqrtamd); /* eden = den1/sqrt(a-d) */ + + fe25519_mul(t_z_inv, h->T, z_inv); /* t_z_inv = T*z_inv */ + rotate = fe25519_isnegative(t_z_inv); + + fe25519_copy(x_, h->X); + fe25519_copy(y_, h->Y); + fe25519_copy(den_inv, den2); + + fe25519_cmov(x_, iy, rotate); + fe25519_cmov(y_, ix, rotate); + fe25519_cmov(den_inv, eden, rotate); + + fe25519_mul(x_z_inv, x_, z_inv); + fe25519_cneg(y_, fe25519_isnegative(x_z_inv)); + + fe25519_sub(s_, h->Z, y_); + fe25519_mul(s_, den_inv, s_); + fe25519_abs(s_); + fe25519_tobytes(s, s_); +} + +static void +ristretto255_elligator(ge25519_p3 *p, const fe25519 t) +{ + fe25519 c; + fe25519 n; + fe25519 one; + fe25519 r; + fe25519 rpd; + fe25519 s, s_prime; + fe25519 ss; + fe25519 u, v; + fe25519 w0, w1, w2, w3; + int wasnt_square; + + fe25519_1(one); + fe25519_sq(r, t); /* r = t^2 */ + fe25519_mul(r, fe25519_sqrtm1, r); /* r = sqrt(-1)*t^2 */ + fe25519_add(u, r, one); /* u = r+1 */ + fe25519_mul(u, u, ed25519_onemsqd);/* u = (r+1)*(1-d^2) */ + fe25519_1(c); + fe25519_neg(c, c); /* c = -1 */ + fe25519_add(rpd, r, ed25519_d); /* rpd = r+d */ + fe25519_mul(v, r, ed25519_d); /* v = r*d */ + fe25519_sub(v, c, v); /* v = c-r*d */ + fe25519_mul(v, v, rpd); /* v = (c-r*d)*(r+d) */ + + wasnt_square = 1 - ristretto255_sqrt_ratio_m1(s, u, v); + fe25519_mul(s_prime, s, t); + fe25519_abs(s_prime); + fe25519_neg(s_prime, s_prime); /* s_prime = -|s*t| */ + fe25519_cmov(s, s_prime, wasnt_square); + fe25519_cmov(c, r, wasnt_square); + + fe25519_sub(n, r, one); /* n = r-1 */ + fe25519_mul(n, n, c); /* n = c*(r-1) */ + fe25519_mul(n, n, ed25519_sqdmone); /* n = c*(r-1)*(d-1)^2 */ + fe25519_sub(n, n, v); /* n = c*(r-1)*(d-1)^2-v */ + + fe25519_add(w0, s, s); /* w0 = 2s */ + fe25519_mul(w0, w0, v); /* w0 = 2s*v */ + fe25519_mul(w1, n, ed25519_sqrtadm1); /* w1 = n*sqrt(ad-1) */ + fe25519_sq(ss, s); /* ss = s^2 */ + fe25519_sub(w2, one, ss); /* w2 = 1-s^2 */ + fe25519_add(w3, one, ss); /* w3 = 1+s^2 */ + + fe25519_mul(p->X, w0, w3); + fe25519_mul(p->Y, w2, w1); + fe25519_mul(p->Z, w1, w3); + fe25519_mul(p->T, w0, w2); +} + +void +ristretto255_from_hash(unsigned char s[32], const unsigned char h[64]) +{ + fe25519 r0, r1; + ge25519_p3 p0, p1; + ge25519_p3 p; + + fe25519_frombytes(r0, h); + fe25519_frombytes(r1, h + 32); + ristretto255_elligator(&p0, r0); + ristretto255_elligator(&p1, r1); + ge25519_p3_add(&p, &p0, &p1); + ristretto255_p3_tobytes(s, &p); +} diff --git a/libs/libsodium/src/crypto_core/ed25519/ref10/fe_25_5/constants.h b/libs/libsodium/src/crypto_core/ed25519/ref10/fe_25_5/constants.h index 4371d4ceb8..4bd679755c 100644 --- a/libs/libsodium/src/crypto_core/ed25519/ref10/fe_25_5/constants.h +++ b/libs/libsodium/src/crypto_core/ed25519/ref10/fe_25_5/constants.h @@ -1,20 +1,46 @@ +/* sqrt(-1) */ +static const fe25519 fe25519_sqrtm1 = { + -32595792, -7943725, 9377950, 3500415, 12389472, -272473, -25146209, -2005654, 326686, 11406482 +}; + +/* sqrt(-486664) */ +static const fe25519 ed25519_sqrtam2 = { + -12222970, -8312128, -11511410, 9067497, -15300785, -241793, 25456130, 14121551, -12187136, 3972024 +}; + /* 37095705934669439343138083508754565189542113879843219016388785533085940283555 */ -static const fe25519 d = { +static const fe25519 ed25519_d = { -10913610, 13857413, -15372611, 6949391, 114729, -8787816, -6275908, -3247719, -18696448, -12055116 }; /* 2 * d = * 16295367250680780974490674513165176452449235426866156013048779062215315747161 */ -static const fe25519 d2 = { +static const fe25519 ed25519_d2 = { -21827239, -5839606, -30745221, 13898782, 229458, 15978800, -12551817, -6495438, 29715968, 9444199 }; -/* sqrt(-1) */ -static const fe25519 sqrtm1 = { - -32595792, -7943725, 9377950, 3500415, 12389472, -272473, -25146209, -2005654, 326686, 11406482 +/* A = 486662 */ +#define ed25519_A_32 486662 +static const fe25519 ed25519_A = { + ed25519_A_32, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; -/* A = 486662 */ -static const fe25519 curve25519_A = { - 486662, 0, 0, 0, 0, 0, 0, 0, 0, 0 +/* sqrt(ad - 1) with a = -1 (mod p) */ +static const fe25519 ed25519_sqrtadm1 = { + 24849947, -153582, -23613485, 6347715, -21072328, -667138, -25271143, -15367704, -870347, 14525639 +}; + +/* 1 / sqrt(a - d) */ +static const fe25519 ed25519_invsqrtamd = { + 6111485, 4156064, -27798727, 12243468, -25904040, 120897, 20826367, -7060776, 6093568, -1986012 +}; + +/* 1 - d ^ 2 */ +static const fe25519 ed25519_onemsqd = { + 6275446, -16617371, -22938544, -3773710, 11667077, 7397348, -27922721, 1766195, -24433858, 672203 +}; + +/* (d - 1) ^ 2 */ +static const fe25519 ed25519_sqdmone = { + 15551795, -11097455, -13425098, -10125071, -11896535, 10178284, -26634327, 4729244, -5282110, -10116402 }; diff --git a/libs/libsodium/src/crypto_core/ed25519/ref10/fe_25_5/fe.h b/libs/libsodium/src/crypto_core/ed25519/ref10/fe_25_5/fe.h index 57062a2dfc..70350baf34 100644 --- a/libs/libsodium/src/crypto_core/ed25519/ref10/fe_25_5/fe.h +++ b/libs/libsodium/src/crypto_core/ed25519/ref10/fe_25_5/fe.h @@ -1,5 +1,7 @@ +#include "private/quirks.h" + /* - Ignores top bit of h. + Ignores top bit of s. */ void diff --git a/libs/libsodium/src/crypto_core/ed25519/ref10/fe_51/constants.h b/libs/libsodium/src/crypto_core/ed25519/ref10/fe_51/constants.h index 35e70fdc06..0a3d685222 100644 --- a/libs/libsodium/src/crypto_core/ed25519/ref10/fe_51/constants.h +++ b/libs/libsodium/src/crypto_core/ed25519/ref10/fe_51/constants.h @@ -1,21 +1,47 @@ +/* sqrt(-1) */ +static const fe25519 fe25519_sqrtm1 = { + 1718705420411056, 234908883556509, 2233514472574048, 2117202627021982, 765476049583133 +}; + +/* sqrt(-486664) */ +static const fe25519 ed25519_sqrtam2 = { + 1693982333959686, 608509411481997, 2235573344831311, 947681270984193, 266558006233600 +}; + /* 37095705934669439343138083508754565189542113879843219016388785533085940283555 */ -static const fe25519 d = { +static const fe25519 ed25519_d = { 929955233495203, 466365720129213, 1662059464998953, 2033849074728123, 1442794654840575 }; /* 2 * d = * 16295367250680780974490674513165176452449235426866156013048779062215315747161 */ -static const fe25519 d2 = { +static const fe25519 ed25519_d2 = { 1859910466990425, 932731440258426, 1072319116312658, 1815898335770999, 633789495995903 }; -/* sqrt(-1) */ -static const fe25519 sqrtm1 = { - 1718705420411056, 234908883556509, 2233514472574048, 2117202627021982, 765476049583133 +/* A = 486662 */ +#define ed25519_A_32 486662 +static const fe25519 ed25519_A = { + ed25519_A_32, 0, 0, 0, 0 }; -/* A = 486662 */ -static const fe25519 curve25519_A = { - 486662, 0, 0, 0, 0 +/* sqrt(ad - 1) with a = -1 (mod p) */ +static const fe25519 ed25519_sqrtadm1 = { + 2241493124984347, 425987919032274, 2207028919301688, 1220490630685848, 974799131293748 +}; + +/* 1 / sqrt(a - d) */ +static const fe25519 ed25519_invsqrtamd = { + 278908739862762, 821645201101625, 8113234426968, 1777959178193151, 2118520810568447 +}; + +/* 1 - d ^ 2 */ +static const fe25519 ed25519_onemsqd = { + 1136626929484150, 1998550399581263, 496427632559748, 118527312129759, 45110755273534 +}; + +/* (d - 1) ^ 2 */ +static const fe25519 ed25519_sqdmone = { + 1507062230895904, 1572317787530805, 683053064812840, 317374165784489, 1572899562415810 }; diff --git a/libs/libsodium/src/crypto_core/ed25519/ref10/fe_51/fe.h b/libs/libsodium/src/crypto_core/ed25519/ref10/fe_51/fe.h index d79370b067..c50567ce45 100644 --- a/libs/libsodium/src/crypto_core/ed25519/ref10/fe_51/fe.h +++ b/libs/libsodium/src/crypto_core/ed25519/ref10/fe_51/fe.h @@ -1,5 +1,7 @@ +#include "private/quirks.h" + /* - Ignores top bit of h. + Ignores top bit of s. */ void diff --git a/libs/libsodium/src/crypto_core/salsa/ref/core_salsa_ref.c b/libs/libsodium/src/crypto_core/salsa/ref/core_salsa_ref.c index ce300f67ea..4cbef62a9c 100644 --- a/libs/libsodium/src/crypto_core/salsa/ref/core_salsa_ref.c +++ b/libs/libsodium/src/crypto_core/salsa/ref/core_salsa_ref.c @@ -127,7 +127,7 @@ crypto_core_salsa20_constbytes(void) } #ifndef MINIMAL - +/* LCOV_EXCL_START */ int crypto_core_salsa2012(unsigned char *out, const unsigned char *in, const unsigned char *k, const unsigned char *c) @@ -191,5 +191,5 @@ crypto_core_salsa208_constbytes(void) { return crypto_core_salsa208_CONSTBYTES; } - +/* LCOV_EXCL_END */ #endif diff --git a/libs/libsodium/src/crypto_core/softaes/softaes.c b/libs/libsodium/src/crypto_core/softaes/softaes.c new file mode 100644 index 0000000000..ae469c8acd --- /dev/null +++ b/libs/libsodium/src/crypto_core/softaes/softaes.c @@ -0,0 +1,143 @@ +#include +#include +#include +#include + +#include "private/common.h" +#include "private/softaes.h" + +uint32_t _aes_lut[256] __attribute__ ((visibility ("hidden"))) = { + 0xa56363c6, 0x847c7cf8, 0x997777ee, 0x8d7b7bf6, 0x0df2f2ff, 0xbd6b6bd6, 0xb16f6fde, 0x54c5c591, + 0x50303060, 0x03010102, 0xa96767ce, 0x7d2b2b56, 0x19fefee7, 0x62d7d7b5, 0xe6abab4d, 0x9a7676ec, + 0x45caca8f, 0x9d82821f, 0x40c9c989, 0x877d7dfa, 0x15fafaef, 0xeb5959b2, 0xc947478e, 0x0bf0f0fb, + 0xecadad41, 0x67d4d4b3, 0xfda2a25f, 0xeaafaf45, 0xbf9c9c23, 0xf7a4a453, 0x967272e4, 0x5bc0c09b, + 0xc2b7b775, 0x1cfdfde1, 0xae93933d, 0x6a26264c, 0x5a36366c, 0x413f3f7e, 0x02f7f7f5, 0x4fcccc83, + 0x5c343468, 0xf4a5a551, 0x34e5e5d1, 0x08f1f1f9, 0x937171e2, 0x73d8d8ab, 0x53313162, 0x3f15152a, + 0x0c040408, 0x52c7c795, 0x65232346, 0x5ec3c39d, 0x28181830, 0xa1969637, 0x0f05050a, 0xb59a9a2f, + 0x0907070e, 0x36121224, 0x9b80801b, 0x3de2e2df, 0x26ebebcd, 0x6927274e, 0xcdb2b27f, 0x9f7575ea, + 0x1b090912, 0x9e83831d, 0x742c2c58, 0x2e1a1a34, 0x2d1b1b36, 0xb26e6edc, 0xee5a5ab4, 0xfba0a05b, + 0xf65252a4, 0x4d3b3b76, 0x61d6d6b7, 0xceb3b37d, 0x7b292952, 0x3ee3e3dd, 0x712f2f5e, 0x97848413, + 0xf55353a6, 0x68d1d1b9, 0x00000000, 0x2cededc1, 0x60202040, 0x1ffcfce3, 0xc8b1b179, 0xed5b5bb6, + 0xbe6a6ad4, 0x46cbcb8d, 0xd9bebe67, 0x4b393972, 0xde4a4a94, 0xd44c4c98, 0xe85858b0, 0x4acfcf85, + 0x6bd0d0bb, 0x2aefefc5, 0xe5aaaa4f, 0x16fbfbed, 0xc5434386, 0xd74d4d9a, 0x55333366, 0x94858511, + 0xcf45458a, 0x10f9f9e9, 0x06020204, 0x817f7ffe, 0xf05050a0, 0x443c3c78, 0xba9f9f25, 0xe3a8a84b, + 0xf35151a2, 0xfea3a35d, 0xc0404080, 0x8a8f8f05, 0xad92923f, 0xbc9d9d21, 0x48383870, 0x04f5f5f1, + 0xdfbcbc63, 0xc1b6b677, 0x75dadaaf, 0x63212142, 0x30101020, 0x1affffe5, 0x0ef3f3fd, 0x6dd2d2bf, + 0x4ccdcd81, 0x140c0c18, 0x35131326, 0x2fececc3, 0xe15f5fbe, 0xa2979735, 0xcc444488, 0x3917172e, + 0x57c4c493, 0xf2a7a755, 0x827e7efc, 0x473d3d7a, 0xac6464c8, 0xe75d5dba, 0x2b191932, 0x957373e6, + 0xa06060c0, 0x98818119, 0xd14f4f9e, 0x7fdcdca3, 0x66222244, 0x7e2a2a54, 0xab90903b, 0x8388880b, + 0xca46468c, 0x29eeeec7, 0xd3b8b86b, 0x3c141428, 0x79dedea7, 0xe25e5ebc, 0x1d0b0b16, 0x76dbdbad, + 0x3be0e0db, 0x56323264, 0x4e3a3a74, 0x1e0a0a14, 0xdb494992, 0x0a06060c, 0x6c242448, 0xe45c5cb8, + 0x5dc2c29f, 0x6ed3d3bd, 0xefacac43, 0xa66262c4, 0xa8919139, 0xa4959531, 0x37e4e4d3, 0x8b7979f2, + 0x32e7e7d5, 0x43c8c88b, 0x5937376e, 0xb76d6dda, 0x8c8d8d01, 0x64d5d5b1, 0xd24e4e9c, 0xe0a9a949, + 0xb46c6cd8, 0xfa5656ac, 0x07f4f4f3, 0x25eaeacf, 0xaf6565ca, 0x8e7a7af4, 0xe9aeae47, 0x18080810, + 0xd5baba6f, 0x887878f0, 0x6f25254a, 0x722e2e5c, 0x241c1c38, 0xf1a6a657, 0xc7b4b473, 0x51c6c697, + 0x23e8e8cb, 0x7cdddda1, 0x9c7474e8, 0x211f1f3e, 0xdd4b4b96, 0xdcbdbd61, 0x868b8b0d, 0x858a8a0f, + 0x907070e0, 0x423e3e7c, 0xc4b5b571, 0xaa6666cc, 0xd8484890, 0x05030306, 0x01f6f6f7, 0x120e0e1c, + 0xa36161c2, 0x5f35356a, 0xf95757ae, 0xd0b9b969, 0x91868617, 0x58c1c199, 0x271d1d3a, 0xb99e9e27, + 0x38e1e1d9, 0x13f8f8eb, 0xb398982b, 0x33111122, 0xbb6969d2, 0x70d9d9a9, 0x898e8e07, 0xa7949433, + 0xb69b9b2d, 0x221e1e3c, 0x92878715, 0x20e9e9c9, 0x49cece87, 0xff5555aa, 0x78282850, 0x7adfdfa5, + 0x8f8c8c03, 0xf8a1a159, 0x80898909, 0x170d0d1a, 0xdabfbf65, 0x31e6e6d7, 0xc6424284, 0xb86868d0, + 0xc3414182, 0xb0999929, 0x772d2d5a, 0x110f0f1e, 0xcbb0b07b, 0xfc5454a8, 0xd6bbbb6d, 0x3a16162c +}; + +static const uint32_t * const LUT = _aes_lut; + +#ifndef SOFTAES_STRIDE +# ifdef FAVOR_PERFORMANCE +# define SOFTAES_STRIDE 256 +# else +# define SOFTAES_STRIDE 16 +# endif +#endif + +static SoftAesBlock +_encrypt(const uint8_t ix0[4], const uint8_t ix1[4], const uint8_t ix2[4], const uint8_t ix3[4]) +{ + CRYPTO_ALIGN(64) uint32_t t[4][4][256 / SOFTAES_STRIDE]; + CRYPTO_ALIGN(64) uint8_t of[4][4]; + CRYPTO_ALIGN(64) SoftAesBlock out; + size_t i; + size_t j; + + for (j = 0; j < 4; j++) { + of[j][0] = ix0[j] % SOFTAES_STRIDE; + of[j][1] = ix1[j] % SOFTAES_STRIDE; + of[j][2] = ix2[j] % SOFTAES_STRIDE; + of[j][3] = ix3[j] % SOFTAES_STRIDE; + } + for (i = 0; i < 256 / SOFTAES_STRIDE; i++) { + for (j = 0; j < 4; j++) { + t[j][0][i] = LUT[(i * SOFTAES_STRIDE) | of[j][0]]; + t[j][1][i] = LUT[(i * SOFTAES_STRIDE) | of[j][1]]; + t[j][2][i] = LUT[(i * SOFTAES_STRIDE) | of[j][2]]; + t[j][3][i] = LUT[(i * SOFTAES_STRIDE) | of[j][3]]; + } + } + +#ifdef HAVE_INLINE_ASM + __asm__ __volatile__("" : : "r"(t) : "memory"); +#endif + + out.w0 = t[0][0][ix0[0] / SOFTAES_STRIDE]; + out.w0 ^= ROTL32(t[0][1][ix1[0] / SOFTAES_STRIDE], 8); + out.w0 ^= ROTL32(t[0][2][ix2[0] / SOFTAES_STRIDE], 16); + out.w0 ^= ROTL32(t[0][3][ix3[0] / SOFTAES_STRIDE], 24); + + out.w1 = t[1][0][ix0[1] / SOFTAES_STRIDE]; + out.w1 ^= ROTL32(t[1][1][ix1[1] / SOFTAES_STRIDE], 8); + out.w1 ^= ROTL32(t[1][2][ix2[1] / SOFTAES_STRIDE], 16); + out.w1 ^= ROTL32(t[1][3][ix3[1] / SOFTAES_STRIDE], 24); + + out.w2 = t[2][0][ix0[2] / SOFTAES_STRIDE]; + out.w2 ^= ROTL32(t[2][1][ix1[2] / SOFTAES_STRIDE], 8); + out.w2 ^= ROTL32(t[2][2][ix2[2] / SOFTAES_STRIDE], 16); + out.w2 ^= ROTL32(t[2][3][ix3[2] / SOFTAES_STRIDE], 24); + + out.w3 = t[3][0][ix0[3] / SOFTAES_STRIDE]; + out.w3 ^= ROTL32(t[3][1][ix1[3] / SOFTAES_STRIDE], 8); + out.w3 ^= ROTL32(t[3][2][ix2[3] / SOFTAES_STRIDE], 16); + out.w3 ^= ROTL32(t[3][3][ix3[3] / SOFTAES_STRIDE], 24); + + return out; +} + +SoftAesBlock +softaes_block_encrypt(const SoftAesBlock block, const SoftAesBlock rk) +{ + CRYPTO_ALIGN(64) SoftAesBlock out; + CRYPTO_ALIGN(64) uint8_t ix0[4], ix1[4], ix2[4], ix3[4]; + const uint32_t s0 = block.w0; + const uint32_t s1 = block.w1; + const uint32_t s2 = block.w2; + const uint32_t s3 = block.w3; + + ix0[0] = (uint8_t) s0; + ix0[1] = (uint8_t) s1; + ix0[2] = (uint8_t) s2; + ix0[3] = (uint8_t) s3; + + ix1[0] = (uint8_t) (s1 >> 8); + ix1[1] = (uint8_t) (s2 >> 8); + ix1[2] = (uint8_t) (s3 >> 8); + ix1[3] = (uint8_t) (s0 >> 8); + + ix2[0] = (uint8_t) (s2 >> 16); + ix2[1] = (uint8_t) (s3 >> 16); + ix2[2] = (uint8_t) (s0 >> 16); + ix2[3] = (uint8_t) (s1 >> 16); + + ix3[0] = (uint8_t) (s3 >> 24); + ix3[1] = (uint8_t) (s0 >> 24); + ix3[2] = (uint8_t) (s1 >> 24); + ix3[3] = (uint8_t) (s2 >> 24); + + out = _encrypt(ix0, ix1, ix2, ix3); + + out.w0 ^= rk.w0; + out.w1 ^= rk.w1; + out.w2 ^= rk.w2; + out.w3 ^= rk.w3; + + return out; +} diff --git a/libs/libsodium/src/crypto_generichash/blake2b/ref/blake2.h b/libs/libsodium/src/crypto_generichash/blake2b/ref/blake2.h index b027a5b834..55ddec64f0 100644 --- a/libs/libsodium/src/crypto_generichash/blake2b/ref/blake2.h +++ b/libs/libsodium/src/crypto_generichash/blake2b/ref/blake2.h @@ -22,20 +22,7 @@ #include "crypto_generichash_blake2b.h" #include "export.h" - -#define blake2b_init_param crypto_generichash_blake2b__init_param -#define blake2b_init crypto_generichash_blake2b__init -#define blake2b_init_salt_personal \ - crypto_generichash_blake2b__init_salt_personal -#define blake2b_init_key crypto_generichash_blake2b__init_key -#define blake2b_init_key_salt_personal \ - crypto_generichash_blake2b__init_key_salt_personal -#define blake2b_update crypto_generichash_blake2b__update -#define blake2b_final crypto_generichash_blake2b__final -#define blake2b crypto_generichash_blake2b__blake2b -#define blake2b_salt_personal crypto_generichash_blake2b__blake2b_salt_personal -#define blake2b_pick_best_implementation \ - crypto_generichash_blake2b__pick_best_implementation +#include "private/quirks.h" enum blake2b_constant { BLAKE2B_BLOCKBYTES = 128, @@ -45,10 +32,12 @@ enum blake2b_constant { BLAKE2B_PERSONALBYTES = 16 }; -#if defined(__IBMC__) || defined(__SUNPRO_C) || defined(__SUNPRO_CC) -#pragma pack(1) +#ifdef __IBMC__ +# pragma pack(1) +#elif defined(__SUNPRO_C) || defined(__SUNPRO_CC) +# pragma pack(1) #else -#pragma pack(push, 1) +# pragma pack(push, 1) #endif typedef struct blake2b_param_ { @@ -74,10 +63,12 @@ typedef struct blake2b_state { uint8_t last_node; } blake2b_state; -#if defined(__IBMC__) || defined(__SUNPRO_C) || defined(__SUNPRO_CC) -#pragma pack() +#ifdef __IBMC__ +# pragma pack(pop) +#elif defined(__SUNPRO_C) || defined(__SUNPRO_CC) +# pragma pack() #else -#pragma pack(pop) +# pragma pack(pop) #endif /* Streaming API */ diff --git a/libs/libsodium/src/crypto_generichash/blake2b/ref/blake2b-compress-avx2.c b/libs/libsodium/src/crypto_generichash/blake2b/ref/blake2b-compress-avx2.c index 2f49862cb2..3303242ede 100644 --- a/libs/libsodium/src/crypto_generichash/blake2b/ref/blake2b-compress-avx2.c +++ b/libs/libsodium/src/crypto_generichash/blake2b/ref/blake2b-compress-avx2.c @@ -8,22 +8,21 @@ #include "blake2.h" #include "private/common.h" -#include "private/sse2_64_32.h" #if defined(HAVE_AVX2INTRIN_H) && defined(HAVE_EMMINTRIN_H) && \ defined(HAVE_TMMINTRIN_H) && defined(HAVE_SMMINTRIN_H) -# ifdef __GNUC__ -# pragma GCC target("sse2") -# pragma GCC target("ssse3") -# pragma GCC target("sse4.1") -# pragma GCC target("avx2") +# ifdef __clang__ +# pragma clang attribute push(__attribute__((target("sse2,ssse3,sse4.1,avx2"))), apply_to = function) +# elif defined(__GNUC__) +# pragma GCC target("sse2,ssse3,sse4.1,avx2") # endif # include # include # include # include +# include "private/sse2_64_32.h" # include "blake2b-compress-avx2.h" @@ -46,4 +45,8 @@ blake2b_compress_avx2(blake2b_state *S, const uint8_t block[BLAKE2B_BLOCKBYTES]) return 0; } +# ifdef __clang__ +# pragma clang attribute pop +# endif + #endif diff --git a/libs/libsodium/src/crypto_generichash/blake2b/ref/blake2b-compress-avx2.h b/libs/libsodium/src/crypto_generichash/blake2b/ref/blake2b-compress-avx2.h index dd325cb267..e1103962e1 100644 --- a/libs/libsodium/src/crypto_generichash/blake2b/ref/blake2b-compress-avx2.h +++ b/libs/libsodium/src/crypto_generichash/blake2b/ref/blake2b-compress-avx2.h @@ -68,17 +68,17 @@ LOADU64(const void *p) #define BLAKE2B_DIAG_V1(a, b, c, d) \ do { \ - d = _mm256_permute4x64_epi64(d, _MM_SHUFFLE(2, 1, 0, 3)); \ - c = _mm256_permute4x64_epi64(c, _MM_SHUFFLE(1, 0, 3, 2)); \ - b = _mm256_permute4x64_epi64(b, _MM_SHUFFLE(0, 3, 2, 1)); \ - } while (0) + a = _mm256_permute4x64_epi64(a, _MM_SHUFFLE(2, 1, 0, 3)); \ + d = _mm256_permute4x64_epi64(d, _MM_SHUFFLE(1, 0, 3, 2)); \ + c = _mm256_permute4x64_epi64(c, _MM_SHUFFLE(0, 3, 2, 1)); \ + } while(0) #define BLAKE2B_UNDIAG_V1(a, b, c, d) \ do { \ - d = _mm256_permute4x64_epi64(d, _MM_SHUFFLE(0, 3, 2, 1)); \ - c = _mm256_permute4x64_epi64(c, _MM_SHUFFLE(1, 0, 3, 2)); \ - b = _mm256_permute4x64_epi64(b, _MM_SHUFFLE(2, 1, 0, 3)); \ - } while (0) + a = _mm256_permute4x64_epi64(a, _MM_SHUFFLE(0, 3, 2, 1)); \ + d = _mm256_permute4x64_epi64(d, _MM_SHUFFLE(1, 0, 3, 2)); \ + c = _mm256_permute4x64_epi64(c, _MM_SHUFFLE(2, 1, 0, 3)); \ + } while(0) #include "blake2b-load-avx2.h" diff --git a/libs/libsodium/src/crypto_generichash/blake2b/ref/blake2b-compress-ref.c b/libs/libsodium/src/crypto_generichash/blake2b/ref/blake2b-compress-ref.c index 05bd59b7ee..90fc5fd0be 100644 --- a/libs/libsodium/src/crypto_generichash/blake2b/ref/blake2b-compress-ref.c +++ b/libs/libsodium/src/crypto_generichash/blake2b/ref/blake2b-compress-ref.c @@ -35,7 +35,7 @@ blake2b_compress_ref(blake2b_state *S, const uint8_t block[BLAKE2B_BLOCKBYTES]) int i; for (i = 0; i < 16; ++i) { - m[i] = LOAD64_LE(block + i * sizeof(m[i])); + m[i] = LOAD64_LE(block + i * sizeof m[i]); } for (i = 0; i < 8; ++i) { v[i] = S->h[i]; @@ -48,16 +48,16 @@ blake2b_compress_ref(blake2b_state *S, const uint8_t block[BLAKE2B_BLOCKBYTES]) v[13] = S->t[1] ^ blake2b_IV[5]; v[14] = S->f[0] ^ blake2b_IV[6]; v[15] = S->f[1] ^ blake2b_IV[7]; -#define G(r, i, a, b, c, d) \ - do { \ - a = a + b + m[blake2b_sigma[r][2 * i + 0]]; \ - d = ROTR64(d ^ a, 32); \ - c = c + d; \ - b = ROTR64(b ^ c, 24); \ - a = a + b + m[blake2b_sigma[r][2 * i + 1]]; \ - d = ROTR64(d ^ a, 16); \ - c = c + d; \ - b = ROTR64(b ^ c, 63); \ +#define G(r, i, a, b, c, d) \ + do { \ + a += b + m[blake2b_sigma[r][2 * i + 0]]; \ + d = ROTR64(d ^ a, 32); \ + c += d; \ + b = ROTR64(b ^ c, 24); \ + a += b + m[blake2b_sigma[r][2 * i + 1]]; \ + d = ROTR64(d ^ a, 16); \ + c += d; \ + b = ROTR64(b ^ c, 63); \ } while (0) #define ROUND(r) \ do { \ diff --git a/libs/libsodium/src/crypto_generichash/blake2b/ref/blake2b-compress-sse41.c b/libs/libsodium/src/crypto_generichash/blake2b/ref/blake2b-compress-sse41.c index 609ada01a0..b4a5acfbc1 100644 --- a/libs/libsodium/src/crypto_generichash/blake2b/ref/blake2b-compress-sse41.c +++ b/libs/libsodium/src/crypto_generichash/blake2b/ref/blake2b-compress-sse41.c @@ -7,20 +7,20 @@ #include "blake2.h" #include "private/common.h" -#include "private/sse2_64_32.h" #if defined(HAVE_EMMINTRIN_H) && defined(HAVE_TMMINTRIN_H) && \ defined(HAVE_SMMINTRIN_H) -# ifdef __GNUC__ -# pragma GCC target("sse2") -# pragma GCC target("ssse3") -# pragma GCC target("sse4.1") +# ifdef __clang__ +# pragma clang attribute push(__attribute__((target("sse2,ssse3,sse4.1"))), apply_to = function) +# elif defined(__GNUC__) +# pragma GCC target("sse2,ssse3,sse4.1") # endif # include # include # include +# include "private/sse2_64_32.h" # include "blake2b-compress-sse41.h" @@ -84,4 +84,8 @@ blake2b_compress_sse41(blake2b_state *S, return 0; } +# ifdef __clang__ +# pragma clang attribute pop +# endif + #endif diff --git a/libs/libsodium/src/crypto_generichash/blake2b/ref/blake2b-compress-sse41.h b/libs/libsodium/src/crypto_generichash/blake2b/ref/blake2b-compress-sse41.h index 59cc279f84..4653f094f9 100644 --- a/libs/libsodium/src/crypto_generichash/blake2b/ref/blake2b-compress-sse41.h +++ b/libs/libsodium/src/crypto_generichash/blake2b/ref/blake2b-compress-sse41.h @@ -5,6 +5,8 @@ #define LOADU(p) _mm_loadu_si128((const __m128i *) (const void *) (p)) #define STOREU(p, r) _mm_storeu_si128((__m128i *) (void *) (p), r) +#if !(defined(_mm_roti_epi64) && defined(__XOP__)) +#undef _mm_roti_epi64 #define _mm_roti_epi64(x, c) \ (-(c) == 32) \ ? _mm_shuffle_epi32((x), _MM_SHUFFLE(2, 3, 0, 1)) \ @@ -17,6 +19,7 @@ _mm_add_epi64((x), (x))) \ : _mm_xor_si128(_mm_srli_epi64((x), -(c)), \ _mm_slli_epi64((x), 64 - (-(c)))) +#endif #define G1(row1l, row2l, row3l, row4l, row1h, row2h, row3h, row4h, b0, b1) \ row1l = _mm_add_epi64(_mm_add_epi64(row1l, b0), row2l); \ diff --git a/libs/libsodium/src/crypto_generichash/blake2b/ref/blake2b-compress-ssse3.c b/libs/libsodium/src/crypto_generichash/blake2b/ref/blake2b-compress-ssse3.c index 6b9bff151c..ed55c2866b 100644 --- a/libs/libsodium/src/crypto_generichash/blake2b/ref/blake2b-compress-ssse3.c +++ b/libs/libsodium/src/crypto_generichash/blake2b/ref/blake2b-compress-ssse3.c @@ -4,17 +4,18 @@ #include "blake2.h" #include "private/common.h" -#include "private/sse2_64_32.h" #if defined(HAVE_EMMINTRIN_H) && defined(HAVE_TMMINTRIN_H) -# ifdef __GNUC__ -# pragma GCC target("sse2") -# pragma GCC target("ssse3") +# ifdef __clang__ +# pragma clang attribute push(__attribute__((target("sse2,ssse3"))), apply_to = function) +# elif defined(__GNUC__) +# pragma GCC target("sse2,ssse3") # endif # include # include +# include "private/sse2_64_32.h" # include "blake2b-compress-ssse3.h" @@ -87,4 +88,8 @@ blake2b_compress_ssse3(blake2b_state *S, return 0; } +# ifdef __clang__ +# pragma clang attribute pop +# endif + #endif diff --git a/libs/libsodium/src/crypto_generichash/blake2b/ref/blake2b-compress-ssse3.h b/libs/libsodium/src/crypto_generichash/blake2b/ref/blake2b-compress-ssse3.h index 7bee1a12b2..93a90dbfb9 100644 --- a/libs/libsodium/src/crypto_generichash/blake2b/ref/blake2b-compress-ssse3.h +++ b/libs/libsodium/src/crypto_generichash/blake2b/ref/blake2b-compress-ssse3.h @@ -5,6 +5,8 @@ #define LOADU(p) _mm_loadu_si128((const __m128i *) (const void *) (p)) #define STOREU(p, r) _mm_storeu_si128((__m128i *) (void *) (p), r) +#if !(defined(_mm_roti_epi64) && defined(__XOP__)) +#undef _mm_roti_epi64 #define _mm_roti_epi64(x, c) \ (-(c) == 32) \ ? _mm_shuffle_epi32((x), _MM_SHUFFLE(2, 3, 0, 1)) \ @@ -17,6 +19,7 @@ _mm_add_epi64((x), (x))) \ : _mm_xor_si128(_mm_srli_epi64((x), -(c)), \ _mm_slli_epi64((x), 64 - (-(c)))) +#endif #define G1(row1l, row2l, row3l, row4l, row1h, row2h, row3h, row4h, b0, b1) \ row1l = _mm_add_epi64(_mm_add_epi64(row1l, b0), row2l); \ diff --git a/libs/libsodium/src/crypto_generichash/blake2b/ref/blake2b-load-avx2.h b/libs/libsodium/src/crypto_generichash/blake2b/ref/blake2b-load-avx2.h index 217a522626..17d6b92289 100644 --- a/libs/libsodium/src/crypto_generichash/blake2b/ref/blake2b-load-avx2.h +++ b/libs/libsodium/src/crypto_generichash/blake2b/ref/blake2b-load-avx2.h @@ -17,15 +17,15 @@ #define BLAKE2B_LOAD_MSG_0_3(b0) \ do { \ - t0 = _mm256_unpacklo_epi64(m4, m5); \ - t1 = _mm256_unpacklo_epi64(m6, m7); \ + t0 = _mm256_unpacklo_epi64(m7, m4); \ + t1 = _mm256_unpacklo_epi64(m5, m6); \ b0 = _mm256_blend_epi32(t0, t1, 0xF0); \ } while (0) #define BLAKE2B_LOAD_MSG_0_4(b0) \ do { \ - t0 = _mm256_unpackhi_epi64(m4, m5); \ - t1 = _mm256_unpackhi_epi64(m6, m7); \ + t0 = _mm256_unpackhi_epi64(m7, m4); \ + t1 = _mm256_unpackhi_epi64(m5, m6); \ b0 = _mm256_blend_epi32(t0, t1, 0xF0); \ } while (0) @@ -43,17 +43,17 @@ b0 = _mm256_blend_epi32(t0, t1, 0xF0); \ } while (0) -#define BLAKE2B_LOAD_MSG_1_3(b0) \ - do { \ - t0 = _mm256_shuffle_epi32(m0, _MM_SHUFFLE(1, 0, 3, 2)); \ - t1 = _mm256_unpackhi_epi64(m5, m2); \ - b0 = _mm256_blend_epi32(t0, t1, 0xF0); \ +#define BLAKE2B_LOAD_MSG_1_3(b0) \ + do { \ + t0 = _mm256_unpackhi_epi64(m2, m0); \ + t1 = _mm256_blend_epi32(m5, m0, 0x33); \ + b0 = _mm256_blend_epi32(t0, t1, 0xF0); \ } while (0) #define BLAKE2B_LOAD_MSG_1_4(b0) \ do { \ - t0 = _mm256_unpacklo_epi64(m6, m1); \ - t1 = _mm256_unpackhi_epi64(m3, m1); \ + t0 = _mm256_alignr_epi8(m6, m1, 8); \ + t1 = _mm256_blend_epi32(m3, m1, 0x33); \ b0 = _mm256_blend_epi32(t0, t1, 0xF0); \ } while (0) @@ -73,15 +73,15 @@ #define BLAKE2B_LOAD_MSG_2_3(b0) \ do { \ - t0 = _mm256_blend_epi32(m1, m5, 0x33); \ - t1 = _mm256_unpackhi_epi64(m3, m4); \ + t0 = _mm256_alignr_epi8(m5, m4, 8); \ + t1 = _mm256_unpackhi_epi64(m1, m3); \ b0 = _mm256_blend_epi32(t0, t1, 0xF0); \ } while (0) #define BLAKE2B_LOAD_MSG_2_4(b0) \ do { \ - t0 = _mm256_unpacklo_epi64(m7, m3); \ - t1 = _mm256_alignr_epi8(m2, m0, 8); \ + t0 = _mm256_unpacklo_epi64(m2, m7); \ + t1 = _mm256_blend_epi32(m0, m3, 0x33); \ b0 = _mm256_blend_epi32(t0, t1, 0xF0); \ } while (0) @@ -99,17 +99,17 @@ b0 = _mm256_blend_epi32(t0, t1, 0xF0); \ } while (0) -#define BLAKE2B_LOAD_MSG_3_3(b0) \ - do { \ - t0 = _mm256_blend_epi32(m2, m1, 0x33); \ - t1 = _mm256_blend_epi32(m7, m2, 0x33); \ - b0 = _mm256_blend_epi32(t0, t1, 0xF0); \ +#define BLAKE2B_LOAD_MSG_3_3(b0) \ + do { \ + t0 = _mm256_alignr_epi8(m1, m7, 8); \ + t1 = _mm256_shuffle_epi32(m2, _MM_SHUFFLE(1, 0, 3, 2)); \ + b0 = _mm256_blend_epi32(t0, t1, 0xF0); \ } while (0) #define BLAKE2B_LOAD_MSG_3_4(b0) \ do { \ - t0 = _mm256_unpacklo_epi64(m3, m5); \ - t1 = _mm256_unpacklo_epi64(m0, m4); \ + t0 = _mm256_unpacklo_epi64(m4, m3); \ + t1 = _mm256_unpacklo_epi64(m5, m0); \ b0 = _mm256_blend_epi32(t0, t1, 0xF0); \ } while (0) @@ -129,15 +129,15 @@ #define BLAKE2B_LOAD_MSG_4_3(b0) \ do { \ - t0 = _mm256_blend_epi32(m5, m7, 0x33); \ - t1 = _mm256_blend_epi32(m1, m3, 0x33); \ + t0 = _mm256_alignr_epi8(m7, m1, 8); \ + t1 = _mm256_alignr_epi8(m3, m5, 8); \ b0 = _mm256_blend_epi32(t0, t1, 0xF0); \ } while (0) #define BLAKE2B_LOAD_MSG_4_4(b0) \ do { \ - t0 = _mm256_alignr_epi8(m6, m0, 8); \ - t1 = _mm256_blend_epi32(m6, m4, 0x33); \ + t0 = _mm256_unpackhi_epi64(m6, m0); \ + t1 = _mm256_unpacklo_epi64(m6, m4); \ b0 = _mm256_blend_epi32(t0, t1, 0xF0); \ } while (0) @@ -157,15 +157,15 @@ #define BLAKE2B_LOAD_MSG_5_3(b0) \ do { \ - t0 = _mm256_blend_epi32(m3, m2, 0x33); \ - t1 = _mm256_unpackhi_epi64(m7, m0); \ + t0 = _mm256_alignr_epi8(m2, m0, 8); \ + t1 = _mm256_unpackhi_epi64(m3, m7); \ b0 = _mm256_blend_epi32(t0, t1, 0xF0); \ } while (0) #define BLAKE2B_LOAD_MSG_5_4(b0) \ do { \ - t0 = _mm256_unpackhi_epi64(m6, m2); \ - t1 = _mm256_blend_epi32(m4, m7, 0x33); \ + t0 = _mm256_unpackhi_epi64(m4, m6); \ + t1 = _mm256_alignr_epi8(m7, m2, 8); \ b0 = _mm256_blend_epi32(t0, t1, 0xF0); \ } while (0) @@ -183,20 +183,20 @@ b0 = _mm256_blend_epi32(t0, t1, 0xF0); \ } while (0) -#define BLAKE2B_LOAD_MSG_6_3(b0) \ - do { \ - t0 = _mm256_unpacklo_epi64(m0, m3); \ - t1 = _mm256_shuffle_epi32(m4, _MM_SHUFFLE(1, 0, 3, 2)); \ - b0 = _mm256_blend_epi32(t0, t1, 0xF0); \ - } while (0) - -#define BLAKE2B_LOAD_MSG_6_4(b0) \ +#define BLAKE2B_LOAD_MSG_6_3(b0) \ do { \ - t0 = _mm256_unpackhi_epi64(m3, m1); \ - t1 = _mm256_blend_epi32(m5, m1, 0x33); \ + t0 = _mm256_unpacklo_epi64(m4, m0); \ + t1 = _mm256_blend_epi32(m4, m3, 0x33); \ b0 = _mm256_blend_epi32(t0, t1, 0xF0); \ } while (0) +#define BLAKE2B_LOAD_MSG_6_4(b0) \ + do { \ + t0 = _mm256_unpackhi_epi64(m5, m3); \ + t1 = _mm256_shuffle_epi32(m1, _MM_SHUFFLE(1, 0, 3, 2)); \ + b0 = _mm256_blend_epi32(t0, t1, 0xF0); \ + } while (0) + #define BLAKE2B_LOAD_MSG_7_1(b0) \ do { \ t0 = _mm256_unpackhi_epi64(m6, m3); \ @@ -213,15 +213,15 @@ #define BLAKE2B_LOAD_MSG_7_3(b0) \ do { \ - t0 = _mm256_unpackhi_epi64(m2, m7); \ - t1 = _mm256_unpacklo_epi64(m4, m1); \ + t0 = _mm256_blend_epi32(m2, m1, 0x33); \ + t1 = _mm256_alignr_epi8(m4, m7, 8); \ b0 = _mm256_blend_epi32(t0, t1, 0xF0); \ } while (0) #define BLAKE2B_LOAD_MSG_7_4(b0) \ do { \ - t0 = _mm256_unpacklo_epi64(m0, m2); \ - t1 = _mm256_unpacklo_epi64(m3, m5); \ + t0 = _mm256_unpacklo_epi64(m5, m0); \ + t1 = _mm256_unpacklo_epi64(m2, m3); \ b0 = _mm256_blend_epi32(t0, t1, 0xF0); \ } while (0) @@ -241,15 +241,15 @@ #define BLAKE2B_LOAD_MSG_8_3(b0) \ do { \ - t0 = m6; \ - t1 = _mm256_alignr_epi8(m5, m0, 8); \ + t0 = _mm256_unpacklo_epi64(m5, m6); \ + t1 = _mm256_unpackhi_epi64(m6, m0); \ b0 = _mm256_blend_epi32(t0, t1, 0xF0); \ } while (0) #define BLAKE2B_LOAD_MSG_8_4(b0) \ do { \ - t0 = _mm256_blend_epi32(m3, m1, 0x33); \ - t1 = m2; \ + t0 = _mm256_alignr_epi8(m1, m2, 8); \ + t1 = _mm256_alignr_epi8(m2, m3, 8); \ b0 = _mm256_blend_epi32(t0, t1, 0xF0); \ } while (0) @@ -269,15 +269,15 @@ #define BLAKE2B_LOAD_MSG_9_3(b0) \ do { \ - t0 = _mm256_unpackhi_epi64(m7, m4); \ - t1 = _mm256_unpackhi_epi64(m1, m6); \ + t0 = _mm256_unpackhi_epi64(m6, m7); \ + t1 = _mm256_unpackhi_epi64(m4, m1); \ b0 = _mm256_blend_epi32(t0, t1, 0xF0); \ } while (0) #define BLAKE2B_LOAD_MSG_9_4(b0) \ do { \ - t0 = _mm256_alignr_epi8(m7, m5, 8); \ - t1 = _mm256_unpacklo_epi64(m6, m0); \ + t0 = _mm256_blend_epi32(m5, m0, 0x33); \ + t1 = _mm256_unpacklo_epi64(m7, m6); \ b0 = _mm256_blend_epi32(t0, t1, 0xF0); \ } while (0) @@ -297,15 +297,15 @@ #define BLAKE2B_LOAD_MSG_10_3(b0) \ do { \ - t0 = _mm256_unpacklo_epi64(m4, m5); \ - t1 = _mm256_unpacklo_epi64(m6, m7); \ + t0 = _mm256_unpacklo_epi64(m7, m4); \ + t1 = _mm256_unpacklo_epi64(m5, m6); \ b0 = _mm256_blend_epi32(t0, t1, 0xF0); \ } while (0) #define BLAKE2B_LOAD_MSG_10_4(b0) \ do { \ - t0 = _mm256_unpackhi_epi64(m4, m5); \ - t1 = _mm256_unpackhi_epi64(m6, m7); \ + t0 = _mm256_unpackhi_epi64(m7, m4); \ + t1 = _mm256_unpackhi_epi64(m5, m6); \ b0 = _mm256_blend_epi32(t0, t1, 0xF0); \ } while (0) @@ -323,17 +323,17 @@ b0 = _mm256_blend_epi32(t0, t1, 0xF0); \ } while (0) -#define BLAKE2B_LOAD_MSG_11_3(b0) \ - do { \ - t0 = _mm256_shuffle_epi32(m0, _MM_SHUFFLE(1, 0, 3, 2)); \ - t1 = _mm256_unpackhi_epi64(m5, m2); \ - b0 = _mm256_blend_epi32(t0, t1, 0xF0); \ +#define BLAKE2B_LOAD_MSG_11_3(b0) \ + do { \ + t0 = _mm256_unpackhi_epi64(m2, m0); \ + t1 = _mm256_blend_epi32(m5, m0, 0x33); \ + b0 = _mm256_blend_epi32(t0, t1, 0xF0); \ } while (0) #define BLAKE2B_LOAD_MSG_11_4(b0) \ do { \ - t0 = _mm256_unpacklo_epi64(m6, m1); \ - t1 = _mm256_unpackhi_epi64(m3, m1); \ + t0 = _mm256_alignr_epi8(m6, m1, 8); \ + t1 = _mm256_blend_epi32(m3, m1, 0x33); \ b0 = _mm256_blend_epi32(t0, t1, 0xF0); \ } while (0) diff --git a/libs/libsodium/src/crypto_hash/sha256/cp/hash_sha256_cp.c b/libs/libsodium/src/crypto_hash/sha256/cp/hash_sha256_cp.c index 3b1acda992..ee1d4ceb27 100644 --- a/libs/libsodium/src/crypto_hash/sha256/cp/hash_sha256_cp.c +++ b/libs/libsodium/src/crypto_hash/sha256/cp/hash_sha256_cp.c @@ -156,6 +156,7 @@ SHA256_Pad(crypto_hash_sha256_state *state, uint32_t tmp32[64 + 8]) unsigned int r; unsigned int i; + ACQUIRE_FENCE; r = (unsigned int) ((state->count >> 3) & 0x3f); if (r < 56) { for (i = 0; i < 56 - r; i++) { @@ -197,6 +198,7 @@ crypto_hash_sha256_update(crypto_hash_sha256_state *state, if (inlen <= 0U) { return 0; } + ACQUIRE_FENCE; r = (unsigned long long) ((state->count >> 3) & 0x3f); state->count += ((uint64_t) inlen) << 3; diff --git a/libs/libsodium/src/crypto_hash/sha512/cp/hash_sha512_cp.c b/libs/libsodium/src/crypto_hash/sha512/cp/hash_sha512_cp.c index 4f342afdb6..8207a440ba 100644 --- a/libs/libsodium/src/crypto_hash/sha512/cp/hash_sha512_cp.c +++ b/libs/libsodium/src/crypto_hash/sha512/cp/hash_sha512_cp.c @@ -175,6 +175,7 @@ SHA512_Pad(crypto_hash_sha512_state *state, uint64_t tmp64[80 + 8]) unsigned int r; unsigned int i; + ACQUIRE_FENCE; r = (unsigned int) ((state->count[1] >> 3) & 0x7f); if (r < 112) { for (i = 0; i < 112 - r; i++) { @@ -218,6 +219,7 @@ crypto_hash_sha512_update(crypto_hash_sha512_state *state, if (inlen <= 0U) { return 0; } + ACQUIRE_FENCE; r = (unsigned long long) ((state->count[1] >> 3) & 0x7f); bitlen[1] = ((uint64_t) inlen) << 3; diff --git a/libs/libsodium/src/crypto_kdf/hkdf/kdf_hkdf_sha256.c b/libs/libsodium/src/crypto_kdf/hkdf/kdf_hkdf_sha256.c new file mode 100644 index 0000000000..f1b369e969 --- /dev/null +++ b/libs/libsodium/src/crypto_kdf/hkdf/kdf_hkdf_sha256.c @@ -0,0 +1,123 @@ +#include +#include + +#include "crypto_auth_hmacsha256.h" +#include "crypto_kdf.h" +#include "crypto_kdf_hkdf_sha256.h" +#include "randombytes.h" +#include "utils.h" + +int +crypto_kdf_hkdf_sha256_extract_init(crypto_kdf_hkdf_sha256_state *state, + const unsigned char *salt, size_t salt_len) +{ + return crypto_auth_hmacsha256_init(&state->st, salt, salt_len); +} + +int +crypto_kdf_hkdf_sha256_extract_update(crypto_kdf_hkdf_sha256_state *state, + const unsigned char *ikm, size_t ikm_len) +{ + return crypto_auth_hmacsha256_update(&state->st, ikm, ikm_len); +} + +int +crypto_kdf_hkdf_sha256_extract_final(crypto_kdf_hkdf_sha256_state *state, + unsigned char prk[crypto_kdf_hkdf_sha256_KEYBYTES]) +{ + crypto_auth_hmacsha256_final(&state->st, prk); + sodium_memzero(state, sizeof *state); + + return 0; +} + +int +crypto_kdf_hkdf_sha256_extract( + unsigned char prk[crypto_kdf_hkdf_sha256_KEYBYTES], + const unsigned char *salt, size_t salt_len, const unsigned char *ikm, + size_t ikm_len) +{ + crypto_kdf_hkdf_sha256_state state; + + crypto_kdf_hkdf_sha256_extract_init(&state, salt, salt_len); + crypto_kdf_hkdf_sha256_extract_update(&state, ikm, ikm_len); + + return crypto_kdf_hkdf_sha256_extract_final(&state, prk); +} + +void +crypto_kdf_hkdf_sha256_keygen(unsigned char prk[crypto_kdf_hkdf_sha256_KEYBYTES]) +{ + randombytes_buf(prk, crypto_kdf_hkdf_sha256_KEYBYTES); +} + +int +crypto_kdf_hkdf_sha256_expand(unsigned char *out, size_t out_len, + const char *ctx, size_t ctx_len, + const unsigned char prk[crypto_kdf_hkdf_sha256_KEYBYTES]) +{ + crypto_auth_hmacsha256_state st; + unsigned char tmp[crypto_auth_hmacsha256_BYTES]; + size_t i; + size_t left; + unsigned char counter = 1U; + + if (out_len > crypto_kdf_hkdf_sha256_BYTES_MAX) { + errno = EINVAL; + return -1; + } + for (i = (size_t) 0U; i + crypto_auth_hmacsha256_BYTES <= out_len; + i += crypto_auth_hmacsha256_BYTES) { + crypto_auth_hmacsha256_init(&st, prk, crypto_kdf_hkdf_sha256_KEYBYTES); + if (i != (size_t) 0U) { + crypto_auth_hmacsha256_update(&st, + &out[i - crypto_auth_hmacsha256_BYTES], + crypto_auth_hmacsha256_BYTES); + } + crypto_auth_hmacsha256_update(&st, + (const unsigned char *) ctx, ctx_len); + crypto_auth_hmacsha256_update(&st, &counter, (size_t) 1U); + crypto_auth_hmacsha256_final(&st, &out[i]); + counter++; + } + if ((left = out_len & (crypto_auth_hmacsha256_BYTES - 1U)) != (size_t) 0U) { + crypto_auth_hmacsha256_init(&st, prk, crypto_kdf_hkdf_sha256_KEYBYTES); + if (i != (size_t) 0U) { + crypto_auth_hmacsha256_update(&st, + &out[i - crypto_auth_hmacsha256_BYTES], + crypto_auth_hmacsha256_BYTES); + } + crypto_auth_hmacsha256_update(&st, + (const unsigned char *) ctx, ctx_len); + crypto_auth_hmacsha256_update(&st, &counter, (size_t) 1U); + crypto_auth_hmacsha256_final(&st, tmp); + memcpy(&out[i], tmp, left); + sodium_memzero(tmp, sizeof tmp); + } + sodium_memzero(&st, sizeof st); + + return 0; +} + +size_t +crypto_kdf_hkdf_sha256_keybytes(void) +{ + return crypto_kdf_hkdf_sha256_KEYBYTES; +} + +size_t +crypto_kdf_hkdf_sha256_bytes_min(void) +{ + return crypto_kdf_hkdf_sha256_BYTES_MIN; +} + +size_t +crypto_kdf_hkdf_sha256_bytes_max(void) +{ + return crypto_kdf_hkdf_sha256_BYTES_MAX; +} + +size_t crypto_kdf_hkdf_sha256_statebytes(void) +{ + return sizeof(crypto_kdf_hkdf_sha256_state); +} diff --git a/libs/libsodium/src/crypto_kdf/hkdf/kdf_hkdf_sha512.c b/libs/libsodium/src/crypto_kdf/hkdf/kdf_hkdf_sha512.c new file mode 100644 index 0000000000..a4144e2d77 --- /dev/null +++ b/libs/libsodium/src/crypto_kdf/hkdf/kdf_hkdf_sha512.c @@ -0,0 +1,123 @@ +#include +#include + +#include "crypto_auth_hmacsha512.h" +#include "crypto_kdf.h" +#include "crypto_kdf_hkdf_sha512.h" +#include "randombytes.h" +#include "utils.h" + +int +crypto_kdf_hkdf_sha512_extract_init(crypto_kdf_hkdf_sha512_state *state, + const unsigned char *salt, size_t salt_len) +{ + return crypto_auth_hmacsha512_init(&state->st, salt, salt_len); +} + +int +crypto_kdf_hkdf_sha512_extract_update(crypto_kdf_hkdf_sha512_state *state, + const unsigned char *ikm, size_t ikm_len) +{ + return crypto_auth_hmacsha512_update(&state->st, ikm, ikm_len); +} + +int +crypto_kdf_hkdf_sha512_extract_final(crypto_kdf_hkdf_sha512_state *state, + unsigned char prk[crypto_kdf_hkdf_sha512_KEYBYTES]) +{ + crypto_auth_hmacsha512_final(&state->st, prk); + sodium_memzero(state, sizeof *state); + + return 0; +} + +int +crypto_kdf_hkdf_sha512_extract( + unsigned char prk[crypto_kdf_hkdf_sha512_KEYBYTES], + const unsigned char *salt, size_t salt_len, const unsigned char *ikm, + size_t ikm_len) +{ + crypto_kdf_hkdf_sha512_state state; + + crypto_kdf_hkdf_sha512_extract_init(&state, salt, salt_len); + crypto_kdf_hkdf_sha512_extract_update(&state, ikm, ikm_len); + + return crypto_kdf_hkdf_sha512_extract_final(&state, prk); +} + +void +crypto_kdf_hkdf_sha512_keygen(unsigned char prk[crypto_kdf_hkdf_sha512_KEYBYTES]) +{ + randombytes_buf(prk, crypto_kdf_hkdf_sha512_KEYBYTES); +} + +int +crypto_kdf_hkdf_sha512_expand(unsigned char *out, size_t out_len, + const char *ctx, size_t ctx_len, + const unsigned char prk[crypto_kdf_hkdf_sha512_KEYBYTES]) +{ + crypto_auth_hmacsha512_state st; + unsigned char tmp[crypto_auth_hmacsha512_BYTES]; + size_t i; + size_t left; + unsigned char counter = 1U; + + if (out_len > crypto_kdf_hkdf_sha512_BYTES_MAX) { + errno = EINVAL; + return -1; + } + for (i = (size_t) 0U; i + crypto_auth_hmacsha512_BYTES <= out_len; + i += crypto_auth_hmacsha512_BYTES) { + crypto_auth_hmacsha512_init(&st, prk, crypto_kdf_hkdf_sha512_KEYBYTES); + if (i != (size_t) 0U) { + crypto_auth_hmacsha512_update(&st, + &out[i - crypto_auth_hmacsha512_BYTES], + crypto_auth_hmacsha512_BYTES); + } + crypto_auth_hmacsha512_update(&st, + (const unsigned char *) ctx, ctx_len); + crypto_auth_hmacsha512_update(&st, &counter, (size_t) 1U); + crypto_auth_hmacsha512_final(&st, &out[i]); + counter++; + } + if ((left = out_len & (crypto_auth_hmacsha512_BYTES - 1U)) != (size_t) 0U) { + crypto_auth_hmacsha512_init(&st, prk, crypto_kdf_hkdf_sha512_KEYBYTES); + if (i != (size_t) 0U) { + crypto_auth_hmacsha512_update(&st, + &out[i - crypto_auth_hmacsha512_BYTES], + crypto_auth_hmacsha512_BYTES); + } + crypto_auth_hmacsha512_update(&st, + (const unsigned char *) ctx, ctx_len); + crypto_auth_hmacsha512_update(&st, &counter, (size_t) 1U); + crypto_auth_hmacsha512_final(&st, tmp); + memcpy(&out[i], tmp, left); + sodium_memzero(tmp, sizeof tmp); + } + sodium_memzero(&st, sizeof st); + + return 0; +} + +size_t +crypto_kdf_hkdf_sha512_keybytes(void) +{ + return crypto_kdf_hkdf_sha512_KEYBYTES; +} + +size_t +crypto_kdf_hkdf_sha512_bytes_min(void) +{ + return crypto_kdf_hkdf_sha512_BYTES_MIN; +} + +size_t +crypto_kdf_hkdf_sha512_bytes_max(void) +{ + return crypto_kdf_hkdf_sha512_BYTES_MAX; +} + +size_t crypto_kdf_hkdf_sha512_statebytes(void) +{ + return sizeof(crypto_kdf_hkdf_sha512_state); +} diff --git a/libs/libsodium/src/crypto_onetimeauth/poly1305/donna/poly1305_donna32.h b/libs/libsodium/src/crypto_onetimeauth/poly1305/donna/poly1305_donna32.h index f6d62e53b9..b2ce5679d3 100644 --- a/libs/libsodium/src/crypto_onetimeauth/poly1305/donna/poly1305_donna32.h +++ b/libs/libsodium/src/crypto_onetimeauth/poly1305/donna/poly1305_donna32.h @@ -122,7 +122,7 @@ poly1305_blocks(poly1305_state_internal_t *st, const unsigned char *m, h4 = (unsigned long) d4 & 0x3ffffff; h0 += c * 5; c = (h0 >> 26); - h0 = h0 & 0x3ffffff; + h0 &= 0x3ffffff; h1 += c; m += poly1305_block_size; diff --git a/libs/libsodium/src/crypto_onetimeauth/poly1305/donna/poly1305_donna64.h b/libs/libsodium/src/crypto_onetimeauth/poly1305/donna/poly1305_donna64.h index ae79f637e0..160e6e4ace 100644 --- a/libs/libsodium/src/crypto_onetimeauth/poly1305/donna/poly1305_donna64.h +++ b/libs/libsodium/src/crypto_onetimeauth/poly1305/donna/poly1305_donna64.h @@ -41,7 +41,7 @@ poly1305_init(poly1305_state_internal_t *st, const unsigned char key[32]) t1 = LOAD64_LE(&key[8]); /* wiped after finalization */ - st->r[0] = (t0) &0xffc0fffffff; + st->r[0] = (t0) & 0xffc0fffffff; st->r[1] = ((t0 >> 44) | (t1 << 20)) & 0xfffffc0ffff; st->r[2] = ((t1 >> 24)) & 0x00ffffffc0f; @@ -88,8 +88,8 @@ poly1305_blocks(poly1305_state_internal_t *st, const unsigned char *m, t0 = LOAD64_LE(&m[0]); t1 = LOAD64_LE(&m[8]); - h0 += ((t0) &0xfffffffffff); - h1 += (((t0 >> 44) | (t1 << 20)) & 0xfffffffffff); + h0 += t0 & 0xfffffffffff; + h1 += ((t0 >> 44) | (t1 << 20)) & 0xfffffffffff; h2 += (((t1 >> 24)) & 0x3ffffffffff) | hibit; /* h *= r */ @@ -120,7 +120,7 @@ poly1305_blocks(poly1305_state_internal_t *st, const unsigned char *m, h2 = LO(d2) & 0x3ffffffffff; h0 += c * 5; c = (h0 >> 44); - h0 = h0 & 0xfffffffffff; + h0 &= 0xfffffffffff; h1 += c; m += poly1305_block_size; @@ -138,6 +138,7 @@ poly1305_finish(poly1305_state_internal_t *st, unsigned char mac[16]) unsigned long long h0, h1, h2, c; unsigned long long g0, g1, g2; unsigned long long t0, t1; + unsigned long long mask; /* process the remaining block */ if (st->leftover) { @@ -157,49 +158,49 @@ poly1305_finish(poly1305_state_internal_t *st, unsigned char mac[16]) h1 = st->h[1]; h2 = st->h[2]; - c = (h1 >> 44); + c = h1 >> 44; h1 &= 0xfffffffffff; h2 += c; - c = (h2 >> 42); + c = h2 >> 42; h2 &= 0x3ffffffffff; h0 += c * 5; - c = (h0 >> 44); + c = h0 >> 44; h0 &= 0xfffffffffff; h1 += c; - c = (h1 >> 44); + c = h1 >> 44; h1 &= 0xfffffffffff; h2 += c; - c = (h2 >> 42); + c = h2 >> 42; h2 &= 0x3ffffffffff; h0 += c * 5; - c = (h0 >> 44); + c = h0 >> 44; h0 &= 0xfffffffffff; h1 += c; /* compute h + -p */ g0 = h0 + 5; - c = (g0 >> 44); + c = g0 >> 44; g0 &= 0xfffffffffff; g1 = h1 + c; - c = (g1 >> 44); + c = g1 >> 44; g1 &= 0xfffffffffff; g2 = h2 + c - (1ULL << 42); /* select h if h < p, or h + -p if h >= p */ - c = (g2 >> ((sizeof(unsigned long long) * 8) - 1)) - 1; - g0 &= c; - g1 &= c; - g2 &= c; - c = ~c; - h0 = (h0 & c) | g0; - h1 = (h1 & c) | g1; - h2 = (h2 & c) | g2; + mask = (g2 >> ((sizeof(unsigned long long) * 8) - 1)) - 1; + g0 &= mask; + g1 &= mask; + g2 &= mask; + mask = ~mask; + h0 = (h0 & mask) | g0; + h1 = (h1 & mask) | g1; + h2 = (h2 & mask) | g2; /* h = (h + pad) */ t0 = st->pad[0]; t1 = st->pad[1]; - h0 += ((t0) &0xfffffffffff); + h0 += ((t0) & 0xfffffffffff); c = (h0 >> 44); h0 &= 0xfffffffffff; h1 += (((t0 >> 44) | (t1 << 20)) & 0xfffffffffff) + c; @@ -209,8 +210,8 @@ poly1305_finish(poly1305_state_internal_t *st, unsigned char mac[16]) h2 &= 0x3ffffffffff; /* mac = h % (2^128) */ - h0 = ((h0) | (h1 << 44)); - h1 = ((h1 >> 20) | (h2 << 24)); + h0 = (h0) | (h1 << 44); + h1 = (h1 >> 20) | (h2 << 24); STORE64_LE(&mac[0], h0); STORE64_LE(&mac[8], h1); diff --git a/libs/libsodium/src/crypto_onetimeauth/poly1305/sse2/poly1305_sse2.c b/libs/libsodium/src/crypto_onetimeauth/poly1305/sse2/poly1305_sse2.c index 77b3862026..53e7c34f43 100644 --- a/libs/libsodium/src/crypto_onetimeauth/poly1305/sse2/poly1305_sse2.c +++ b/libs/libsodium/src/crypto_onetimeauth/poly1305/sse2/poly1305_sse2.c @@ -6,16 +6,18 @@ #include "crypto_verify_16.h" #include "poly1305_sse2.h" #include "private/common.h" -#include "private/sse2_64_32.h" #include "utils.h" #if defined(HAVE_TI_MODE) && defined(HAVE_EMMINTRIN_H) -# ifdef __GNUC__ +# ifdef __clang__ +# pragma clang attribute push(__attribute__((target("sse2"))), apply_to = function) +# elif defined(__GNUC__) # pragma GCC target("sse2") # endif # include +# include "private/sse2_64_32.h" typedef __m128i xmmi; @@ -41,14 +43,14 @@ typedef struct poly1305_state_internal_t { union { uint64_t h[3]; uint32_t hh[10]; - } H; /* 40 bytes */ - uint32_t R[5]; /* 20 bytes */ - uint32_t R2[5]; /* 20 bytes */ - uint32_t R4[5]; /* 20 bytes */ - uint64_t pad[2]; /* 16 bytes */ - uint64_t flags; /* 8 bytes */ - unsigned long long leftover; /* 8 bytes */ - unsigned char buffer[poly1305_block_size]; /* 32 bytes */ + } H; /* 40 bytes */ + uint32_t R[5]; /* 20 bytes */ + uint32_t R2[5]; /* 20 bytes */ + uint32_t R4[5]; /* 20 bytes */ + uint64_t pad[2]; /* 16 bytes */ + uint64_t flags; /* 8 bytes */ + unsigned long long leftover; /* 8 bytes */ + unsigned char buffer[poly1305_block_size]; /* 32 bytes */ } poly1305_state_internal_t; /* 164 bytes total */ /* @@ -946,4 +948,8 @@ struct crypto_onetimeauth_poly1305_implementation SODIUM_C99(.onetimeauth_final =) crypto_onetimeauth_poly1305_sse2_final }; +#ifdef __clang__ +# pragma clang attribute pop +#endif + #endif diff --git a/libs/libsodium/src/crypto_pwhash/argon2/argon2-core.c b/libs/libsodium/src/crypto_pwhash/argon2/argon2-core.c index 893dcd5985..ee09450ca6 100644 --- a/libs/libsodium/src/crypto_pwhash/argon2/argon2-core.c +++ b/libs/libsodium/src/crypto_pwhash/argon2/argon2-core.c @@ -35,13 +35,17 @@ # define MAP_ANON MAP_ANONYMOUS #endif #ifndef MAP_NOCORE -# define MAP_NOCORE 0 +# ifdef MAP_CONCEAL +# define MAP_NOCORE MAP_CONCEAL +# else +# define MAP_NOCORE 0 +# endif #endif #ifndef MAP_POPULATE # define MAP_POPULATE 0 #endif -static fill_segment_fn fill_segment = fill_segment_ref; +static fill_segment_fn fill_segment = argon2_fill_segment_ref; static void load_block(block *dst, const void *input) @@ -72,7 +76,7 @@ static int allocate_memory(block_region **region, uint32_t m_cost); static int allocate_memory(block_region **region, uint32_t m_cost) { - void * base; + void *base; block *memory; size_t memory_size; @@ -95,12 +99,12 @@ allocate_memory(block_region **region, uint32_t m_cost) -1, 0)) == MAP_FAILED) { base = NULL; /* LCOV_EXCL_LINE */ } /* LCOV_EXCL_LINE */ - memcpy(&memory, &base, sizeof memory); + memory = (block *) base; #elif defined(HAVE_POSIX_MEMALIGN) if ((errno = posix_memalign((void **) &base, 64, memory_size)) != 0) { base = NULL; } - memcpy(&memory, &base, sizeof memory); + memory = (block *) base; #else memory = NULL; if (memory_size + 63 < memory_size) { @@ -109,13 +113,15 @@ allocate_memory(block_region **region, uint32_t m_cost) } else if ((base = malloc(memory_size + 63)) != NULL) { uint8_t *aligned = ((uint8_t *) base) + 63; aligned -= (uintptr_t) aligned & 63; - memcpy(&memory, &aligned, sizeof memory); + memory = (block *) aligned; } #endif if (base == NULL) { + /* LCOV_EXCL_START */ free(*region); *region = NULL; - return ARGON2_MEMORY_ALLOCATION_ERROR; /* LCOV_EXCL_LINE */ + return ARGON2_MEMORY_ALLOCATION_ERROR; + /* LCOV_EXCL_STOP */ } (*region)->base = base; (*region)->memory = memory; @@ -126,29 +132,6 @@ allocate_memory(block_region **region, uint32_t m_cost) /*********Memory functions*/ -/* Clears memory - * @param instance pointer to the current instance - * @param clear_memory indicates if we clear the memory with zeros. - */ -static void clear_memory(argon2_instance_t *instance, int clear); - -static void -clear_memory(argon2_instance_t *instance, int clear) -{ - /* LCOV_EXCL_START */ - if (clear) { - if (instance->region != NULL) { - sodium_memzero(instance->region->memory, - sizeof(block) * instance->memory_blocks); - } - if (instance->pseudo_rands != NULL) { - sodium_memzero(instance->pseudo_rands, - sizeof(uint64_t) * instance->segment_length); - } - } - /* LCOV_EXCL_STOP */ -} - /* Deallocates memory * @param memory pointer to the blocks */ @@ -157,7 +140,7 @@ static void free_memory(block_region *region); static void free_memory(block_region *region) { - if (region && region->base) { + if (region != NULL && region->base != NULL) { #if defined(MAP_ANON) && defined(HAVE_MMAP) if (munmap(region->base, region->size)) { return; /* LCOV_EXCL_LINE */ @@ -169,12 +152,9 @@ free_memory(block_region *region) free(region); } -void -free_instance(argon2_instance_t *instance, int flags) +static void +argon2_free_instance(argon2_instance_t *instance, int flags) { - /* Clear memory */ - clear_memory(instance, flags & ARGON2_FLAG_CLEAR_MEMORY); - /* Deallocate the memory */ free(instance->pseudo_rands); instance->pseudo_rands = NULL; @@ -183,7 +163,7 @@ free_instance(argon2_instance_t *instance, int flags) } void -finalize(const argon2_context *context, argon2_instance_t *instance) +argon2_finalize(const argon2_context *context, argon2_instance_t *instance) { if (context != NULL && instance != NULL) { block blockhash; @@ -212,12 +192,12 @@ finalize(const argon2_context *context, argon2_instance_t *instance) ARGON2_BLOCK_SIZE); /* clear blockhash_bytes */ } - free_instance(instance, context->flags); + argon2_free_instance(instance, context->flags); } } void -fill_memory_blocks(argon2_instance_t *instance, uint32_t pass) +argon2_fill_memory_blocks(argon2_instance_t *instance, uint32_t pass) { argon2_position_t position; uint32_t l; @@ -239,7 +219,7 @@ fill_memory_blocks(argon2_instance_t *instance, uint32_t pass) } int -validate_inputs(const argon2_context *context) +argon2_validate_inputs(const argon2_context *context) { /* LCOV_EXCL_START */ if (NULL == context) { @@ -319,6 +299,15 @@ validate_inputs(const argon2_context *context) } } + /* Validate lanes */ + if (ARGON2_MIN_LANES > context->lanes) { + return ARGON2_LANES_TOO_FEW; + } + + if (ARGON2_MAX_LANES < context->lanes) { + return ARGON2_LANES_TOO_MANY; + } + /* Validate memory cost */ if (ARGON2_MIN_MEMORY > context->m_cost) { return ARGON2_MEMORY_TOO_LITTLE; @@ -341,15 +330,6 @@ validate_inputs(const argon2_context *context) return ARGON2_TIME_TOO_LARGE; } - /* Validate lanes */ - if (ARGON2_MIN_LANES > context->lanes) { - return ARGON2_LANES_TOO_FEW; - } - - if (ARGON2_MAX_LANES < context->lanes) { - return ARGON2_LANES_TOO_MANY; - } - /* Validate threads */ if (ARGON2_MIN_THREADS > context->threads) { return ARGON2_THREADS_TOO_FEW; @@ -363,8 +343,8 @@ validate_inputs(const argon2_context *context) return ARGON2_OK; } -void -fill_first_blocks(uint8_t *blockhash, const argon2_instance_t *instance) +static void +argon2_fill_first_blocks(uint8_t *blockhash, const argon2_instance_t *instance) { uint32_t l; /* Make the first and second block in each lane as G(H0||i||0) or @@ -387,8 +367,9 @@ fill_first_blocks(uint8_t *blockhash, const argon2_instance_t *instance) sodium_memzero(blockhash_bytes, ARGON2_BLOCK_SIZE); } -void -initial_hash(uint8_t *blockhash, argon2_context *context, argon2_type type) +static void +argon2_initial_hash(uint8_t *blockhash, argon2_context *context, + argon2_type type) { crypto_generichash_blake2b_state BlakeHash; uint8_t value[4U /* sizeof(uint32_t) */]; @@ -471,7 +452,7 @@ initial_hash(uint8_t *blockhash, argon2_context *context, argon2_type type) } int -initialize(argon2_instance_t *instance, argon2_context *context) +argon2_initialize(argon2_instance_t *instance, argon2_context *context) { uint8_t blockhash[ARGON2_PREHASH_SEED_LENGTH]; int result = ARGON2_OK; @@ -489,7 +470,7 @@ initialize(argon2_instance_t *instance, argon2_context *context) result = allocate_memory(&(instance->region), instance->memory_blocks); if (ARGON2_OK != result) { - free_instance(instance, context->flags); + argon2_free_instance(instance, context->flags); return result; } @@ -497,45 +478,45 @@ initialize(argon2_instance_t *instance, argon2_context *context) /* H_0 + 8 extra bytes to produce the first blocks */ /* uint8_t blockhash[ARGON2_PREHASH_SEED_LENGTH]; */ /* Hashing all inputs */ - initial_hash(blockhash, context, instance->type); + argon2_initial_hash(blockhash, context, instance->type); /* Zeroing 8 extra bytes */ sodium_memzero(blockhash + ARGON2_PREHASH_DIGEST_LENGTH, ARGON2_PREHASH_SEED_LENGTH - ARGON2_PREHASH_DIGEST_LENGTH); /* 3. Creating first blocks, we always have at least two blocks in a slice */ - fill_first_blocks(blockhash, instance); + argon2_fill_first_blocks(blockhash, instance); /* Clearing the hash */ sodium_memzero(blockhash, ARGON2_PREHASH_SEED_LENGTH); return ARGON2_OK; } -int +static int argon2_pick_best_implementation(void) { /* LCOV_EXCL_START */ #if defined(HAVE_AVX512FINTRIN_H) && defined(HAVE_AVX2INTRIN_H) && \ defined(HAVE_TMMINTRIN_H) && defined(HAVE_SMMINTRIN_H) if (sodium_runtime_has_avx512f()) { - fill_segment = fill_segment_avx512f; + fill_segment = argon2_fill_segment_avx512f; return 0; } #endif #if defined(HAVE_AVX2INTRIN_H) && defined(HAVE_TMMINTRIN_H) && \ defined(HAVE_SMMINTRIN_H) if (sodium_runtime_has_avx2()) { - fill_segment = fill_segment_avx2; + fill_segment = argon2_fill_segment_avx2; return 0; } #endif #if defined(HAVE_EMMINTRIN_H) && defined(HAVE_TMMINTRIN_H) if (sodium_runtime_has_ssse3()) { - fill_segment = fill_segment_ssse3; + fill_segment = argon2_fill_segment_ssse3; return 0; } #endif - fill_segment = fill_segment_ref; + fill_segment = argon2_fill_segment_ref; return 0; /* LCOV_EXCL_STOP */ diff --git a/libs/libsodium/src/crypto_pwhash/argon2/argon2-core.h b/libs/libsodium/src/crypto_pwhash/argon2/argon2-core.h index 4af519b28e..359b1d8d32 100644 --- a/libs/libsodium/src/crypto_pwhash/argon2/argon2-core.h +++ b/libs/libsodium/src/crypto_pwhash/argon2/argon2-core.h @@ -17,6 +17,7 @@ #include #include "argon2.h" +#include "private/quirks.h" /*************************Argon2 internal * constants**************************************************/ @@ -214,28 +215,7 @@ static uint32_t index_alpha(const argon2_instance_t *instance, * @return ARGON2_OK if everything is all right, otherwise one of error codes * (all defined in */ -int validate_inputs(const argon2_context *context); - -/* - * Hashes all the inputs into @a blockhash[PREHASH_DIGEST_LENGTH], clears - * password and secret if needed - * @param context Pointer to the Argon2 internal structure containing memory - * pointer, and parameters for time and space requirements. - * @param blockhash Buffer for pre-hashing digest - * @param type Argon2 type - * @pre @a blockhash must have at least @a PREHASH_DIGEST_LENGTH bytes - * allocated - */ -void initial_hash(uint8_t *blockhash, argon2_context *context, - argon2_type type); - -/* - * Function creates first 2 blocks per lane - * @param instance Pointer to the current instance - * @param blockhash Pointer to the pre-hashing digest - * @pre blockhash must point to @a PREHASH_SEED_LENGTH allocated values - */ -void fill_first_blocks(uint8_t *blockhash, const argon2_instance_t *instance); +int argon2_validate_inputs(const argon2_context *context); /* * Function allocates memory, hashes the inputs with Blake, and creates first @@ -247,12 +227,7 @@ void fill_first_blocks(uint8_t *blockhash, const argon2_instance_t *instance); * @return Zero if successful, -1 if memory failed to allocate. @context->state * will be modified if successful. */ -int initialize(argon2_instance_t *instance, argon2_context *context); - -/* - * Deallocates memory. Used on error path. - */ -void free_instance(argon2_instance_t *instance, int flags); +int argon2_initialize(argon2_instance_t *instance, argon2_context *context); /* * XORing the last block of each lane, hashing it, making the tag. Deallocates @@ -265,7 +240,8 @@ void free_instance(argon2_instance_t *instance, int flags); * @pre if context->free_cbk is not NULL, it should point to a function that * deallocates memory */ -void finalize(const argon2_context *context, argon2_instance_t *instance); +void argon2_finalize(const argon2_context *context, + argon2_instance_t *instance); /* * Function that fills the segment using previous segments also from other @@ -276,15 +252,14 @@ void finalize(const argon2_context *context, argon2_instance_t *instance); */ typedef void (*fill_segment_fn)(const argon2_instance_t *instance, argon2_position_t position); -int argon2_pick_best_implementation(void); -void fill_segment_avx512f(const argon2_instance_t *instance, - argon2_position_t position); -void fill_segment_avx2(const argon2_instance_t *instance, - argon2_position_t position); -void fill_segment_ssse3(const argon2_instance_t *instance, - argon2_position_t position); -void fill_segment_ref(const argon2_instance_t *instance, - argon2_position_t position); +void argon2_fill_segment_avx512f(const argon2_instance_t *instance, + argon2_position_t position); +void argon2_fill_segment_avx2(const argon2_instance_t *instance, + argon2_position_t position); +void argon2_fill_segment_ssse3(const argon2_instance_t *instance, + argon2_position_t position); +void argon2_fill_segment_ref(const argon2_instance_t *instance, + argon2_position_t position); /* * Function that fills the entire memory t_cost times based on the first two @@ -292,6 +267,6 @@ void fill_segment_ref(const argon2_instance_t *instance, * @param instance Pointer to the current instance * @return Zero if successful, -1 if memory failed to allocate */ -void fill_memory_blocks(argon2_instance_t *instance, uint32_t pass); +void argon2_fill_memory_blocks(argon2_instance_t *instance, uint32_t pass); #endif diff --git a/libs/libsodium/src/crypto_pwhash/argon2/argon2-encoding.c b/libs/libsodium/src/crypto_pwhash/argon2/argon2-encoding.c index a9a2b4872d..6221f285be 100644 --- a/libs/libsodium/src/crypto_pwhash/argon2/argon2-encoding.c +++ b/libs/libsodium/src/crypto_pwhash/argon2/argon2-encoding.c @@ -83,7 +83,7 @@ decode_decimal(const char *str, unsigned long *v) * output length must be in the allowed ranges defined in argon2.h. * * The ctx struct must contain buffers large enough to hold the salt and pwd - * when it is fed into decode_string. + * when it is fed into argon2_decode_string. */ /* @@ -91,7 +91,7 @@ decode_decimal(const char *str, unsigned long *v) * Returned value is ARGON2_OK on success. */ int -decode_string(argon2_context *ctx, const char *str, argon2_type type) +argon2_decode_string(argon2_context *ctx, const char *str, argon2_type type) { /* Prefix checking */ #define CC(prefix) \ @@ -193,7 +193,7 @@ decode_string(argon2_context *ctx, const char *str, argon2_type type) BIN(ctx->salt, maxsaltlen, ctx->saltlen); CC("$"); BIN(ctx->out, maxoutlen, ctx->outlen); - validation_result = validate_inputs(ctx); + validation_result = argon2_validate_inputs(ctx); if (validation_result != ARGON2_OK) { return validation_result; } @@ -238,7 +238,8 @@ u32_to_string(char *str, uint32_t x) * On success, ARGON2_OK is returned. */ int -encode_string(char *dst, size_t dst_len, argon2_context *ctx, argon2_type type) +argon2_encode_string(char *dst, size_t dst_len, argon2_context *ctx, + argon2_type type) { #define SS(str) \ do { \ @@ -280,7 +281,7 @@ encode_string(char *dst, size_t dst_len, argon2_context *ctx, argon2_type type) default: return ARGON2_ENCODING_FAIL; } - validation_result = validate_inputs(ctx); + validation_result = argon2_validate_inputs(ctx); if (validation_result != ARGON2_OK) { return validation_result; } diff --git a/libs/libsodium/src/crypto_pwhash/argon2/argon2-encoding.h b/libs/libsodium/src/crypto_pwhash/argon2/argon2-encoding.h index c0a54f8274..4ba93d1543 100644 --- a/libs/libsodium/src/crypto_pwhash/argon2/argon2-encoding.h +++ b/libs/libsodium/src/crypto_pwhash/argon2/argon2-encoding.h @@ -2,6 +2,7 @@ #define argon2_encoding_H #include "argon2.h" +#include "private/quirks.h" /* * encode an Argon2 hash string into the provided buffer. 'dst_len' @@ -17,8 +18,8 @@ * * No other parameters are checked */ -int encode_string(char *dst, size_t dst_len, argon2_context *ctx, - argon2_type type); +int argon2_encode_string(char *dst, size_t dst_len, argon2_context *ctx, + argon2_type type); /* * Decodes an Argon2 hash string into the provided structure 'ctx'. @@ -28,6 +29,7 @@ int encode_string(char *dst, size_t dst_len, argon2_context *ctx, * * Returned value is ARGON2_OK on success. */ -int decode_string(argon2_context *ctx, const char *str, argon2_type type); +int argon2_decode_string(argon2_context *ctx, const char *str, + argon2_type type); #endif diff --git a/libs/libsodium/src/crypto_pwhash/argon2/argon2-fill-block-avx2.c b/libs/libsodium/src/crypto_pwhash/argon2/argon2-fill-block-avx2.c index c41037fd43..fbbd5c773e 100644 --- a/libs/libsodium/src/crypto_pwhash/argon2/argon2-fill-block-avx2.c +++ b/libs/libsodium/src/crypto_pwhash/argon2/argon2-fill-block-avx2.c @@ -18,25 +18,24 @@ #include "argon2-core.h" #include "argon2.h" #include "private/common.h" -#include "private/sse2_64_32.h" #if defined(HAVE_AVX2INTRIN_H) && defined(HAVE_EMMINTRIN_H) && \ defined(HAVE_TMMINTRIN_H) && defined(HAVE_SMMINTRIN_H) -# ifdef __GNUC__ -# pragma GCC target("sse2") -# pragma GCC target("ssse3") -# pragma GCC target("sse4.1") -# pragma GCC target("avx2") +# ifdef __clang__ +# pragma clang attribute push(__attribute__((target("sse2,ssse3,sse4.1,avx2"))), apply_to = function) +# elif defined(__GNUC__) +# pragma GCC target("sse2,ssse3,sse4.1,avx2") # endif # ifdef _MSC_VER # include /* for _mm_set_epi64x */ # endif -#include -#include -#include -#include +# include +# include +# include +# include +# include "private/sse2_64_32.h" # include "blamka-round-avx2.h" @@ -141,8 +140,8 @@ generate_addresses(const argon2_instance_t *instance, } void -fill_segment_avx2(const argon2_instance_t *instance, - argon2_position_t position) +argon2_fill_segment_avx2(const argon2_instance_t *instance, + argon2_position_t position) { block *ref_block = NULL, *curr_block = NULL; uint64_t pseudo_rand, ref_index, ref_lane; @@ -236,4 +235,9 @@ fill_segment_avx2(const argon2_instance_t *instance, } } } + +#ifdef __clang__ +# pragma clang attribute pop +#endif + #endif diff --git a/libs/libsodium/src/crypto_pwhash/argon2/argon2-fill-block-avx512f.c b/libs/libsodium/src/crypto_pwhash/argon2/argon2-fill-block-avx512f.c index e6a8d18455..d50c40d18e 100644 --- a/libs/libsodium/src/crypto_pwhash/argon2/argon2-fill-block-avx512f.c +++ b/libs/libsodium/src/crypto_pwhash/argon2/argon2-fill-block-avx512f.c @@ -18,26 +18,28 @@ #include "argon2-core.h" #include "argon2.h" #include "private/common.h" -#include "private/sse2_64_32.h" #if defined(HAVE_AVX512FINTRIN_H) && defined(HAVE_AVX2INTRIN_H) && \ defined(HAVE_EMMINTRIN_H) && defined(HAVE_TMMINTRIN_H) && defined(HAVE_SMMINTRIN_H) -# ifdef __GNUC__ -# pragma GCC target("sse2") -# pragma GCC target("ssse3") -# pragma GCC target("sse4.1") -# pragma GCC target("avx2") -# pragma GCC target("avx512f") +# ifdef __clang__ +# if __clang_major__ >= 18 +# pragma clang attribute push(__attribute__((target("sse2,ssse3,sse4.1,avx2,avx512f,evex512"))), apply_to = function) +# else +# pragma clang attribute push(__attribute__((target("sse2,ssse3,sse4.1,avx2,avx512f"))), apply_to = function) +# endif +# elif defined(__GNUC__) +# pragma GCC target("sse2,ssse3,sse4.1,avx2,avx512f") # endif # ifdef _MSC_VER # include /* for _mm_set_epi64x */ # endif -#include -#include -#include -#include +# include +# include +# include +# include +# include "private/sse2_64_32.h" # include "blamka-round-avx512f.h" @@ -146,8 +148,8 @@ generate_addresses(const argon2_instance_t *instance, } void -fill_segment_avx512f(const argon2_instance_t *instance, - argon2_position_t position) +argon2_fill_segment_avx512f(const argon2_instance_t *instance, + argon2_position_t position) { block *ref_block = NULL, *curr_block = NULL; uint64_t pseudo_rand, ref_index, ref_lane; @@ -241,4 +243,9 @@ fill_segment_avx512f(const argon2_instance_t *instance, } } } + +#ifdef __clang__ +# pragma clang attribute pop +#endif + #endif diff --git a/libs/libsodium/src/crypto_pwhash/argon2/argon2-fill-block-ref.c b/libs/libsodium/src/crypto_pwhash/argon2/argon2-fill-block-ref.c index c973e8b489..85375fcc13 100644 --- a/libs/libsodium/src/crypto_pwhash/argon2/argon2-fill-block-ref.c +++ b/libs/libsodium/src/crypto_pwhash/argon2/argon2-fill-block-ref.c @@ -141,7 +141,8 @@ generate_addresses(const argon2_instance_t *instance, } void -fill_segment_ref(const argon2_instance_t *instance, argon2_position_t position) +argon2_fill_segment_ref(const argon2_instance_t *instance, + argon2_position_t position) { block *ref_block = NULL, *curr_block = NULL; /* Pseudo-random values that determine the reference block position */ diff --git a/libs/libsodium/src/crypto_pwhash/argon2/argon2-fill-block-ssse3.c b/libs/libsodium/src/crypto_pwhash/argon2/argon2-fill-block-ssse3.c index 85de04f132..151f9c78bd 100644 --- a/libs/libsodium/src/crypto_pwhash/argon2/argon2-fill-block-ssse3.c +++ b/libs/libsodium/src/crypto_pwhash/argon2/argon2-fill-block-ssse3.c @@ -18,13 +18,13 @@ #include "argon2-core.h" #include "argon2.h" #include "private/common.h" -#include "private/sse2_64_32.h" #if defined(HAVE_EMMINTRIN_H) && defined(HAVE_TMMINTRIN_H) -# ifdef __GNUC__ -# pragma GCC target("sse2") -# pragma GCC target("ssse3") +# ifdef __clang__ +# pragma clang attribute push(__attribute__((target("sse2,ssse3"))), apply_to = function) +# elif defined(__GNUC__) +# pragma GCC target("sse2,ssse3") # endif # ifdef _MSC_VER @@ -32,6 +32,7 @@ # endif # include # include +# include "private/sse2_64_32.h" # include "blamka-round-ssse3.h" @@ -140,8 +141,8 @@ generate_addresses(const argon2_instance_t *instance, } void -fill_segment_ssse3(const argon2_instance_t *instance, - argon2_position_t position) +argon2_fill_segment_ssse3(const argon2_instance_t *instance, + argon2_position_t position) { block *ref_block = NULL, *curr_block = NULL; uint64_t pseudo_rand, ref_index, ref_lane; @@ -235,4 +236,9 @@ fill_segment_ssse3(const argon2_instance_t *instance, } } } + +#ifdef __clang__ +# pragma clang attribute pop +#endif + #endif diff --git a/libs/libsodium/src/crypto_pwhash/argon2/argon2.c b/libs/libsodium/src/crypto_pwhash/argon2/argon2.c index 3b0f2f2723..a098feba9d 100644 --- a/libs/libsodium/src/crypto_pwhash/argon2/argon2.c +++ b/libs/libsodium/src/crypto_pwhash/argon2/argon2.c @@ -17,6 +17,7 @@ #include #include +#include "randombytes.h" #include "utils.h" #include "argon2-core.h" @@ -27,7 +28,7 @@ int argon2_ctx(argon2_context *context, argon2_type type) { /* 1. Validate all inputs */ - int result = validate_inputs(context); + int result = argon2_validate_inputs(context); uint32_t memory_blocks, segment_length; uint32_t pass; argon2_instance_t instance; @@ -65,7 +66,7 @@ argon2_ctx(argon2_context *context, argon2_type type) /* 3. Initialization: Hashing inputs, allocating memory, filling first * blocks */ - result = initialize(&instance, context); + result = argon2_initialize(&instance, context); if (ARGON2_OK != result) { return result; @@ -73,11 +74,11 @@ argon2_ctx(argon2_context *context, argon2_type type) /* 4. Filling memory */ for (pass = 0; pass < instance.passes; pass++) { - fill_memory_blocks(&instance, pass); + argon2_fill_memory_blocks(&instance, pass); } /* 5. Finalization */ - finalize(context, &instance); + argon2_finalize(context, &instance); return ARGON2_OK; } @@ -93,6 +94,10 @@ argon2_hash(const uint32_t t_cost, const uint32_t m_cost, int result; uint8_t *out; + if (hash != NULL) { + randombytes_buf(hash, hashlen); + } + if (pwdlen > ARGON2_MAX_PWD_LENGTH) { return ARGON2_PWD_TOO_LONG; } @@ -134,14 +139,10 @@ argon2_hash(const uint32_t t_cost, const uint32_t m_cost, return result; } - /* if raw hash requested, write it */ - if (hash) { - memcpy(hash, out, hashlen); - } - /* if encoding requested, write it */ if (encoded && encodedlen) { - if (encode_string(encoded, encodedlen, &context, type) != ARGON2_OK) { + if (argon2_encode_string(encoded, encodedlen, + &context, type) != ARGON2_OK) { sodium_memzero(out, hashlen); sodium_memzero(encoded, encodedlen); free(out); @@ -149,6 +150,11 @@ argon2_hash(const uint32_t t_cost, const uint32_t m_cost, } } + /* if raw hash requested, write it */ + if (hash) { + memcpy(hash, out, hashlen); + } + sodium_memzero(out, hashlen); free(out); @@ -214,7 +220,7 @@ argon2_verify(const char *encoded, const void *pwd, const size_t pwdlen, ctx.secret = NULL; ctx.secretlen = 0; - /* max values, to be updated in decode_string */ + /* max values, to be updated in argon2_decode_string */ encoded_len = strlen(encoded); if (encoded_len > UINT32_MAX) { return ARGON2_DECODING_LENGTH_FAIL; @@ -240,7 +246,7 @@ argon2_verify(const char *encoded, const void *pwd, const size_t pwdlen, return ARGON2_MEMORY_ALLOCATION_ERROR; } - decode_result = decode_string(&ctx, encoded, type); + decode_result = argon2_decode_string(&ctx, encoded, type); if (decode_result != ARGON2_OK) { free(ctx.ad); free(ctx.salt); @@ -255,7 +261,7 @@ argon2_verify(const char *encoded, const void *pwd, const size_t pwdlen, free(ctx.ad); free(ctx.salt); - if (ret != ARGON2_OK || sodium_memcmp(out, ctx.out, ctx.outlen) != 0) { + if (ret == ARGON2_OK && sodium_memcmp(out, ctx.out, ctx.outlen) != 0) { ret = ARGON2_VERIFY_MISMATCH; } free(out); diff --git a/libs/libsodium/src/crypto_pwhash/argon2/argon2.h b/libs/libsodium/src/crypto_pwhash/argon2/argon2.h index 034a1be276..12c29c16f9 100644 --- a/libs/libsodium/src/crypto_pwhash/argon2/argon2.h +++ b/libs/libsodium/src/crypto_pwhash/argon2/argon2.h @@ -16,6 +16,8 @@ #include #include +#include "private/quirks.h" + /* * Argon2 input parameter restrictions */ @@ -68,7 +70,6 @@ #define ARGON2_FLAG_CLEAR_PASSWORD (UINT32_C(1) << 0) #define ARGON2_FLAG_CLEAR_SECRET (UINT32_C(1) << 1) -#define ARGON2_FLAG_CLEAR_MEMORY (UINT32_C(1) << 2) #define ARGON2_DEFAULT_FLAGS (UINT32_C(0)) /* Error codes */ @@ -283,7 +284,7 @@ int argon2_hash(const uint32_t t_cost, const uint32_t m_cost, /** * Verifies a password against an encoded string - * Encoded string is restricted as in validate_inputs() + * Encoded string is restricted as in argon2_validate_inputs() * @param encoded String encoding parameters, salt, hash * @param pwd Pointer to password * @pre Returns ARGON2_OK if successful @@ -292,7 +293,7 @@ int argon2i_verify(const char *encoded, const void *pwd, const size_t pwdlen); /** * Verifies a password against an encoded string - * Encoded string is restricted as in validate_inputs() + * Encoded string is restricted as in argon2_validate_inputs() * @param encoded String encoding parameters, salt, hash * @param pwd Pointer to password * @pre Returns ARGON2_OK if successful diff --git a/libs/libsodium/src/crypto_pwhash/argon2/blake2b-long.h b/libs/libsodium/src/crypto_pwhash/argon2/blake2b-long.h index f7275e0a78..9e308b8c04 100644 --- a/libs/libsodium/src/crypto_pwhash/argon2/blake2b-long.h +++ b/libs/libsodium/src/crypto_pwhash/argon2/blake2b-long.h @@ -2,6 +2,7 @@ #define blake2b_long_H #include +#include "private/quirks.h" int blake2b_long(void *pout, size_t outlen, const void *in, size_t inlen); diff --git a/libs/libsodium/src/crypto_pwhash/argon2/blamka-round-ssse3.h b/libs/libsodium/src/crypto_pwhash/argon2/blamka-round-ssse3.h index f7290dbd49..d860405bc3 100644 --- a/libs/libsodium/src/crypto_pwhash/argon2/blamka-round-ssse3.h +++ b/libs/libsodium/src/crypto_pwhash/argon2/blamka-round-ssse3.h @@ -8,6 +8,9 @@ (_mm_setr_epi8(2, 3, 4, 5, 6, 7, 0, 1, 10, 11, 12, 13, 14, 15, 8, 9)) #define r24 \ (_mm_setr_epi8(3, 4, 5, 6, 7, 0, 1, 2, 11, 12, 13, 14, 15, 8, 9, 10)) + +#if !(defined(_mm_roti_epi64) && defined(__XOP__)) +#undef _mm_roti_epi64 #define _mm_roti_epi64(x, c) \ (-(c) == 32) \ ? _mm_shuffle_epi32((x), _MM_SHUFFLE(2, 3, 0, 1)) \ @@ -20,6 +23,7 @@ _mm_add_epi64((x), (x))) \ : _mm_xor_si128(_mm_srli_epi64((x), -(c)), \ _mm_slli_epi64((x), 64 - (-(c)))) +#endif static inline __m128i fBlaMka(__m128i x, __m128i y) diff --git a/libs/libsodium/src/crypto_pwhash/argon2/pwhash_argon2i.c b/libs/libsodium/src/crypto_pwhash/argon2/pwhash_argon2i.c index e83a958e44..43b7a497bc 100644 --- a/libs/libsodium/src/crypto_pwhash/argon2/pwhash_argon2i.c +++ b/libs/libsodium/src/crypto_pwhash/argon2/pwhash_argon2i.c @@ -72,14 +72,14 @@ crypto_pwhash_argon2i_strprefix(void) return crypto_pwhash_argon2i_STRPREFIX; } -size_t +unsigned long long crypto_pwhash_argon2i_opslimit_min(void) { COMPILER_ASSERT(crypto_pwhash_argon2i_OPSLIMIT_MIN >= ARGON2_MIN_TIME); return crypto_pwhash_argon2i_OPSLIMIT_MIN; } -size_t +unsigned long long crypto_pwhash_argon2i_opslimit_max(void) { COMPILER_ASSERT(crypto_pwhash_argon2i_OPSLIMIT_MAX <= ARGON2_MAX_TIME); @@ -100,7 +100,7 @@ crypto_pwhash_argon2i_memlimit_max(void) return crypto_pwhash_argon2i_MEMLIMIT_MAX; } -size_t +unsigned long long crypto_pwhash_argon2i_opslimit_interactive(void) { return crypto_pwhash_argon2i_OPSLIMIT_INTERACTIVE; @@ -112,7 +112,7 @@ crypto_pwhash_argon2i_memlimit_interactive(void) return crypto_pwhash_argon2i_MEMLIMIT_INTERACTIVE; } -size_t +unsigned long long crypto_pwhash_argon2i_opslimit_moderate(void) { return crypto_pwhash_argon2i_OPSLIMIT_MODERATE; @@ -124,7 +124,7 @@ crypto_pwhash_argon2i_memlimit_moderate(void) return crypto_pwhash_argon2i_MEMLIMIT_MODERATE; } -size_t +unsigned long long crypto_pwhash_argon2i_opslimit_sensitive(void) { return crypto_pwhash_argon2i_OPSLIMIT_SENSITIVE; @@ -163,6 +163,10 @@ crypto_pwhash_argon2i(unsigned char *const out, unsigned long long outlen, errno = EINVAL; return -1; } + if ((const void *) out == (const void *) passwd) { + errno = EINVAL; + return -1; + } switch (alg) { case crypto_pwhash_argon2i_ALG_ARGON2I13: if (argon2i_hash_raw((uint32_t) opslimit, (uint32_t) (memlimit / 1024U), @@ -210,8 +214,8 @@ crypto_pwhash_argon2i_str(char out[crypto_pwhash_argon2i_STRBYTES], } int -crypto_pwhash_argon2i_str_verify(const char str[crypto_pwhash_argon2i_STRBYTES], - const char *const passwd, +crypto_pwhash_argon2i_str_verify(const char * str, + const char * const passwd, unsigned long long passwdlen) { int verify_ret; @@ -261,7 +265,7 @@ _needs_rehash(const char *str, unsigned long long opslimit, size_t memlimit, ctx.outlen = ctx.pwdlen = ctx.saltlen = (uint32_t) fodder_len; ctx.ad = ctx.secret = NULL; ctx.adlen = ctx.secretlen = 0U; - if (decode_string(&ctx, str, type) != 0) { + if (argon2_decode_string(&ctx, str, type) != 0) { errno = EINVAL; ret = -1; } else if (ctx.t_cost != (uint32_t) opslimit || @@ -276,14 +280,14 @@ _needs_rehash(const char *str, unsigned long long opslimit, size_t memlimit, } int -crypto_pwhash_argon2i_str_needs_rehash(const char str[crypto_pwhash_argon2i_STRBYTES], +crypto_pwhash_argon2i_str_needs_rehash(const char * str, unsigned long long opslimit, size_t memlimit) { return _needs_rehash(str, opslimit, memlimit, Argon2_i); } int -crypto_pwhash_argon2id_str_needs_rehash(const char str[crypto_pwhash_argon2id_STRBYTES], +crypto_pwhash_argon2id_str_needs_rehash(const char * str, unsigned long long opslimit, size_t memlimit) { return _needs_rehash(str, opslimit, memlimit, Argon2_id); diff --git a/libs/libsodium/src/crypto_pwhash/argon2/pwhash_argon2id.c b/libs/libsodium/src/crypto_pwhash/argon2/pwhash_argon2id.c index 6105116c46..93e0ec2efc 100644 --- a/libs/libsodium/src/crypto_pwhash/argon2/pwhash_argon2id.c +++ b/libs/libsodium/src/crypto_pwhash/argon2/pwhash_argon2id.c @@ -68,14 +68,14 @@ crypto_pwhash_argon2id_strprefix(void) return crypto_pwhash_argon2id_STRPREFIX; } -size_t +unsigned long long crypto_pwhash_argon2id_opslimit_min(void) { COMPILER_ASSERT(crypto_pwhash_argon2id_OPSLIMIT_MIN >= ARGON2_MIN_TIME); return crypto_pwhash_argon2id_OPSLIMIT_MIN; } -size_t +unsigned long long crypto_pwhash_argon2id_opslimit_max(void) { COMPILER_ASSERT(crypto_pwhash_argon2id_OPSLIMIT_MAX <= ARGON2_MAX_TIME); @@ -96,7 +96,7 @@ crypto_pwhash_argon2id_memlimit_max(void) return crypto_pwhash_argon2id_MEMLIMIT_MAX; } -size_t +unsigned long long crypto_pwhash_argon2id_opslimit_interactive(void) { return crypto_pwhash_argon2id_OPSLIMIT_INTERACTIVE; @@ -108,7 +108,7 @@ crypto_pwhash_argon2id_memlimit_interactive(void) return crypto_pwhash_argon2id_MEMLIMIT_INTERACTIVE; } -size_t +unsigned long long crypto_pwhash_argon2id_opslimit_moderate(void) { return crypto_pwhash_argon2id_OPSLIMIT_MODERATE; @@ -120,7 +120,7 @@ crypto_pwhash_argon2id_memlimit_moderate(void) return crypto_pwhash_argon2id_MEMLIMIT_MODERATE; } -size_t +unsigned long long crypto_pwhash_argon2id_opslimit_sensitive(void) { return crypto_pwhash_argon2id_OPSLIMIT_SENSITIVE; @@ -159,6 +159,10 @@ crypto_pwhash_argon2id(unsigned char *const out, unsigned long long outlen, errno = EINVAL; return -1; } + if ((const void *) out == (const void *) passwd) { + errno = EINVAL; + return -1; + } switch (alg) { case crypto_pwhash_argon2id_ALG_ARGON2ID13: if (argon2id_hash_raw((uint32_t) opslimit, (uint32_t) (memlimit / 1024U), @@ -206,8 +210,8 @@ crypto_pwhash_argon2id_str(char out[crypto_pwhash_argon2id_STRBYTES], } int -crypto_pwhash_argon2id_str_verify(const char str[crypto_pwhash_argon2id_STRBYTES], - const char *const passwd, +crypto_pwhash_argon2id_str_verify(const char * str, + const char * const passwd, unsigned long long passwdlen) { int verify_ret; diff --git a/libs/libsodium/src/crypto_pwhash/crypto_pwhash.c b/libs/libsodium/src/crypto_pwhash/crypto_pwhash.c index 50f5a8efee..61cab56692 100644 --- a/libs/libsodium/src/crypto_pwhash/crypto_pwhash.c +++ b/libs/libsodium/src/crypto_pwhash/crypto_pwhash.c @@ -65,13 +65,13 @@ crypto_pwhash_strprefix(void) return crypto_pwhash_STRPREFIX; } -size_t +unsigned long long crypto_pwhash_opslimit_min(void) { return crypto_pwhash_OPSLIMIT_MIN; } -size_t +unsigned long long crypto_pwhash_opslimit_max(void) { return crypto_pwhash_OPSLIMIT_MAX; @@ -89,7 +89,7 @@ crypto_pwhash_memlimit_max(void) return crypto_pwhash_MEMLIMIT_MAX; } -size_t +unsigned long long crypto_pwhash_opslimit_interactive(void) { return crypto_pwhash_OPSLIMIT_INTERACTIVE; @@ -101,7 +101,7 @@ crypto_pwhash_memlimit_interactive(void) return crypto_pwhash_MEMLIMIT_INTERACTIVE; } -size_t +unsigned long long crypto_pwhash_opslimit_moderate(void) { return crypto_pwhash_OPSLIMIT_MODERATE; @@ -113,7 +113,7 @@ crypto_pwhash_memlimit_moderate(void) return crypto_pwhash_MEMLIMIT_MODERATE; } -size_t +unsigned long long crypto_pwhash_opslimit_sensitive(void) { return crypto_pwhash_OPSLIMIT_SENSITIVE; @@ -172,7 +172,7 @@ crypto_pwhash_str_alg(char out[crypto_pwhash_STRBYTES], } int -crypto_pwhash_str_verify(const char str[crypto_pwhash_STRBYTES], +crypto_pwhash_str_verify(const char * str, const char * const passwd, unsigned long long passwdlen) { @@ -190,7 +190,7 @@ crypto_pwhash_str_verify(const char str[crypto_pwhash_STRBYTES], } int -crypto_pwhash_str_needs_rehash(const char str[crypto_pwhash_STRBYTES], +crypto_pwhash_str_needs_rehash(const char * str, unsigned long long opslimit, size_t memlimit) { if (strncmp(str, crypto_pwhash_argon2id_STRPREFIX, diff --git a/libs/libsodium/src/crypto_pwhash/scryptsalsa208sha256/crypto_scrypt-common.c b/libs/libsodium/src/crypto_pwhash/scryptsalsa208sha256/crypto_scrypt-common.c index 9b81377ad4..eea04da8cb 100644 --- a/libs/libsodium/src/crypto_pwhash/scryptsalsa208sha256/crypto_scrypt-common.c +++ b/libs/libsodium/src/crypto_pwhash/scryptsalsa208sha256/crypto_scrypt-common.c @@ -24,6 +24,7 @@ #include "crypto_pwhash_scryptsalsa208sha256.h" #include "crypto_scrypt.h" #include "private/common.h" +#include "randombytes.h" #include "runtime.h" #include "utils.h" @@ -150,6 +151,10 @@ escrypt_r(escrypt_local_t *local, const uint8_t *passwd, size_t passwdlen, uint32_t r; uint32_t p; + if (buf != NULL) { + randombytes_buf(buf, buflen); + } + src = escrypt_parse_setting(setting, &N_log2, &r, &p); if (!src) { return NULL; diff --git a/libs/libsodium/src/crypto_pwhash/scryptsalsa208sha256/crypto_scrypt.h b/libs/libsodium/src/crypto_pwhash/scryptsalsa208sha256/crypto_scrypt.h index bc40196f1d..4c094f29a6 100644 --- a/libs/libsodium/src/crypto_pwhash/scryptsalsa208sha256/crypto_scrypt.h +++ b/libs/libsodium/src/crypto_pwhash/scryptsalsa208sha256/crypto_scrypt.h @@ -34,11 +34,7 @@ #include #include -#if SIZE_MAX > 0xffffffffULL -#define ARCH_BITS 64 -#else -#define ARCH_BITS 32 -#endif +#include "private/quirks.h" #define crypto_pwhash_scryptsalsa208sha256_STRPREFIXBYTES 14 #define crypto_pwhash_scryptsalsa208sha256_STRSETTINGBYTES 57 @@ -54,45 +50,40 @@ typedef struct { size_t size; } escrypt_region_t; -typedef union { - uint64_t d[8]; - uint32_t w[16]; -} escrypt_block_t; - typedef escrypt_region_t escrypt_local_t; -extern int escrypt_init_local(escrypt_local_t *__local); +int escrypt_init_local(escrypt_local_t *__local); -extern int escrypt_free_local(escrypt_local_t *__local); +int escrypt_free_local(escrypt_local_t *__local); -extern void *alloc_region(escrypt_region_t *region, size_t size); -extern int free_region(escrypt_region_t *region); +void *escrypt_alloc_region(escrypt_region_t *region, size_t size); +int escrypt_free_region(escrypt_region_t *region); typedef int (*escrypt_kdf_t)(escrypt_local_t *__local, const uint8_t *__passwd, size_t __passwdlen, const uint8_t *__salt, size_t __saltlen, uint64_t __N, uint32_t __r, uint32_t __p, uint8_t *__buf, size_t __buflen); -extern int escrypt_kdf_nosse(escrypt_local_t *__local, const uint8_t *__passwd, - size_t __passwdlen, const uint8_t *__salt, - size_t __saltlen, uint64_t __N, uint32_t __r, - uint32_t __p, uint8_t *__buf, size_t __buflen); +int escrypt_kdf_nosse(escrypt_local_t *__local, const uint8_t *__passwd, + size_t __passwdlen, const uint8_t *__salt, + size_t __saltlen, uint64_t __N, uint32_t __r, + uint32_t __p, uint8_t *__buf, size_t __buflen); -extern int escrypt_kdf_sse(escrypt_local_t *__local, const uint8_t *__passwd, - size_t __passwdlen, const uint8_t *__salt, - size_t __saltlen, uint64_t __N, uint32_t __r, - uint32_t __p, uint8_t *__buf, size_t __buflen); +int escrypt_kdf_sse(escrypt_local_t *__local, const uint8_t *__passwd, + size_t __passwdlen, const uint8_t *__salt, + size_t __saltlen, uint64_t __N, uint32_t __r, + uint32_t __p, uint8_t *__buf, size_t __buflen); -extern uint8_t *escrypt_r(escrypt_local_t *__local, const uint8_t *__passwd, - size_t __passwdlen, const uint8_t *__setting, - uint8_t *__buf, size_t __buflen); +uint8_t *escrypt_r(escrypt_local_t *__local, const uint8_t *__passwd, + size_t __passwdlen, const uint8_t *__setting, + uint8_t *__buf, size_t __buflen); -extern uint8_t *escrypt_gensalt_r(uint32_t __N_log2, uint32_t __r, uint32_t __p, - const uint8_t *__src, size_t __srclen, - uint8_t *__buf, size_t __buflen); +uint8_t *escrypt_gensalt_r(uint32_t __N_log2, uint32_t __r, uint32_t __p, + const uint8_t *__src, size_t __srclen, + uint8_t *__buf, size_t __buflen); -extern const uint8_t *escrypt_parse_setting(const uint8_t *setting, - uint32_t *N_log2_p, uint32_t *r_p, - uint32_t *p_p); +const uint8_t *escrypt_parse_setting(const uint8_t *setting, + uint32_t *N_log2_p, uint32_t *r_p, + uint32_t *p_p); #endif /* !_CRYPTO_SCRYPT_H_ */ diff --git a/libs/libsodium/src/crypto_pwhash/scryptsalsa208sha256/nosse/pwhash_scryptsalsa208sha256_nosse.c b/libs/libsodium/src/crypto_pwhash/scryptsalsa208sha256/nosse/pwhash_scryptsalsa208sha256_nosse.c index a60ec6dcd4..5c1a578eeb 100644 --- a/libs/libsodium/src/crypto_pwhash/scryptsalsa208sha256/nosse/pwhash_scryptsalsa208sha256_nosse.c +++ b/libs/libsodium/src/crypto_pwhash/scryptsalsa208sha256/nosse/pwhash_scryptsalsa208sha256_nosse.c @@ -39,85 +39,32 @@ #include "private/common.h" static inline void -blkcpy_64(escrypt_block_t *dest, const escrypt_block_t *src) +blkcpy(uint32_t *dest, const uint32_t *src, size_t len) { - int i; - -#if (ARCH_BITS == 32) - for (i = 0; i < 16; ++i) { - dest->w[i] = src->w[i]; - } -#else - for (i = 0; i < 8; ++i) { - dest->d[i] = src->d[i]; - } -#endif -} - -static inline void -blkxor_64(escrypt_block_t *dest, const escrypt_block_t *src) -{ - int i; - -#if (ARCH_BITS == 32) - for (i = 0; i < 16; ++i) { - dest->w[i] ^= src->w[i]; - } -#else - for (i = 0; i < 8; ++i) { - dest->d[i] ^= src->d[i]; - } -#endif + memcpy(dest, src, len * 64); } static inline void -blkcpy(escrypt_block_t *dest, const escrypt_block_t *src, size_t len) +blkxor(uint32_t *dest, const uint32_t *src, size_t len) { - size_t i, L; - -#if (ARCH_BITS == 32) - L = (len >> 2); - for (i = 0; i < L; ++i) { - dest->w[i] = src->w[i]; - } -#else - L = (len >> 3); - for (i = 0; i < L; ++i) { - dest->d[i] = src->d[i]; - } -#endif -} - -static inline void -blkxor(escrypt_block_t *dest, const escrypt_block_t *src, size_t len) -{ - size_t i, L; + size_t i; -#if (ARCH_BITS == 32) - L = (len >> 2); - for (i = 0; i < L; ++i) { - dest->w[i] ^= src->w[i]; + for (i = 0; i < len * 16; i++) { + dest[i] ^= src[i]; } -#else - L = (len >> 3); - for (i = 0; i < L; ++i) { - dest->d[i] ^= src->d[i]; - } -#endif } -/** +/* * salsa20_8(B): * Apply the salsa20/8 core to the provided block. */ static void salsa20_8(uint32_t B[16]) { - escrypt_block_t X; - uint32_t *x = X.w; - size_t i; + uint32_t x[16]; + size_t i; - blkcpy_64(&X, (escrypt_block_t *) B); + blkcpy(x, B, 1); for (i = 0; i < 8; i += 2) { #define R(a, b) (((a) << (b)) | ((a) >> (32 - (b)))) /* Operate on columns. */ @@ -168,11 +115,12 @@ salsa20_8(uint32_t B[16]) } } -/** +/* * blockmix_salsa8(Bin, Bout, X, r): - * Compute Bout = BlockMix_{salsa20/8, r}(Bin). The input Bin must be 128r - * bytes in length; the output Bout must also be the same size. The - * temporary space X must be 64 bytes. + * Compute Bout = BlockMix_{salsa20/8, r}(Bin). + * The input Bin must be 128r bytes in length; + * The output Bout must also be the same size. + * The temporary space X must be 64 bytes. */ static void blockmix_salsa8(const uint32_t *Bin, uint32_t *Bout, uint32_t *X, size_t r) @@ -180,46 +128,41 @@ blockmix_salsa8(const uint32_t *Bin, uint32_t *Bout, uint32_t *X, size_t r) size_t i; /* 1: X <-- B_{2r - 1} */ - blkcpy_64((escrypt_block_t *) X, - (const escrypt_block_t *) &Bin[(2 * r - 1) * 16]); + blkcpy(X, &Bin[(2 * r - 1) * 16], 1); /* 2: for i = 0 to 2r - 1 do */ for (i = 0; i < 2 * r; i += 2) { /* 3: X <-- H(X \xor B_i) */ - blkxor_64((escrypt_block_t *) X, - (const escrypt_block_t *) &Bin[i * 16]); + blkxor(X, &Bin[i * 16], 1); salsa20_8(X); /* 4: Y_i <-- X */ /* 6: B' <-- (Y_0, Y_2 ... Y_{2r-2}, Y_1, Y_3 ... Y_{2r-1}) */ - blkcpy_64((escrypt_block_t *) &Bout[i * 8], - (const escrypt_block_t *) X); + blkcpy(&Bout[i * 8], X, 1); /* 3: X <-- H(X \xor B_i) */ - blkxor_64((escrypt_block_t *) X, - (const escrypt_block_t *) &Bin[i * 16 + 16]); + blkxor(X, &Bin[i * 16 + 16], 1); salsa20_8(X); /* 4: Y_i <-- X */ /* 6: B' <-- (Y_0, Y_2 ... Y_{2r-2}, Y_1, Y_3 ... Y_{2r-1}) */ - blkcpy_64((escrypt_block_t *) &Bout[i * 8 + r * 16], - (escrypt_block_t *) X); + blkcpy(&Bout[i * 8 + r * 16], X, 1); } } -/** +/* * integerify(B, r): * Return the result of parsing B_{2r-1} as a little-endian integer. */ static inline uint64_t -integerify(const void *B, size_t r) +integerify(const uint32_t *B, size_t r) { - const uint32_t *X = (const uint32_t *) ((uintptr_t)(B) + (2 * r - 1) * 64); + const uint32_t *X = B + (2 * r - 1) * 16; - return (((uint64_t)(X[1]) << 32) + X[0]); + return ((uint64_t) (X[1]) << 32) + X[0]; } -/** +/* * smix(B, r, N, V, XY): * Compute B = SMix_r(B, N). The input B must be 128r bytes in length; * the temporary storage V must be 128rN bytes in length; the temporary @@ -244,15 +187,13 @@ smix(uint8_t *B, size_t r, uint64_t N, uint32_t *V, uint32_t *XY) /* 2: for i = 0 to N - 1 do */ for (i = 0; i < N; i += 2) { /* 3: V_i <-- X */ - blkcpy((escrypt_block_t *) &V[i * (32 * r)], (escrypt_block_t *) X, - 128 * r); + blkcpy(&V[i * (32 * r)], X, 2 * r); /* 4: X <-- H(X) */ blockmix_salsa8(X, Y, Z, r); /* 3: V_i <-- X */ - blkcpy((escrypt_block_t *) &V[(i + 1) * (32 * r)], - (escrypt_block_t *) Y, 128 * r); + blkcpy(&V[(i + 1) * (32 * r)], Y, 2 * r); /* 4: X <-- H(X) */ blockmix_salsa8(Y, X, Z, r); @@ -264,16 +205,14 @@ smix(uint8_t *B, size_t r, uint64_t N, uint32_t *V, uint32_t *XY) j = integerify(X, r) & (N - 1); /* 8: X <-- H(X \xor V_j) */ - blkxor((escrypt_block_t *) X, (escrypt_block_t *) &V[j * (32 * r)], - 128 * r); + blkxor(X, &V[j * (32 * r)], 2 * r); blockmix_salsa8(X, Y, Z, r); /* 7: j <-- Integerify(X) mod N */ j = integerify(Y, r) & (N - 1); /* 8: X <-- H(X \xor V_j) */ - blkxor((escrypt_block_t *) Y, (escrypt_block_t *) &V[j * (32 * r)], - 128 * r); + blkxor(Y, &V[j * (32 * r)], 2 * r); blockmix_salsa8(Y, X, Z, r); } /* 10: B' <-- X */ @@ -282,7 +221,7 @@ smix(uint8_t *B, size_t r, uint64_t N, uint32_t *V, uint32_t *XY) } } -/** +/* * escrypt_kdf(local, passwd, passwdlen, salt, saltlen, * N, r, p, buf, buflen): * Compute scrypt(passwd[0 .. passwdlen - 1], salt[0 .. saltlen - 1], N, r, @@ -351,10 +290,10 @@ escrypt_kdf_nosse(escrypt_local_t *local, const uint8_t *passwd, return -1; } if (local->size < need) { - if (free_region(local)) { + if (escrypt_free_region(local)) { return -1; } - if (!alloc_region(local, need)) { + if (!escrypt_alloc_region(local, need)) { return -1; } } @@ -363,7 +302,7 @@ escrypt_kdf_nosse(escrypt_local_t *local, const uint8_t *passwd, XY = (uint32_t *) ((uint8_t *) V + V_size); /* 1: (B_0 ... B_{p-1}) <-- PBKDF2(P, S, 1, p * MFLen) */ - PBKDF2_SHA256(passwd, passwdlen, salt, saltlen, 1, B, B_size); + escrypt_PBKDF2_SHA256(passwd, passwdlen, salt, saltlen, 1, B, B_size); /* 2: for i = 0 to p - 1 do */ for (i = 0; i < p; i++) { @@ -372,7 +311,7 @@ escrypt_kdf_nosse(escrypt_local_t *local, const uint8_t *passwd, } /* 5: DK <-- PBKDF2(P, B, 1, dkLen) */ - PBKDF2_SHA256(passwd, passwdlen, B, B_size, 1, buf, buflen); + escrypt_PBKDF2_SHA256(passwd, passwdlen, B, B_size, 1, buf, buflen); /* Success! */ return 0; diff --git a/libs/libsodium/src/crypto_pwhash/scryptsalsa208sha256/pbkdf2-sha256.c b/libs/libsodium/src/crypto_pwhash/scryptsalsa208sha256/pbkdf2-sha256.c index ba1a56a97c..c200645cc1 100644 --- a/libs/libsodium/src/crypto_pwhash/scryptsalsa208sha256/pbkdf2-sha256.c +++ b/libs/libsodium/src/crypto_pwhash/scryptsalsa208sha256/pbkdf2-sha256.c @@ -39,13 +39,14 @@ #include "utils.h" /** - * PBKDF2_SHA256(passwd, passwdlen, salt, saltlen, c, buf, dkLen): + * escrypt_PBKDF2_SHA256(passwd, passwdlen, salt, saltlen, c, buf, dkLen): * Compute PBKDF2(passwd, salt, c, dkLen) using HMAC-SHA256 as the PRF, and * write the output to buf. The value dkLen must be at most 32 * (2^32 - 1). */ void -PBKDF2_SHA256(const uint8_t *passwd, size_t passwdlen, const uint8_t *salt, - size_t saltlen, uint64_t c, uint8_t *buf, size_t dkLen) +escrypt_PBKDF2_SHA256(const uint8_t *passwd, size_t passwdlen, + const uint8_t *salt, size_t saltlen, uint64_t c, + uint8_t *buf, size_t dkLen) { crypto_auth_hmacsha256_state PShctx, hctx; size_t i; diff --git a/libs/libsodium/src/crypto_pwhash/scryptsalsa208sha256/pbkdf2-sha256.h b/libs/libsodium/src/crypto_pwhash/scryptsalsa208sha256/pbkdf2-sha256.h index f5b32a5880..59bd115944 100644 --- a/libs/libsodium/src/crypto_pwhash/scryptsalsa208sha256/pbkdf2-sha256.h +++ b/libs/libsodium/src/crypto_pwhash/scryptsalsa208sha256/pbkdf2-sha256.h @@ -33,13 +33,14 @@ #include #include "crypto_auth_hmacsha256.h" +#include "private/quirks.h" /** - * PBKDF2_SHA256(passwd, passwdlen, salt, saltlen, c, buf, dkLen): + * escrypt_PBKDF2_SHA256(passwd, passwdlen, salt, saltlen, c, buf, dkLen): * Compute PBKDF2(passwd, salt, c, dkLen) using HMAC-SHA256 as the PRF, and * write the output to buf. The value dkLen must be at most 32 * (2^32 - 1). */ -void PBKDF2_SHA256(const uint8_t *, size_t, const uint8_t *, size_t, uint64_t, - uint8_t *, size_t); +void escrypt_PBKDF2_SHA256(const uint8_t *, size_t, const uint8_t *, size_t, + uint64_t, uint8_t *, size_t); #endif /* !_SHA256_H_ */ diff --git a/libs/libsodium/src/crypto_pwhash/scryptsalsa208sha256/pwhash_scryptsalsa208sha256.c b/libs/libsodium/src/crypto_pwhash/scryptsalsa208sha256/pwhash_scryptsalsa208sha256.c index 2a009030e1..742320bf4e 100644 --- a/libs/libsodium/src/crypto_pwhash/scryptsalsa208sha256/pwhash_scryptsalsa208sha256.c +++ b/libs/libsodium/src/crypto_pwhash/scryptsalsa208sha256/pwhash_scryptsalsa208sha256.c @@ -57,6 +57,7 @@ sodium_strnlen(const char *str, size_t maxlen) { size_t i = 0U; + ACQUIRE_FENCE; while (i < maxlen && str[i] != 0) { i++; } @@ -105,13 +106,13 @@ crypto_pwhash_scryptsalsa208sha256_strprefix(void) return crypto_pwhash_scryptsalsa208sha256_STRPREFIX; } -size_t +unsigned long long crypto_pwhash_scryptsalsa208sha256_opslimit_min(void) { return crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_MIN; } -size_t +unsigned long long crypto_pwhash_scryptsalsa208sha256_opslimit_max(void) { return crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_MAX; @@ -129,7 +130,7 @@ crypto_pwhash_scryptsalsa208sha256_memlimit_max(void) return crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_MAX; } -size_t +unsigned long long crypto_pwhash_scryptsalsa208sha256_opslimit_interactive(void) { return crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_INTERACTIVE; @@ -141,7 +142,7 @@ crypto_pwhash_scryptsalsa208sha256_memlimit_interactive(void) return crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_INTERACTIVE; } -size_t +unsigned long long crypto_pwhash_scryptsalsa208sha256_opslimit_sensitive(void) { return crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_SENSITIVE; @@ -176,6 +177,10 @@ crypto_pwhash_scryptsalsa208sha256(unsigned char *const out, errno = EINVAL; /* LCOV_EXCL_LINE */ return -1; /* LCOV_EXCL_LINE */ } + if ((const void *) out == (const void *) passwd) { + errno = EINVAL; + return -1; + } return crypto_pwhash_scryptsalsa208sha256_ll( (const uint8_t *) passwd, (size_t) passwdlen, (const uint8_t *) salt, crypto_pwhash_scryptsalsa208sha256_SALTBYTES, (uint64_t)(1) << N_log2, @@ -238,7 +243,7 @@ crypto_pwhash_scryptsalsa208sha256_str( int crypto_pwhash_scryptsalsa208sha256_str_verify( - const char str[crypto_pwhash_scryptsalsa208sha256_STRBYTES], + const char *str, const char *const passwd, unsigned long long passwdlen) { char wanted[crypto_pwhash_scryptsalsa208sha256_STRBYTES]; @@ -268,7 +273,7 @@ crypto_pwhash_scryptsalsa208sha256_str_verify( int crypto_pwhash_scryptsalsa208sha256_str_needs_rehash( - const char str[crypto_pwhash_scryptsalsa208sha256_STRBYTES], + const char * str, unsigned long long opslimit, size_t memlimit) { uint32_t N_log2, N_log2_; diff --git a/libs/libsodium/src/crypto_pwhash/scryptsalsa208sha256/scrypt_platform.c b/libs/libsodium/src/crypto_pwhash/scryptsalsa208sha256/scrypt_platform.c index 44963ab2ec..00e888b5b6 100644 --- a/libs/libsodium/src/crypto_pwhash/scryptsalsa208sha256/scrypt_platform.c +++ b/libs/libsodium/src/crypto_pwhash/scryptsalsa208sha256/scrypt_platform.c @@ -31,14 +31,18 @@ # define MAP_ANON MAP_ANONYMOUS #endif #ifndef MAP_NOCORE -# define MAP_NOCORE 0 +# ifdef MAP_CONCEAL +# define MAP_NOCORE MAP_CONCEAL +# else +# define MAP_NOCORE 0 +# endif #endif #ifndef MAP_POPULATE # define MAP_POPULATE 0 #endif void * -alloc_region(escrypt_region_t *region, size_t size) +escrypt_alloc_region(escrypt_region_t *region, size_t size) { uint8_t *base, *aligned; #if defined(MAP_ANON) && defined(HAVE_MMAP) @@ -77,7 +81,7 @@ init_region(escrypt_region_t *region) } int -free_region(escrypt_region_t *region) +escrypt_free_region(escrypt_region_t *region) { if (region->base) { #if defined(MAP_ANON) && defined(HAVE_MMAP) @@ -104,5 +108,5 @@ escrypt_init_local(escrypt_local_t *local) int escrypt_free_local(escrypt_local_t *local) { - return free_region(local); + return escrypt_free_region(local); } diff --git a/libs/libsodium/src/crypto_pwhash/scryptsalsa208sha256/sse/pwhash_scryptsalsa208sha256_sse.c b/libs/libsodium/src/crypto_pwhash/scryptsalsa208sha256/sse/pwhash_scryptsalsa208sha256_sse.c index fb2723708b..04da24891d 100644 --- a/libs/libsodium/src/crypto_pwhash/scryptsalsa208sha256/sse/pwhash_scryptsalsa208sha256_sse.c +++ b/libs/libsodium/src/crypto_pwhash/scryptsalsa208sha256/sse/pwhash_scryptsalsa208sha256_sse.c @@ -35,32 +35,28 @@ #include #include "private/common.h" -#include "private/sse2_64_32.h" #ifdef HAVE_EMMINTRIN_H -# ifdef __GNUC__ +# ifdef __clang__ +# pragma clang attribute push(__attribute__((target("sse2"))), apply_to = function) +# elif defined(__GNUC__) # pragma GCC target("sse2") # endif + # include -# if defined(__XOP__) && defined(DISABLED) -# include -# endif + +# include "private/sse2_64_32.h" # include "../crypto_scrypt.h" # include "../pbkdf2-sha256.h" -# if defined(__XOP__) && defined(DISABLED) -# define ARX(out, in1, in2, s) \ - out = _mm_xor_si128(out, _mm_roti_epi32(_mm_add_epi32(in1, in2), s)); -# else -# define ARX(out, in1, in2, s) \ +# define ARX(out, in1, in2, s) \ { \ __m128i T = _mm_add_epi32(in1, in2); \ out = _mm_xor_si128(out, _mm_slli_epi32(T, s)); \ out = _mm_xor_si128(out, _mm_srli_epi32(T, 32 - s)); \ } -# endif # define SALSA20_2ROUNDS \ /* Operate on "columns". */ \ @@ -85,7 +81,7 @@ X2 = _mm_shuffle_epi32(X2, 0x4E); \ X3 = _mm_shuffle_epi32(X3, 0x93); -/** +/* * Apply the salsa20/8 core to the block provided in (X0 ... X3) ^ (Z0 ... Z3). */ # define SALSA20_8_XOR(in, out) \ @@ -103,10 +99,11 @@ (out)[3] = X3 = _mm_add_epi32(X3, Y3); \ } -/** +/* * blockmix_salsa8(Bin, Bout, r): - * Compute Bout = BlockMix_{salsa20/8, r}(Bin). The input Bin must be 128r - * bytes in length; the output Bout must also be the same size. + * Compute Bout = BlockMix_{salsa20/8, r}(Bin). + * The input Bin must be 128r bytes in length; + * the output Bout must also be the same size. */ static inline void blockmix_salsa8(const __m128i *Bin, __m128i *Bout, size_t r) @@ -208,18 +205,22 @@ blockmix_salsa8_xor(const __m128i *Bin1, const __m128i *Bin2, __m128i *Bout, # undef XOR4 # undef XOR4_2 -/** +/* * integerify(B, r): * Return the result of parsing B_{2r-1} as a little-endian integer. * Note that B's layout is permuted compared to the generic implementation. */ -static inline uint32_t -integerify(const void *B, size_t r) +static inline uint64_t +integerify(const __m128i *B, size_t r) { - return *(const uint32_t *) ((uintptr_t)(B) + (2 * r - 1) * 64); + const __m128i * X = B + (2*r - 1) * 4; + const uint32_t X0 = (uint32_t) _mm_cvtsi128_si32(X[0]); + const uint32_t X13 = (uint32_t) _mm_cvtsi128_si32(_mm_srli_si128(X[3], 4)); + + return (((uint64_t)(X13) << 32) + X0); } -/** +/* * smix(B, r, N, V, XY): * Compute B = SMix_r(B, N). The input B must be 128r bytes in length; * the temporary storage V must be 128rN bytes in length; the temporary @@ -228,12 +229,12 @@ integerify(const void *B, size_t r) * multiple of 64 bytes. */ static void -smix(uint8_t *B, size_t r, uint32_t N, void *V, void *XY) +smix(uint8_t *B, size_t r, uint64_t N, void *V, void *XY) { size_t s = 128 * r; - __m128i * X = (__m128i *) V, *Y; + __m128i *X = (__m128i *) V, *Y; uint32_t *X32 = (uint32_t *) V; - uint32_t i, j; + uint64_t i, j; size_t k; /* 1: X <-- B */ @@ -295,7 +296,7 @@ smix(uint8_t *B, size_t r, uint32_t N, void *V, void *XY) } } -/** +/* * escrypt_kdf(local, passwd, passwdlen, salt, saltlen, * N, r, p, buf, buflen): * Compute scrypt(passwd[0 .. passwdlen - 1], salt[0 .. saltlen - 1], N, r, @@ -371,10 +372,10 @@ escrypt_kdf_sse(escrypt_local_t *local, const uint8_t *passwd, size_t passwdlen, } /* LCOV_EXCL_END */ if (local->size < need) { - if (free_region(local)) { + if (escrypt_free_region(local)) { return -1; /* LCOV_EXCL_LINE */ } - if (!alloc_region(local, need)) { + if (!escrypt_alloc_region(local, need)) { return -1; /* LCOV_EXCL_LINE */ } } @@ -383,18 +384,23 @@ escrypt_kdf_sse(escrypt_local_t *local, const uint8_t *passwd, size_t passwdlen, XY = (uint32_t *) ((uint8_t *) V + V_size); /* 1: (B_0 ... B_{p-1}) <-- PBKDF2(P, S, 1, p * MFLen) */ - PBKDF2_SHA256(passwd, passwdlen, salt, saltlen, 1, B, B_size); + escrypt_PBKDF2_SHA256(passwd, passwdlen, salt, saltlen, 1, B, B_size); /* 2: for i = 0 to p - 1 do */ for (i = 0; i < p; i++) { /* 3: B_i <-- MF(B_i, N) */ - smix(&B[(size_t) 128 * i * r], r, (uint32_t) N, V, XY); + smix(&B[(size_t) 128 * i * r], r, N, V, XY); } /* 5: DK <-- PBKDF2(P, B, 1, dkLen) */ - PBKDF2_SHA256(passwd, passwdlen, B, B_size, 1, buf, buflen); + escrypt_PBKDF2_SHA256(passwd, passwdlen, B, B_size, 1, buf, buflen); /* Success! */ return 0; } + +# ifdef __clang__ +# pragma clang attribute pop +# endif + #endif diff --git a/libs/libsodium/src/crypto_scalarmult/curve25519/ref10/x25519_ref10.c b/libs/libsodium/src/crypto_scalarmult/curve25519/ref10/x25519_ref10.c index 7a430f0f28..195435947b 100644 --- a/libs/libsodium/src/crypto_scalarmult/curve25519/ref10/x25519_ref10.c +++ b/libs/libsodium/src/crypto_scalarmult/curve25519/ref10/x25519_ref10.c @@ -17,7 +17,7 @@ static int has_small_order(const unsigned char s[32]) { CRYPTO_ALIGN(16) - static const unsigned char blacklist[][32] = { + static const unsigned char blocklist[][32] = { /* 0 (order 4) */ { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -53,17 +53,17 @@ has_small_order(const unsigned char s[32]) unsigned int k; size_t i, j; - COMPILER_ASSERT(7 == sizeof blacklist / sizeof blacklist[0]); + COMPILER_ASSERT(7 == sizeof blocklist / sizeof blocklist[0]); for (j = 0; j < 31; j++) { - for (i = 0; i < sizeof blacklist / sizeof blacklist[0]; i++) { - c[i] |= s[j] ^ blacklist[i][j]; + for (i = 0; i < sizeof blocklist / sizeof blocklist[0]; i++) { + c[i] |= s[j] ^ blocklist[i][j]; } } - for (i = 0; i < sizeof blacklist / sizeof blacklist[0]; i++) { - c[i] |= (s[j] & 0x7f) ^ blacklist[i][j]; + for (i = 0; i < sizeof blocklist / sizeof blocklist[0]; i++) { + c[i] |= (s[j] & 0x7f) ^ blocklist[i][j]; } k = 0; - for (i = 0; i < sizeof blacklist / sizeof blacklist[0]; i++) { + for (i = 0; i < sizeof blocklist / sizeof blocklist[0]; i++) { k |= (c[i] - 1); } return (int) ((k >> 8) & 1); @@ -74,18 +74,13 @@ crypto_scalarmult_curve25519_ref10(unsigned char *q, const unsigned char *n, const unsigned char *p) { - unsigned char *t = q; + unsigned char t[32]; unsigned int i; - fe25519 x1; - fe25519 x2; - fe25519 z2; - fe25519 x3; - fe25519 z3; - fe25519 tmp0; - fe25519 tmp1; + fe25519 x1, x2, x3, z2, z3; + fe25519 a, b, aa, bb, e, da, cb; int pos; unsigned int swap; - unsigned int b; + unsigned int bit; if (has_small_order(p)) { return -1; @@ -104,30 +99,30 @@ crypto_scalarmult_curve25519_ref10(unsigned char *q, swap = 0; for (pos = 254; pos >= 0; --pos) { - b = t[pos / 8] >> (pos & 7); - b &= 1; - swap ^= b; + bit = t[pos / 8] >> (pos & 7); + bit &= 1; + swap ^= bit; fe25519_cswap(x2, x3, swap); fe25519_cswap(z2, z3, swap); - swap = b; - fe25519_sub(tmp0, x3, z3); - fe25519_sub(tmp1, x2, z2); - fe25519_add(x2, x2, z2); - fe25519_add(z2, x3, z3); - fe25519_mul(z3, tmp0, x2); - fe25519_mul(z2, z2, tmp1); - fe25519_sq(tmp0, tmp1); - fe25519_sq(tmp1, x2); - fe25519_add(x3, z3, z2); - fe25519_sub(z2, z3, z2); - fe25519_mul(x2, tmp1, tmp0); - fe25519_sub(tmp1, tmp1, tmp0); - fe25519_sq(z2, z2); - fe25519_scalar_product(z3, tmp1, 121666); + swap = bit; + fe25519_add(a, x2, z2); + fe25519_sub(b, x2, z2); + fe25519_sq(aa, a); + fe25519_sq(bb, b); + fe25519_mul(x2, aa, bb); + fe25519_sub(e, aa, bb); + fe25519_sub(da, x3, z3); + fe25519_mul(da, da, a); + fe25519_add(cb, x3, z3); + fe25519_mul(cb, cb, b); + fe25519_add(x3, da, cb); fe25519_sq(x3, x3); - fe25519_add(tmp0, tmp0, z3); - fe25519_mul(z3, x1, z2); - fe25519_mul(z2, tmp1, tmp0); + fe25519_sub(z3, da, cb); + fe25519_sq(z3, z3); + fe25519_mul(z3, z3, x1); + fe25519_mul32(z2, e, 121666); + fe25519_add(z2, z2, bb); + fe25519_mul(z2, z2, e); } fe25519_cswap(x2, x3, swap); fe25519_cswap(z2, z3, swap); @@ -136,6 +131,8 @@ crypto_scalarmult_curve25519_ref10(unsigned char *q, fe25519_mul(x2, x2, z2); fe25519_tobytes(q, x2); + sodium_memzero(t, sizeof t); + return 0; } diff --git a/libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/consts_namespace.h b/libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/consts_namespace.h index abbbc00c6d..fcb67e11ce 100644 --- a/libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/consts_namespace.h +++ b/libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/consts_namespace.h @@ -1,20 +1,20 @@ #ifndef consts_namespace_H #define consts_namespace_H -#define v0_0 crypto_scalarmult_curve25519_sandy2x_v0_0 -#define v1_0 crypto_scalarmult_curve25519_sandy2x_v1_0 -#define v2_1 crypto_scalarmult_curve25519_sandy2x_v2_1 -#define v9_0 crypto_scalarmult_curve25519_sandy2x_v9_0 -#define v9_9 crypto_scalarmult_curve25519_sandy2x_v9_9 -#define v19_19 crypto_scalarmult_curve25519_sandy2x_v19_19 -#define v38_1 crypto_scalarmult_curve25519_sandy2x_v38_1 -#define v38_38 crypto_scalarmult_curve25519_sandy2x_v38_38 -#define v121666_121666 crypto_scalarmult_curve25519_sandy2x_v121666_121666 -#define m25 crypto_scalarmult_curve25519_sandy2x_m25 -#define m26 crypto_scalarmult_curve25519_sandy2x_m26 -#define subc0 crypto_scalarmult_curve25519_sandy2x_subc0 -#define subc2 crypto_scalarmult_curve25519_sandy2x_subc2 -#define REDMASK51 crypto_scalarmult_curve25519_sandy2x_REDMASK51 +#define v0_0 _sodium_scalarmult_curve25519_sandy2x_v0_0 +#define v1_0 _sodium_scalarmult_curve25519_sandy2x_v1_0 +#define v2_1 _sodium_scalarmult_curve25519_sandy2x_v2_1 +#define v9_0 _sodium_scalarmult_curve25519_sandy2x_v9_0 +#define v9_9 _sodium_scalarmult_curve25519_sandy2x_v9_9 +#define v19_19 _sodium_scalarmult_curve25519_sandy2x_v19_19 +#define v38_1 _sodium_scalarmult_curve25519_sandy2x_v38_1 +#define v38_38 _sodium_scalarmult_curve25519_sandy2x_v38_38 +#define v121666_121666 _sodium_scalarmult_curve25519_sandy2x_v121666_121666 +#define m25 _sodium_scalarmult_curve25519_sandy2x_m25 +#define m26 _sodium_scalarmult_curve25519_sandy2x_m26 +#define subc0 _sodium_scalarmult_curve25519_sandy2x_subc0 +#define subc2 _sodium_scalarmult_curve25519_sandy2x_subc2 +#define REDMASK51 _sodium_scalarmult_curve25519_sandy2x_REDMASK51 #endif /* ifndef consts_namespace_H */ diff --git a/libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/curve25519_sandy2x.c b/libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/curve25519_sandy2x.c index cfb772837e..cf565968d7 100644 --- a/libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/curve25519_sandy2x.c +++ b/libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/curve25519_sandy2x.c @@ -15,7 +15,6 @@ #include "fe.h" #include "fe51.h" #include "ladder.h" -#include "ladder_base.h" #define x1 var[0] #define x2 var[1] @@ -25,90 +24,48 @@ static int crypto_scalarmult_curve25519_sandy2x(unsigned char *q, const unsigned char *n, const unsigned char *p) { - unsigned char *t = q; - fe var[3]; - fe51 x_51; - fe51 z_51; - unsigned int i; - - for (i = 0; i < 32; i++) { - t[i] = n[i]; - } - t[0] &= 248; - t[31] &= 127; - t[31] |= 64; - - fe_frombytes(x1, p); - - ladder(var, t); - - z_51.v[0] = (z2[1] << 26) + z2[0]; - z_51.v[1] = (z2[3] << 26) + z2[2]; - z_51.v[2] = (z2[5] << 26) + z2[4]; - z_51.v[3] = (z2[7] << 26) + z2[6]; - z_51.v[4] = (z2[9] << 26) + z2[8]; - - x_51.v[0] = (x2[1] << 26) + x2[0]; - x_51.v[1] = (x2[3] << 26) + x2[2]; - x_51.v[2] = (x2[5] << 26) + x2[4]; - x_51.v[3] = (x2[7] << 26) + x2[6]; - x_51.v[4] = (x2[9] << 26) + x2[8]; - - fe51_invert(&z_51, &z_51); - fe51_mul(&x_51, &x_51, &z_51); - fe51_pack(q, &x_51); - - return 0; -} - -#undef x2 -#undef z2 - -#define x2 var[0] -#define z2 var[1] - -static int -crypto_scalarmult_curve25519_sandy2x_base(unsigned char *q, - const unsigned char *n) -{ - unsigned char *t = q; - fe var[3]; - fe51 x_51; - fe51 z_51; - unsigned int i; - - for (i = 0;i < 32; i++) { - t[i] = n[i]; - } - t[0] &= 248; - t[31] &= 127; - t[31] |= 64; - - ladder_base(var, t); - - z_51.v[0] = (z2[1] << 26) + z2[0]; - z_51.v[1] = (z2[3] << 26) + z2[2]; - z_51.v[2] = (z2[5] << 26) + z2[4]; - z_51.v[3] = (z2[7] << 26) + z2[6]; - z_51.v[4] = (z2[9] << 26) + z2[8]; - - x_51.v[0] = (x2[1] << 26) + x2[0]; - x_51.v[1] = (x2[3] << 26) + x2[2]; - x_51.v[2] = (x2[5] << 26) + x2[4]; - x_51.v[3] = (x2[7] << 26) + x2[6]; - x_51.v[4] = (x2[9] << 26) + x2[8]; - - fe51_invert(&z_51, &z_51); - fe51_mul(&x_51, &x_51, &z_51); - fe51_pack(q, &x_51); - - return 0; + unsigned char t[32]; + fe var[3]; + fe51 x_51; + fe51 z_51; + unsigned int i; + + for (i = 0; i < 32; i++) { + t[i] = n[i]; + } + t[0] &= 248; + t[31] &= 127; + t[31] |= 64; + + fe_frombytes(x1, p); + + ladder(var, t); + + z_51.v[0] = (z2[1] << 26) + z2[0]; + z_51.v[1] = (z2[3] << 26) + z2[2]; + z_51.v[2] = (z2[5] << 26) + z2[4]; + z_51.v[3] = (z2[7] << 26) + z2[6]; + z_51.v[4] = (z2[9] << 26) + z2[8]; + + x_51.v[0] = (x2[1] << 26) + x2[0]; + x_51.v[1] = (x2[3] << 26) + x2[2]; + x_51.v[2] = (x2[5] << 26) + x2[4]; + x_51.v[3] = (x2[7] << 26) + x2[6]; + x_51.v[4] = (x2[9] << 26) + x2[8]; + + fe51_invert(&z_51, &z_51); + fe51_mul(&x_51, &x_51, &z_51); + fe51_pack(q, &x_51); + + sodium_memzero(t, sizeof t); + + return 0; } struct crypto_scalarmult_curve25519_implementation crypto_scalarmult_curve25519_sandy2x_implementation = { SODIUM_C99(.mult = ) crypto_scalarmult_curve25519_sandy2x, - SODIUM_C99(.mult_base = ) crypto_scalarmult_curve25519_sandy2x_base + SODIUM_C99(.mult_base = ) NULL }; #endif diff --git a/libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/fe.h b/libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/fe.h index c8ec4ff49d..fd8a0f7650 100644 --- a/libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/fe.h +++ b/libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/fe.h @@ -19,7 +19,7 @@ t[0]+2^26 t[1]+2^51 t[2]+2^77 t[3]+2^102 t[4]+...+2^230 t[9]. Bounds on each t[i] vary depending on context. */ -#define fe_frombytes crypto_scalarmult_curve25519_sandy2x_fe_frombytes +#define fe_frombytes _sodium_scalarmult_curve25519_sandy2x_fe_frombytes extern void fe_frombytes(fe, const unsigned char *); diff --git a/libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/fe51_mul.S b/libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/fe51_mul.S index 33e0347277..7c72bdaf30 100644 --- a/libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/fe51_mul.S +++ b/libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/fe51_mul.S @@ -3,6 +3,7 @@ /* This file is basically amd64-51/fe25519_mul.s. */ +#include "private/asm_cet.h" #include "fe51_namespace.h" #include "consts_namespace.h" .text @@ -19,6 +20,8 @@ ASM_HIDE_SYMBOL _fe51_mul #endif fe51_mul: _fe51_mul: + +_CET_ENDBR mov %rsp,%r11 and $31,%r11 add $96,%r11 @@ -30,7 +33,6 @@ movq %r14,24(%rsp) movq %r15,32(%rsp) movq %rbx,40(%rsp) movq %rbp,48(%rsp) -movq %rdi,56(%rsp) mov %rdx,%rcx movq 24(%rsi),%rdx imulq $19,%rdx,%rax diff --git a/libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/fe51_namespace.h b/libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/fe51_namespace.h index 3b2561ac1d..94ff8f0984 100644 --- a/libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/fe51_namespace.h +++ b/libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/fe51_namespace.h @@ -1,16 +1,16 @@ #ifndef fe51_namespace_H #define fe51_namespace_H -#define fe51 crypto_scalarmult_curve25519_sandy2x_fe51 -#define _fe51 _crypto_scalarmult_curve25519_sandy2x_fe51 -#define fe51_pack crypto_scalarmult_curve25519_sandy2x_fe51_pack -#define _fe51_pack _crypto_scalarmult_curve25519_sandy2x_fe51_pack -#define fe51_mul crypto_scalarmult_curve25519_sandy2x_fe51_mul -#define _fe51_mul _crypto_scalarmult_curve25519_sandy2x_fe51_mul -#define fe51_nsquare crypto_scalarmult_curve25519_sandy2x_fe51_nsquare -#define _fe51_nsquare _crypto_scalarmult_curve25519_sandy2x_fe51_nsquare +#define fe51 _sodium_scalarmult_curve25519_sandy2x_fe51 +#define _fe51 __sodium_scalarmult_curve25519_sandy2x_fe51 +#define fe51_pack _sodium_scalarmult_curve25519_sandy2x_fe51_pack +#define _fe51_pack __sodium_scalarmult_curve25519_sandy2x_fe51_pack +#define fe51_mul _sodium_scalarmult_curve25519_sandy2x_fe51_mul +#define _fe51_mul __sodium_scalarmult_curve25519_sandy2x_fe51_mul +#define fe51_nsquare _sodium_scalarmult_curve25519_sandy2x_fe51_nsquare +#define _fe51_nsquare __sodium_scalarmult_curve25519_sandy2x_fe51_nsquare -#define fe51_invert crypto_scalarmult_curve25519_sandy2x_fe51_invert +#define fe51_invert _sodium_scalarmult_curve25519_sandy2x_fe51_invert #endif /* ifndef fe51_namespace_H */ diff --git a/libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/fe51_nsquare.S b/libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/fe51_nsquare.S index d0e4839006..7cf6146adf 100644 --- a/libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/fe51_nsquare.S +++ b/libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/fe51_nsquare.S @@ -4,6 +4,7 @@ This file is adapted from amd64-51/fe25519_square.s: Adding loop to perform n squares. */ +#include "private/asm_cet.h" #include "fe51_namespace.h" #include "consts_namespace.h" .p2align 5 @@ -21,6 +22,7 @@ ASM_HIDE_SYMBOL _fe51_nsquare fe51_nsquare: _fe51_nsquare: +_CET_ENDBR mov %rsp,%r11 and $31,%r11 add $64,%r11 diff --git a/libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/fe51_pack.S b/libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/fe51_pack.S index d6c035379d..22e0cd37c7 100644 --- a/libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/fe51_pack.S +++ b/libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/fe51_pack.S @@ -4,6 +4,7 @@ This file is the result of merging amd64-51/fe25519_pack.c and amd64-51/fe25519_freeze.s. */ +#include "private/asm_cet.h" #include "fe51_namespace.h" #include "consts_namespace.h" .p2align 5 @@ -21,6 +22,7 @@ ASM_HIDE_SYMBOL _fe51_pack fe51_pack: _fe51_pack: +_CET_ENDBR mov %rsp,%r11 and $31,%r11 add $32,%r11 diff --git a/libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/fe_frombytes_sandy2x.c b/libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/fe_frombytes_sandy2x.c index f8d0d1ac29..695ccc5df9 100644 --- a/libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/fe_frombytes_sandy2x.c +++ b/libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/fe_frombytes_sandy2x.c @@ -9,70 +9,70 @@ static uint64_t load_3(const unsigned char *in) { - uint64_t result; - result = (uint64_t) in[0]; - result |= ((uint64_t) in[1]) << 8; - result |= ((uint64_t) in[2]) << 16; - return result; + uint64_t result; + result = (uint64_t) in[0]; + result |= ((uint64_t) in[1]) << 8; + result |= ((uint64_t) in[2]) << 16; + return result; } static uint64_t load_4(const unsigned char *in) { - uint64_t result; - result = (uint64_t) in[0]; - result |= ((uint64_t) in[1]) << 8; - result |= ((uint64_t) in[2]) << 16; - result |= ((uint64_t) in[3]) << 24; - return result; + uint64_t result; + result = (uint64_t) in[0]; + result |= ((uint64_t) in[1]) << 8; + result |= ((uint64_t) in[2]) << 16; + result |= ((uint64_t) in[3]) << 24; + return result; } void fe_frombytes(fe h, const unsigned char *s) { - uint64_t h0 = load_4(s); - uint64_t h1 = load_3(s + 4) << 6; - uint64_t h2 = load_3(s + 7) << 5; - uint64_t h3 = load_3(s + 10) << 3; - uint64_t h4 = load_3(s + 13) << 2; - uint64_t h5 = load_4(s + 16); - uint64_t h6 = load_3(s + 20) << 7; - uint64_t h7 = load_3(s + 23) << 5; - uint64_t h8 = load_3(s + 26) << 4; - uint64_t h9 = (load_3(s + 29) & 8388607) << 2; - uint64_t carry0; - uint64_t carry1; - uint64_t carry2; - uint64_t carry3; - uint64_t carry4; - uint64_t carry5; - uint64_t carry6; - uint64_t carry7; - uint64_t carry8; - uint64_t carry9; + uint64_t h0 = load_4(s); + uint64_t h1 = load_3(s + 4) << 6; + uint64_t h2 = load_3(s + 7) << 5; + uint64_t h3 = load_3(s + 10) << 3; + uint64_t h4 = load_3(s + 13) << 2; + uint64_t h5 = load_4(s + 16); + uint64_t h6 = load_3(s + 20) << 7; + uint64_t h7 = load_3(s + 23) << 5; + uint64_t h8 = load_3(s + 26) << 4; + uint64_t h9 = (load_3(s + 29) & 8388607) << 2; + uint64_t carry0; + uint64_t carry1; + uint64_t carry2; + uint64_t carry3; + uint64_t carry4; + uint64_t carry5; + uint64_t carry6; + uint64_t carry7; + uint64_t carry8; + uint64_t carry9; - carry9 = h9 >> 25; h0 += carry9 * 19; h9 &= 0x1FFFFFF; - carry1 = h1 >> 25; h2 += carry1; h1 &= 0x1FFFFFF; - carry3 = h3 >> 25; h4 += carry3; h3 &= 0x1FFFFFF; - carry5 = h5 >> 25; h6 += carry5; h5 &= 0x1FFFFFF; - carry7 = h7 >> 25; h8 += carry7; h7 &= 0x1FFFFFF; + carry9 = h9 >> 25; h0 += carry9 * 19; h9 &= 0x1FFFFFF; + carry1 = h1 >> 25; h2 += carry1; h1 &= 0x1FFFFFF; + carry3 = h3 >> 25; h4 += carry3; h3 &= 0x1FFFFFF; + carry5 = h5 >> 25; h6 += carry5; h5 &= 0x1FFFFFF; + carry7 = h7 >> 25; h8 += carry7; h7 &= 0x1FFFFFF; - carry0 = h0 >> 26; h1 += carry0; h0 &= 0x3FFFFFF; - carry2 = h2 >> 26; h3 += carry2; h2 &= 0x3FFFFFF; - carry4 = h4 >> 26; h5 += carry4; h4 &= 0x3FFFFFF; - carry6 = h6 >> 26; h7 += carry6; h6 &= 0x3FFFFFF; - carry8 = h8 >> 26; h9 += carry8; h8 &= 0x3FFFFFF; + carry0 = h0 >> 26; h1 += carry0; h0 &= 0x3FFFFFF; + carry2 = h2 >> 26; h3 += carry2; h2 &= 0x3FFFFFF; + carry4 = h4 >> 26; h5 += carry4; h4 &= 0x3FFFFFF; + carry6 = h6 >> 26; h7 += carry6; h6 &= 0x3FFFFFF; + carry8 = h8 >> 26; h9 += carry8; h8 &= 0x3FFFFFF; - h[0] = h0; - h[1] = h1; - h[2] = h2; - h[3] = h3; - h[4] = h4; - h[5] = h5; - h[6] = h6; - h[7] = h7; - h[8] = h8; - h[9] = h9; + h[0] = h0; + h[1] = h1; + h[2] = h2; + h[3] = h3; + h[4] = h4; + h[5] = h5; + h[6] = h6; + h[7] = h7; + h[8] = h8; + h[9] = h9; } #endif diff --git a/libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/ladder.S b/libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/ladder.S index 24f0f084d4..ed77bce199 100644 --- a/libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/ladder.S +++ b/libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/ladder.S @@ -1,5 +1,6 @@ #ifdef IN_SANDY2X +#include "private/asm_cet.h" #include "ladder_namespace.h" #include "consts_namespace.h" .p2align 5 @@ -17,6 +18,7 @@ ASM_HIDE_SYMBOL _ladder ladder: _ladder: +_CET_ENDBR mov %rsp,%r11 and $31,%r11 add $1856,%r11 diff --git a/libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/ladder_base.S b/libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/ladder_base.S deleted file mode 100644 index 465f01733c..0000000000 --- a/libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/ladder_base.S +++ /dev/null @@ -1,1295 +0,0 @@ -#ifdef IN_SANDY2X - -#include "ladder_base_namespace.h" -#include "consts_namespace.h" -.p2align 5 - -#ifdef ASM_HIDE_SYMBOL -ASM_HIDE_SYMBOL ladder_base -ASM_HIDE_SYMBOL _ladder_base -#endif -.globl ladder_base -.globl _ladder_base -#ifdef __ELF__ -.type ladder_base, @function -.type _ladder_base, @function -#endif -ladder_base: -_ladder_base: - -mov %rsp,%r11 -and $31,%r11 -add $1568,%r11 -sub %r11,%rsp -movq %r11,1536(%rsp) -movq %r12,1544(%rsp) -movq %r13,1552(%rsp) -vmovdqa v0_0(%rip),%xmm0 -vmovdqa v1_0(%rip),%xmm1 -vmovdqa v9_0(%rip),%xmm2 -vmovdqa %xmm2,0(%rsp) -vmovdqa %xmm0,16(%rsp) -vmovdqa %xmm0,32(%rsp) -vmovdqa %xmm0,48(%rsp) -vmovdqa %xmm0,64(%rsp) -vmovdqa %xmm1,80(%rsp) -vmovdqa %xmm0,96(%rsp) -vmovdqa %xmm0,112(%rsp) -vmovdqa %xmm0,128(%rsp) -vmovdqa %xmm0,144(%rsp) -vmovdqa %xmm1,%xmm0 -vpxor %xmm1,%xmm1,%xmm1 -vpxor %xmm2,%xmm2,%xmm2 -vpxor %xmm3,%xmm3,%xmm3 -vpxor %xmm4,%xmm4,%xmm4 -vpxor %xmm5,%xmm5,%xmm5 -vpxor %xmm6,%xmm6,%xmm6 -vpxor %xmm7,%xmm7,%xmm7 -vpxor %xmm8,%xmm8,%xmm8 -vpxor %xmm9,%xmm9,%xmm9 -movq 0(%rsi),%rdx -movq 8(%rsi),%rcx -movq 16(%rsi),%r8 -movq 24(%rsi),%r9 -shrd $1,%rcx,%rdx -shrd $1,%r8,%rcx -shrd $1,%r9,%r8 -shr $1,%r9 -xorq 0(%rsi),%rdx -xorq 8(%rsi),%rcx -xorq 16(%rsi),%r8 -xorq 24(%rsi),%r9 -leaq 512(%rsp),%rsi -mov $64,%rax - -.p2align 4 -._ladder_base_small_loop: -mov %rdx,%r10 -mov %rcx,%r11 -mov %r8,%r12 -mov %r9,%r13 -shr $1,%rdx -shr $1,%rcx -shr $1,%r8 -shr $1,%r9 -and $1,%r10d -and $1,%r11d -and $1,%r12d -and $1,%r13d -neg %r10 -neg %r11 -neg %r12 -neg %r13 -movl %r10d,0(%rsi) -movl %r11d,256(%rsi) -movl %r12d,512(%rsi) -movl %r13d,768(%rsi) -add $4,%rsi -sub $1,%rax -jne ._ladder_base_small_loop -mov $255,%rdx -add $760,%rsi - -.p2align 4 -._ladder_base_loop: -sub $1,%rdx -vbroadcastss 0(%rsi),%xmm10 -sub $4,%rsi -vmovdqa 0(%rsp),%xmm11 -vmovdqa 80(%rsp),%xmm12 -vpxor %xmm11,%xmm0,%xmm13 -vpand %xmm10,%xmm13,%xmm13 -vpxor %xmm13,%xmm0,%xmm0 -vpxor %xmm13,%xmm11,%xmm11 -vpxor %xmm12,%xmm1,%xmm13 -vpand %xmm10,%xmm13,%xmm13 -vpxor %xmm13,%xmm1,%xmm1 -vpxor %xmm13,%xmm12,%xmm12 -vmovdqa 16(%rsp),%xmm13 -vmovdqa 96(%rsp),%xmm14 -vpxor %xmm13,%xmm2,%xmm15 -vpand %xmm10,%xmm15,%xmm15 -vpxor %xmm15,%xmm2,%xmm2 -vpxor %xmm15,%xmm13,%xmm13 -vpxor %xmm14,%xmm3,%xmm15 -vpand %xmm10,%xmm15,%xmm15 -vpxor %xmm15,%xmm3,%xmm3 -vpxor %xmm15,%xmm14,%xmm14 -vmovdqa %xmm13,0(%rsp) -vmovdqa %xmm14,16(%rsp) -vmovdqa 32(%rsp),%xmm13 -vmovdqa 112(%rsp),%xmm14 -vpxor %xmm13,%xmm4,%xmm15 -vpand %xmm10,%xmm15,%xmm15 -vpxor %xmm15,%xmm4,%xmm4 -vpxor %xmm15,%xmm13,%xmm13 -vpxor %xmm14,%xmm5,%xmm15 -vpand %xmm10,%xmm15,%xmm15 -vpxor %xmm15,%xmm5,%xmm5 -vpxor %xmm15,%xmm14,%xmm14 -vmovdqa %xmm13,32(%rsp) -vmovdqa %xmm14,80(%rsp) -vmovdqa 48(%rsp),%xmm13 -vmovdqa 128(%rsp),%xmm14 -vpxor %xmm13,%xmm6,%xmm15 -vpand %xmm10,%xmm15,%xmm15 -vpxor %xmm15,%xmm6,%xmm6 -vpxor %xmm15,%xmm13,%xmm13 -vpxor %xmm14,%xmm7,%xmm15 -vpand %xmm10,%xmm15,%xmm15 -vpxor %xmm15,%xmm7,%xmm7 -vpxor %xmm15,%xmm14,%xmm14 -vmovdqa %xmm13,48(%rsp) -vmovdqa %xmm14,96(%rsp) -vmovdqa 64(%rsp),%xmm13 -vmovdqa 144(%rsp),%xmm14 -vpxor %xmm13,%xmm8,%xmm15 -vpand %xmm10,%xmm15,%xmm15 -vpxor %xmm15,%xmm8,%xmm8 -vpxor %xmm15,%xmm13,%xmm13 -vpxor %xmm14,%xmm9,%xmm15 -vpand %xmm10,%xmm15,%xmm15 -vpxor %xmm15,%xmm9,%xmm9 -vpxor %xmm15,%xmm14,%xmm14 -vmovdqa %xmm13,64(%rsp) -vmovdqa %xmm14,112(%rsp) -vpaddq subc0(%rip),%xmm11,%xmm10 -vpsubq %xmm12,%xmm10,%xmm10 -vpaddq %xmm12,%xmm11,%xmm11 -vpunpckhqdq %xmm10,%xmm11,%xmm12 -vpunpcklqdq %xmm10,%xmm11,%xmm10 -vpaddq %xmm1,%xmm0,%xmm11 -vpaddq subc0(%rip),%xmm0,%xmm0 -vpsubq %xmm1,%xmm0,%xmm0 -vpunpckhqdq %xmm11,%xmm0,%xmm1 -vpunpcklqdq %xmm11,%xmm0,%xmm0 -vpmuludq %xmm0,%xmm10,%xmm11 -vpmuludq %xmm1,%xmm10,%xmm13 -vmovdqa %xmm1,128(%rsp) -vpaddq %xmm1,%xmm1,%xmm1 -vpmuludq %xmm0,%xmm12,%xmm14 -vmovdqa %xmm0,144(%rsp) -vpaddq %xmm14,%xmm13,%xmm13 -vpmuludq %xmm1,%xmm12,%xmm0 -vmovdqa %xmm1,160(%rsp) -vpaddq %xmm3,%xmm2,%xmm1 -vpaddq subc2(%rip),%xmm2,%xmm2 -vpsubq %xmm3,%xmm2,%xmm2 -vpunpckhqdq %xmm1,%xmm2,%xmm3 -vpunpcklqdq %xmm1,%xmm2,%xmm1 -vpmuludq %xmm1,%xmm10,%xmm2 -vpaddq %xmm2,%xmm0,%xmm0 -vpmuludq %xmm3,%xmm10,%xmm2 -vmovdqa %xmm3,176(%rsp) -vpaddq %xmm3,%xmm3,%xmm3 -vpmuludq %xmm1,%xmm12,%xmm14 -vmovdqa %xmm1,192(%rsp) -vpaddq %xmm14,%xmm2,%xmm2 -vpmuludq %xmm3,%xmm12,%xmm1 -vmovdqa %xmm3,208(%rsp) -vpaddq %xmm5,%xmm4,%xmm3 -vpaddq subc2(%rip),%xmm4,%xmm4 -vpsubq %xmm5,%xmm4,%xmm4 -vpunpckhqdq %xmm3,%xmm4,%xmm5 -vpunpcklqdq %xmm3,%xmm4,%xmm3 -vpmuludq %xmm3,%xmm10,%xmm4 -vpaddq %xmm4,%xmm1,%xmm1 -vpmuludq %xmm5,%xmm10,%xmm4 -vmovdqa %xmm5,224(%rsp) -vpaddq %xmm5,%xmm5,%xmm5 -vpmuludq %xmm3,%xmm12,%xmm14 -vmovdqa %xmm3,240(%rsp) -vpaddq %xmm14,%xmm4,%xmm4 -vpaddq %xmm7,%xmm6,%xmm3 -vpaddq subc2(%rip),%xmm6,%xmm6 -vpsubq %xmm7,%xmm6,%xmm6 -vpunpckhqdq %xmm3,%xmm6,%xmm7 -vpunpcklqdq %xmm3,%xmm6,%xmm3 -vpmuludq %xmm3,%xmm10,%xmm6 -vpmuludq %xmm5,%xmm12,%xmm14 -vmovdqa %xmm5,256(%rsp) -vpmuludq v19_19(%rip),%xmm5,%xmm5 -vmovdqa %xmm5,272(%rsp) -vpaddq %xmm14,%xmm6,%xmm6 -vpmuludq %xmm7,%xmm10,%xmm5 -vmovdqa %xmm7,288(%rsp) -vpaddq %xmm7,%xmm7,%xmm7 -vpmuludq %xmm3,%xmm12,%xmm14 -vmovdqa %xmm3,304(%rsp) -vpaddq %xmm14,%xmm5,%xmm5 -vpmuludq v19_19(%rip),%xmm3,%xmm3 -vmovdqa %xmm3,320(%rsp) -vpaddq %xmm9,%xmm8,%xmm3 -vpaddq subc2(%rip),%xmm8,%xmm8 -vpsubq %xmm9,%xmm8,%xmm8 -vpunpckhqdq %xmm3,%xmm8,%xmm9 -vpunpcklqdq %xmm3,%xmm8,%xmm3 -vmovdqa %xmm3,336(%rsp) -vpmuludq %xmm7,%xmm12,%xmm8 -vmovdqa %xmm7,352(%rsp) -vpmuludq v19_19(%rip),%xmm7,%xmm7 -vmovdqa %xmm7,368(%rsp) -vpmuludq %xmm3,%xmm10,%xmm7 -vpaddq %xmm7,%xmm8,%xmm8 -vpmuludq %xmm9,%xmm10,%xmm7 -vmovdqa %xmm9,384(%rsp) -vpaddq %xmm9,%xmm9,%xmm9 -vpmuludq %xmm3,%xmm12,%xmm10 -vpaddq %xmm10,%xmm7,%xmm7 -vpmuludq v19_19(%rip),%xmm3,%xmm3 -vmovdqa %xmm3,400(%rsp) -vpmuludq v19_19(%rip),%xmm12,%xmm12 -vpmuludq %xmm9,%xmm12,%xmm3 -vmovdqa %xmm9,416(%rsp) -vpaddq %xmm3,%xmm11,%xmm11 -vmovdqa 0(%rsp),%xmm3 -vmovdqa 16(%rsp),%xmm9 -vpaddq subc2(%rip),%xmm3,%xmm10 -vpsubq %xmm9,%xmm10,%xmm10 -vpaddq %xmm9,%xmm3,%xmm3 -vpunpckhqdq %xmm10,%xmm3,%xmm9 -vpunpcklqdq %xmm10,%xmm3,%xmm3 -vpmuludq 144(%rsp),%xmm3,%xmm10 -vpaddq %xmm10,%xmm0,%xmm0 -vpmuludq 128(%rsp),%xmm3,%xmm10 -vpaddq %xmm10,%xmm2,%xmm2 -vpmuludq 192(%rsp),%xmm3,%xmm10 -vpaddq %xmm10,%xmm1,%xmm1 -vpmuludq 176(%rsp),%xmm3,%xmm10 -vpaddq %xmm10,%xmm4,%xmm4 -vpmuludq 240(%rsp),%xmm3,%xmm10 -vpaddq %xmm10,%xmm6,%xmm6 -vpmuludq 224(%rsp),%xmm3,%xmm10 -vpaddq %xmm10,%xmm5,%xmm5 -vpmuludq 304(%rsp),%xmm3,%xmm10 -vpaddq %xmm10,%xmm8,%xmm8 -vpmuludq 288(%rsp),%xmm3,%xmm10 -vpaddq %xmm10,%xmm7,%xmm7 -vpmuludq v19_19(%rip),%xmm3,%xmm3 -vpmuludq 336(%rsp),%xmm3,%xmm10 -vpaddq %xmm10,%xmm11,%xmm11 -vpmuludq 384(%rsp),%xmm3,%xmm3 -vpaddq %xmm3,%xmm13,%xmm13 -vpmuludq 144(%rsp),%xmm9,%xmm3 -vpaddq %xmm3,%xmm2,%xmm2 -vpmuludq 160(%rsp),%xmm9,%xmm3 -vpaddq %xmm3,%xmm1,%xmm1 -vpmuludq 192(%rsp),%xmm9,%xmm3 -vpaddq %xmm3,%xmm4,%xmm4 -vpmuludq 208(%rsp),%xmm9,%xmm3 -vpaddq %xmm3,%xmm6,%xmm6 -vpmuludq 240(%rsp),%xmm9,%xmm3 -vpaddq %xmm3,%xmm5,%xmm5 -vpmuludq 256(%rsp),%xmm9,%xmm3 -vpaddq %xmm3,%xmm8,%xmm8 -vpmuludq 304(%rsp),%xmm9,%xmm3 -vpaddq %xmm3,%xmm7,%xmm7 -vpmuludq v19_19(%rip),%xmm9,%xmm9 -vpmuludq 352(%rsp),%xmm9,%xmm3 -vpaddq %xmm3,%xmm11,%xmm11 -vpmuludq 336(%rsp),%xmm9,%xmm3 -vpaddq %xmm3,%xmm13,%xmm13 -vpmuludq 416(%rsp),%xmm9,%xmm9 -vpaddq %xmm9,%xmm0,%xmm0 -vmovdqa 32(%rsp),%xmm3 -vmovdqa 80(%rsp),%xmm9 -vpaddq subc2(%rip),%xmm3,%xmm10 -vpsubq %xmm9,%xmm10,%xmm10 -vpaddq %xmm9,%xmm3,%xmm3 -vpunpckhqdq %xmm10,%xmm3,%xmm9 -vpunpcklqdq %xmm10,%xmm3,%xmm3 -vpmuludq 144(%rsp),%xmm3,%xmm10 -vpaddq %xmm10,%xmm1,%xmm1 -vpmuludq 128(%rsp),%xmm3,%xmm10 -vpaddq %xmm10,%xmm4,%xmm4 -vpmuludq 192(%rsp),%xmm3,%xmm10 -vpaddq %xmm10,%xmm6,%xmm6 -vpmuludq 176(%rsp),%xmm3,%xmm10 -vpaddq %xmm10,%xmm5,%xmm5 -vpmuludq 240(%rsp),%xmm3,%xmm10 -vpaddq %xmm10,%xmm8,%xmm8 -vpmuludq 224(%rsp),%xmm3,%xmm10 -vpaddq %xmm10,%xmm7,%xmm7 -vpmuludq v19_19(%rip),%xmm3,%xmm3 -vpmuludq 304(%rsp),%xmm3,%xmm10 -vpaddq %xmm10,%xmm11,%xmm11 -vpmuludq 288(%rsp),%xmm3,%xmm10 -vpaddq %xmm10,%xmm13,%xmm13 -vpmuludq 336(%rsp),%xmm3,%xmm10 -vpaddq %xmm10,%xmm0,%xmm0 -vpmuludq 384(%rsp),%xmm3,%xmm3 -vpaddq %xmm3,%xmm2,%xmm2 -vpmuludq 144(%rsp),%xmm9,%xmm3 -vpaddq %xmm3,%xmm4,%xmm4 -vpmuludq 160(%rsp),%xmm9,%xmm3 -vpaddq %xmm3,%xmm6,%xmm6 -vpmuludq 192(%rsp),%xmm9,%xmm3 -vpaddq %xmm3,%xmm5,%xmm5 -vpmuludq 208(%rsp),%xmm9,%xmm3 -vpaddq %xmm3,%xmm8,%xmm8 -vpmuludq 240(%rsp),%xmm9,%xmm3 -vpaddq %xmm3,%xmm7,%xmm7 -vpmuludq v19_19(%rip),%xmm9,%xmm9 -vpmuludq 256(%rsp),%xmm9,%xmm3 -vpaddq %xmm3,%xmm11,%xmm11 -vpmuludq 304(%rsp),%xmm9,%xmm3 -vpaddq %xmm3,%xmm13,%xmm13 -vpmuludq 352(%rsp),%xmm9,%xmm3 -vpaddq %xmm3,%xmm0,%xmm0 -vpmuludq 336(%rsp),%xmm9,%xmm3 -vpaddq %xmm3,%xmm2,%xmm2 -vpmuludq 416(%rsp),%xmm9,%xmm9 -vpaddq %xmm9,%xmm1,%xmm1 -vmovdqa 48(%rsp),%xmm3 -vmovdqa 96(%rsp),%xmm9 -vpaddq subc2(%rip),%xmm3,%xmm10 -vpsubq %xmm9,%xmm10,%xmm10 -vpaddq %xmm9,%xmm3,%xmm3 -vpunpckhqdq %xmm10,%xmm3,%xmm9 -vpunpcklqdq %xmm10,%xmm3,%xmm3 -vpmuludq 144(%rsp),%xmm3,%xmm10 -vpaddq %xmm10,%xmm6,%xmm6 -vpmuludq 128(%rsp),%xmm3,%xmm10 -vpaddq %xmm10,%xmm5,%xmm5 -vpmuludq 192(%rsp),%xmm3,%xmm10 -vpaddq %xmm10,%xmm8,%xmm8 -vpmuludq 176(%rsp),%xmm3,%xmm10 -vpaddq %xmm10,%xmm7,%xmm7 -vpmuludq v19_19(%rip),%xmm3,%xmm3 -vpmuludq 240(%rsp),%xmm3,%xmm10 -vpaddq %xmm10,%xmm11,%xmm11 -vpmuludq 224(%rsp),%xmm3,%xmm10 -vpaddq %xmm10,%xmm13,%xmm13 -vpmuludq 304(%rsp),%xmm3,%xmm10 -vpaddq %xmm10,%xmm0,%xmm0 -vpmuludq 288(%rsp),%xmm3,%xmm10 -vpaddq %xmm10,%xmm2,%xmm2 -vpmuludq 336(%rsp),%xmm3,%xmm10 -vpaddq %xmm10,%xmm1,%xmm1 -vpmuludq 384(%rsp),%xmm3,%xmm3 -vpaddq %xmm3,%xmm4,%xmm4 -vpmuludq 144(%rsp),%xmm9,%xmm3 -vpaddq %xmm3,%xmm5,%xmm5 -vpmuludq 160(%rsp),%xmm9,%xmm3 -vpaddq %xmm3,%xmm8,%xmm8 -vpmuludq 192(%rsp),%xmm9,%xmm3 -vpaddq %xmm3,%xmm7,%xmm7 -vpmuludq v19_19(%rip),%xmm9,%xmm9 -vpmuludq 208(%rsp),%xmm9,%xmm3 -vpaddq %xmm3,%xmm11,%xmm11 -vpmuludq 240(%rsp),%xmm9,%xmm3 -vpaddq %xmm3,%xmm13,%xmm13 -vpmuludq 256(%rsp),%xmm9,%xmm3 -vpaddq %xmm3,%xmm0,%xmm0 -vpmuludq 304(%rsp),%xmm9,%xmm3 -vpaddq %xmm3,%xmm2,%xmm2 -vpmuludq 352(%rsp),%xmm9,%xmm3 -vpaddq %xmm3,%xmm1,%xmm1 -vpmuludq 336(%rsp),%xmm9,%xmm3 -vpaddq %xmm3,%xmm4,%xmm4 -vpmuludq 416(%rsp),%xmm9,%xmm9 -vpaddq %xmm9,%xmm6,%xmm6 -vmovdqa 64(%rsp),%xmm3 -vmovdqa 112(%rsp),%xmm9 -vpaddq subc2(%rip),%xmm3,%xmm10 -vpsubq %xmm9,%xmm10,%xmm10 -vpaddq %xmm9,%xmm3,%xmm3 -vpunpckhqdq %xmm10,%xmm3,%xmm9 -vpunpcklqdq %xmm10,%xmm3,%xmm3 -vpmuludq 144(%rsp),%xmm3,%xmm10 -vpaddq %xmm10,%xmm8,%xmm8 -vpmuludq 128(%rsp),%xmm3,%xmm10 -vpaddq %xmm10,%xmm7,%xmm7 -vpmuludq v19_19(%rip),%xmm3,%xmm3 -vpmuludq 192(%rsp),%xmm3,%xmm10 -vpaddq %xmm10,%xmm11,%xmm11 -vpmuludq 176(%rsp),%xmm3,%xmm10 -vpaddq %xmm10,%xmm13,%xmm13 -vpmuludq 240(%rsp),%xmm3,%xmm10 -vpaddq %xmm10,%xmm0,%xmm0 -vpmuludq 224(%rsp),%xmm3,%xmm10 -vpaddq %xmm10,%xmm2,%xmm2 -vpmuludq 304(%rsp),%xmm3,%xmm10 -vpaddq %xmm10,%xmm1,%xmm1 -vpmuludq 288(%rsp),%xmm3,%xmm10 -vpaddq %xmm10,%xmm4,%xmm4 -vpmuludq 336(%rsp),%xmm3,%xmm10 -vpaddq %xmm10,%xmm6,%xmm6 -vpmuludq 384(%rsp),%xmm3,%xmm3 -vpaddq %xmm3,%xmm5,%xmm5 -vpmuludq 144(%rsp),%xmm9,%xmm3 -vpaddq %xmm3,%xmm7,%xmm7 -vpmuludq v19_19(%rip),%xmm9,%xmm9 -vpmuludq 160(%rsp),%xmm9,%xmm3 -vpaddq %xmm3,%xmm11,%xmm11 -vpmuludq 192(%rsp),%xmm9,%xmm3 -vpaddq %xmm3,%xmm13,%xmm13 -vpmuludq 208(%rsp),%xmm9,%xmm3 -vpaddq %xmm3,%xmm0,%xmm0 -vpmuludq 240(%rsp),%xmm9,%xmm3 -vpaddq %xmm3,%xmm2,%xmm2 -vpmuludq 256(%rsp),%xmm9,%xmm3 -vpaddq %xmm3,%xmm1,%xmm1 -vpmuludq 304(%rsp),%xmm9,%xmm3 -vpaddq %xmm3,%xmm4,%xmm4 -vpmuludq 352(%rsp),%xmm9,%xmm3 -vpaddq %xmm3,%xmm6,%xmm6 -vpmuludq 336(%rsp),%xmm9,%xmm3 -vpaddq %xmm3,%xmm5,%xmm5 -vpmuludq 416(%rsp),%xmm9,%xmm9 -vpaddq %xmm9,%xmm8,%xmm8 -vpsrlq $25,%xmm4,%xmm3 -vpaddq %xmm3,%xmm6,%xmm6 -vpand m25(%rip),%xmm4,%xmm4 -vpsrlq $26,%xmm11,%xmm3 -vpaddq %xmm3,%xmm13,%xmm13 -vpand m26(%rip),%xmm11,%xmm11 -vpsrlq $26,%xmm6,%xmm3 -vpaddq %xmm3,%xmm5,%xmm5 -vpand m26(%rip),%xmm6,%xmm6 -vpsrlq $25,%xmm13,%xmm3 -vpaddq %xmm3,%xmm0,%xmm0 -vpand m25(%rip),%xmm13,%xmm13 -vpsrlq $25,%xmm5,%xmm3 -vpaddq %xmm3,%xmm8,%xmm8 -vpand m25(%rip),%xmm5,%xmm5 -vpsrlq $26,%xmm0,%xmm3 -vpaddq %xmm3,%xmm2,%xmm2 -vpand m26(%rip),%xmm0,%xmm0 -vpsrlq $26,%xmm8,%xmm3 -vpaddq %xmm3,%xmm7,%xmm7 -vpand m26(%rip),%xmm8,%xmm8 -vpsrlq $25,%xmm2,%xmm3 -vpaddq %xmm3,%xmm1,%xmm1 -vpand m25(%rip),%xmm2,%xmm2 -vpsrlq $25,%xmm7,%xmm3 -vpsllq $4,%xmm3,%xmm9 -vpaddq %xmm3,%xmm11,%xmm11 -vpsllq $1,%xmm3,%xmm3 -vpaddq %xmm3,%xmm9,%xmm9 -vpaddq %xmm9,%xmm11,%xmm11 -vpand m25(%rip),%xmm7,%xmm7 -vpsrlq $26,%xmm1,%xmm3 -vpaddq %xmm3,%xmm4,%xmm4 -vpand m26(%rip),%xmm1,%xmm1 -vpsrlq $26,%xmm11,%xmm3 -vpaddq %xmm3,%xmm13,%xmm13 -vpand m26(%rip),%xmm11,%xmm11 -vpsrlq $25,%xmm4,%xmm3 -vpaddq %xmm3,%xmm6,%xmm6 -vpand m25(%rip),%xmm4,%xmm4 -vpunpcklqdq %xmm13,%xmm11,%xmm3 -vpunpckhqdq %xmm13,%xmm11,%xmm9 -vpaddq subc0(%rip),%xmm9,%xmm10 -vpsubq %xmm3,%xmm10,%xmm10 -vpaddq %xmm9,%xmm3,%xmm3 -vpunpckhqdq %xmm3,%xmm10,%xmm9 -vpunpcklqdq %xmm3,%xmm10,%xmm10 -vpmuludq %xmm10,%xmm10,%xmm3 -vpaddq %xmm10,%xmm10,%xmm10 -vpmuludq %xmm9,%xmm10,%xmm11 -vpunpcklqdq %xmm2,%xmm0,%xmm12 -vpunpckhqdq %xmm2,%xmm0,%xmm0 -vpaddq subc2(%rip),%xmm0,%xmm2 -vpsubq %xmm12,%xmm2,%xmm2 -vpaddq %xmm0,%xmm12,%xmm12 -vpunpckhqdq %xmm12,%xmm2,%xmm0 -vpunpcklqdq %xmm12,%xmm2,%xmm2 -vpmuludq %xmm2,%xmm10,%xmm12 -vpaddq %xmm9,%xmm9,%xmm13 -vpmuludq %xmm13,%xmm9,%xmm9 -vpaddq %xmm9,%xmm12,%xmm12 -vpmuludq %xmm0,%xmm10,%xmm9 -vpmuludq %xmm2,%xmm13,%xmm14 -vpaddq %xmm14,%xmm9,%xmm9 -vpunpcklqdq %xmm4,%xmm1,%xmm14 -vpunpckhqdq %xmm4,%xmm1,%xmm1 -vpaddq subc2(%rip),%xmm1,%xmm4 -vpsubq %xmm14,%xmm4,%xmm4 -vpaddq %xmm1,%xmm14,%xmm14 -vpunpckhqdq %xmm14,%xmm4,%xmm1 -vpunpcklqdq %xmm14,%xmm4,%xmm4 -vmovdqa %xmm1,0(%rsp) -vpaddq %xmm1,%xmm1,%xmm1 -vmovdqa %xmm1,16(%rsp) -vpmuludq v19_19(%rip),%xmm1,%xmm1 -vmovdqa %xmm1,32(%rsp) -vpmuludq %xmm4,%xmm10,%xmm1 -vpmuludq %xmm2,%xmm2,%xmm14 -vpaddq %xmm14,%xmm1,%xmm1 -vpmuludq 0(%rsp),%xmm10,%xmm14 -vpmuludq %xmm4,%xmm13,%xmm15 -vpaddq %xmm15,%xmm14,%xmm14 -vpunpcklqdq %xmm5,%xmm6,%xmm15 -vpunpckhqdq %xmm5,%xmm6,%xmm5 -vpaddq subc2(%rip),%xmm5,%xmm6 -vpsubq %xmm15,%xmm6,%xmm6 -vpaddq %xmm5,%xmm15,%xmm15 -vpunpckhqdq %xmm15,%xmm6,%xmm5 -vpunpcklqdq %xmm15,%xmm6,%xmm6 -vmovdqa %xmm6,48(%rsp) -vpmuludq v19_19(%rip),%xmm6,%xmm6 -vmovdqa %xmm6,64(%rsp) -vmovdqa %xmm5,80(%rsp) -vpmuludq v38_38(%rip),%xmm5,%xmm5 -vmovdqa %xmm5,96(%rsp) -vpmuludq 48(%rsp),%xmm10,%xmm5 -vpaddq %xmm0,%xmm0,%xmm6 -vpmuludq %xmm6,%xmm0,%xmm0 -vpaddq %xmm0,%xmm5,%xmm5 -vpmuludq 80(%rsp),%xmm10,%xmm0 -vpmuludq %xmm4,%xmm6,%xmm15 -vpaddq %xmm15,%xmm0,%xmm0 -vpmuludq %xmm6,%xmm13,%xmm15 -vpaddq %xmm15,%xmm1,%xmm1 -vpmuludq %xmm6,%xmm2,%xmm15 -vpaddq %xmm15,%xmm14,%xmm14 -vpunpcklqdq %xmm7,%xmm8,%xmm15 -vpunpckhqdq %xmm7,%xmm8,%xmm7 -vpaddq subc2(%rip),%xmm7,%xmm8 -vpsubq %xmm15,%xmm8,%xmm8 -vpaddq %xmm7,%xmm15,%xmm15 -vpunpckhqdq %xmm15,%xmm8,%xmm7 -vpunpcklqdq %xmm15,%xmm8,%xmm8 -vmovdqa %xmm8,112(%rsp) -vpmuludq v19_19(%rip),%xmm8,%xmm8 -vmovdqa %xmm8,160(%rsp) -vpmuludq 112(%rsp),%xmm10,%xmm8 -vpmuludq %xmm7,%xmm10,%xmm10 -vpmuludq v38_38(%rip),%xmm7,%xmm15 -vpmuludq %xmm15,%xmm7,%xmm7 -vpaddq %xmm7,%xmm8,%xmm8 -vpmuludq %xmm15,%xmm13,%xmm7 -vpaddq %xmm7,%xmm3,%xmm3 -vpmuludq %xmm15,%xmm2,%xmm7 -vpaddq %xmm7,%xmm11,%xmm11 -vpmuludq 80(%rsp),%xmm13,%xmm7 -vpaddq %xmm7,%xmm7,%xmm7 -vpaddq %xmm7,%xmm8,%xmm8 -vpmuludq 16(%rsp),%xmm13,%xmm7 -vpaddq %xmm7,%xmm5,%xmm5 -vpmuludq 48(%rsp),%xmm13,%xmm7 -vpaddq %xmm7,%xmm0,%xmm0 -vpmuludq 112(%rsp),%xmm13,%xmm7 -vpaddq %xmm7,%xmm10,%xmm10 -vpmuludq %xmm15,%xmm6,%xmm7 -vpaddq %xmm7,%xmm12,%xmm12 -vpmuludq %xmm15,%xmm4,%xmm7 -vpaddq %xmm7,%xmm9,%xmm9 -vpaddq %xmm2,%xmm2,%xmm2 -vpmuludq %xmm4,%xmm2,%xmm7 -vpaddq %xmm7,%xmm5,%xmm5 -vpmuludq 160(%rsp),%xmm2,%xmm7 -vpaddq %xmm7,%xmm3,%xmm3 -vpmuludq 160(%rsp),%xmm6,%xmm7 -vpaddq %xmm7,%xmm11,%xmm11 -vpmuludq 0(%rsp),%xmm2,%xmm7 -vpaddq %xmm7,%xmm0,%xmm0 -vpmuludq 48(%rsp),%xmm2,%xmm7 -vpaddq %xmm7,%xmm8,%xmm8 -vpmuludq 80(%rsp),%xmm2,%xmm2 -vpaddq %xmm2,%xmm10,%xmm10 -vpmuludq 96(%rsp),%xmm4,%xmm2 -vpaddq %xmm2,%xmm11,%xmm11 -vpmuludq %xmm4,%xmm4,%xmm2 -vpaddq %xmm2,%xmm8,%xmm8 -vpaddq %xmm4,%xmm4,%xmm2 -vpmuludq 160(%rsp),%xmm2,%xmm4 -vpaddq %xmm4,%xmm12,%xmm12 -vpmuludq 16(%rsp),%xmm15,%xmm4 -vpaddq %xmm4,%xmm1,%xmm1 -vpmuludq 48(%rsp),%xmm15,%xmm4 -vpaddq %xmm4,%xmm14,%xmm14 -vpmuludq 96(%rsp),%xmm6,%xmm4 -vpaddq %xmm4,%xmm3,%xmm3 -vmovdqa 16(%rsp),%xmm4 -vpmuludq 160(%rsp),%xmm4,%xmm4 -vpaddq %xmm4,%xmm9,%xmm9 -vpmuludq 16(%rsp),%xmm6,%xmm4 -vpaddq %xmm4,%xmm8,%xmm8 -vpmuludq 48(%rsp),%xmm6,%xmm4 -vpaddq %xmm4,%xmm10,%xmm10 -vpmuludq 80(%rsp),%xmm15,%xmm4 -vpaddq %xmm4,%xmm4,%xmm4 -vpaddq %xmm4,%xmm5,%xmm5 -vpmuludq 112(%rsp),%xmm15,%xmm4 -vpaddq %xmm4,%xmm0,%xmm0 -vmovdqa 48(%rsp),%xmm4 -vpaddq %xmm4,%xmm4,%xmm4 -vpmuludq 160(%rsp),%xmm4,%xmm4 -vpaddq %xmm4,%xmm1,%xmm1 -vmovdqa 80(%rsp),%xmm4 -vpaddq %xmm4,%xmm4,%xmm4 -vpmuludq 160(%rsp),%xmm4,%xmm4 -vpaddq %xmm4,%xmm14,%xmm14 -vpmuludq 64(%rsp),%xmm2,%xmm4 -vpaddq %xmm4,%xmm3,%xmm3 -vmovdqa 16(%rsp),%xmm4 -vpmuludq 64(%rsp),%xmm4,%xmm4 -vpaddq %xmm4,%xmm11,%xmm11 -vmovdqa 16(%rsp),%xmm4 -vpmuludq 96(%rsp),%xmm4,%xmm4 -vpaddq %xmm4,%xmm12,%xmm12 -vmovdqa 48(%rsp),%xmm4 -vpmuludq 96(%rsp),%xmm4,%xmm4 -vpaddq %xmm4,%xmm9,%xmm9 -vpmuludq 0(%rsp),%xmm2,%xmm2 -vpaddq %xmm2,%xmm10,%xmm10 -vmovdqa 32(%rsp),%xmm2 -vpmuludq 0(%rsp),%xmm2,%xmm2 -vpaddq %xmm2,%xmm3,%xmm3 -vmovdqa 64(%rsp),%xmm2 -vpmuludq 48(%rsp),%xmm2,%xmm2 -vpaddq %xmm2,%xmm12,%xmm12 -vmovdqa 96(%rsp),%xmm2 -vpmuludq 80(%rsp),%xmm2,%xmm2 -vpaddq %xmm2,%xmm1,%xmm1 -vmovdqa 160(%rsp),%xmm2 -vpmuludq 112(%rsp),%xmm2,%xmm2 -vpaddq %xmm2,%xmm5,%xmm5 -vpsrlq $26,%xmm3,%xmm2 -vpaddq %xmm2,%xmm11,%xmm11 -vpand m26(%rip),%xmm3,%xmm3 -vpsrlq $25,%xmm14,%xmm2 -vpaddq %xmm2,%xmm5,%xmm5 -vpand m25(%rip),%xmm14,%xmm14 -vpsrlq $25,%xmm11,%xmm2 -vpaddq %xmm2,%xmm12,%xmm12 -vpand m25(%rip),%xmm11,%xmm11 -vpsrlq $26,%xmm5,%xmm2 -vpaddq %xmm2,%xmm0,%xmm0 -vpand m26(%rip),%xmm5,%xmm5 -vpsrlq $26,%xmm12,%xmm2 -vpaddq %xmm2,%xmm9,%xmm9 -vpand m26(%rip),%xmm12,%xmm12 -vpsrlq $25,%xmm0,%xmm2 -vpaddq %xmm2,%xmm8,%xmm8 -vpand m25(%rip),%xmm0,%xmm0 -vpsrlq $25,%xmm9,%xmm2 -vpaddq %xmm2,%xmm1,%xmm1 -vpand m25(%rip),%xmm9,%xmm9 -vpsrlq $26,%xmm8,%xmm2 -vpaddq %xmm2,%xmm10,%xmm10 -vpand m26(%rip),%xmm8,%xmm8 -vpsrlq $26,%xmm1,%xmm2 -vpaddq %xmm2,%xmm14,%xmm14 -vpand m26(%rip),%xmm1,%xmm1 -vpsrlq $25,%xmm10,%xmm2 -vpsllq $4,%xmm2,%xmm4 -vpaddq %xmm2,%xmm3,%xmm3 -vpsllq $1,%xmm2,%xmm2 -vpaddq %xmm2,%xmm4,%xmm4 -vpaddq %xmm4,%xmm3,%xmm3 -vpand m25(%rip),%xmm10,%xmm10 -vpsrlq $25,%xmm14,%xmm2 -vpaddq %xmm2,%xmm5,%xmm5 -vpand m25(%rip),%xmm14,%xmm14 -vpsrlq $26,%xmm3,%xmm2 -vpaddq %xmm2,%xmm11,%xmm11 -vpand m26(%rip),%xmm3,%xmm3 -vpunpckhqdq %xmm11,%xmm3,%xmm2 -vmovdqa %xmm2,0(%rsp) -vpunpcklqdq %xmm11,%xmm3,%xmm2 -vpmuludq v9_9(%rip),%xmm2,%xmm2 -vmovdqa %xmm2,80(%rsp) -vpunpckhqdq %xmm9,%xmm12,%xmm2 -vmovdqa %xmm2,16(%rsp) -vpunpcklqdq %xmm9,%xmm12,%xmm2 -vpmuludq v9_9(%rip),%xmm2,%xmm2 -vmovdqa %xmm2,96(%rsp) -vpunpckhqdq %xmm14,%xmm1,%xmm2 -vmovdqa %xmm2,32(%rsp) -vpunpcklqdq %xmm14,%xmm1,%xmm1 -vpmuludq v9_9(%rip),%xmm1,%xmm1 -vmovdqa %xmm1,112(%rsp) -vpunpckhqdq %xmm0,%xmm5,%xmm1 -vmovdqa %xmm1,48(%rsp) -vpunpcklqdq %xmm0,%xmm5,%xmm0 -vpmuludq v9_9(%rip),%xmm0,%xmm0 -vmovdqa %xmm0,160(%rsp) -vpunpckhqdq %xmm10,%xmm8,%xmm0 -vmovdqa %xmm0,64(%rsp) -vpunpcklqdq %xmm10,%xmm8,%xmm0 -vpmuludq v9_9(%rip),%xmm0,%xmm0 -vmovdqa %xmm0,208(%rsp) -vmovdqa 144(%rsp),%xmm0 -vpmuludq %xmm0,%xmm0,%xmm1 -vpaddq %xmm0,%xmm0,%xmm0 -vmovdqa 128(%rsp),%xmm2 -vpmuludq %xmm2,%xmm0,%xmm3 -vmovdqa 192(%rsp),%xmm4 -vpmuludq %xmm4,%xmm0,%xmm5 -vmovdqa 176(%rsp),%xmm6 -vpmuludq %xmm6,%xmm0,%xmm7 -vmovdqa 240(%rsp),%xmm8 -vpmuludq %xmm8,%xmm0,%xmm9 -vpmuludq 224(%rsp),%xmm0,%xmm10 -vpmuludq 304(%rsp),%xmm0,%xmm11 -vpmuludq 288(%rsp),%xmm0,%xmm12 -vpmuludq 336(%rsp),%xmm0,%xmm13 -vmovdqa 384(%rsp),%xmm14 -vpmuludq %xmm14,%xmm0,%xmm0 -vpmuludq v38_38(%rip),%xmm14,%xmm15 -vpmuludq %xmm15,%xmm14,%xmm14 -vpaddq %xmm14,%xmm13,%xmm13 -vpaddq %xmm6,%xmm6,%xmm14 -vpmuludq %xmm14,%xmm6,%xmm6 -vpaddq %xmm6,%xmm11,%xmm11 -vpaddq %xmm2,%xmm2,%xmm6 -vpmuludq %xmm6,%xmm2,%xmm2 -vpaddq %xmm2,%xmm5,%xmm5 -vpmuludq %xmm15,%xmm6,%xmm2 -vpaddq %xmm2,%xmm1,%xmm1 -vpmuludq %xmm15,%xmm4,%xmm2 -vpaddq %xmm2,%xmm3,%xmm3 -vpmuludq 256(%rsp),%xmm6,%xmm2 -vpaddq %xmm2,%xmm11,%xmm11 -vpmuludq 304(%rsp),%xmm6,%xmm2 -vpaddq %xmm2,%xmm12,%xmm12 -vpmuludq 352(%rsp),%xmm6,%xmm2 -vpaddq %xmm2,%xmm13,%xmm13 -vpmuludq 336(%rsp),%xmm6,%xmm2 -vpaddq %xmm2,%xmm0,%xmm0 -vpmuludq %xmm4,%xmm6,%xmm2 -vpaddq %xmm2,%xmm7,%xmm7 -vpmuludq %xmm14,%xmm6,%xmm2 -vpaddq %xmm2,%xmm9,%xmm9 -vpmuludq %xmm8,%xmm6,%xmm2 -vpaddq %xmm2,%xmm10,%xmm10 -vpmuludq %xmm15,%xmm14,%xmm2 -vpaddq %xmm2,%xmm5,%xmm5 -vpmuludq %xmm15,%xmm8,%xmm2 -vpaddq %xmm2,%xmm7,%xmm7 -vpmuludq %xmm4,%xmm4,%xmm2 -vpaddq %xmm2,%xmm9,%xmm9 -vpmuludq %xmm14,%xmm4,%xmm2 -vpaddq %xmm2,%xmm10,%xmm10 -vpaddq %xmm4,%xmm4,%xmm2 -vpmuludq %xmm8,%xmm2,%xmm4 -vpaddq %xmm4,%xmm11,%xmm11 -vpmuludq 400(%rsp),%xmm2,%xmm4 -vpaddq %xmm4,%xmm1,%xmm1 -vpmuludq 400(%rsp),%xmm14,%xmm4 -vpaddq %xmm4,%xmm3,%xmm3 -vpmuludq 224(%rsp),%xmm2,%xmm4 -vpaddq %xmm4,%xmm12,%xmm12 -vpmuludq 304(%rsp),%xmm2,%xmm4 -vpaddq %xmm4,%xmm13,%xmm13 -vpmuludq 288(%rsp),%xmm2,%xmm2 -vpaddq %xmm2,%xmm0,%xmm0 -vpmuludq 368(%rsp),%xmm8,%xmm2 -vpaddq %xmm2,%xmm3,%xmm3 -vpmuludq %xmm8,%xmm14,%xmm2 -vpaddq %xmm2,%xmm12,%xmm12 -vpmuludq %xmm8,%xmm8,%xmm2 -vpaddq %xmm2,%xmm13,%xmm13 -vpaddq %xmm8,%xmm8,%xmm2 -vpmuludq 400(%rsp),%xmm2,%xmm4 -vpaddq %xmm4,%xmm5,%xmm5 -vpmuludq 256(%rsp),%xmm15,%xmm4 -vpaddq %xmm4,%xmm9,%xmm9 -vpmuludq 304(%rsp),%xmm15,%xmm4 -vpaddq %xmm4,%xmm10,%xmm10 -vpmuludq 368(%rsp),%xmm14,%xmm4 -vpaddq %xmm4,%xmm1,%xmm1 -vmovdqa 256(%rsp),%xmm4 -vpmuludq 400(%rsp),%xmm4,%xmm4 -vpaddq %xmm4,%xmm7,%xmm7 -vpmuludq 256(%rsp),%xmm14,%xmm4 -vpaddq %xmm4,%xmm13,%xmm13 -vpmuludq 304(%rsp),%xmm14,%xmm4 -vpaddq %xmm4,%xmm0,%xmm0 -vpmuludq 352(%rsp),%xmm15,%xmm4 -vpaddq %xmm4,%xmm11,%xmm11 -vpmuludq 336(%rsp),%xmm15,%xmm4 -vpaddq %xmm4,%xmm12,%xmm12 -vmovdqa 304(%rsp),%xmm4 -vpaddq %xmm4,%xmm4,%xmm4 -vpmuludq 400(%rsp),%xmm4,%xmm4 -vpaddq %xmm4,%xmm9,%xmm9 -vpmuludq 320(%rsp),%xmm2,%xmm4 -vpaddq %xmm4,%xmm1,%xmm1 -vmovdqa 256(%rsp),%xmm4 -vpmuludq 320(%rsp),%xmm4,%xmm4 -vpaddq %xmm4,%xmm3,%xmm3 -vmovdqa 256(%rsp),%xmm4 -vpmuludq 368(%rsp),%xmm4,%xmm4 -vpaddq %xmm4,%xmm5,%xmm5 -vmovdqa 304(%rsp),%xmm4 -vpmuludq 368(%rsp),%xmm4,%xmm4 -vpaddq %xmm4,%xmm7,%xmm7 -vmovdqa 352(%rsp),%xmm4 -vpmuludq 400(%rsp),%xmm4,%xmm4 -vpaddq %xmm4,%xmm10,%xmm10 -vpmuludq 224(%rsp),%xmm2,%xmm2 -vpaddq %xmm2,%xmm0,%xmm0 -vmovdqa 272(%rsp),%xmm2 -vpmuludq 224(%rsp),%xmm2,%xmm2 -vpaddq %xmm2,%xmm1,%xmm1 -vmovdqa 320(%rsp),%xmm2 -vpmuludq 304(%rsp),%xmm2,%xmm2 -vpaddq %xmm2,%xmm5,%xmm5 -vmovdqa 368(%rsp),%xmm2 -vpmuludq 288(%rsp),%xmm2,%xmm2 -vpaddq %xmm2,%xmm9,%xmm9 -vmovdqa 400(%rsp),%xmm2 -vpmuludq 336(%rsp),%xmm2,%xmm2 -vpaddq %xmm2,%xmm11,%xmm11 -vpsrlq $26,%xmm1,%xmm2 -vpaddq %xmm2,%xmm3,%xmm3 -vpand m26(%rip),%xmm1,%xmm1 -vpsrlq $25,%xmm10,%xmm2 -vpaddq %xmm2,%xmm11,%xmm11 -vpand m25(%rip),%xmm10,%xmm10 -vpsrlq $25,%xmm3,%xmm2 -vpaddq %xmm2,%xmm5,%xmm5 -vpand m25(%rip),%xmm3,%xmm3 -vpsrlq $26,%xmm11,%xmm2 -vpaddq %xmm2,%xmm12,%xmm12 -vpand m26(%rip),%xmm11,%xmm11 -vpsrlq $26,%xmm5,%xmm2 -vpaddq %xmm2,%xmm7,%xmm7 -vpand m26(%rip),%xmm5,%xmm5 -vpsrlq $25,%xmm12,%xmm2 -vpaddq %xmm2,%xmm13,%xmm13 -vpand m25(%rip),%xmm12,%xmm12 -vpsrlq $25,%xmm7,%xmm2 -vpaddq %xmm2,%xmm9,%xmm9 -vpand m25(%rip),%xmm7,%xmm7 -vpsrlq $26,%xmm13,%xmm2 -vpaddq %xmm2,%xmm0,%xmm0 -vpand m26(%rip),%xmm13,%xmm13 -vpsrlq $26,%xmm9,%xmm2 -vpaddq %xmm2,%xmm10,%xmm10 -vpand m26(%rip),%xmm9,%xmm9 -vpsrlq $25,%xmm0,%xmm2 -vpsllq $4,%xmm2,%xmm4 -vpaddq %xmm2,%xmm1,%xmm1 -vpsllq $1,%xmm2,%xmm2 -vpaddq %xmm2,%xmm4,%xmm4 -vpaddq %xmm4,%xmm1,%xmm1 -vpand m25(%rip),%xmm0,%xmm0 -vpsrlq $25,%xmm10,%xmm2 -vpaddq %xmm2,%xmm11,%xmm11 -vpand m25(%rip),%xmm10,%xmm10 -vpsrlq $26,%xmm1,%xmm2 -vpaddq %xmm2,%xmm3,%xmm3 -vpand m26(%rip),%xmm1,%xmm1 -vpunpckhqdq %xmm3,%xmm1,%xmm2 -vpunpcklqdq %xmm3,%xmm1,%xmm1 -vmovdqa %xmm1,176(%rsp) -vpaddq subc0(%rip),%xmm2,%xmm3 -vpsubq %xmm1,%xmm3,%xmm3 -vpunpckhqdq %xmm3,%xmm2,%xmm1 -vpunpcklqdq %xmm3,%xmm2,%xmm2 -vmovdqa %xmm2,192(%rsp) -vmovdqa %xmm1,224(%rsp) -vpsllq $1,%xmm1,%xmm1 -vmovdqa %xmm1,240(%rsp) -vpmuludq v121666_121666(%rip),%xmm3,%xmm3 -vmovdqa 80(%rsp),%xmm1 -vpunpcklqdq %xmm1,%xmm3,%xmm2 -vpunpckhqdq %xmm1,%xmm3,%xmm1 -vpunpckhqdq %xmm7,%xmm5,%xmm3 -vpunpcklqdq %xmm7,%xmm5,%xmm4 -vmovdqa %xmm4,256(%rsp) -vpaddq subc2(%rip),%xmm3,%xmm5 -vpsubq %xmm4,%xmm5,%xmm5 -vpunpckhqdq %xmm5,%xmm3,%xmm4 -vpunpcklqdq %xmm5,%xmm3,%xmm3 -vmovdqa %xmm3,272(%rsp) -vmovdqa %xmm4,288(%rsp) -vpsllq $1,%xmm4,%xmm4 -vmovdqa %xmm4,304(%rsp) -vpmuludq v121666_121666(%rip),%xmm5,%xmm5 -vmovdqa 96(%rsp),%xmm3 -vpunpcklqdq %xmm3,%xmm5,%xmm4 -vpunpckhqdq %xmm3,%xmm5,%xmm3 -vpunpckhqdq %xmm10,%xmm9,%xmm5 -vpunpcklqdq %xmm10,%xmm9,%xmm6 -vmovdqa %xmm6,320(%rsp) -vpaddq subc2(%rip),%xmm5,%xmm7 -vpsubq %xmm6,%xmm7,%xmm7 -vpunpckhqdq %xmm7,%xmm5,%xmm6 -vpunpcklqdq %xmm7,%xmm5,%xmm5 -vmovdqa %xmm5,336(%rsp) -vmovdqa %xmm6,352(%rsp) -vpsllq $1,%xmm6,%xmm6 -vmovdqa %xmm6,368(%rsp) -vpmuludq v121666_121666(%rip),%xmm7,%xmm7 -vmovdqa 112(%rsp),%xmm5 -vpunpcklqdq %xmm5,%xmm7,%xmm6 -vpunpckhqdq %xmm5,%xmm7,%xmm5 -vpunpckhqdq %xmm12,%xmm11,%xmm7 -vpunpcklqdq %xmm12,%xmm11,%xmm8 -vmovdqa %xmm8,384(%rsp) -vpaddq subc2(%rip),%xmm7,%xmm9 -vpsubq %xmm8,%xmm9,%xmm9 -vpunpckhqdq %xmm9,%xmm7,%xmm8 -vpunpcklqdq %xmm9,%xmm7,%xmm7 -vmovdqa %xmm7,400(%rsp) -vmovdqa %xmm8,416(%rsp) -vpsllq $1,%xmm8,%xmm8 -vmovdqa %xmm8,432(%rsp) -vpmuludq v121666_121666(%rip),%xmm9,%xmm9 -vmovdqa 160(%rsp),%xmm7 -vpunpcklqdq %xmm7,%xmm9,%xmm8 -vpunpckhqdq %xmm7,%xmm9,%xmm7 -vpunpckhqdq %xmm0,%xmm13,%xmm9 -vpunpcklqdq %xmm0,%xmm13,%xmm0 -vmovdqa %xmm0,160(%rsp) -vpaddq subc2(%rip),%xmm9,%xmm10 -vpsubq %xmm0,%xmm10,%xmm10 -vpunpckhqdq %xmm10,%xmm9,%xmm0 -vpunpcklqdq %xmm10,%xmm9,%xmm9 -vmovdqa %xmm9,448(%rsp) -vmovdqa %xmm0,464(%rsp) -vpsllq $1,%xmm0,%xmm0 -vmovdqa %xmm0,480(%rsp) -vpmuludq v121666_121666(%rip),%xmm10,%xmm10 -vmovdqa 208(%rsp),%xmm0 -vpunpcklqdq %xmm0,%xmm10,%xmm9 -vpunpckhqdq %xmm0,%xmm10,%xmm0 -vpsrlq $26,%xmm2,%xmm10 -vpaddq %xmm10,%xmm1,%xmm1 -vpand m26(%rip),%xmm2,%xmm2 -vpsrlq $25,%xmm5,%xmm10 -vpaddq %xmm10,%xmm8,%xmm8 -vpand m25(%rip),%xmm5,%xmm5 -vpsrlq $25,%xmm1,%xmm10 -vpaddq %xmm10,%xmm4,%xmm4 -vpand m25(%rip),%xmm1,%xmm1 -vpsrlq $26,%xmm8,%xmm10 -vpaddq %xmm10,%xmm7,%xmm7 -vpand m26(%rip),%xmm8,%xmm8 -vpsrlq $26,%xmm4,%xmm10 -vpaddq %xmm10,%xmm3,%xmm3 -vpand m26(%rip),%xmm4,%xmm4 -vpsrlq $25,%xmm7,%xmm10 -vpaddq %xmm10,%xmm9,%xmm9 -vpand m25(%rip),%xmm7,%xmm7 -vpsrlq $25,%xmm3,%xmm10 -vpaddq %xmm10,%xmm6,%xmm6 -vpand m25(%rip),%xmm3,%xmm3 -vpsrlq $26,%xmm9,%xmm10 -vpaddq %xmm10,%xmm0,%xmm0 -vpand m26(%rip),%xmm9,%xmm9 -vpsrlq $26,%xmm6,%xmm10 -vpaddq %xmm10,%xmm5,%xmm5 -vpand m26(%rip),%xmm6,%xmm6 -vpsrlq $25,%xmm0,%xmm10 -vpsllq $4,%xmm10,%xmm11 -vpaddq %xmm10,%xmm2,%xmm2 -vpsllq $1,%xmm10,%xmm10 -vpaddq %xmm10,%xmm11,%xmm11 -vpaddq %xmm11,%xmm2,%xmm2 -vpand m25(%rip),%xmm0,%xmm0 -vpsrlq $25,%xmm5,%xmm10 -vpaddq %xmm10,%xmm8,%xmm8 -vpand m25(%rip),%xmm5,%xmm5 -vpsrlq $26,%xmm2,%xmm10 -vpaddq %xmm10,%xmm1,%xmm1 -vpand m26(%rip),%xmm2,%xmm2 -vpunpckhqdq %xmm1,%xmm2,%xmm10 -vmovdqa %xmm10,80(%rsp) -vpunpcklqdq %xmm1,%xmm2,%xmm1 -vpunpckhqdq %xmm3,%xmm4,%xmm2 -vmovdqa %xmm2,96(%rsp) -vpunpcklqdq %xmm3,%xmm4,%xmm2 -vpunpckhqdq %xmm5,%xmm6,%xmm3 -vmovdqa %xmm3,112(%rsp) -vpunpcklqdq %xmm5,%xmm6,%xmm3 -vpunpckhqdq %xmm7,%xmm8,%xmm4 -vmovdqa %xmm4,128(%rsp) -vpunpcklqdq %xmm7,%xmm8,%xmm4 -vpunpckhqdq %xmm0,%xmm9,%xmm5 -vmovdqa %xmm5,144(%rsp) -vpunpcklqdq %xmm0,%xmm9,%xmm0 -vmovdqa 176(%rsp),%xmm5 -vpaddq %xmm5,%xmm1,%xmm1 -vpunpcklqdq %xmm1,%xmm5,%xmm6 -vpunpckhqdq %xmm1,%xmm5,%xmm1 -vpmuludq 224(%rsp),%xmm6,%xmm5 -vpmuludq 192(%rsp),%xmm1,%xmm7 -vpaddq %xmm7,%xmm5,%xmm5 -vpmuludq 272(%rsp),%xmm6,%xmm7 -vpmuludq 240(%rsp),%xmm1,%xmm8 -vpaddq %xmm8,%xmm7,%xmm7 -vpmuludq 288(%rsp),%xmm6,%xmm8 -vpmuludq 272(%rsp),%xmm1,%xmm9 -vpaddq %xmm9,%xmm8,%xmm8 -vpmuludq 336(%rsp),%xmm6,%xmm9 -vpmuludq 304(%rsp),%xmm1,%xmm10 -vpaddq %xmm10,%xmm9,%xmm9 -vpmuludq 352(%rsp),%xmm6,%xmm10 -vpmuludq 336(%rsp),%xmm1,%xmm11 -vpaddq %xmm11,%xmm10,%xmm10 -vpmuludq 400(%rsp),%xmm6,%xmm11 -vpmuludq 368(%rsp),%xmm1,%xmm12 -vpaddq %xmm12,%xmm11,%xmm11 -vpmuludq 416(%rsp),%xmm6,%xmm12 -vpmuludq 400(%rsp),%xmm1,%xmm13 -vpaddq %xmm13,%xmm12,%xmm12 -vpmuludq 448(%rsp),%xmm6,%xmm13 -vpmuludq 432(%rsp),%xmm1,%xmm14 -vpaddq %xmm14,%xmm13,%xmm13 -vpmuludq 464(%rsp),%xmm6,%xmm14 -vpmuludq 448(%rsp),%xmm1,%xmm15 -vpaddq %xmm15,%xmm14,%xmm14 -vpmuludq 192(%rsp),%xmm6,%xmm6 -vpmuludq v19_19(%rip),%xmm1,%xmm1 -vpmuludq 480(%rsp),%xmm1,%xmm1 -vpaddq %xmm1,%xmm6,%xmm6 -vmovdqa 256(%rsp),%xmm1 -vpaddq %xmm1,%xmm2,%xmm2 -vpunpcklqdq %xmm2,%xmm1,%xmm15 -vpunpckhqdq %xmm2,%xmm1,%xmm1 -vpmuludq 192(%rsp),%xmm15,%xmm2 -vpaddq %xmm2,%xmm7,%xmm7 -vpmuludq 224(%rsp),%xmm15,%xmm2 -vpaddq %xmm2,%xmm8,%xmm8 -vpmuludq 272(%rsp),%xmm15,%xmm2 -vpaddq %xmm2,%xmm9,%xmm9 -vpmuludq 288(%rsp),%xmm15,%xmm2 -vpaddq %xmm2,%xmm10,%xmm10 -vpmuludq 336(%rsp),%xmm15,%xmm2 -vpaddq %xmm2,%xmm11,%xmm11 -vpmuludq 352(%rsp),%xmm15,%xmm2 -vpaddq %xmm2,%xmm12,%xmm12 -vpmuludq 400(%rsp),%xmm15,%xmm2 -vpaddq %xmm2,%xmm13,%xmm13 -vpmuludq 416(%rsp),%xmm15,%xmm2 -vpaddq %xmm2,%xmm14,%xmm14 -vpmuludq v19_19(%rip),%xmm15,%xmm15 -vpmuludq 448(%rsp),%xmm15,%xmm2 -vpaddq %xmm2,%xmm6,%xmm6 -vpmuludq 464(%rsp),%xmm15,%xmm15 -vpaddq %xmm15,%xmm5,%xmm5 -vpmuludq 192(%rsp),%xmm1,%xmm2 -vpaddq %xmm2,%xmm8,%xmm8 -vpmuludq 240(%rsp),%xmm1,%xmm2 -vpaddq %xmm2,%xmm9,%xmm9 -vpmuludq 272(%rsp),%xmm1,%xmm2 -vpaddq %xmm2,%xmm10,%xmm10 -vpmuludq 304(%rsp),%xmm1,%xmm2 -vpaddq %xmm2,%xmm11,%xmm11 -vpmuludq 336(%rsp),%xmm1,%xmm2 -vpaddq %xmm2,%xmm12,%xmm12 -vpmuludq 368(%rsp),%xmm1,%xmm2 -vpaddq %xmm2,%xmm13,%xmm13 -vpmuludq 400(%rsp),%xmm1,%xmm2 -vpaddq %xmm2,%xmm14,%xmm14 -vpmuludq v19_19(%rip),%xmm1,%xmm1 -vpmuludq 432(%rsp),%xmm1,%xmm2 -vpaddq %xmm2,%xmm6,%xmm6 -vpmuludq 448(%rsp),%xmm1,%xmm2 -vpaddq %xmm2,%xmm5,%xmm5 -vpmuludq 480(%rsp),%xmm1,%xmm1 -vpaddq %xmm1,%xmm7,%xmm7 -vmovdqa 320(%rsp),%xmm1 -vpaddq %xmm1,%xmm3,%xmm3 -vpunpcklqdq %xmm3,%xmm1,%xmm2 -vpunpckhqdq %xmm3,%xmm1,%xmm1 -vpmuludq 192(%rsp),%xmm2,%xmm3 -vpaddq %xmm3,%xmm9,%xmm9 -vpmuludq 224(%rsp),%xmm2,%xmm3 -vpaddq %xmm3,%xmm10,%xmm10 -vpmuludq 272(%rsp),%xmm2,%xmm3 -vpaddq %xmm3,%xmm11,%xmm11 -vpmuludq 288(%rsp),%xmm2,%xmm3 -vpaddq %xmm3,%xmm12,%xmm12 -vpmuludq 336(%rsp),%xmm2,%xmm3 -vpaddq %xmm3,%xmm13,%xmm13 -vpmuludq 352(%rsp),%xmm2,%xmm3 -vpaddq %xmm3,%xmm14,%xmm14 -vpmuludq v19_19(%rip),%xmm2,%xmm2 -vpmuludq 400(%rsp),%xmm2,%xmm3 -vpaddq %xmm3,%xmm6,%xmm6 -vpmuludq 416(%rsp),%xmm2,%xmm3 -vpaddq %xmm3,%xmm5,%xmm5 -vpmuludq 448(%rsp),%xmm2,%xmm3 -vpaddq %xmm3,%xmm7,%xmm7 -vpmuludq 464(%rsp),%xmm2,%xmm2 -vpaddq %xmm2,%xmm8,%xmm8 -vpmuludq 192(%rsp),%xmm1,%xmm2 -vpaddq %xmm2,%xmm10,%xmm10 -vpmuludq 240(%rsp),%xmm1,%xmm2 -vpaddq %xmm2,%xmm11,%xmm11 -vpmuludq 272(%rsp),%xmm1,%xmm2 -vpaddq %xmm2,%xmm12,%xmm12 -vpmuludq 304(%rsp),%xmm1,%xmm2 -vpaddq %xmm2,%xmm13,%xmm13 -vpmuludq 336(%rsp),%xmm1,%xmm2 -vpaddq %xmm2,%xmm14,%xmm14 -vpmuludq v19_19(%rip),%xmm1,%xmm1 -vpmuludq 368(%rsp),%xmm1,%xmm2 -vpaddq %xmm2,%xmm6,%xmm6 -vpmuludq 400(%rsp),%xmm1,%xmm2 -vpaddq %xmm2,%xmm5,%xmm5 -vpmuludq 432(%rsp),%xmm1,%xmm2 -vpaddq %xmm2,%xmm7,%xmm7 -vpmuludq 448(%rsp),%xmm1,%xmm2 -vpaddq %xmm2,%xmm8,%xmm8 -vpmuludq 480(%rsp),%xmm1,%xmm1 -vpaddq %xmm1,%xmm9,%xmm9 -vmovdqa 384(%rsp),%xmm1 -vpaddq %xmm1,%xmm4,%xmm4 -vpunpcklqdq %xmm4,%xmm1,%xmm2 -vpunpckhqdq %xmm4,%xmm1,%xmm1 -vpmuludq 192(%rsp),%xmm2,%xmm3 -vpaddq %xmm3,%xmm11,%xmm11 -vpmuludq 224(%rsp),%xmm2,%xmm3 -vpaddq %xmm3,%xmm12,%xmm12 -vpmuludq 272(%rsp),%xmm2,%xmm3 -vpaddq %xmm3,%xmm13,%xmm13 -vpmuludq 288(%rsp),%xmm2,%xmm3 -vpaddq %xmm3,%xmm14,%xmm14 -vpmuludq v19_19(%rip),%xmm2,%xmm2 -vpmuludq 336(%rsp),%xmm2,%xmm3 -vpaddq %xmm3,%xmm6,%xmm6 -vpmuludq 352(%rsp),%xmm2,%xmm3 -vpaddq %xmm3,%xmm5,%xmm5 -vpmuludq 400(%rsp),%xmm2,%xmm3 -vpaddq %xmm3,%xmm7,%xmm7 -vpmuludq 416(%rsp),%xmm2,%xmm3 -vpaddq %xmm3,%xmm8,%xmm8 -vpmuludq 448(%rsp),%xmm2,%xmm3 -vpaddq %xmm3,%xmm9,%xmm9 -vpmuludq 464(%rsp),%xmm2,%xmm2 -vpaddq %xmm2,%xmm10,%xmm10 -vpmuludq 192(%rsp),%xmm1,%xmm2 -vpaddq %xmm2,%xmm12,%xmm12 -vpmuludq 240(%rsp),%xmm1,%xmm2 -vpaddq %xmm2,%xmm13,%xmm13 -vpmuludq 272(%rsp),%xmm1,%xmm2 -vpaddq %xmm2,%xmm14,%xmm14 -vpmuludq v19_19(%rip),%xmm1,%xmm1 -vpmuludq 304(%rsp),%xmm1,%xmm2 -vpaddq %xmm2,%xmm6,%xmm6 -vpmuludq 336(%rsp),%xmm1,%xmm2 -vpaddq %xmm2,%xmm5,%xmm5 -vpmuludq 368(%rsp),%xmm1,%xmm2 -vpaddq %xmm2,%xmm7,%xmm7 -vpmuludq 400(%rsp),%xmm1,%xmm2 -vpaddq %xmm2,%xmm8,%xmm8 -vpmuludq 432(%rsp),%xmm1,%xmm2 -vpaddq %xmm2,%xmm9,%xmm9 -vpmuludq 448(%rsp),%xmm1,%xmm2 -vpaddq %xmm2,%xmm10,%xmm10 -vpmuludq 480(%rsp),%xmm1,%xmm1 -vpaddq %xmm1,%xmm11,%xmm11 -vmovdqa 160(%rsp),%xmm1 -vpaddq %xmm1,%xmm0,%xmm0 -vpunpcklqdq %xmm0,%xmm1,%xmm2 -vpunpckhqdq %xmm0,%xmm1,%xmm0 -vpmuludq 192(%rsp),%xmm2,%xmm1 -vpaddq %xmm1,%xmm13,%xmm13 -vpmuludq 224(%rsp),%xmm2,%xmm1 -vpaddq %xmm1,%xmm14,%xmm14 -vpmuludq v19_19(%rip),%xmm2,%xmm2 -vpmuludq 272(%rsp),%xmm2,%xmm1 -vpaddq %xmm1,%xmm6,%xmm6 -vpmuludq 288(%rsp),%xmm2,%xmm1 -vpaddq %xmm1,%xmm5,%xmm5 -vpmuludq 336(%rsp),%xmm2,%xmm1 -vpaddq %xmm1,%xmm7,%xmm7 -vpmuludq 352(%rsp),%xmm2,%xmm1 -vpaddq %xmm1,%xmm8,%xmm8 -vpmuludq 400(%rsp),%xmm2,%xmm1 -vpaddq %xmm1,%xmm9,%xmm9 -vpmuludq 416(%rsp),%xmm2,%xmm1 -vpaddq %xmm1,%xmm10,%xmm10 -vpmuludq 448(%rsp),%xmm2,%xmm1 -vpaddq %xmm1,%xmm11,%xmm11 -vpmuludq 464(%rsp),%xmm2,%xmm2 -vpaddq %xmm2,%xmm12,%xmm12 -vpmuludq 192(%rsp),%xmm0,%xmm1 -vpaddq %xmm1,%xmm14,%xmm14 -vpmuludq v19_19(%rip),%xmm0,%xmm0 -vpmuludq 240(%rsp),%xmm0,%xmm1 -vpaddq %xmm1,%xmm6,%xmm6 -vpmuludq 272(%rsp),%xmm0,%xmm1 -vpaddq %xmm1,%xmm5,%xmm5 -vpmuludq 304(%rsp),%xmm0,%xmm1 -vpaddq %xmm1,%xmm7,%xmm7 -vpmuludq 336(%rsp),%xmm0,%xmm1 -vpaddq %xmm1,%xmm8,%xmm8 -vpmuludq 368(%rsp),%xmm0,%xmm1 -vpaddq %xmm1,%xmm9,%xmm9 -vpmuludq 400(%rsp),%xmm0,%xmm1 -vpaddq %xmm1,%xmm10,%xmm10 -vpmuludq 432(%rsp),%xmm0,%xmm1 -vpaddq %xmm1,%xmm11,%xmm11 -vpmuludq 448(%rsp),%xmm0,%xmm1 -vpaddq %xmm1,%xmm12,%xmm12 -vpmuludq 480(%rsp),%xmm0,%xmm0 -vpaddq %xmm0,%xmm13,%xmm13 -vpsrlq $26,%xmm6,%xmm0 -vpaddq %xmm0,%xmm5,%xmm5 -vpand m26(%rip),%xmm6,%xmm6 -vpsrlq $25,%xmm10,%xmm0 -vpaddq %xmm0,%xmm11,%xmm11 -vpand m25(%rip),%xmm10,%xmm10 -vpsrlq $25,%xmm5,%xmm0 -vpaddq %xmm0,%xmm7,%xmm7 -vpand m25(%rip),%xmm5,%xmm5 -vpsrlq $26,%xmm11,%xmm0 -vpaddq %xmm0,%xmm12,%xmm12 -vpand m26(%rip),%xmm11,%xmm11 -vpsrlq $26,%xmm7,%xmm0 -vpaddq %xmm0,%xmm8,%xmm8 -vpand m26(%rip),%xmm7,%xmm7 -vpsrlq $25,%xmm12,%xmm0 -vpaddq %xmm0,%xmm13,%xmm13 -vpand m25(%rip),%xmm12,%xmm12 -vpsrlq $25,%xmm8,%xmm0 -vpaddq %xmm0,%xmm9,%xmm9 -vpand m25(%rip),%xmm8,%xmm8 -vpsrlq $26,%xmm13,%xmm0 -vpaddq %xmm0,%xmm14,%xmm14 -vpand m26(%rip),%xmm13,%xmm13 -vpsrlq $26,%xmm9,%xmm0 -vpaddq %xmm0,%xmm10,%xmm10 -vpand m26(%rip),%xmm9,%xmm9 -vpsrlq $25,%xmm14,%xmm0 -vpsllq $4,%xmm0,%xmm1 -vpaddq %xmm0,%xmm6,%xmm6 -vpsllq $1,%xmm0,%xmm0 -vpaddq %xmm0,%xmm1,%xmm1 -vpaddq %xmm1,%xmm6,%xmm6 -vpand m25(%rip),%xmm14,%xmm14 -vpsrlq $25,%xmm10,%xmm0 -vpaddq %xmm0,%xmm11,%xmm11 -vpand m25(%rip),%xmm10,%xmm10 -vpsrlq $26,%xmm6,%xmm0 -vpaddq %xmm0,%xmm5,%xmm5 -vpand m26(%rip),%xmm6,%xmm6 -vpunpckhqdq %xmm5,%xmm6,%xmm1 -vpunpcklqdq %xmm5,%xmm6,%xmm0 -vpunpckhqdq %xmm8,%xmm7,%xmm3 -vpunpcklqdq %xmm8,%xmm7,%xmm2 -vpunpckhqdq %xmm10,%xmm9,%xmm5 -vpunpcklqdq %xmm10,%xmm9,%xmm4 -vpunpckhqdq %xmm12,%xmm11,%xmm7 -vpunpcklqdq %xmm12,%xmm11,%xmm6 -vpunpckhqdq %xmm14,%xmm13,%xmm9 -vpunpcklqdq %xmm14,%xmm13,%xmm8 -cmp $0,%rdx -jne ._ladder_base_loop -vmovdqu %xmm1,80(%rdi) -vmovdqu %xmm0,0(%rdi) -vmovdqu %xmm3,96(%rdi) -vmovdqu %xmm2,16(%rdi) -vmovdqu %xmm5,112(%rdi) -vmovdqu %xmm4,32(%rdi) -vmovdqu %xmm7,128(%rdi) -vmovdqu %xmm6,48(%rdi) -vmovdqu %xmm9,144(%rdi) -vmovdqu %xmm8,64(%rdi) -movq 1536(%rsp),%r11 -movq 1544(%rsp),%r12 -movq 1552(%rsp),%r13 -add %r11,%rsp -ret - -#endif diff --git a/libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/ladder_base.h b/libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/ladder_base.h deleted file mode 100644 index ff8262f065..0000000000 --- a/libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/ladder_base.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef ladder_base_H -#define ladder_base_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include "fe.h" -#include "ladder_base_namespace.h" - -extern void ladder_base(fe *, const unsigned char *); - -#ifdef __cplusplus -} -#endif - -#endif /* ifndef ladder_base_H */ - diff --git a/libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/ladder_base_namespace.h b/libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/ladder_base_namespace.h deleted file mode 100644 index 958935daaf..0000000000 --- a/libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/ladder_base_namespace.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef ladder_base_namespace_H -#define ladder_base_namespace_H - -#define ladder_base crypto_scalarmult_curve25519_sandy2x_ladder_base -#define _ladder_base _crypto_scalarmult_curve25519_sandy2x_ladder_base - -#endif /* ifndef ladder_base_namespace_H */ - diff --git a/libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/ladder_namespace.h b/libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/ladder_namespace.h index 1906fd5e05..92b7eff94a 100644 --- a/libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/ladder_namespace.h +++ b/libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/ladder_namespace.h @@ -1,8 +1,8 @@ #ifndef ladder_namespace_H #define ladder_namespace_H -#define ladder crypto_scalarmult_curve25519_sandy2x_ladder -#define _ladder _crypto_scalarmult_curve25519_sandy2x_ladder +#define ladder _sodium_scalarmult_curve25519_sandy2x_ladder +#define _ladder __sodium_scalarmult_curve25519_sandy2x_ladder #endif /* ifndef ladder_namespace_H */ diff --git a/libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/sandy2x.S b/libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/sandy2x.S index 5afdb0efc8..3d30673cb0 100644 --- a/libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/sandy2x.S +++ b/libs/libsodium/src/crypto_scalarmult/curve25519/sandy2x/sandy2x.S @@ -1,4 +1,3 @@ - #ifdef HAVE_AVX_ASM #define IN_SANDY2X @@ -8,7 +7,6 @@ #include "fe51_nsquare.S" #include "fe51_pack.S" #include "ladder.S" -#include "ladder_base.S" #if defined(__linux__) && defined(__ELF__) .section .note.GNU-stack,"",%progbits diff --git a/libs/libsodium/src/crypto_scalarmult/curve25519/scalarmult_curve25519.c b/libs/libsodium/src/crypto_scalarmult/curve25519/scalarmult_curve25519.c index d97b7a8b50..6882709c5d 100644 --- a/libs/libsodium/src/crypto_scalarmult/curve25519/scalarmult_curve25519.c +++ b/libs/libsodium/src/crypto_scalarmult/curve25519/scalarmult_curve25519.c @@ -30,7 +30,8 @@ crypto_scalarmult_curve25519(unsigned char *q, const unsigned char *n, int crypto_scalarmult_curve25519_base(unsigned char *q, const unsigned char *n) { - return implementation->mult_base(q, n); + return crypto_scalarmult_curve25519_ref10_implementation + .mult_base(q, n); } size_t diff --git a/libs/libsodium/src/crypto_scalarmult/ed25519/ref10/scalarmult_ed25519_ref10.c b/libs/libsodium/src/crypto_scalarmult/ed25519/ref10/scalarmult_ed25519_ref10.c index 7fbd5da072..a66ac99758 100644 --- a/libs/libsodium/src/crypto_scalarmult/ed25519/ref10/scalarmult_ed25519_ref10.c +++ b/libs/libsodium/src/crypto_scalarmult/ed25519/ref10/scalarmult_ed25519_ref10.c @@ -24,7 +24,6 @@ static inline void _crypto_scalarmult_ed25519_clamp(unsigned char k[32]) { k[0] &= 248; - k[31] &= 127; k[31] |= 64; } @@ -37,8 +36,8 @@ _crypto_scalarmult_ed25519(unsigned char *q, const unsigned char *n, ge25519_p3 P; unsigned int i; - if (ge25519_is_canonical(p) == 0 || ge25519_has_small_order(p) != 0 || - ge25519_frombytes(&P, p) != 0 || ge25519_is_on_main_subgroup(&P) == 0) { + if (ge25519_is_canonical(p) == 0 || ge25519_frombytes(&P, p) != 0 || + ge25519_has_small_order(&P) != 0 || ge25519_is_on_main_subgroup(&P) == 0) { return -1; } for (i = 0; i < 32; ++i) { @@ -47,6 +46,8 @@ _crypto_scalarmult_ed25519(unsigned char *q, const unsigned char *n, if (clamp != 0) { _crypto_scalarmult_ed25519_clamp(t); } + t[31] &= 127; + ge25519_scalarmult(&Q, t, &P); ge25519_p3_tobytes(q, &Q); if (_crypto_scalarmult_ed25519_is_inf(q) != 0 || sodium_is_zero(n, 32)) { @@ -83,6 +84,8 @@ _crypto_scalarmult_ed25519_base(unsigned char *q, if (clamp != 0) { _crypto_scalarmult_ed25519_clamp(t); } + t[31] &= 127; + ge25519_scalarmult_base(&Q, t); ge25519_p3_tobytes(q, &Q); if (_crypto_scalarmult_ed25519_is_inf(q) != 0 || sodium_is_zero(n, 32)) { diff --git a/libs/libsodium/src/crypto_scalarmult/ristretto255/ref10/scalarmult_ristretto255_ref10.c b/libs/libsodium/src/crypto_scalarmult/ristretto255/ref10/scalarmult_ristretto255_ref10.c new file mode 100644 index 0000000000..433a9a26dc --- /dev/null +++ b/libs/libsodium/src/crypto_scalarmult/ristretto255/ref10/scalarmult_ristretto255_ref10.c @@ -0,0 +1,63 @@ + +#include + +#include "crypto_scalarmult_ed25519.h" +#include "crypto_scalarmult_ristretto255.h" +#include "private/ed25519_ref10.h" +#include "utils.h" + +int +crypto_scalarmult_ristretto255(unsigned char *q, const unsigned char *n, + const unsigned char *p) +{ + unsigned char *t = q; + ge25519_p3 Q; + ge25519_p3 P; + unsigned int i; + + if (ristretto255_frombytes(&P, p) != 0) { + return -1; + } + for (i = 0; i < 32; ++i) { + t[i] = n[i]; + } + t[31] &= 127; + ge25519_scalarmult(&Q, t, &P); + ristretto255_p3_tobytes(q, &Q); + if (sodium_is_zero(q, 32)) { + return -1; + } + return 0; +} + +int +crypto_scalarmult_ristretto255_base(unsigned char *q, + const unsigned char *n) +{ + unsigned char *t = q; + ge25519_p3 Q; + unsigned int i; + + for (i = 0; i < 32; ++i) { + t[i] = n[i]; + } + t[31] &= 127; + ge25519_scalarmult_base(&Q, t); + ristretto255_p3_tobytes(q, &Q); + if (sodium_is_zero(q, 32)) { + return -1; + } + return 0; +} + +size_t +crypto_scalarmult_ristretto255_bytes(void) +{ + return crypto_scalarmult_ristretto255_BYTES; +} + +size_t +crypto_scalarmult_ristretto255_scalarbytes(void) +{ + return crypto_scalarmult_ristretto255_SCALARBYTES; +} diff --git a/libs/libsodium/src/crypto_secretbox/crypto_secretbox_easy.c b/libs/libsodium/src/crypto_secretbox/crypto_secretbox_easy.c index bddbf7c5de..d3004fcdb4 100644 --- a/libs/libsodium/src/crypto_secretbox/crypto_secretbox_easy.c +++ b/libs/libsodium/src/crypto_secretbox/crypto_secretbox_easy.c @@ -27,6 +27,14 @@ crypto_secretbox_detached(unsigned char *c, unsigned char *mac, crypto_core_hsalsa20(subkey, n, k, NULL); + /* + * Allow the m and c buffers to partially overlap, by calling + * memmove() if necessary. + * + * Note that there is no fully portable way to compare pointers. + * Some tools even report undefined behavior, despite the conversion. + * Nevertheless, this works on all supported platforms. + */ if (((uintptr_t) c > (uintptr_t) m && (uintptr_t) c - (uintptr_t) m < mlen) || ((uintptr_t) m > (uintptr_t) c && @@ -43,9 +51,7 @@ crypto_secretbox_detached(unsigned char *c, unsigned char *mac, for (i = 0U; i < mlen0; i++) { block0[i + crypto_secretbox_ZEROBYTES] = m[i]; } - crypto_stream_salsa20_xor(block0, block0, - mlen0 + crypto_secretbox_ZEROBYTES, - n + 16, subkey); + crypto_stream_salsa20_xor(block0, block0, 64U, n + 16, subkey); COMPILER_ASSERT(crypto_secretbox_ZEROBYTES >= crypto_onetimeauth_poly1305_KEYBYTES); crypto_onetimeauth_poly1305_init(&state, block0); @@ -92,8 +98,16 @@ crypto_secretbox_open_detached(unsigned char *m, const unsigned char *c, unsigned long long mlen0; crypto_core_hsalsa20(subkey, n, k, NULL); - crypto_stream_salsa20(block0, crypto_stream_salsa20_KEYBYTES, - n + 16, subkey); + + memset(block0, 0U, crypto_secretbox_ZEROBYTES); + mlen0 = clen; + if (mlen0 > 64U - crypto_secretbox_ZEROBYTES) { + mlen0 = 64U - crypto_secretbox_ZEROBYTES; + } + for (i = 0U; i < mlen0; i++) { + block0[crypto_secretbox_ZEROBYTES + i] = c[i]; + } + crypto_stream_salsa20_xor(block0, block0, 64, n + 16, subkey); if (crypto_onetimeauth_poly1305_verify(mac, c, clen, block0) != 0) { sodium_memzero(subkey, sizeof subkey); return -1; @@ -101,26 +115,26 @@ crypto_secretbox_open_detached(unsigned char *m, const unsigned char *c, if (m == NULL) { return 0; } - if (((uintptr_t) c >= (uintptr_t) m && + + /* + * Allow the m and c buffers to partially overlap, by calling + * memmove() if necessary. + * + * Note that there is no fully portable way to compare pointers. + * Some tools even report undefined behavior, despite the conversion. + * Nevertheless, this works on all supported platforms. + */ + if (((uintptr_t) c > (uintptr_t) m && (uintptr_t) c - (uintptr_t) m < clen) || - ((uintptr_t) m >= (uintptr_t) c && + ((uintptr_t) m > (uintptr_t) c && (uintptr_t) m - (uintptr_t) c < clen)) { /* LCOV_EXCL_LINE */ memmove(m, c, clen); c = m; } - mlen0 = clen; - if (mlen0 > 64U - crypto_secretbox_ZEROBYTES) { - mlen0 = 64U - crypto_secretbox_ZEROBYTES; - } for (i = 0U; i < mlen0; i++) { - block0[crypto_secretbox_ZEROBYTES + i] = c[i]; - } - crypto_stream_salsa20_xor(block0, block0, - crypto_secretbox_ZEROBYTES + mlen0, - n + 16, subkey); - for (i = 0U; i < mlen0; i++) { - m[i] = block0[i + crypto_secretbox_ZEROBYTES]; + m[i] = block0[crypto_secretbox_ZEROBYTES + i]; } + sodium_memzero(block0, sizeof block0); if (clen > mlen0) { crypto_stream_salsa20_xor_ic(m + mlen0, c + mlen0, clen - mlen0, n + 16, 1U, subkey); diff --git a/libs/libsodium/src/crypto_secretbox/xchacha20poly1305/secretbox_xchacha20poly1305.c b/libs/libsodium/src/crypto_secretbox/xchacha20poly1305/secretbox_xchacha20poly1305.c index f000a66730..628f6f90f8 100644 --- a/libs/libsodium/src/crypto_secretbox/xchacha20poly1305/secretbox_xchacha20poly1305.c +++ b/libs/libsodium/src/crypto_secretbox/xchacha20poly1305/secretbox_xchacha20poly1305.c @@ -31,6 +31,14 @@ crypto_secretbox_xchacha20poly1305_detached(unsigned char *c, crypto_core_hchacha20(subkey, n, k, NULL); + /* + * Allow the m and c buffers to partially overlap, by calling + * memmove() if necessary. + * + * Note that there is no fully portable way to compare pointers. + * Some tools even report undefined behavior, despite the conversion. + * Nevertheless, this works on all supported platforms. + */ if (((uintptr_t) c > (uintptr_t) m && (uintptr_t) c - (uintptr_t) m < mlen) || ((uintptr_t) m > (uintptr_t) c && @@ -99,8 +107,16 @@ crypto_secretbox_xchacha20poly1305_open_detached(unsigned char *m, unsigned long long mlen0; crypto_core_hchacha20(subkey, n, k, NULL); - crypto_stream_chacha20(block0, crypto_stream_chacha20_KEYBYTES, - n + 16, subkey); + + memset(block0, 0, crypto_secretbox_xchacha20poly1305_ZEROBYTES); + mlen0 = clen; + if (mlen0 > 64U - crypto_secretbox_xchacha20poly1305_ZEROBYTES) { + mlen0 = 64U - crypto_secretbox_xchacha20poly1305_ZEROBYTES; + } + for (i = 0U; i < mlen0; i++) { + block0[crypto_secretbox_xchacha20poly1305_ZEROBYTES + i] = c[i]; + } + crypto_stream_chacha20_xor(block0, block0, 64, n + 16, subkey); if (crypto_onetimeauth_poly1305_verify(mac, c, clen, block0) != 0) { sodium_memzero(subkey, sizeof subkey); return -1; @@ -108,25 +124,24 @@ crypto_secretbox_xchacha20poly1305_open_detached(unsigned char *m, if (m == NULL) { return 0; } - if (((uintptr_t) c >= (uintptr_t) m && + + /* + * Allow the m and c buffers to partially overlap, by calling + * memmove() if necessary. + * + * Note that there is no fully portable way to compare pointers. + * Some tools even report undefined behavior, despite the conversion. + * Nevertheless, this works on all supported platforms. + */ + if (((uintptr_t) c > (uintptr_t) m && (uintptr_t) c - (uintptr_t) m < clen) || - ((uintptr_t) m >= (uintptr_t) c && + ((uintptr_t) m > (uintptr_t) c && (uintptr_t) m - (uintptr_t) c < clen)) { /* LCOV_EXCL_LINE */ memmove(m, c, clen); c = m; } - mlen0 = clen; - if (mlen0 > 64U - crypto_secretbox_xchacha20poly1305_ZEROBYTES) { - mlen0 = 64U - crypto_secretbox_xchacha20poly1305_ZEROBYTES; - } - for (i = 0U; i < mlen0; i++) { - block0[crypto_secretbox_xchacha20poly1305_ZEROBYTES + i] = c[i]; - } - crypto_stream_chacha20_xor(block0, block0, - crypto_secretbox_xchacha20poly1305_ZEROBYTES + mlen0, - n + 16, subkey); for (i = 0U; i < mlen0; i++) { - m[i] = block0[i + crypto_secretbox_xchacha20poly1305_ZEROBYTES]; + m[i] = block0[crypto_secretbox_xchacha20poly1305_ZEROBYTES + i]; } if (clen > mlen0) { crypto_stream_chacha20_xor_ic(m + mlen0, c + mlen0, clen - mlen0, diff --git a/libs/libsodium/src/crypto_secretstream/xchacha20poly1305/secretstream_xchacha20poly1305.c b/libs/libsodium/src/crypto_secretstream/xchacha20poly1305/secretstream_xchacha20poly1305.c index 9c321ceced..e731689293 100644 --- a/libs/libsodium/src/crypto_secretstream/xchacha20poly1305/secretstream_xchacha20poly1305.c +++ b/libs/libsodium/src/crypto_secretstream/xchacha20poly1305/secretstream_xchacha20poly1305.c @@ -148,6 +148,7 @@ crypto_secretstream_xchacha20poly1305_push crypto_onetimeauth_poly1305_update(&poly1305_state, c, mlen); crypto_onetimeauth_poly1305_update (&poly1305_state, _pad0, (0x10 - (sizeof block) + mlen) & 0xf); + /* should have been (0x10 - (sizeof block + mlen)) & 0xf to keep input blocks aligned */ STORE64_LE(slen, (uint64_t) adlen); crypto_onetimeauth_poly1305_update(&poly1305_state, slen, sizeof slen); @@ -224,6 +225,7 @@ crypto_secretstream_xchacha20poly1305_pull crypto_onetimeauth_poly1305_update(&poly1305_state, c, mlen); crypto_onetimeauth_poly1305_update (&poly1305_state, _pad0, (0x10 - (sizeof block) + mlen) & 0xf); + /* should have been (0x10 - (sizeof block + mlen)) & 0xf to keep input blocks aligned */ STORE64_LE(slen, (uint64_t) adlen); crypto_onetimeauth_poly1305_update(&poly1305_state, slen, sizeof slen); diff --git a/libs/libsodium/src/crypto_sign/ed25519/ref10/keypair.c b/libs/libsodium/src/crypto_sign/ed25519/ref10/keypair.c index 5d0e6a0006..6c15b2d6c6 100644 --- a/libs/libsodium/src/crypto_sign/ed25519/ref10/keypair.c +++ b/libs/libsodium/src/crypto_sign/ed25519/ref10/keypair.c @@ -50,12 +50,13 @@ crypto_sign_ed25519_pk_to_curve25519(unsigned char *curve25519_pk, fe25519 x; fe25519 one_minus_y; - if (ge25519_has_small_order(ed25519_pk) != 0 || - ge25519_frombytes_negate_vartime(&A, ed25519_pk) != 0 || + if (ge25519_frombytes_negate_vartime(&A, ed25519_pk) != 0 || + ge25519_has_small_order(&A) != 0 || ge25519_is_on_main_subgroup(&A) == 0) { return -1; } fe25519_1(one_minus_y); + /* assumes A.Z=1 */ fe25519_sub(one_minus_y, one_minus_y, A.Y); fe25519_1(x); fe25519_add(x, x, A.Y); diff --git a/libs/libsodium/src/crypto_sign/ed25519/ref10/obsolete.c b/libs/libsodium/src/crypto_sign/ed25519/ref10/obsolete.c deleted file mode 100644 index f0d53b7335..0000000000 --- a/libs/libsodium/src/crypto_sign/ed25519/ref10/obsolete.c +++ /dev/null @@ -1,116 +0,0 @@ - -#include -#include -#include - -#include "crypto_hash_sha512.h" -#include "crypto_sign_edwards25519sha512batch.h" -#include "crypto_verify_32.h" -#include "private/ed25519_ref10.h" -#include "randombytes.h" -#include "utils.h" - -int -crypto_sign_edwards25519sha512batch_keypair(unsigned char *pk, - unsigned char *sk) -{ - ge25519_p3 A; - - randombytes_buf(sk, 32); - crypto_hash_sha512(sk, sk, 32); - sk[0] &= 248; - sk[31] &= 127; - sk[31] |= 64; - ge25519_scalarmult_base(&A, sk); - ge25519_p3_tobytes(pk, &A); - - return 0; -} - -int -crypto_sign_edwards25519sha512batch(unsigned char *sm, - unsigned long long *smlen_p, - const unsigned char *m, - unsigned long long mlen, - const unsigned char *sk) -{ - crypto_hash_sha512_state hs; - unsigned char nonce[64]; - unsigned char hram[64]; - unsigned char sig[64]; - ge25519_p3 A; - ge25519_p3 R; - - crypto_hash_sha512_init(&hs); - crypto_hash_sha512_update(&hs, sk + 32, 32); - crypto_hash_sha512_update(&hs, m, mlen); - crypto_hash_sha512_final(&hs, nonce); - ge25519_scalarmult_base(&A, sk); - ge25519_p3_tobytes(sig + 32, &A); - sc25519_reduce(nonce); - ge25519_scalarmult_base(&R, nonce); - ge25519_p3_tobytes(sig, &R); - crypto_hash_sha512_init(&hs); - crypto_hash_sha512_update(&hs, sig, 32); - crypto_hash_sha512_update(&hs, m, mlen); - crypto_hash_sha512_final(&hs, hram); - sc25519_reduce(hram); - sc25519_muladd(sig + 32, hram, nonce, sk); - sodium_memzero(hram, sizeof hram); - memmove(sm + 32, m, (size_t) mlen); - memcpy(sm, sig, 32); - memcpy(sm + 32 + mlen, sig + 32, 32); - *smlen_p = mlen + 64U; - - return 0; -} - -int -crypto_sign_edwards25519sha512batch_open(unsigned char *m, - unsigned long long *mlen_p, - const unsigned char *sm, - unsigned long long smlen, - const unsigned char *pk) -{ - unsigned char h[64]; - unsigned char t1[32], t2[32]; - unsigned long long mlen; - ge25519_cached Ai; - ge25519_p1p1 csa; - ge25519_p2 cs; - ge25519_p3 A; - ge25519_p3 R; - ge25519_p3 cs3; - - *mlen_p = 0; - if (smlen < 64 || smlen - 64 > crypto_sign_edwards25519sha512batch_MESSAGEBYTES_MAX) { - return -1; - } - mlen = smlen - 64; - if (sm[smlen - 1] & 224) { - return -1; - } - if (ge25519_has_small_order(pk) != 0 || - ge25519_frombytes_negate_vartime(&A, pk) != 0 || - ge25519_has_small_order(sm) != 0 || - ge25519_frombytes_negate_vartime(&R, sm) != 0) { - return -1; - } - ge25519_p3_to_cached(&Ai, &A); - crypto_hash_sha512(h, sm, mlen + 32); - sc25519_reduce(h); - ge25519_scalarmult(&cs3, h, &R); - ge25519_add(&csa, &cs3, &Ai); - ge25519_p1p1_to_p2(&cs, &csa); - ge25519_tobytes(t1, &cs); - t1[31] ^= 1 << 7; - ge25519_scalarmult_base(&R, sm + 32 + mlen); - ge25519_p3_tobytes(t2, &R); - if (crypto_verify_32(t1, t2) != 0) { - return -1; - } - *mlen_p = mlen; - memmove(m, sm + 32, mlen); - - return 0; -} diff --git a/libs/libsodium/src/crypto_sign/ed25519/ref10/open.c b/libs/libsodium/src/crypto_sign/ed25519/ref10/open.c index d4b3f26980..b4654e3bee 100644 --- a/libs/libsodium/src/crypto_sign/ed25519/ref10/open.c +++ b/libs/libsodium/src/crypto_sign/ed25519/ref10/open.c @@ -7,6 +7,7 @@ #include "crypto_sign_ed25519.h" #include "crypto_verify_32.h" #include "sign_ed25519_ref10.h" +#include "private/common.h" #include "private/ed25519_ref10.h" #include "utils.h" @@ -19,25 +20,32 @@ _crypto_sign_ed25519_verify_detached(const unsigned char *sig, { crypto_hash_sha512_state hs; unsigned char h[64]; - unsigned char rcheck[32]; + ge25519_p3 check; + ge25519_p3 expected_r; ge25519_p3 A; - ge25519_p2 R; + ge25519_p3 sb_ah; + ge25519_p2 sb_ah_p2; + ACQUIRE_FENCE; #ifdef ED25519_COMPAT if (sig[63] & 224) { return -1; } #else - if (sc25519_is_canonical(sig + 32) == 0 || - ge25519_has_small_order(sig) != 0) { + if ((sig[63] & 240) != 0 && + sc25519_is_canonical(sig + 32) == 0) { return -1; } - if (ge25519_is_canonical(pk) == 0 || - ge25519_has_small_order(pk) != 0) { + if (ge25519_is_canonical(pk) == 0) { return -1; } #endif - if (ge25519_frombytes_negate_vartime(&A, pk) != 0) { + if (ge25519_frombytes_negate_vartime(&A, pk) != 0 || + ge25519_has_small_order(&A) != 0) { + return -1; + } + if (ge25519_frombytes(&expected_r, sig) != 0 || + ge25519_has_small_order(&expected_r) != 0) { return -1; } _crypto_sign_ed25519_ref10_hinit(&hs, prehashed); @@ -47,11 +55,11 @@ _crypto_sign_ed25519_verify_detached(const unsigned char *sig, crypto_hash_sha512_final(&hs, h); sc25519_reduce(h); - ge25519_double_scalarmult_vartime(&R, h, &A, sig + 32); - ge25519_tobytes(rcheck, &R); + ge25519_double_scalarmult_vartime(&sb_ah_p2, h, &A, sig + 32, NULL); + ge25519_p2_to_p3(&sb_ah, &sb_ah_p2); + ge25519_p3_sub(&check, &expected_r, &sb_ah); - return crypto_verify_32(rcheck, sig) | (-(rcheck == sig)) | - sodium_memcmp(sig, rcheck, 32); + return ge25519_has_small_order(&check) - 1; } int diff --git a/libs/libsodium/src/crypto_sign/ed25519/ref10/sign.c b/libs/libsodium/src/crypto_sign/ed25519/ref10/sign.c index 74a8100927..c00c08b40e 100644 --- a/libs/libsodium/src/crypto_sign/ed25519/ref10/sign.c +++ b/libs/libsodium/src/crypto_sign/ed25519/ref10/sign.c @@ -33,31 +33,16 @@ _crypto_sign_ed25519_clamp(unsigned char k[32]) } #ifdef ED25519_NONDETERMINISTIC -/* r = hash(B || empty_labelset || Z || pad1 || k || pad2 || empty_labelset || K || extra || M) (mod q) */ +/* r = hash(k || K || noise || pad || M) (mod q) */ static void _crypto_sign_ed25519_synthetic_r_hv(crypto_hash_sha512_state *hs, - unsigned char Z[32], - const unsigned char sk[64]) + unsigned char tmp[64], + const unsigned char az[64]) { - static const unsigned char B[32] = { - 0x58, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, - 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, - 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, - 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, - }; - static const unsigned char zeros[128] = { 0x00 }; - static const unsigned char empty_labelset[3] = { 0x02, 0x00, 0x00 }; - - crypto_hash_sha512_update(hs, B, 32); - crypto_hash_sha512_update(hs, empty_labelset, 3); - randombytes_buf(Z, 32); - crypto_hash_sha512_update(hs, Z, 32); - crypto_hash_sha512_update(hs, zeros, 128 - (32 + 3 + 32) % 128); - crypto_hash_sha512_update(hs, sk, 32); - crypto_hash_sha512_update(hs, zeros, 128 - 32 % 128); - crypto_hash_sha512_update(hs, empty_labelset, 3); - crypto_hash_sha512_update(hs, sk + 32, 32); - /* empty extra */ + crypto_hash_sha512_update(hs, az, 64); + randombytes_buf(tmp, 32); + memset(tmp + 32, 0, 32); + crypto_hash_sha512_update(hs, tmp, 64); } #endif @@ -76,7 +61,7 @@ _crypto_sign_ed25519_detached(unsigned char *sig, unsigned long long *siglen_p, crypto_hash_sha512(az, sk, 32); #ifdef ED25519_NONDETERMINISTIC - _crypto_sign_ed25519_synthetic_r_hv(&hs, nonce, az); + _crypto_sign_ed25519_synthetic_r_hv(&hs, nonce /* tmp */, az); #else crypto_hash_sha512_update(&hs, az + 32, 32); #endif diff --git a/libs/libsodium/src/crypto_sign/ed25519/ref10/sign_ed25519_ref10.h b/libs/libsodium/src/crypto_sign/ed25519/ref10/sign_ed25519_ref10.h index 29db3269de..4c36638c7e 100644 --- a/libs/libsodium/src/crypto_sign/ed25519/ref10/sign_ed25519_ref10.h +++ b/libs/libsodium/src/crypto_sign/ed25519/ref10/sign_ed25519_ref10.h @@ -1,6 +1,8 @@ #ifndef sign_ed25519_ref10_H #define sign_ed25519_ref10_H +#include "private/quirks.h" + void _crypto_sign_ed25519_ref10_hinit(crypto_hash_sha512_state *hs, int prehashed); diff --git a/libs/libsodium/src/crypto_stream/chacha20/dolbeau/chacha20_dolbeau-avx2.c b/libs/libsodium/src/crypto_stream/chacha20/dolbeau/chacha20_dolbeau-avx2.c index 1e2cdf266c..ea27928964 100644 --- a/libs/libsodium/src/crypto_stream/chacha20/dolbeau/chacha20_dolbeau-avx2.c +++ b/libs/libsodium/src/crypto_stream/chacha20/dolbeau/chacha20_dolbeau-avx2.c @@ -6,23 +6,22 @@ #include "core.h" #include "crypto_stream_chacha20.h" #include "private/common.h" -#include "private/sse2_64_32.h" #include "utils.h" #if defined(HAVE_AVX2INTRIN_H) && defined(HAVE_EMMINTRIN_H) && \ defined(HAVE_TMMINTRIN_H) && defined(HAVE_SMMINTRIN_H) -# ifdef __GNUC__ -# pragma GCC target("sse2") -# pragma GCC target("ssse3") -# pragma GCC target("sse4.1") -# pragma GCC target("avx2") +# ifdef __clang__ +# pragma clang attribute push(__attribute__((target("sse2,ssse3,sse4.1,avx2"))), apply_to = function) +# elif defined(__GNUC__) +# pragma GCC target("sse2,ssse3,sse4.1,avx2") # endif # include # include # include # include +# include "private/sse2_64_32.h" # include "../stream_chacha20.h" # include "chacha20_dolbeau-avx2.h" @@ -174,4 +173,8 @@ struct crypto_stream_chacha20_implementation SODIUM_C99(.stream_ietf_ext_xor_ic =) stream_ietf_ext_ref_xor_ic }; +# ifdef __clang__ +# pragma clang attribute pop +# endif + #endif diff --git a/libs/libsodium/src/crypto_stream/chacha20/dolbeau/chacha20_dolbeau-ssse3.c b/libs/libsodium/src/crypto_stream/chacha20/dolbeau/chacha20_dolbeau-ssse3.c index ae5df1cc28..5175624fbb 100644 --- a/libs/libsodium/src/crypto_stream/chacha20/dolbeau/chacha20_dolbeau-ssse3.c +++ b/libs/libsodium/src/crypto_stream/chacha20/dolbeau/chacha20_dolbeau-ssse3.c @@ -6,18 +6,19 @@ #include "core.h" #include "crypto_stream_chacha20.h" #include "private/common.h" -#include "private/sse2_64_32.h" #include "utils.h" #if defined(HAVE_EMMINTRIN_H) && defined(HAVE_TMMINTRIN_H) -# ifdef __GNUC__ -# pragma GCC target("sse2") -# pragma GCC target("ssse3") +# ifdef __clang__ +# pragma clang attribute push(__attribute__((target("sse2,ssse3"))), apply_to = function) +# elif defined(__GNUC__) +# pragma GCC target("sse2,ssse3") # endif # include # include +# include "private/sse2_64_32.h" # include "../stream_chacha20.h" # include "chacha20_dolbeau-ssse3.h" @@ -168,4 +169,8 @@ struct crypto_stream_chacha20_implementation SODIUM_C99(.stream_ietf_ext_xor_ic =) stream_ietf_ext_ref_xor_ic }; +# ifdef __clang__ +# pragma clang attribute pop +# endif + #endif diff --git a/libs/libsodium/src/crypto_stream/chacha20/dolbeau/u8.h b/libs/libsodium/src/crypto_stream/chacha20/dolbeau/u8.h index c92fbd3514..adc7da9ab8 100644 --- a/libs/libsodium/src/crypto_stream/chacha20/dolbeau/u8.h +++ b/libs/libsodium/src/crypto_stream/chacha20/dolbeau/u8.h @@ -2,21 +2,6 @@ #define VEC8_ROT(A, IMM) \ _mm256_or_si256(_mm256_slli_epi32(A, IMM), _mm256_srli_epi32(A, (32 - IMM))) -/* implements a vector quarter round by-the-book (naive!) */ -#define VEC8_QUARTERROUND_NAIVE(A, B, C, D) \ - x_##A = _mm256_add_epi32(x_##A, x_##B); \ - t_##A = _mm256_xor_si256(x_##D, x_##A); \ - x_##D = VEC8_ROT(t_##A, 16); \ - x_##C = _mm256_add_epi32(x_##C, x_##D); \ - t_##C = _mm256_xor_si256(x_##B, x_##C); \ - x_##B = VEC8_ROT(t_##C, 12); \ - x_##A = _mm256_add_epi32(x_##A, x_##B); \ - t_##A = _mm256_xor_si256(x_##D, x_##A); \ - x_##D = VEC8_ROT(t_##A, 8); \ - x_##C = _mm256_add_epi32(x_##C, x_##D); \ - t_##C = _mm256_xor_si256(x_##B, x_##C); \ - x_##B = VEC8_ROT(t_##C, 7) - /* same, but replace 2 of the shift/shift/or "rotation" by byte shuffles (8 & * 16) (better) */ #define VEC8_QUARTERROUND_SHUFFLE(A, B, C, D) \ @@ -33,22 +18,6 @@ t_##C = _mm256_xor_si256(x_##B, x_##C); \ x_##B = VEC8_ROT(t_##C, 7) -/* same, but replace 2 of the shift/shift/or "rotation" by byte & word shuffles - * (8 & 16) (not as good as previous) */ -#define VEC8_QUARTERROUND_SHUFFLE2(A, B, C, D) \ - x_##A = _mm256_add_epi32(x_##A, x_##B); \ - t_##A = _mm256_xor_si256(x_##D, x_##A); \ - x_##D = _mm256_shufflehi_epi16(_mm256_shufflelo_epi16(t_##A, 0xb1), 0xb1); \ - x_##C = _mm256_add_epi32(x_##C, x_##D); \ - t_##C = _mm256_xor_si256(x_##B, x_##C); \ - x_##B = VEC8_ROT(t_##C, 12); \ - x_##A = _mm256_add_epi32(x_##A, x_##B); \ - t_##A = _mm256_xor_si256(x_##D, x_##A); \ - x_##D = _mm256_shuffle_epi8(t_##A, rot8); \ - x_##C = _mm256_add_epi32(x_##C, x_##D); \ - t_##C = _mm256_xor_si256(x_##B, x_##C); \ - x_##B = VEC8_ROT(t_##C, 7) - #define VEC8_QUARTERROUND(A, B, C, D) VEC8_QUARTERROUND_SHUFFLE(A, B, C, D) #define VEC8_LINE1(A, B, C, D) \ diff --git a/libs/libsodium/src/crypto_stream/salsa20/stream_salsa20.h b/libs/libsodium/src/crypto_stream/salsa20/stream_salsa20.h index 0b5971ca48..0b5f3ab184 100644 --- a/libs/libsodium/src/crypto_stream/salsa20/stream_salsa20.h +++ b/libs/libsodium/src/crypto_stream/salsa20/stream_salsa20.h @@ -4,6 +4,8 @@ #include +#include "private/quirks.h" + typedef struct crypto_stream_salsa20_implementation { int (*stream)(unsigned char *c, unsigned long long clen, const unsigned char *n, const unsigned char *k); diff --git a/libs/libsodium/src/crypto_stream/salsa20/xmm6/salsa20_xmm6-asm.S b/libs/libsodium/src/crypto_stream/salsa20/xmm6/salsa20_xmm6-asm.S index 9ecea1b088..0406b29da9 100644 --- a/libs/libsodium/src/crypto_stream/salsa20/xmm6/salsa20_xmm6-asm.S +++ b/libs/libsodium/src/crypto_stream/salsa20/xmm6/salsa20_xmm6-asm.S @@ -1,5 +1,8 @@ #ifdef HAVE_AMD64_ASM +#include "private/asm_cet.h" +#include "salsa20_xmm6-asm_namespace.h" + .text .p2align 5 @@ -15,6 +18,8 @@ ASM_HIDE_SYMBOL _stream_salsa20_xmm6 #endif stream_salsa20_xmm6: _stream_salsa20_xmm6: + +_CET_ENDBR mov %rsp,%r11 and $31,%r11 add $512,%r11 @@ -56,6 +61,7 @@ ASM_HIDE_SYMBOL _stream_salsa20_xmm6_xor_ic stream_salsa20_xmm6_xor_ic: _stream_salsa20_xmm6_xor_ic: +_CET_ENDBR mov %rsp,%r11 and $31,%r11 add $512,%r11 diff --git a/libs/libsodium/src/crypto_stream/salsa20/xmm6/salsa20_xmm6-asm_namespace.h b/libs/libsodium/src/crypto_stream/salsa20/xmm6/salsa20_xmm6-asm_namespace.h new file mode 100644 index 0000000000..15c5212ebf --- /dev/null +++ b/libs/libsodium/src/crypto_stream/salsa20/xmm6/salsa20_xmm6-asm_namespace.h @@ -0,0 +1,10 @@ +#ifndef salsa20_xmm6_asm_namespace_H +#define salsa20_xmm6_asm_namespace_H + +#define stream_salsa20_xmm6 _sodium_stream_salsa20_xmm6 +#define _stream_salsa20_xmm6 __sodium_stream_salsa20_xmm6 + +#define stream_salsa20_xmm6_xor_ic _sodium_stream_salsa20_xmm6_xor_ic +#define _stream_salsa20_xmm6_xor_ic __sodium_stream_salsa20_xmm6_xor_ic + +#endif diff --git a/libs/libsodium/src/crypto_stream/salsa20/xmm6/salsa20_xmm6.h b/libs/libsodium/src/crypto_stream/salsa20/xmm6/salsa20_xmm6.h index 3ccbb5e8e6..d88542fd24 100644 --- a/libs/libsodium/src/crypto_stream/salsa20/xmm6/salsa20_xmm6.h +++ b/libs/libsodium/src/crypto_stream/salsa20/xmm6/salsa20_xmm6.h @@ -3,6 +3,7 @@ #include "../stream_salsa20.h" #include "crypto_stream_salsa20.h" +#include "salsa20_xmm6-asm_namespace.h" extern struct crypto_stream_salsa20_implementation crypto_stream_salsa20_xmm6_implementation; diff --git a/libs/libsodium/src/crypto_stream/salsa20/xmm6int/salsa20_xmm6int-avx2.c b/libs/libsodium/src/crypto_stream/salsa20/xmm6int/salsa20_xmm6int-avx2.c index 95bb63fd13..41cc8a610a 100644 --- a/libs/libsodium/src/crypto_stream/salsa20/xmm6int/salsa20_xmm6int-avx2.c +++ b/libs/libsodium/src/crypto_stream/salsa20/xmm6int/salsa20_xmm6int-avx2.c @@ -5,23 +5,22 @@ #include "crypto_stream_salsa20.h" #include "private/common.h" -#include "private/sse2_64_32.h" #include "utils.h" #if defined(HAVE_AVX2INTRIN_H) && defined(HAVE_EMMINTRIN_H) && \ defined(HAVE_TMMINTRIN_H) && defined(HAVE_SMMINTRIN_H) -# ifdef __GNUC__ -# pragma GCC target("sse2") -# pragma GCC target("ssse3") -# pragma GCC target("sse4.1") -# pragma GCC target("avx2") +# ifdef __clang__ +# pragma clang attribute push(__attribute__((target("sse2,ssse3,sse4.1,avx2"))), apply_to = function) +# elif defined(__GNUC__) +# pragma GCC target("sse2,ssse3,sse4.1,avx2") # endif -#include -#include -#include -#include +# include +# include +# include +# include +# include "private/sse2_64_32.h" # include "../stream_salsa20.h" # include "salsa20_xmm6int-avx2.h" @@ -128,4 +127,8 @@ struct crypto_stream_salsa20_implementation SODIUM_C99(.stream_xor_ic =) stream_avx2_xor_ic }; +#ifdef __clang__ +# pragma clang attribute pop +#endif + #endif diff --git a/libs/libsodium/src/crypto_stream/salsa20/xmm6int/salsa20_xmm6int-sse2.c b/libs/libsodium/src/crypto_stream/salsa20/xmm6int/salsa20_xmm6int-sse2.c index 41dc8193fc..c3694cd70f 100644 --- a/libs/libsodium/src/crypto_stream/salsa20/xmm6int/salsa20_xmm6int-sse2.c +++ b/libs/libsodium/src/crypto_stream/salsa20/xmm6int/salsa20_xmm6int-sse2.c @@ -5,15 +5,17 @@ #include "crypto_stream_salsa20.h" #include "private/common.h" -#include "private/sse2_64_32.h" #include "utils.h" #ifdef HAVE_EMMINTRIN_H -# ifdef __GNUC__ +# ifdef __clang__ +# pragma clang attribute push(__attribute__((target("sse2"))), apply_to = function) +# elif defined(__GNUC__) # pragma GCC target("sse2") # endif # include +# include "private/sse2_64_32.h" # include "../stream_salsa20.h" # include "salsa20_xmm6int-sse2.h" @@ -119,4 +121,8 @@ struct crypto_stream_salsa20_implementation SODIUM_C99(.stream_xor_ic =) stream_sse2_xor_ic }; +#ifdef __clang__ +# pragma clang attribute pop +#endif + #endif diff --git a/libs/libsodium/src/crypto_stream/salsa20/xmm6int/u0.h b/libs/libsodium/src/crypto_stream/salsa20/xmm6int/u0.h index e2634b4a3e..cce494af6e 100644 --- a/libs/libsodium/src/crypto_stream/salsa20/xmm6int/u0.h +++ b/libs/libsodium/src/crypto_stream/salsa20/xmm6int/u0.h @@ -5,7 +5,7 @@ if (bytes > 0) { __m128i diag3 = _mm_loadu_si128((const __m128i *) (x + 12)); __m128i a0, a1, a2, a3, a4, a5, a6, a7; __m128i b0, b1, b2, b3, b4, b5, b6, b7; - uint8_t partialblock[64]; + uint8_t partialblock[64] = { 0 }; unsigned int i; diff --git a/libs/libsodium/src/crypto_stream/xchacha20/stream_xchacha20.c b/libs/libsodium/src/crypto_stream/xchacha20/stream_xchacha20.c index 47807e0a44..c9d7e70dcc 100644 --- a/libs/libsodium/src/crypto_stream/xchacha20/stream_xchacha20.c +++ b/libs/libsodium/src/crypto_stream/xchacha20/stream_xchacha20.c @@ -35,7 +35,7 @@ crypto_stream_xchacha20(unsigned char *c, unsigned long long clen, COMPILER_ASSERT(crypto_stream_chacha20_KEYBYTES <= sizeof k2); COMPILER_ASSERT(crypto_stream_chacha20_NONCEBYTES == crypto_stream_xchacha20_NONCEBYTES - - crypto_core_hchacha20_INPUTBYTES); + crypto_core_hchacha20_INPUTBYTES); return crypto_stream_chacha20(c, clen, n + crypto_core_hchacha20_INPUTBYTES, k2); diff --git a/libs/libsodium/src/crypto_verify/sodium/verify.c b/libs/libsodium/src/crypto_verify/sodium/verify.c deleted file mode 100644 index 18e8c9c898..0000000000 --- a/libs/libsodium/src/crypto_verify/sodium/verify.c +++ /dev/null @@ -1,98 +0,0 @@ - -#include -#include - -#include "crypto_verify_16.h" -#include "crypto_verify_32.h" -#include "crypto_verify_64.h" - -size_t -crypto_verify_16_bytes(void) -{ - return crypto_verify_16_BYTES; -} - -size_t -crypto_verify_32_bytes(void) -{ - return crypto_verify_32_BYTES; -} - -size_t -crypto_verify_64_bytes(void) -{ - return crypto_verify_64_BYTES; -} - -#if defined(HAVE_EMMINTRIN_H) && defined(__SSE2__) - -# ifdef __GNUC__ -# pragma GCC target("sse2") -# endif -# include - -static inline int -crypto_verify_n(const unsigned char *x_, const unsigned char *y_, - const int n) -{ - const __m128i zero = _mm_setzero_si128(); - volatile __m128i v1, v2, z; - volatile int m; - int i; - - const volatile __m128i *volatile x = - (const volatile __m128i *volatile) (const void *) x_; - const volatile __m128i *volatile y = - (const volatile __m128i *volatile) (const void *) y_; - v1 = _mm_loadu_si128((const __m128i *) &x[0]); - v2 = _mm_loadu_si128((const __m128i *) &y[0]); - z = _mm_xor_si128(v1, v2); - for (i = 1; i < n / 16; i++) { - v1 = _mm_loadu_si128((const __m128i *) &x[i]); - v2 = _mm_loadu_si128((const __m128i *) &y[i]); - z = _mm_or_si128(z, _mm_xor_si128(v1, v2)); - } - m = _mm_movemask_epi8(_mm_cmpeq_epi32(z, zero)); - v1 = zero; v2 = zero; z = zero; - - return (int) (((uint32_t) m + 1U) >> 16) - 1; -} - -#else - -static inline int -crypto_verify_n(const unsigned char *x_, const unsigned char *y_, - const int n) -{ - const volatile unsigned char *volatile x = - (const volatile unsigned char *volatile) x_; - const volatile unsigned char *volatile y = - (const volatile unsigned char *volatile) y_; - volatile uint_fast16_t d = 0U; - int i; - - for (i = 0; i < n; i++) { - d |= x[i] ^ y[i]; - } - return (1 & ((d - 1) >> 8)) - 1; -} - -#endif - -int -crypto_verify_16(const unsigned char *x, const unsigned char *y) -{ - return crypto_verify_n(x, y, crypto_verify_16_BYTES); -} - -int -crypto_verify_32(const unsigned char *x, const unsigned char *y) -{ - return crypto_verify_n(x, y, crypto_verify_32_BYTES); -} - -int -crypto_verify_64(const unsigned char *x, const unsigned char *y) -{ - return crypto_verify_n(x, y, crypto_verify_64_BYTES); -} diff --git a/libs/libsodium/src/crypto_verify/verify.c b/libs/libsodium/src/crypto_verify/verify.c new file mode 100644 index 0000000000..c79d4aaf22 --- /dev/null +++ b/libs/libsodium/src/crypto_verify/verify.c @@ -0,0 +1,96 @@ + +#include +#include + +#include "crypto_verify_16.h" +#include "crypto_verify_32.h" +#include "crypto_verify_64.h" +#include "private/common.h" + +size_t +crypto_verify_16_bytes(void) +{ + return crypto_verify_16_BYTES; +} + +size_t +crypto_verify_32_bytes(void) +{ + return crypto_verify_32_BYTES; +} + +size_t +crypto_verify_64_bytes(void) +{ + return crypto_verify_64_BYTES; +} + +#if defined(HAVE_EMMINTRIN_H) && defined(__SSE2__) + +# include + +static inline int +crypto_verify_n(const unsigned char *x_, const unsigned char *y_, + const int n) +{ + const __m128i zero = _mm_setzero_si128(); + volatile __m128i v1, v2, z; + volatile int m; + int i; + + const volatile __m128i *volatile x = + (const volatile __m128i *volatile) (const void *) x_; + const volatile __m128i *volatile y = + (const volatile __m128i *volatile) (const void *) y_; + v1 = _mm_loadu_si128((const __m128i *) &x[0]); + v2 = _mm_loadu_si128((const __m128i *) &y[0]); + z = _mm_xor_si128(v1, v2); + for (i = 1; i < n / 16; i++) { + v1 = _mm_loadu_si128((const __m128i *) &x[i]); + v2 = _mm_loadu_si128((const __m128i *) &y[i]); + z = _mm_or_si128(z, _mm_xor_si128(v1, v2)); + } + m = _mm_movemask_epi8(_mm_cmpeq_epi32(z, zero)); + v1 = zero; v2 = zero; z = zero; + + return (int) (((uint32_t) m + 1U) >> 16) - 1; +} + +#else + +static inline int +crypto_verify_n(const unsigned char *x_, const unsigned char *y_, + const int n) +{ + const volatile unsigned char *volatile x = + (const volatile unsigned char *volatile) x_; + const volatile unsigned char *volatile y = + (const volatile unsigned char *volatile) y_; + volatile uint_fast16_t d = 0U; + int i; + + for (i = 0; i < n; i++) { + d |= x[i] ^ y[i]; + } + return (1 & ((d - 1) >> 8)) - 1; +} + +#endif + +int +crypto_verify_16(const unsigned char *x, const unsigned char *y) +{ + return crypto_verify_n(x, y, crypto_verify_16_BYTES); +} + +int +crypto_verify_32(const unsigned char *x, const unsigned char *y) +{ + return crypto_verify_n(x, y, crypto_verify_32_BYTES); +} + +int +crypto_verify_64(const unsigned char *x, const unsigned char *y) +{ + return crypto_verify_n(x, y, crypto_verify_64_BYTES); +} diff --git a/libs/libsodium/src/crypto_vrf/crypto_vrf.c b/libs/libsodium/src/crypto_vrf/crypto_vrf.c new file mode 100644 index 0000000000..52f024dd64 --- /dev/null +++ b/libs/libsodium/src/crypto_vrf/crypto_vrf.c @@ -0,0 +1,72 @@ + +#include "crypto_vrf.h" + +size_t +crypto_vrf_publickeybytes(void) +{ + return crypto_vrf_PUBLICKEYBYTES; +} + +size_t +crypto_vrf_secretkeybytes(void) +{ + return crypto_vrf_SECRETKEYBYTES; +} + +size_t +crypto_vrf_seedbytes(void) +{ + return crypto_vrf_SEEDBYTES; +} + +size_t +crypto_vrf_proofbytes(void) +{ + return crypto_vrf_PROOFBYTES; +} + +size_t +crypto_vrf_outputbytes(void) +{ + return crypto_vrf_OUTPUTBYTES; +} + +const char * +crypto_vrf_primitive(void) +{ + return crypto_vrf_PRIMITIVE; +} + +int +crypto_vrf_keypair(unsigned char *pk, unsigned char *sk) +{ + return crypto_vrf_rfc9381_keypair(pk, sk); +} + +int +crypto_vrf_seed_keypair(unsigned char *pk, unsigned char *sk, + const unsigned char *seed) +{ + return crypto_vrf_rfc9381_seed_keypair(pk, sk, seed); +} + +int +crypto_vrf_prove(unsigned char *proof, const unsigned char *m, const unsigned long long mlen, + const unsigned char *skpk) +{ + return crypto_vrf_rfc9381_prove(proof, m, mlen, skpk); +} + +int +crypto_vrf_verify(unsigned char *output, const unsigned char *pk, + const unsigned char *proof, const unsigned char *m, + const unsigned long long mlen) +{ + return crypto_vrf_rfc9381_verify(output, pk, proof, m, mlen); +} + +int +crypto_vrf_proof_to_hash(unsigned char *hash, const unsigned char *proof) +{ + return crypto_vrf_rfc9381_proof_to_hash(hash, proof); +} diff --git a/libs/libsodium/src/crypto_vrf/rfc9381/keypair.c b/libs/libsodium/src/crypto_vrf/rfc9381/keypair.c new file mode 100644 index 0000000000..ecefa5e054 --- /dev/null +++ b/libs/libsodium/src/crypto_vrf/rfc9381/keypair.c @@ -0,0 +1,40 @@ +#include + +#include "crypto_hash_sha512.h" +#include "crypto_vrf_rfc9381.h" +#include "private/ed25519_ref10.h" +#include "randombytes.h" +#include "utils.h" + +int +crypto_vrf_rfc9381_seed_keypair(unsigned char *pk, unsigned char *sk, + const unsigned char *seed) +{ + ge25519_p3 A; + + crypto_hash_sha512(sk, seed, 32); + sk[0] &= 248; + sk[31] &= 127; + sk[31] |= 64; + + ge25519_scalarmult_base(&A, sk); + ge25519_p3_tobytes(pk, &A); + + memmove(sk, seed, 32); + memmove(sk + 32, pk, 32); + + return 0; +} + +int +crypto_vrf_rfc9381_keypair(unsigned char *pk, unsigned char *sk) +{ + unsigned char seed[32]; + int ret; + + randombytes_buf(seed, sizeof seed); + ret = crypto_vrf_rfc9381_seed_keypair(pk, sk, seed); + sodium_memzero(seed, sizeof seed); + + return ret; +} diff --git a/libs/libsodium/src/crypto_vrf/rfc9381/prove.c b/libs/libsodium/src/crypto_vrf/rfc9381/prove.c new file mode 100644 index 0000000000..1dffed2774 --- /dev/null +++ b/libs/libsodium/src/crypto_vrf/rfc9381/prove.c @@ -0,0 +1,69 @@ +#include +#include + +#include "crypto_hash_sha512.h" +#include "crypto_vrf_rfc9381.h" +#include "private/ed25519_ref10.h" +#include "utils.h" +#include "vrf_rfc9381.h" + + +int +crypto_vrf_rfc9381_prove(unsigned char *proof, + const unsigned char *m, unsigned long long mlen, + const unsigned char *sk) +{ + + crypto_hash_sha512_state hs; + unsigned char az[64]; + unsigned char H_string[32]; + unsigned char kB_string[32], kH_string[32]; + unsigned char string_to_hash[32 + mlen]; + unsigned char challenge[64], nonce[64]; + ge25519_p3 H, Gamma, kB, kH; + + crypto_hash_sha512(az, sk, 32); + az[0] &= 248; + az[31] &= 127; + az[31] |= 64; + + memmove(string_to_hash, sk + 32, 32); + memmove(string_to_hash + 32, m, mlen); + ge25519_from_string(H_string, "ECVRF_edwards25519_XMD:SHA-512_ELL2_NU_\4", string_to_hash, 32 + mlen, 2); /* elligator2 */ + + ge25519_frombytes(&H, H_string); + ge25519_scalarmult(&Gamma, az, &H); + + crypto_hash_sha512_init(&hs); + crypto_hash_sha512_update(&hs, az + 32, 32); + crypto_hash_sha512_update(&hs, H_string, 32); + crypto_hash_sha512_final(&hs, nonce); + + sc25519_reduce(nonce); + ge25519_scalarmult_base(&kB, nonce); + ge25519_scalarmult(&kH, nonce, &H); + + ge25519_p3_tobytes(proof, &Gamma); + ge25519_p3_tobytes(kB_string, &kB); + ge25519_p3_tobytes(kH_string, &kH); + + crypto_hash_sha512_init(&hs); + crypto_hash_sha512_update(&hs, &SUITE, 1); + crypto_hash_sha512_update(&hs, &TWO, 1); + crypto_hash_sha512_update(&hs, sk + 32, 32); + crypto_hash_sha512_update(&hs, H_string, 32); + crypto_hash_sha512_update(&hs, proof, 32); + crypto_hash_sha512_update(&hs, kB_string, 32); + crypto_hash_sha512_update(&hs, kH_string, 32); + crypto_hash_sha512_update(&hs, &ZERO, 1); + crypto_hash_sha512_final(&hs, challenge); + + memmove(proof + 32, challenge, 16); + memset(challenge + 16, 0, 48); /* we zero out the last 48 bytes of the challenge */ + sc25519_muladd(proof + 48, challenge, az, nonce); + + sodium_memzero(az, sizeof az); + sodium_memzero(nonce, sizeof nonce); + + return 0; +} diff --git a/libs/libsodium/src/crypto_vrf/rfc9381/verify.c b/libs/libsodium/src/crypto_vrf/rfc9381/verify.c new file mode 100644 index 0000000000..40bcbb503b --- /dev/null +++ b/libs/libsodium/src/crypto_vrf/rfc9381/verify.c @@ -0,0 +1,116 @@ +#include +#include +#include + +#include "crypto_hash_sha512.h" +#include "crypto_vrf_rfc9381.h" +#include "private/ed25519_ref10.h" +#include "vrf_rfc9381.h" +#include "crypto_verify_16.h" + +int +crypto_vrf_rfc9381_proof_to_hash(unsigned char *beta, + const unsigned char *pi) +{ + ge25519_p3 Gamma; + unsigned char gamma_string[32]; + + if (ge25519_is_canonical(pi) == 0 || + ge25519_frombytes(&Gamma, pi) != 0) { + return -1; + } + + if (pi[48 + 31] & 240 && + sc25519_is_canonical(pi + 48) == 0) { + return -1; + } + + ge25519_clear_cofactor(&Gamma); + ge25519_p3_tobytes(gamma_string, &Gamma); + + /* beta_string = Hash(suite_string || three_string || point_to_string(cofactor * Gamma) || zero_string ) */ + crypto_hash_sha512_state hs; + crypto_hash_sha512_init(&hs); + crypto_hash_sha512_update(&hs, &SUITE, 1); + crypto_hash_sha512_update(&hs, &THREE, 1); + crypto_hash_sha512_update(&hs, gamma_string, 32); + crypto_hash_sha512_update(&hs, &ZERO, 1); + crypto_hash_sha512_final(&hs, beta); + + return 0; +} + +static int +vrf_verify(const unsigned char *pi, + const unsigned char *alpha, unsigned long long alphalen, + const ge25519_p3 *Y_point) +{ + unsigned char H_string[32], U_string[32], V_string[32], Y_string[32]; + unsigned char cn[32], c[32], s[32]; + unsigned char string_to_hash[32 + alphalen], challenge[64]; + + crypto_hash_sha512_state hs; + ge25519_p2 U, V; + ge25519_p3 H, Gamma; + ge25519_p1p1 tmp_p1p1_point; + ge25519_cached tmp_cached_point; + + ge25519_p3_tobytes(Y_string, Y_point); + + if (ge25519_is_canonical(pi) == 0 || + ge25519_frombytes(&Gamma, pi) != 0) { + return -1; + } + + memmove(c, pi + 32, 16); /* c = pi[32:48] */ + memmove(s, pi + 48, 32); /* s = pi[48:80] */ + + if (s[31] & 240 && + sc25519_is_canonical(s) == 0) { + return -1; + } + + memset(c + 16, 0, 16); + + memmove(string_to_hash, Y_string, 32); + memmove(string_to_hash + 32, alpha, alphalen); + ge25519_from_string(H_string, "ECVRF_edwards25519_XMD:SHA-512_ELL2_NU_\4", string_to_hash, 32 + alphalen, 2); /* elligator2 */ + + ge25519_frombytes(&H, H_string); + sc25519_negate(cn, c); /* negate scalar c */ + + ge25519_double_scalarmult_vartime(&U, cn, Y_point, s, NULL); + + ge25519_double_scalarmult_vartime(&V, cn, &Gamma, s, &H); + + ge25519_tobytes(U_string, &U); + ge25519_tobytes(V_string, &V); + + crypto_hash_sha512_init(&hs); + crypto_hash_sha512_update(&hs, &SUITE, 1); + crypto_hash_sha512_update(&hs, &TWO, 1); + crypto_hash_sha512_update(&hs, Y_string, 32); + crypto_hash_sha512_update(&hs, H_string, 32); + crypto_hash_sha512_update(&hs, pi, 32); + crypto_hash_sha512_update(&hs, U_string, 32); + crypto_hash_sha512_update(&hs, V_string, 32); + crypto_hash_sha512_update(&hs, &ZERO, 1); + crypto_hash_sha512_final(&hs, challenge); + + return crypto_verify_16(c, challenge); +} + +int +crypto_vrf_rfc9381_verify(unsigned char *output, + const unsigned char *pk, + const unsigned char *proof, + const unsigned char *msg, const unsigned long long msglen) +{ + ge25519_p3 Y; + if (ge25519_frombytes(&Y, pk) == 0 && ge25519_has_small_order(&Y) == 0 && + ge25519_is_canonical(pk) == 1 && (vrf_verify(proof, msg, msglen, &Y) == 0)) { + return crypto_vrf_rfc9381_proof_to_hash(output, proof); + } else { + return -1; + } +} diff --git a/libs/libsodium/src/crypto_vrf/rfc9381/vrf.c b/libs/libsodium/src/crypto_vrf/rfc9381/vrf.c new file mode 100644 index 0000000000..f6660b9dd6 --- /dev/null +++ b/libs/libsodium/src/crypto_vrf/rfc9381/vrf.c @@ -0,0 +1,31 @@ +#include "crypto_vrf_rfc9381.h" + +size_t +crypto_vrf_rfc9381_bytes(void) +{ + return crypto_vrf_rfc9381_BYTES; +} + +size_t +crypto_vrf_rfc9381_outputbytes(void) +{ + return crypto_vrf_rfc9381_OUTPUTBYTES; +} + +size_t +crypto_vrf_rfc9381_seedbytes(void) +{ + return crypto_vrf_rfc9381_SEEDBYTES; +} + +size_t +crypto_vrf_rfc9381_publickeybytes(void) +{ + return crypto_vrf_rfc9381_PUBLICKEYBYTES; +} + +size_t +crypto_vrf_rfc9381_secretkeybytes(void) +{ + return crypto_vrf_rfc9381_SECRETKEYBYTES; +} diff --git a/libs/libsodium/src/crypto_vrf/rfc9381/vrf_rfc9381.h b/libs/libsodium/src/crypto_vrf/rfc9381/vrf_rfc9381.h new file mode 100644 index 0000000000..2d263632e5 --- /dev/null +++ b/libs/libsodium/src/crypto_vrf/rfc9381/vrf_rfc9381.h @@ -0,0 +1,10 @@ +#ifndef vrf_rfc9381_H +#define vrf_rfc9381_H + +static const unsigned char SUITE = 0x04; /* ECVRF-ED25519-SHA512-ELL2 */ + +static const unsigned char ZERO = 0x00; +static const unsigned char TWO = 0x02; +static const unsigned char THREE = 0x03; + +#endif diff --git a/libs/libsodium/src/include/Makefile.am b/libs/libsodium/src/include/Makefile.am index 0e1ed2634c..d1ea666cb6 100644 --- a/libs/libsodium/src/include/Makefile.am +++ b/libs/libsodium/src/include/Makefile.am @@ -3,6 +3,8 @@ SODIUM_EXPORT = \ sodium.h \ sodium/core.h \ sodium/crypto_aead_aes256gcm.h \ + sodium/crypto_aead_aegis128l.h \ + sodium/crypto_aead_aegis256.h \ sodium/crypto_aead_chacha20poly1305.h \ sodium/crypto_aead_xchacha20poly1305.h \ sodium/crypto_auth.h \ @@ -13,6 +15,7 @@ SODIUM_EXPORT = \ sodium/crypto_box_curve25519xchacha20poly1305.h \ sodium/crypto_box_curve25519xsalsa20poly1305.h \ sodium/crypto_core_ed25519.h \ + sodium/crypto_core_ristretto255.h \ sodium/crypto_core_hchacha20.h \ sodium/crypto_core_hsalsa20.h \ sodium/crypto_core_salsa20.h \ @@ -25,6 +28,8 @@ SODIUM_EXPORT = \ sodium/crypto_hash_sha512.h \ sodium/crypto_kdf.h \ sodium/crypto_kdf_blake2b.h \ + sodium/crypto_kdf_hkdf_sha256.h \ + sodium/crypto_kdf_hkdf_sha512.h \ sodium/crypto_kx.h \ sodium/crypto_onetimeauth.h \ sodium/crypto_onetimeauth_poly1305.h \ @@ -35,6 +40,7 @@ SODIUM_EXPORT = \ sodium/crypto_scalarmult.h \ sodium/crypto_scalarmult_curve25519.h \ sodium/crypto_scalarmult_ed25519.h \ + sodium/crypto_scalarmult_ristretto255.h \ sodium/crypto_secretbox.h \ sodium/crypto_secretbox_xchacha20poly1305.h \ sodium/crypto_secretbox_xsalsa20poly1305.h \ @@ -43,7 +49,6 @@ SODIUM_EXPORT = \ sodium/crypto_shorthash_siphash24.h \ sodium/crypto_sign.h \ sodium/crypto_sign_ed25519.h \ - sodium/crypto_sign_edwards25519sha512batch.h \ sodium/crypto_stream.h \ sodium/crypto_stream_chacha20.h \ sodium/crypto_stream_salsa20.h \ @@ -54,18 +59,15 @@ SODIUM_EXPORT = \ sodium/crypto_verify_16.h \ sodium/crypto_verify_32.h \ sodium/crypto_verify_64.h \ + sodium/crypto_vrf.h \ + sodium/crypto_vrf_rfc9381.h \ sodium/export.h \ sodium/randombytes.h \ - sodium/randombytes_salsa20_random.h \ + sodium/randombytes_internal_random.h \ sodium/randombytes_sysrandom.h \ sodium/runtime.h \ sodium/utils.h -if NATIVECLIENT -SODIUM_EXPORT += \ - sodium/randombytes_nativeclient.h -endif - EXTRA_SRC = $(SODIUM_EXPORT) \ sodium/version.h.in diff --git a/libs/libsodium/src/include/sodium.h b/libs/libsodium/src/include/sodium.h index 3cd9b5b79a..a47300c36f 100644 --- a/libs/libsodium/src/include/sodium.h +++ b/libs/libsodium/src/include/sodium.h @@ -6,6 +6,8 @@ #include "sodium/core.h" #include "sodium/crypto_aead_aes256gcm.h" +#include "sodium/crypto_aead_aegis128l.h" +#include "sodium/crypto_aead_aegis256.h" #include "sodium/crypto_aead_chacha20poly1305.h" #include "sodium/crypto_aead_xchacha20poly1305.h" #include "sodium/crypto_auth.h" @@ -25,6 +27,8 @@ #include "sodium/crypto_hash_sha256.h" #include "sodium/crypto_hash_sha512.h" #include "sodium/crypto_kdf.h" +#include "sodium/crypto_kdf_hkdf_sha256.h" +#include "sodium/crypto_kdf_hkdf_sha512.h" #include "sodium/crypto_kdf_blake2b.h" #include "sodium/crypto_kx.h" #include "sodium/crypto_onetimeauth.h" @@ -47,11 +51,10 @@ #include "sodium/crypto_verify_16.h" #include "sodium/crypto_verify_32.h" #include "sodium/crypto_verify_64.h" +#include "sodium/crypto_vrf.h" +#include "sodium/crypto_vrf_rfc9381.h" #include "sodium/randombytes.h" -#ifdef __native_client__ -# include "sodium/randombytes_nativeclient.h" -#endif -#include "sodium/randombytes_salsa20_random.h" +#include "sodium/randombytes_internal_random.h" #include "sodium/randombytes_sysrandom.h" #include "sodium/runtime.h" #include "sodium/utils.h" @@ -59,7 +62,9 @@ #ifndef SODIUM_LIBRARY_MINIMAL # include "sodium/crypto_box_curve25519xchacha20poly1305.h" # include "sodium/crypto_core_ed25519.h" +# include "sodium/crypto_core_ristretto255.h" # include "sodium/crypto_scalarmult_ed25519.h" +# include "sodium/crypto_scalarmult_ristretto255.h" # include "sodium/crypto_secretbox_xchacha20poly1305.h" # include "sodium/crypto_pwhash_scryptsalsa208sha256.h" # include "sodium/crypto_stream_salsa2012.h" diff --git a/libs/libsodium/src/include/sodium/crypto_aead_aegis128l.h b/libs/libsodium/src/include/sodium/crypto_aead_aegis128l.h new file mode 100644 index 0000000000..0ad019fc94 --- /dev/null +++ b/libs/libsodium/src/include/sodium/crypto_aead_aegis128l.h @@ -0,0 +1,92 @@ +#ifndef crypto_aead_aegis128l_H +#define crypto_aead_aegis128l_H + +#include + +#include "export.h" + +#ifdef __cplusplus +#ifdef __GNUC__ +#pragma GCC diagnostic ignored "-Wlong-long" +#endif +extern "C" { +#endif + +#define crypto_aead_aegis128l_KEYBYTES 16U +SODIUM_EXPORT +size_t crypto_aead_aegis128l_keybytes(void); + +#define crypto_aead_aegis128l_NSECBYTES 0U +SODIUM_EXPORT +size_t crypto_aead_aegis128l_nsecbytes(void); + +#define crypto_aead_aegis128l_NPUBBYTES 16U +SODIUM_EXPORT +size_t crypto_aead_aegis128l_npubbytes(void); + +#define crypto_aead_aegis128l_ABYTES 32U +SODIUM_EXPORT +size_t crypto_aead_aegis128l_abytes(void); + +#define crypto_aead_aegis128l_MESSAGEBYTES_MAX \ + SODIUM_MIN(SODIUM_SIZE_MAX - crypto_aead_aegis128l_ABYTES, (1ULL << 61) - 1) +SODIUM_EXPORT +size_t crypto_aead_aegis128l_messagebytes_max(void); + +SODIUM_EXPORT +int crypto_aead_aegis128l_encrypt(unsigned char *c, + unsigned long long *clen_p, + const unsigned char *m, + unsigned long long mlen, + const unsigned char *ad, + unsigned long long adlen, + const unsigned char *nsec, + const unsigned char *npub, + const unsigned char *k) __attribute__((nonnull(1, 8, 9))); + +SODIUM_EXPORT +int crypto_aead_aegis128l_decrypt(unsigned char *m, + unsigned long long *mlen_p, + unsigned char *nsec, + const unsigned char *c, + unsigned long long clen, + const unsigned char *ad, + unsigned long long adlen, + const unsigned char *npub, + const unsigned char *k) __attribute__((warn_unused_result)) +__attribute__((nonnull(4, 8, 9))); + +SODIUM_EXPORT +int crypto_aead_aegis128l_encrypt_detached(unsigned char *c, + unsigned char *mac, + unsigned long long *maclen_p, + const unsigned char *m, + unsigned long long mlen, + const unsigned char *ad, + unsigned long long adlen, + const unsigned char *nsec, + const unsigned char *npub, + const unsigned char *k) + __attribute__((nonnull(1, 2, 9, 10))); + +SODIUM_EXPORT +int crypto_aead_aegis128l_decrypt_detached(unsigned char *m, + unsigned char *nsec, + const unsigned char *c, + unsigned long long clen, + const unsigned char *mac, + const unsigned char *ad, + unsigned long long adlen, + const unsigned char *npub, + const unsigned char *k) + __attribute__((warn_unused_result)) __attribute__((nonnull(3, 5, 8, 9))); + +SODIUM_EXPORT +void crypto_aead_aegis128l_keygen(unsigned char k[crypto_aead_aegis128l_KEYBYTES]) + __attribute__((nonnull)); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libs/libsodium/src/include/sodium/crypto_aead_aegis256.h b/libs/libsodium/src/include/sodium/crypto_aead_aegis256.h new file mode 100644 index 0000000000..26bd18ace1 --- /dev/null +++ b/libs/libsodium/src/include/sodium/crypto_aead_aegis256.h @@ -0,0 +1,92 @@ +#ifndef crypto_aead_aegis256_H +#define crypto_aead_aegis256_H + +#include + +#include "export.h" + +#ifdef __cplusplus +#ifdef __GNUC__ +#pragma GCC diagnostic ignored "-Wlong-long" +#endif +extern "C" { +#endif + +#define crypto_aead_aegis256_KEYBYTES 32U +SODIUM_EXPORT +size_t crypto_aead_aegis256_keybytes(void); + +#define crypto_aead_aegis256_NSECBYTES 0U +SODIUM_EXPORT +size_t crypto_aead_aegis256_nsecbytes(void); + +#define crypto_aead_aegis256_NPUBBYTES 32U +SODIUM_EXPORT +size_t crypto_aead_aegis256_npubbytes(void); + +#define crypto_aead_aegis256_ABYTES 32U +SODIUM_EXPORT +size_t crypto_aead_aegis256_abytes(void); + +#define crypto_aead_aegis256_MESSAGEBYTES_MAX \ + SODIUM_MIN(SODIUM_SIZE_MAX - crypto_aead_aegis256_ABYTES, (1ULL << 61) - 1) +SODIUM_EXPORT +size_t crypto_aead_aegis256_messagebytes_max(void); + +SODIUM_EXPORT +int crypto_aead_aegis256_encrypt(unsigned char *c, + unsigned long long *clen_p, + const unsigned char *m, + unsigned long long mlen, + const unsigned char *ad, + unsigned long long adlen, + const unsigned char *nsec, + const unsigned char *npub, + const unsigned char *k) __attribute__((nonnull(1, 8, 9))); + +SODIUM_EXPORT +int crypto_aead_aegis256_decrypt(unsigned char *m, + unsigned long long *mlen_p, + unsigned char *nsec, + const unsigned char *c, + unsigned long long clen, + const unsigned char *ad, + unsigned long long adlen, + const unsigned char *npub, + const unsigned char *k) __attribute__((warn_unused_result)) +__attribute__((nonnull(4, 8, 9))); + +SODIUM_EXPORT +int crypto_aead_aegis256_encrypt_detached(unsigned char *c, + unsigned char *mac, + unsigned long long *maclen_p, + const unsigned char *m, + unsigned long long mlen, + const unsigned char *ad, + unsigned long long adlen, + const unsigned char *nsec, + const unsigned char *npub, + const unsigned char *k) + __attribute__((nonnull(1, 2, 9, 10))); + +SODIUM_EXPORT +int crypto_aead_aegis256_decrypt_detached(unsigned char *m, + unsigned char *nsec, + const unsigned char *c, + unsigned long long clen, + const unsigned char *mac, + const unsigned char *ad, + unsigned long long adlen, + const unsigned char *npub, + const unsigned char *k) + __attribute__((warn_unused_result)) __attribute__((nonnull(3, 5, 8, 9))); + +SODIUM_EXPORT +void crypto_aead_aegis256_keygen(unsigned char k[crypto_aead_aegis256_KEYBYTES]) + __attribute__((nonnull)); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libs/libsodium/src/include/sodium/crypto_aead_aes256gcm.h b/libs/libsodium/src/include/sodium/crypto_aead_aes256gcm.h index 47c32b06df..78b6138240 100644 --- a/libs/libsodium/src/include/sodium/crypto_aead_aes256gcm.h +++ b/libs/libsodium/src/include/sodium/crypto_aead_aes256gcm.h @@ -56,7 +56,7 @@ size_t crypto_aead_aes256gcm_abytes(void); SODIUM_EXPORT size_t crypto_aead_aes256gcm_messagebytes_max(void); -typedef CRYPTO_ALIGN(16) struct crypto_aead_aes256gcm_state_ { +typedef struct CRYPTO_ALIGN(16) crypto_aead_aes256gcm_state_ { unsigned char opaque[512]; } crypto_aead_aes256gcm_state; diff --git a/libs/libsodium/src/include/sodium/crypto_aead_xchacha20poly1305.h b/libs/libsodium/src/include/sodium/crypto_aead_xchacha20poly1305.h index 5e2eb5bb61..e179543517 100644 --- a/libs/libsodium/src/include/sodium/crypto_aead_xchacha20poly1305.h +++ b/libs/libsodium/src/include/sodium/crypto_aead_xchacha20poly1305.h @@ -79,7 +79,7 @@ int crypto_aead_xchacha20poly1305_ietf_decrypt_detached(unsigned char *m, unsigned long long adlen, const unsigned char *npub, const unsigned char *k) - __attribute__ ((warn_unused_result)) __attribute__ ((nonnull(3, 5, 9, 9))); + __attribute__ ((warn_unused_result)) __attribute__ ((nonnull(3, 5, 8, 9))); SODIUM_EXPORT void crypto_aead_xchacha20poly1305_ietf_keygen(unsigned char k[crypto_aead_xchacha20poly1305_ietf_KEYBYTES]) diff --git a/libs/libsodium/src/include/sodium/crypto_auth.h b/libs/libsodium/src/include/sodium/crypto_auth.h index 44e8f7e91a..e98f8a3bf7 100644 --- a/libs/libsodium/src/include/sodium/crypto_auth.h +++ b/libs/libsodium/src/include/sodium/crypto_auth.h @@ -28,12 +28,12 @@ const char *crypto_auth_primitive(void); SODIUM_EXPORT int crypto_auth(unsigned char *out, const unsigned char *in, unsigned long long inlen, const unsigned char *k) - __attribute__ ((nonnull)); + __attribute__ ((nonnull(1, 4))); SODIUM_EXPORT int crypto_auth_verify(const unsigned char *h, const unsigned char *in, unsigned long long inlen, const unsigned char *k) - __attribute__ ((warn_unused_result)) __attribute__ ((nonnull)); + __attribute__ ((warn_unused_result)) __attribute__ ((nonnull(1, 4))); SODIUM_EXPORT void crypto_auth_keygen(unsigned char k[crypto_auth_KEYBYTES]) diff --git a/libs/libsodium/src/include/sodium/crypto_auth_hmacsha256.h b/libs/libsodium/src/include/sodium/crypto_auth_hmacsha256.h index 7c3959cb52..07e63d9a19 100644 --- a/libs/libsodium/src/include/sodium/crypto_auth_hmacsha256.h +++ b/libs/libsodium/src/include/sodium/crypto_auth_hmacsha256.h @@ -24,14 +24,14 @@ SODIUM_EXPORT int crypto_auth_hmacsha256(unsigned char *out, const unsigned char *in, unsigned long long inlen, - const unsigned char *k) __attribute__ ((nonnull)); + const unsigned char *k) __attribute__ ((nonnull(1, 4))); SODIUM_EXPORT int crypto_auth_hmacsha256_verify(const unsigned char *h, const unsigned char *in, unsigned long long inlen, const unsigned char *k) - __attribute__ ((warn_unused_result)) __attribute__ ((nonnull)); + __attribute__ ((warn_unused_result)) __attribute__ ((nonnull(1, 4))); /* ------------------------------------------------------------------------- */ @@ -52,7 +52,7 @@ SODIUM_EXPORT int crypto_auth_hmacsha256_update(crypto_auth_hmacsha256_state *state, const unsigned char *in, unsigned long long inlen) - __attribute__ ((nonnull)); + __attribute__ ((nonnull(1))); SODIUM_EXPORT int crypto_auth_hmacsha256_final(crypto_auth_hmacsha256_state *state, diff --git a/libs/libsodium/src/include/sodium/crypto_auth_hmacsha512.h b/libs/libsodium/src/include/sodium/crypto_auth_hmacsha512.h index fe49556329..c3b3e7176c 100644 --- a/libs/libsodium/src/include/sodium/crypto_auth_hmacsha512.h +++ b/libs/libsodium/src/include/sodium/crypto_auth_hmacsha512.h @@ -24,14 +24,14 @@ SODIUM_EXPORT int crypto_auth_hmacsha512(unsigned char *out, const unsigned char *in, unsigned long long inlen, - const unsigned char *k) __attribute__ ((nonnull)); + const unsigned char *k) __attribute__ ((nonnull(1, 4))); SODIUM_EXPORT int crypto_auth_hmacsha512_verify(const unsigned char *h, const unsigned char *in, unsigned long long inlen, const unsigned char *k) - __attribute__ ((warn_unused_result)) __attribute__ ((nonnull)); + __attribute__ ((warn_unused_result)) __attribute__ ((nonnull(1, 4))); /* ------------------------------------------------------------------------- */ @@ -51,7 +51,7 @@ int crypto_auth_hmacsha512_init(crypto_auth_hmacsha512_state *state, SODIUM_EXPORT int crypto_auth_hmacsha512_update(crypto_auth_hmacsha512_state *state, const unsigned char *in, - unsigned long long inlen) __attribute__ ((nonnull)); + unsigned long long inlen) __attribute__ ((nonnull(1))); SODIUM_EXPORT int crypto_auth_hmacsha512_final(crypto_auth_hmacsha512_state *state, diff --git a/libs/libsodium/src/include/sodium/crypto_auth_hmacsha512256.h b/libs/libsodium/src/include/sodium/crypto_auth_hmacsha512256.h index 8754baa142..a7752f152a 100644 --- a/libs/libsodium/src/include/sodium/crypto_auth_hmacsha512256.h +++ b/libs/libsodium/src/include/sodium/crypto_auth_hmacsha512256.h @@ -21,15 +21,17 @@ SODIUM_EXPORT size_t crypto_auth_hmacsha512256_keybytes(void); SODIUM_EXPORT -int crypto_auth_hmacsha512256(unsigned char *out, const unsigned char *in, - unsigned long long inlen,const unsigned char *k); +int crypto_auth_hmacsha512256(unsigned char *out, + const unsigned char *in, + unsigned long long inlen, + const unsigned char *k) __attribute__ ((nonnull(1, 4))); SODIUM_EXPORT int crypto_auth_hmacsha512256_verify(const unsigned char *h, const unsigned char *in, unsigned long long inlen, const unsigned char *k) - __attribute__ ((warn_unused_result)) __attribute__ ((nonnull)); + __attribute__ ((warn_unused_result)) __attribute__ ((nonnull(1, 4))); /* ------------------------------------------------------------------------- */ @@ -46,7 +48,7 @@ int crypto_auth_hmacsha512256_init(crypto_auth_hmacsha512256_state *state, SODIUM_EXPORT int crypto_auth_hmacsha512256_update(crypto_auth_hmacsha512256_state *state, const unsigned char *in, - unsigned long long inlen) __attribute__ ((nonnull)); + unsigned long long inlen) __attribute__ ((nonnull(1))); SODIUM_EXPORT int crypto_auth_hmacsha512256_final(crypto_auth_hmacsha512256_state *state, diff --git a/libs/libsodium/src/include/sodium/crypto_box.h b/libs/libsodium/src/include/sodium/crypto_box.h index 33787e9d8d..8f7835f184 100644 --- a/libs/libsodium/src/include/sodium/crypto_box.h +++ b/libs/libsodium/src/include/sodium/crypto_box.h @@ -61,7 +61,7 @@ SODIUM_EXPORT int crypto_box_easy(unsigned char *c, const unsigned char *m, unsigned long long mlen, const unsigned char *n, const unsigned char *pk, const unsigned char *sk) - __attribute__ ((warn_unused_result)) __attribute__ ((nonnull)); + __attribute__ ((warn_unused_result)) __attribute__ ((nonnull(1, 4, 5, 6))); SODIUM_EXPORT int crypto_box_open_easy(unsigned char *m, const unsigned char *c, @@ -74,7 +74,7 @@ int crypto_box_detached(unsigned char *c, unsigned char *mac, const unsigned char *m, unsigned long long mlen, const unsigned char *n, const unsigned char *pk, const unsigned char *sk) - __attribute__ ((warn_unused_result)) __attribute__ ((nonnull)); + __attribute__ ((warn_unused_result)) __attribute__ ((nonnull(1, 2, 5, 6, 7))); SODIUM_EXPORT int crypto_box_open_detached(unsigned char *m, const unsigned char *c, @@ -99,7 +99,7 @@ int crypto_box_beforenm(unsigned char *k, const unsigned char *pk, SODIUM_EXPORT int crypto_box_easy_afternm(unsigned char *c, const unsigned char *m, unsigned long long mlen, const unsigned char *n, - const unsigned char *k) __attribute__ ((nonnull)); + const unsigned char *k) __attribute__ ((nonnull(1, 4, 5))); SODIUM_EXPORT int crypto_box_open_easy_afternm(unsigned char *m, const unsigned char *c, @@ -111,7 +111,7 @@ SODIUM_EXPORT int crypto_box_detached_afternm(unsigned char *c, unsigned char *mac, const unsigned char *m, unsigned long long mlen, const unsigned char *n, const unsigned char *k) - __attribute__ ((nonnull)); + __attribute__ ((nonnull(1, 2, 5, 6))); SODIUM_EXPORT int crypto_box_open_detached_afternm(unsigned char *m, const unsigned char *c, @@ -129,7 +129,7 @@ size_t crypto_box_sealbytes(void); SODIUM_EXPORT int crypto_box_seal(unsigned char *c, const unsigned char *m, unsigned long long mlen, const unsigned char *pk) - __attribute__ ((nonnull)); + __attribute__ ((nonnull(1, 4))); SODIUM_EXPORT int crypto_box_seal_open(unsigned char *m, const unsigned char *c, @@ -141,34 +141,34 @@ int crypto_box_seal_open(unsigned char *m, const unsigned char *c, #define crypto_box_ZEROBYTES crypto_box_curve25519xsalsa20poly1305_ZEROBYTES SODIUM_EXPORT -size_t crypto_box_zerobytes(void); +size_t crypto_box_zerobytes(void) __attribute__ ((deprecated)); #define crypto_box_BOXZEROBYTES crypto_box_curve25519xsalsa20poly1305_BOXZEROBYTES SODIUM_EXPORT -size_t crypto_box_boxzerobytes(void); +size_t crypto_box_boxzerobytes(void) __attribute__ ((deprecated)); SODIUM_EXPORT int crypto_box(unsigned char *c, const unsigned char *m, unsigned long long mlen, const unsigned char *n, const unsigned char *pk, const unsigned char *sk) - __attribute__ ((warn_unused_result)) __attribute__ ((nonnull)); + __attribute__ ((deprecated)) __attribute__ ((warn_unused_result)) __attribute__ ((nonnull(1, 4, 5, 6))); SODIUM_EXPORT int crypto_box_open(unsigned char *m, const unsigned char *c, unsigned long long clen, const unsigned char *n, const unsigned char *pk, const unsigned char *sk) - __attribute__ ((warn_unused_result)) __attribute__ ((nonnull(2, 4, 5, 6))); + __attribute__ ((deprecated)) __attribute__ ((warn_unused_result)) __attribute__ ((nonnull(2, 4, 5, 6))); SODIUM_EXPORT int crypto_box_afternm(unsigned char *c, const unsigned char *m, unsigned long long mlen, const unsigned char *n, - const unsigned char *k) __attribute__ ((nonnull)); + const unsigned char *k) __attribute__ ((deprecated)) __attribute__ ((nonnull(1, 4, 5))); SODIUM_EXPORT int crypto_box_open_afternm(unsigned char *m, const unsigned char *c, unsigned long long clen, const unsigned char *n, const unsigned char *k) - __attribute__ ((warn_unused_result)) __attribute__ ((nonnull(2, 4, 5))); + __attribute__ ((warn_unused_result)) __attribute__ ((deprecated)) __attribute__ ((nonnull(2, 4, 5))); #ifdef __cplusplus } diff --git a/libs/libsodium/src/include/sodium/crypto_box_curve25519xchacha20poly1305.h b/libs/libsodium/src/include/sodium/crypto_box_curve25519xchacha20poly1305.h index 2616e9b2b8..50288b35f3 100644 --- a/libs/libsodium/src/include/sodium/crypto_box_curve25519xchacha20poly1305.h +++ b/libs/libsodium/src/include/sodium/crypto_box_curve25519xchacha20poly1305.h @@ -60,7 +60,7 @@ int crypto_box_curve25519xchacha20poly1305_easy(unsigned char *c, const unsigned char *n, const unsigned char *pk, const unsigned char *sk) - __attribute__ ((warn_unused_result)) __attribute__ ((nonnull)); + __attribute__ ((warn_unused_result)) __attribute__ ((nonnull(1, 4, 5, 6))); SODIUM_EXPORT int crypto_box_curve25519xchacha20poly1305_open_easy(unsigned char *m, @@ -79,7 +79,7 @@ int crypto_box_curve25519xchacha20poly1305_detached(unsigned char *c, const unsigned char *n, const unsigned char *pk, const unsigned char *sk) - __attribute__ ((warn_unused_result)) __attribute__ ((nonnull)); + __attribute__ ((warn_unused_result)) __attribute__ ((nonnull(1, 2, 5, 6, 7))); SODIUM_EXPORT int crypto_box_curve25519xchacha20poly1305_open_detached(unsigned char *m, @@ -105,7 +105,7 @@ int crypto_box_curve25519xchacha20poly1305_easy_afternm(unsigned char *c, unsigned long long mlen, const unsigned char *n, const unsigned char *k) - __attribute__ ((nonnull)); + __attribute__ ((nonnull(1, 4, 5))); SODIUM_EXPORT int crypto_box_curve25519xchacha20poly1305_open_easy_afternm(unsigned char *m, @@ -122,7 +122,7 @@ int crypto_box_curve25519xchacha20poly1305_detached_afternm(unsigned char *c, unsigned long long mlen, const unsigned char *n, const unsigned char *k) - __attribute__ ((nonnull)); + __attribute__ ((nonnull(1, 2, 5, 6))); SODIUM_EXPORT int crypto_box_curve25519xchacha20poly1305_open_detached_afternm(unsigned char *m, @@ -147,7 +147,7 @@ int crypto_box_curve25519xchacha20poly1305_seal(unsigned char *c, const unsigned char *m, unsigned long long mlen, const unsigned char *pk) - __attribute__ ((nonnull)); + __attribute__ ((nonnull(1, 4))); SODIUM_EXPORT int crypto_box_curve25519xchacha20poly1305_seal_open(unsigned char *m, diff --git a/libs/libsodium/src/include/sodium/crypto_box_curve25519xsalsa20poly1305.h b/libs/libsodium/src/include/sodium/crypto_box_curve25519xsalsa20poly1305.h index ffaead2bff..a5d8a3947e 100644 --- a/libs/libsodium/src/include/sodium/crypto_box_curve25519xsalsa20poly1305.h +++ b/libs/libsodium/src/include/sodium/crypto_box_curve25519xsalsa20poly1305.h @@ -69,7 +69,8 @@ size_t crypto_box_curve25519xsalsa20poly1305_boxzerobytes(void); (crypto_box_curve25519xsalsa20poly1305_BOXZEROBYTES + \ crypto_box_curve25519xsalsa20poly1305_MACBYTES) SODIUM_EXPORT -size_t crypto_box_curve25519xsalsa20poly1305_zerobytes(void); +size_t crypto_box_curve25519xsalsa20poly1305_zerobytes(void) + __attribute__ ((deprecated)); SODIUM_EXPORT int crypto_box_curve25519xsalsa20poly1305(unsigned char *c, @@ -78,7 +79,7 @@ int crypto_box_curve25519xsalsa20poly1305(unsigned char *c, const unsigned char *n, const unsigned char *pk, const unsigned char *sk) - __attribute__ ((warn_unused_result)) __attribute__ ((nonnull)); + __attribute__ ((deprecated)) __attribute__ ((warn_unused_result)) __attribute__ ((nonnull(1, 4, 5, 6))); SODIUM_EXPORT int crypto_box_curve25519xsalsa20poly1305_open(unsigned char *m, @@ -87,7 +88,7 @@ int crypto_box_curve25519xsalsa20poly1305_open(unsigned char *m, const unsigned char *n, const unsigned char *pk, const unsigned char *sk) - __attribute__ ((warn_unused_result)) __attribute__ ((nonnull(2, 4, 5, 6))); + __attribute__ ((deprecated)) __attribute__ ((warn_unused_result)) __attribute__ ((nonnull(2, 4, 5, 6))); SODIUM_EXPORT int crypto_box_curve25519xsalsa20poly1305_afternm(unsigned char *c, @@ -95,7 +96,7 @@ int crypto_box_curve25519xsalsa20poly1305_afternm(unsigned char *c, unsigned long long mlen, const unsigned char *n, const unsigned char *k) - __attribute__ ((nonnull)); + __attribute__ ((deprecated)) __attribute__ ((nonnull(1, 4, 5))); SODIUM_EXPORT int crypto_box_curve25519xsalsa20poly1305_open_afternm(unsigned char *m, @@ -103,7 +104,7 @@ int crypto_box_curve25519xsalsa20poly1305_open_afternm(unsigned char *m, unsigned long long clen, const unsigned char *n, const unsigned char *k) - __attribute__ ((warn_unused_result)) __attribute__ ((nonnull(2, 4, 5))); + __attribute__ ((deprecated)) __attribute__ ((warn_unused_result)) __attribute__ ((nonnull(2, 4, 5))); #ifdef __cplusplus } diff --git a/libs/libsodium/src/include/sodium/crypto_core_ed25519.h b/libs/libsodium/src/include/sodium/crypto_core_ed25519.h index 003ac3565b..dd9a0439ad 100644 --- a/libs/libsodium/src/include/sodium/crypto_core_ed25519.h +++ b/libs/libsodium/src/include/sodium/crypto_core_ed25519.h @@ -16,6 +16,10 @@ size_t crypto_core_ed25519_bytes(void); SODIUM_EXPORT size_t crypto_core_ed25519_uniformbytes(void); +#define crypto_core_ed25519_HASHBYTES 64 +SODIUM_EXPORT +size_t crypto_core_ed25519_hashbytes(void); + #define crypto_core_ed25519_SCALARBYTES 32 SODIUM_EXPORT size_t crypto_core_ed25519_scalarbytes(void); @@ -24,6 +28,9 @@ size_t crypto_core_ed25519_scalarbytes(void); SODIUM_EXPORT size_t crypto_core_ed25519_nonreducedscalarbytes(void); +#define crypto_core_ed25519_H2CSHA256 1 +#define crypto_core_ed25519_H2CSHA512 2 + SODIUM_EXPORT int crypto_core_ed25519_is_valid_point(const unsigned char *p) __attribute__ ((nonnull)); @@ -42,6 +49,22 @@ SODIUM_EXPORT int crypto_core_ed25519_from_uniform(unsigned char *p, const unsigned char *r) __attribute__ ((nonnull)); +SODIUM_EXPORT +int crypto_core_ed25519_from_string(unsigned char p[crypto_core_ed25519_BYTES], + const char *ctx, const unsigned char *msg, + size_t msg_len, int hash_alg) + __attribute__ ((nonnull(1))); + +SODIUM_EXPORT +int crypto_core_ed25519_from_string_ro(unsigned char p[crypto_core_ed25519_BYTES], + const char *ctx, const unsigned char *msg, + size_t msg_len, int hash_alg) + __attribute__ ((nonnull(1))); + +SODIUM_EXPORT +void crypto_core_ed25519_random(unsigned char *p) + __attribute__ ((nonnull)); + SODIUM_EXPORT void crypto_core_ed25519_scalar_random(unsigned char *r) __attribute__ ((nonnull)); @@ -68,6 +91,11 @@ void crypto_core_ed25519_scalar_sub(unsigned char *z, const unsigned char *x, const unsigned char *y) __attribute__ ((nonnull)); +SODIUM_EXPORT +void crypto_core_ed25519_scalar_mul(unsigned char *z, const unsigned char *x, + const unsigned char *y) + __attribute__ ((nonnull)); + /* * The interval `s` is sampled from should be at least 317 bits to ensure almost * uniformity of `r` over `L`. @@ -76,6 +104,10 @@ SODIUM_EXPORT void crypto_core_ed25519_scalar_reduce(unsigned char *r, const unsigned char *s) __attribute__ ((nonnull)); +SODIUM_EXPORT +int crypto_core_ed25519_scalar_is_canonical(const unsigned char *s) + __attribute__ ((nonnull)); + #ifdef __cplusplus } #endif diff --git a/libs/libsodium/src/include/sodium/crypto_core_ristretto255.h b/libs/libsodium/src/include/sodium/crypto_core_ristretto255.h new file mode 100644 index 0000000000..5fc3a1be6e --- /dev/null +++ b/libs/libsodium/src/include/sodium/crypto_core_ristretto255.h @@ -0,0 +1,121 @@ +#ifndef crypto_core_ristretto255_H +#define crypto_core_ristretto255_H + +#include +#include "export.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define crypto_core_ristretto255_BYTES 32 +SODIUM_EXPORT +size_t crypto_core_ristretto255_bytes(void); + +#define crypto_core_ristretto255_HASHBYTES 64 +SODIUM_EXPORT +size_t crypto_core_ristretto255_hashbytes(void); + +#define crypto_core_ristretto255_SCALARBYTES 32 +SODIUM_EXPORT +size_t crypto_core_ristretto255_scalarbytes(void); + +#define crypto_core_ristretto255_NONREDUCEDSCALARBYTES 64 +SODIUM_EXPORT +size_t crypto_core_ristretto255_nonreducedscalarbytes(void); + +#define crypto_core_ristretto255_H2CSHA256 1 +#define crypto_core_ristretto255_H2CSHA512 2 + +SODIUM_EXPORT +int crypto_core_ristretto255_is_valid_point(const unsigned char *p) + __attribute__ ((nonnull)); + +SODIUM_EXPORT +int crypto_core_ristretto255_add(unsigned char *r, + const unsigned char *p, const unsigned char *q) + __attribute__ ((nonnull)); + +SODIUM_EXPORT +int crypto_core_ristretto255_sub(unsigned char *r, + const unsigned char *p, const unsigned char *q) + __attribute__ ((nonnull)); + +SODIUM_EXPORT +int crypto_core_ristretto255_from_hash(unsigned char *p, + const unsigned char *r) + __attribute__ ((nonnull)); + +SODIUM_EXPORT +int crypto_core_ristretto255_from_string(unsigned char p[crypto_core_ristretto255_BYTES], + const char *ctx, + const unsigned char *msg, + size_t msg_len, int hash_alg) + __attribute__ ((nonnull(1))); + +SODIUM_EXPORT +int crypto_core_ristretto255_from_string_ro(unsigned char p[crypto_core_ristretto255_BYTES], + const char *ctx, + const unsigned char *msg, + size_t msg_len, int hash_alg) + __attribute__ ((nonnull(1))); + +SODIUM_EXPORT +void crypto_core_ristretto255_random(unsigned char *p) + __attribute__ ((nonnull)); + +SODIUM_EXPORT +void crypto_core_ristretto255_scalar_random(unsigned char *r) + __attribute__ ((nonnull)); + +SODIUM_EXPORT +int crypto_core_ristretto255_scalar_invert(unsigned char *recip, + const unsigned char *s) + __attribute__ ((nonnull)); + +SODIUM_EXPORT +void crypto_core_ristretto255_scalar_negate(unsigned char *neg, + const unsigned char *s) + __attribute__ ((nonnull)); + +SODIUM_EXPORT +void crypto_core_ristretto255_scalar_complement(unsigned char *comp, + const unsigned char *s) + __attribute__ ((nonnull)); + +SODIUM_EXPORT +void crypto_core_ristretto255_scalar_add(unsigned char *z, + const unsigned char *x, + const unsigned char *y) + __attribute__ ((nonnull)); + +SODIUM_EXPORT +void crypto_core_ristretto255_scalar_sub(unsigned char *z, + const unsigned char *x, + const unsigned char *y) + __attribute__ ((nonnull)); + +SODIUM_EXPORT +void crypto_core_ristretto255_scalar_mul(unsigned char *z, + const unsigned char *x, + const unsigned char *y) + __attribute__ ((nonnull)); + +/* + * The interval `s` is sampled from should be at least 317 bits to ensure almost + * uniformity of `r` over `L`. + */ +SODIUM_EXPORT +void crypto_core_ristretto255_scalar_reduce(unsigned char *r, + const unsigned char *s) + __attribute__ ((nonnull)); + +SODIUM_EXPORT +int crypto_core_ristretto255_scalar_is_canonical(const unsigned char *s) + __attribute__ ((nonnull)); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libs/libsodium/src/include/sodium/crypto_generichash.h b/libs/libsodium/src/include/sodium/crypto_generichash.h index c1cc435fd7..a240d5f9ff 100644 --- a/libs/libsodium/src/include/sodium/crypto_generichash.h +++ b/libs/libsodium/src/include/sodium/crypto_generichash.h @@ -66,7 +66,7 @@ SODIUM_EXPORT int crypto_generichash_update(crypto_generichash_state *state, const unsigned char *in, unsigned long long inlen) - __attribute__ ((nonnull)); + __attribute__ ((nonnull(1))); SODIUM_EXPORT int crypto_generichash_final(crypto_generichash_state *state, diff --git a/libs/libsodium/src/include/sodium/crypto_generichash_blake2b.h b/libs/libsodium/src/include/sodium/crypto_generichash_blake2b.h index 3e4b8a1059..d3064ab409 100644 --- a/libs/libsodium/src/include/sodium/crypto_generichash_blake2b.h +++ b/libs/libsodium/src/include/sodium/crypto_generichash_blake2b.h @@ -14,7 +14,9 @@ extern "C" { #endif -#if defined(__IBMC__) || defined(__SUNPRO_C) || defined(__SUNPRO_CC) +#ifdef __IBMC__ +# pragma pack(1) +#elif defined(__SUNPRO_C) || defined(__SUNPRO_CC) # pragma pack(1) #else # pragma pack(push, 1) @@ -24,7 +26,9 @@ typedef struct CRYPTO_ALIGN(64) crypto_generichash_blake2b_state { unsigned char opaque[384]; } crypto_generichash_blake2b_state; -#if defined(__IBMC__) || defined(__SUNPRO_C) || defined(__SUNPRO_CC) +#ifdef __IBMC__ +# pragma pack(pop) +#elif defined(__SUNPRO_C) || defined(__SUNPRO_CC) # pragma pack() #else # pragma pack(pop) @@ -100,7 +104,7 @@ SODIUM_EXPORT int crypto_generichash_blake2b_update(crypto_generichash_blake2b_state *state, const unsigned char *in, unsigned long long inlen) - __attribute__ ((nonnull)); + __attribute__ ((nonnull(1))); SODIUM_EXPORT int crypto_generichash_blake2b_final(crypto_generichash_blake2b_state *state, diff --git a/libs/libsodium/src/include/sodium/crypto_hash.h b/libs/libsodium/src/include/sodium/crypto_hash.h index c5e338e3ba..57db1f5381 100644 --- a/libs/libsodium/src/include/sodium/crypto_hash.h +++ b/libs/libsodium/src/include/sodium/crypto_hash.h @@ -2,7 +2,7 @@ #define crypto_hash_H /* - * WARNING: Unless you absolutely need to use SHA512 for interoperatibility, + * WARNING: Unless you absolutely need to use SHA512 for interoperability, * purposes, you might want to consider crypto_generichash() instead. * Unlike SHA512, crypto_generichash() is not vulnerable to length * extension attacks. @@ -26,7 +26,7 @@ size_t crypto_hash_bytes(void); SODIUM_EXPORT int crypto_hash(unsigned char *out, const unsigned char *in, - unsigned long long inlen) __attribute__ ((nonnull)); + unsigned long long inlen) __attribute__ ((nonnull(1))); #define crypto_hash_PRIMITIVE "sha512" SODIUM_EXPORT diff --git a/libs/libsodium/src/include/sodium/crypto_hash_sha256.h b/libs/libsodium/src/include/sodium/crypto_hash_sha256.h index a53c2f104d..d3be86a8e1 100644 --- a/libs/libsodium/src/include/sodium/crypto_hash_sha256.h +++ b/libs/libsodium/src/include/sodium/crypto_hash_sha256.h @@ -2,7 +2,7 @@ #define crypto_hash_sha256_H /* - * WARNING: Unless you absolutely need to use SHA256 for interoperatibility, + * WARNING: Unless you absolutely need to use SHA256 for interoperability, * purposes, you might want to consider crypto_generichash() instead. * Unlike SHA256, crypto_generichash() is not vulnerable to length * extension attacks. @@ -36,7 +36,7 @@ size_t crypto_hash_sha256_bytes(void); SODIUM_EXPORT int crypto_hash_sha256(unsigned char *out, const unsigned char *in, - unsigned long long inlen) __attribute__ ((nonnull)); + unsigned long long inlen) __attribute__ ((nonnull(1))); SODIUM_EXPORT int crypto_hash_sha256_init(crypto_hash_sha256_state *state) @@ -46,7 +46,7 @@ SODIUM_EXPORT int crypto_hash_sha256_update(crypto_hash_sha256_state *state, const unsigned char *in, unsigned long long inlen) - __attribute__ ((nonnull)); + __attribute__ ((nonnull(1))); SODIUM_EXPORT int crypto_hash_sha256_final(crypto_hash_sha256_state *state, diff --git a/libs/libsodium/src/include/sodium/crypto_hash_sha512.h b/libs/libsodium/src/include/sodium/crypto_hash_sha512.h index 02aea29641..2c5cfd5a8c 100644 --- a/libs/libsodium/src/include/sodium/crypto_hash_sha512.h +++ b/libs/libsodium/src/include/sodium/crypto_hash_sha512.h @@ -2,7 +2,7 @@ #define crypto_hash_sha512_H /* - * WARNING: Unless you absolutely need to use SHA512 for interoperatibility, + * WARNING: Unless you absolutely need to use SHA512 for interoperability, * purposes, you might want to consider crypto_generichash() instead. * Unlike SHA512, crypto_generichash() is not vulnerable to length * extension attacks. @@ -36,7 +36,7 @@ size_t crypto_hash_sha512_bytes(void); SODIUM_EXPORT int crypto_hash_sha512(unsigned char *out, const unsigned char *in, - unsigned long long inlen) __attribute__ ((nonnull)); + unsigned long long inlen) __attribute__ ((nonnull(1))); SODIUM_EXPORT int crypto_hash_sha512_init(crypto_hash_sha512_state *state) @@ -46,7 +46,7 @@ SODIUM_EXPORT int crypto_hash_sha512_update(crypto_hash_sha512_state *state, const unsigned char *in, unsigned long long inlen) - __attribute__ ((nonnull)); + __attribute__ ((nonnull(1))); SODIUM_EXPORT int crypto_hash_sha512_final(crypto_hash_sha512_state *state, diff --git a/libs/libsodium/src/include/sodium/crypto_kdf_blake2b.h b/libs/libsodium/src/include/sodium/crypto_kdf_blake2b.h index add4a1921c..be917017f6 100644 --- a/libs/libsodium/src/include/sodium/crypto_kdf_blake2b.h +++ b/libs/libsodium/src/include/sodium/crypto_kdf_blake2b.h @@ -3,8 +3,8 @@ #include #include +#include -#include "crypto_kdf_blake2b.h" #include "export.h" #ifdef __cplusplus diff --git a/libs/libsodium/src/include/sodium/crypto_kdf_hkdf_sha256.h b/libs/libsodium/src/include/sodium/crypto_kdf_hkdf_sha256.h new file mode 100644 index 0000000000..e7e7f4db6d --- /dev/null +++ b/libs/libsodium/src/include/sodium/crypto_kdf_hkdf_sha256.h @@ -0,0 +1,74 @@ +#ifndef crypto_kdf_hkdf_sha256_H +#define crypto_kdf_hkdf_sha256_H + +#include +#include +#include + +#include "crypto_kdf.h" +#include "crypto_auth_hmacsha256.h" +#include "export.h" + +#ifdef __cplusplus +# ifdef __GNUC__ +# pragma GCC diagnostic ignored "-Wlong-long" +# endif +extern "C" { +#endif + +#define crypto_kdf_hkdf_sha256_KEYBYTES crypto_auth_hmacsha256_BYTES +SODIUM_EXPORT +size_t crypto_kdf_hkdf_sha256_keybytes(void); + +#define crypto_kdf_hkdf_sha256_BYTES_MIN 0U +SODIUM_EXPORT +size_t crypto_kdf_hkdf_sha256_bytes_min(void); + +#define crypto_kdf_hkdf_sha256_BYTES_MAX (0xff * crypto_auth_hmacsha256_BYTES) +SODIUM_EXPORT +size_t crypto_kdf_hkdf_sha256_bytes_max(void); + +SODIUM_EXPORT +int crypto_kdf_hkdf_sha256_extract(unsigned char prk[crypto_kdf_hkdf_sha256_KEYBYTES], + const unsigned char *salt, size_t salt_len, + const unsigned char *ikm, size_t ikm_len) + __attribute__ ((nonnull(4))); + +SODIUM_EXPORT +void crypto_kdf_hkdf_sha256_keygen(unsigned char prk[crypto_kdf_hkdf_sha256_KEYBYTES]); + +SODIUM_EXPORT +int crypto_kdf_hkdf_sha256_expand(unsigned char *out, size_t out_len, + const char *ctx, size_t ctx_len, + const unsigned char prk[crypto_kdf_hkdf_sha256_KEYBYTES]) + __attribute__ ((nonnull(1))); + +/* ------------------------------------------------------------------------- */ + +typedef struct crypto_kdf_hkdf_sha256_state { + crypto_auth_hmacsha256_state st; +} crypto_kdf_hkdf_sha256_state; + +SODIUM_EXPORT +size_t crypto_kdf_hkdf_sha256_statebytes(void); + +SODIUM_EXPORT +int crypto_kdf_hkdf_sha256_extract_init(crypto_kdf_hkdf_sha256_state *state, + const unsigned char *salt, size_t salt_len) + __attribute__ ((nonnull(1))); + +SODIUM_EXPORT +int crypto_kdf_hkdf_sha256_extract_update(crypto_kdf_hkdf_sha256_state *state, + const unsigned char *ikm, size_t ikm_len) + __attribute__ ((nonnull)); + +SODIUM_EXPORT +int crypto_kdf_hkdf_sha256_extract_final(crypto_kdf_hkdf_sha256_state *state, + unsigned char prk[crypto_kdf_hkdf_sha256_KEYBYTES]) + __attribute__ ((nonnull)); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libs/libsodium/src/include/sodium/crypto_kdf_hkdf_sha512.h b/libs/libsodium/src/include/sodium/crypto_kdf_hkdf_sha512.h new file mode 100644 index 0000000000..0ed205dfb8 --- /dev/null +++ b/libs/libsodium/src/include/sodium/crypto_kdf_hkdf_sha512.h @@ -0,0 +1,75 @@ +#ifndef crypto_kdf_hkdf_sha512_H +#define crypto_kdf_hkdf_sha512_H + +#include +#include +#include + +#include "crypto_kdf.h" +#include "crypto_auth_hmacsha512.h" +#include "export.h" + +#ifdef __cplusplus +# ifdef __GNUC__ +# pragma GCC diagnostic ignored "-Wlong-long" +# endif +extern "C" { +#endif + +#define crypto_kdf_hkdf_sha512_KEYBYTES crypto_auth_hmacsha512_BYTES +SODIUM_EXPORT +size_t crypto_kdf_hkdf_sha512_keybytes(void); + +#define crypto_kdf_hkdf_sha512_BYTES_MIN 0U +SODIUM_EXPORT +size_t crypto_kdf_hkdf_sha512_bytes_min(void); + +#define crypto_kdf_hkdf_sha512_BYTES_MAX (0xff * crypto_auth_hmacsha512_BYTES) +SODIUM_EXPORT +size_t crypto_kdf_hkdf_sha512_bytes_max(void); + +SODIUM_EXPORT +int crypto_kdf_hkdf_sha512_extract(unsigned char prk[crypto_kdf_hkdf_sha512_KEYBYTES], + const unsigned char *salt, size_t salt_len, + const unsigned char *ikm, size_t ikm_len) + __attribute__ ((nonnull(1))); + +SODIUM_EXPORT +void crypto_kdf_hkdf_sha512_keygen(unsigned char prk[crypto_kdf_hkdf_sha512_KEYBYTES]) + __attribute__ ((nonnull)); + +SODIUM_EXPORT +int crypto_kdf_hkdf_sha512_expand(unsigned char *out, size_t out_len, + const char *ctx, size_t ctx_len, + const unsigned char prk[crypto_kdf_hkdf_sha512_KEYBYTES]) + __attribute__ ((nonnull(1))); + +/* ------------------------------------------------------------------------- */ + +typedef struct crypto_kdf_hkdf_sha512_state { + crypto_auth_hmacsha512_state st; +} crypto_kdf_hkdf_sha512_state; + +SODIUM_EXPORT +size_t crypto_kdf_hkdf_sha512_statebytes(void); + +SODIUM_EXPORT +int crypto_kdf_hkdf_sha512_extract_init(crypto_kdf_hkdf_sha512_state *state, + const unsigned char *salt, size_t salt_len) + __attribute__ ((nonnull(1))); + +SODIUM_EXPORT +int crypto_kdf_hkdf_sha512_extract_update(crypto_kdf_hkdf_sha512_state *state, + const unsigned char *ikm, size_t ikm_len) + __attribute__ ((nonnull)); + +SODIUM_EXPORT +int crypto_kdf_hkdf_sha512_extract_final(crypto_kdf_hkdf_sha512_state *state, + unsigned char prk[crypto_kdf_hkdf_sha512_KEYBYTES]) + __attribute__ ((nonnull)); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libs/libsodium/src/include/sodium/crypto_onetimeauth.h b/libs/libsodium/src/include/sodium/crypto_onetimeauth.h index ab856b9cbe..4aee8b4b5d 100644 --- a/libs/libsodium/src/include/sodium/crypto_onetimeauth.h +++ b/libs/libsodium/src/include/sodium/crypto_onetimeauth.h @@ -33,12 +33,12 @@ const char *crypto_onetimeauth_primitive(void); SODIUM_EXPORT int crypto_onetimeauth(unsigned char *out, const unsigned char *in, unsigned long long inlen, const unsigned char *k) - __attribute__ ((nonnull)); + __attribute__ ((nonnull(1, 4))); SODIUM_EXPORT int crypto_onetimeauth_verify(const unsigned char *h, const unsigned char *in, unsigned long long inlen, const unsigned char *k) - __attribute__ ((warn_unused_result)) __attribute__ ((nonnull)); + __attribute__ ((warn_unused_result)) __attribute__ ((nonnull(1, 4))); SODIUM_EXPORT int crypto_onetimeauth_init(crypto_onetimeauth_state *state, @@ -48,7 +48,7 @@ SODIUM_EXPORT int crypto_onetimeauth_update(crypto_onetimeauth_state *state, const unsigned char *in, unsigned long long inlen) - __attribute__ ((nonnull)); + __attribute__ ((nonnull(1))); SODIUM_EXPORT int crypto_onetimeauth_final(crypto_onetimeauth_state *state, diff --git a/libs/libsodium/src/include/sodium/crypto_onetimeauth_poly1305.h b/libs/libsodium/src/include/sodium/crypto_onetimeauth_poly1305.h index 510f20561b..67f6dee122 100644 --- a/libs/libsodium/src/include/sodium/crypto_onetimeauth_poly1305.h +++ b/libs/libsodium/src/include/sodium/crypto_onetimeauth_poly1305.h @@ -1,13 +1,6 @@ #ifndef crypto_onetimeauth_poly1305_H #define crypto_onetimeauth_poly1305_H -#ifdef __cplusplus -# ifdef __GNUC__ -# pragma GCC diagnostic ignored "-Wlong-long" -# endif -extern "C" { -#endif - #include #include #include @@ -16,6 +9,13 @@ extern "C" { #include "export.h" +#ifdef __cplusplus +# ifdef __GNUC__ +# pragma GCC diagnostic ignored "-Wlong-long" +# endif +extern "C" { +#endif + typedef struct CRYPTO_ALIGN(16) crypto_onetimeauth_poly1305_state { unsigned char opaque[256]; } crypto_onetimeauth_poly1305_state; @@ -36,14 +36,14 @@ int crypto_onetimeauth_poly1305(unsigned char *out, const unsigned char *in, unsigned long long inlen, const unsigned char *k) - __attribute__ ((nonnull)); + __attribute__ ((nonnull(1, 4))); SODIUM_EXPORT int crypto_onetimeauth_poly1305_verify(const unsigned char *h, const unsigned char *in, unsigned long long inlen, const unsigned char *k) - __attribute__ ((warn_unused_result)) __attribute__ ((nonnull)); + __attribute__ ((warn_unused_result)) __attribute__ ((nonnull(1, 4))); SODIUM_EXPORT int crypto_onetimeauth_poly1305_init(crypto_onetimeauth_poly1305_state *state, @@ -54,7 +54,7 @@ SODIUM_EXPORT int crypto_onetimeauth_poly1305_update(crypto_onetimeauth_poly1305_state *state, const unsigned char *in, unsigned long long inlen) - __attribute__ ((nonnull)); + __attribute__ ((nonnull(1))); SODIUM_EXPORT int crypto_onetimeauth_poly1305_final(crypto_onetimeauth_poly1305_state *state, diff --git a/libs/libsodium/src/include/sodium/crypto_pwhash.h b/libs/libsodium/src/include/sodium/crypto_pwhash.h index e398522b82..60efc9f570 100644 --- a/libs/libsodium/src/include/sodium/crypto_pwhash.h +++ b/libs/libsodium/src/include/sodium/crypto_pwhash.h @@ -56,11 +56,11 @@ const char *crypto_pwhash_strprefix(void); #define crypto_pwhash_OPSLIMIT_MIN crypto_pwhash_argon2id_OPSLIMIT_MIN SODIUM_EXPORT -size_t crypto_pwhash_opslimit_min(void); +unsigned long long crypto_pwhash_opslimit_min(void); #define crypto_pwhash_OPSLIMIT_MAX crypto_pwhash_argon2id_OPSLIMIT_MAX SODIUM_EXPORT -size_t crypto_pwhash_opslimit_max(void); +unsigned long long crypto_pwhash_opslimit_max(void); #define crypto_pwhash_MEMLIMIT_MIN crypto_pwhash_argon2id_MEMLIMIT_MIN SODIUM_EXPORT @@ -72,7 +72,7 @@ size_t crypto_pwhash_memlimit_max(void); #define crypto_pwhash_OPSLIMIT_INTERACTIVE crypto_pwhash_argon2id_OPSLIMIT_INTERACTIVE SODIUM_EXPORT -size_t crypto_pwhash_opslimit_interactive(void); +unsigned long long crypto_pwhash_opslimit_interactive(void); #define crypto_pwhash_MEMLIMIT_INTERACTIVE crypto_pwhash_argon2id_MEMLIMIT_INTERACTIVE SODIUM_EXPORT @@ -80,7 +80,7 @@ size_t crypto_pwhash_memlimit_interactive(void); #define crypto_pwhash_OPSLIMIT_MODERATE crypto_pwhash_argon2id_OPSLIMIT_MODERATE SODIUM_EXPORT -size_t crypto_pwhash_opslimit_moderate(void); +unsigned long long crypto_pwhash_opslimit_moderate(void); #define crypto_pwhash_MEMLIMIT_MODERATE crypto_pwhash_argon2id_MEMLIMIT_MODERATE SODIUM_EXPORT @@ -88,7 +88,7 @@ size_t crypto_pwhash_memlimit_moderate(void); #define crypto_pwhash_OPSLIMIT_SENSITIVE crypto_pwhash_argon2id_OPSLIMIT_SENSITIVE SODIUM_EXPORT -size_t crypto_pwhash_opslimit_sensitive(void); +unsigned long long crypto_pwhash_opslimit_sensitive(void); #define crypto_pwhash_MEMLIMIT_SENSITIVE crypto_pwhash_argon2id_MEMLIMIT_SENSITIVE SODIUM_EXPORT @@ -125,17 +125,17 @@ int crypto_pwhash_str_alg(char out[crypto_pwhash_STRBYTES], __attribute__ ((warn_unused_result)) __attribute__ ((nonnull)); SODIUM_EXPORT -int crypto_pwhash_str_verify(const char str[crypto_pwhash_STRBYTES], +int crypto_pwhash_str_verify(const char *str, const char * const passwd, unsigned long long passwdlen) __attribute__ ((warn_unused_result)) __attribute__ ((nonnull)); SODIUM_EXPORT -int crypto_pwhash_str_needs_rehash(const char str[crypto_pwhash_STRBYTES], +int crypto_pwhash_str_needs_rehash(const char *str, unsigned long long opslimit, size_t memlimit) __attribute__ ((warn_unused_result)) __attribute__ ((nonnull)); -#define crypto_pwhash_PRIMITIVE "argon2i" +#define crypto_pwhash_PRIMITIVE "argon2id,argon2i" SODIUM_EXPORT const char *crypto_pwhash_primitive(void) __attribute__ ((warn_unused_result)); diff --git a/libs/libsodium/src/include/sodium/crypto_pwhash_argon2i.h b/libs/libsodium/src/include/sodium/crypto_pwhash_argon2i.h index c5e940c869..44b7d6fa02 100644 --- a/libs/libsodium/src/include/sodium/crypto_pwhash_argon2i.h +++ b/libs/libsodium/src/include/sodium/crypto_pwhash_argon2i.h @@ -48,11 +48,11 @@ const char *crypto_pwhash_argon2i_strprefix(void); #define crypto_pwhash_argon2i_OPSLIMIT_MIN 3U SODIUM_EXPORT -size_t crypto_pwhash_argon2i_opslimit_min(void); +unsigned long long crypto_pwhash_argon2i_opslimit_min(void); #define crypto_pwhash_argon2i_OPSLIMIT_MAX 4294967295U SODIUM_EXPORT -size_t crypto_pwhash_argon2i_opslimit_max(void); +unsigned long long crypto_pwhash_argon2i_opslimit_max(void); #define crypto_pwhash_argon2i_MEMLIMIT_MIN 8192U SODIUM_EXPORT @@ -65,7 +65,7 @@ size_t crypto_pwhash_argon2i_memlimit_max(void); #define crypto_pwhash_argon2i_OPSLIMIT_INTERACTIVE 4U SODIUM_EXPORT -size_t crypto_pwhash_argon2i_opslimit_interactive(void); +unsigned long long crypto_pwhash_argon2i_opslimit_interactive(void); #define crypto_pwhash_argon2i_MEMLIMIT_INTERACTIVE 33554432U SODIUM_EXPORT @@ -73,7 +73,7 @@ size_t crypto_pwhash_argon2i_memlimit_interactive(void); #define crypto_pwhash_argon2i_OPSLIMIT_MODERATE 6U SODIUM_EXPORT -size_t crypto_pwhash_argon2i_opslimit_moderate(void); +unsigned long long crypto_pwhash_argon2i_opslimit_moderate(void); #define crypto_pwhash_argon2i_MEMLIMIT_MODERATE 134217728U SODIUM_EXPORT @@ -81,7 +81,7 @@ size_t crypto_pwhash_argon2i_memlimit_moderate(void); #define crypto_pwhash_argon2i_OPSLIMIT_SENSITIVE 8U SODIUM_EXPORT -size_t crypto_pwhash_argon2i_opslimit_sensitive(void); +unsigned long long crypto_pwhash_argon2i_opslimit_sensitive(void); #define crypto_pwhash_argon2i_MEMLIMIT_SENSITIVE 536870912U SODIUM_EXPORT @@ -105,13 +105,13 @@ int crypto_pwhash_argon2i_str(char out[crypto_pwhash_argon2i_STRBYTES], __attribute__ ((warn_unused_result)) __attribute__ ((nonnull)); SODIUM_EXPORT -int crypto_pwhash_argon2i_str_verify(const char str[crypto_pwhash_argon2i_STRBYTES], +int crypto_pwhash_argon2i_str_verify(const char * str, const char * const passwd, unsigned long long passwdlen) __attribute__ ((warn_unused_result)) __attribute__ ((nonnull)); SODIUM_EXPORT -int crypto_pwhash_argon2i_str_needs_rehash(const char str[crypto_pwhash_argon2i_STRBYTES], +int crypto_pwhash_argon2i_str_needs_rehash(const char * str, unsigned long long opslimit, size_t memlimit) __attribute__ ((warn_unused_result)) __attribute__ ((nonnull)); diff --git a/libs/libsodium/src/include/sodium/crypto_pwhash_argon2id.h b/libs/libsodium/src/include/sodium/crypto_pwhash_argon2id.h index a8dd1a5260..9d4ae6a8ae 100644 --- a/libs/libsodium/src/include/sodium/crypto_pwhash_argon2id.h +++ b/libs/libsodium/src/include/sodium/crypto_pwhash_argon2id.h @@ -48,11 +48,11 @@ const char *crypto_pwhash_argon2id_strprefix(void); #define crypto_pwhash_argon2id_OPSLIMIT_MIN 1U SODIUM_EXPORT -size_t crypto_pwhash_argon2id_opslimit_min(void); +unsigned long long crypto_pwhash_argon2id_opslimit_min(void); #define crypto_pwhash_argon2id_OPSLIMIT_MAX 4294967295U SODIUM_EXPORT -size_t crypto_pwhash_argon2id_opslimit_max(void); +unsigned long long crypto_pwhash_argon2id_opslimit_max(void); #define crypto_pwhash_argon2id_MEMLIMIT_MIN 8192U SODIUM_EXPORT @@ -65,7 +65,7 @@ size_t crypto_pwhash_argon2id_memlimit_max(void); #define crypto_pwhash_argon2id_OPSLIMIT_INTERACTIVE 2U SODIUM_EXPORT -size_t crypto_pwhash_argon2id_opslimit_interactive(void); +unsigned long long crypto_pwhash_argon2id_opslimit_interactive(void); #define crypto_pwhash_argon2id_MEMLIMIT_INTERACTIVE 67108864U SODIUM_EXPORT @@ -73,7 +73,7 @@ size_t crypto_pwhash_argon2id_memlimit_interactive(void); #define crypto_pwhash_argon2id_OPSLIMIT_MODERATE 3U SODIUM_EXPORT -size_t crypto_pwhash_argon2id_opslimit_moderate(void); +unsigned long long crypto_pwhash_argon2id_opslimit_moderate(void); #define crypto_pwhash_argon2id_MEMLIMIT_MODERATE 268435456U SODIUM_EXPORT @@ -81,7 +81,7 @@ size_t crypto_pwhash_argon2id_memlimit_moderate(void); #define crypto_pwhash_argon2id_OPSLIMIT_SENSITIVE 4U SODIUM_EXPORT -size_t crypto_pwhash_argon2id_opslimit_sensitive(void); +unsigned long long crypto_pwhash_argon2id_opslimit_sensitive(void); #define crypto_pwhash_argon2id_MEMLIMIT_SENSITIVE 1073741824U SODIUM_EXPORT @@ -105,13 +105,13 @@ int crypto_pwhash_argon2id_str(char out[crypto_pwhash_argon2id_STRBYTES], __attribute__ ((warn_unused_result)) __attribute__ ((nonnull)); SODIUM_EXPORT -int crypto_pwhash_argon2id_str_verify(const char str[crypto_pwhash_argon2id_STRBYTES], +int crypto_pwhash_argon2id_str_verify(const char * str, const char * const passwd, unsigned long long passwdlen) __attribute__ ((warn_unused_result)) __attribute__ ((nonnull)); SODIUM_EXPORT -int crypto_pwhash_argon2id_str_needs_rehash(const char str[crypto_pwhash_argon2id_STRBYTES], +int crypto_pwhash_argon2id_str_needs_rehash(const char * str, unsigned long long opslimit, size_t memlimit) __attribute__ ((warn_unused_result)) __attribute__ ((nonnull)); diff --git a/libs/libsodium/src/include/sodium/crypto_pwhash_scryptsalsa208sha256.h b/libs/libsodium/src/include/sodium/crypto_pwhash_scryptsalsa208sha256.h index 71893bdd65..c9c0469bbb 100644 --- a/libs/libsodium/src/include/sodium/crypto_pwhash_scryptsalsa208sha256.h +++ b/libs/libsodium/src/include/sodium/crypto_pwhash_scryptsalsa208sha256.h @@ -45,11 +45,11 @@ const char *crypto_pwhash_scryptsalsa208sha256_strprefix(void); #define crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_MIN 32768U SODIUM_EXPORT -size_t crypto_pwhash_scryptsalsa208sha256_opslimit_min(void); +unsigned long long crypto_pwhash_scryptsalsa208sha256_opslimit_min(void); #define crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_MAX 4294967295U SODIUM_EXPORT -size_t crypto_pwhash_scryptsalsa208sha256_opslimit_max(void); +unsigned long long crypto_pwhash_scryptsalsa208sha256_opslimit_max(void); #define crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_MIN 16777216U SODIUM_EXPORT @@ -62,7 +62,7 @@ size_t crypto_pwhash_scryptsalsa208sha256_memlimit_max(void); #define crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_INTERACTIVE 524288U SODIUM_EXPORT -size_t crypto_pwhash_scryptsalsa208sha256_opslimit_interactive(void); +unsigned long long crypto_pwhash_scryptsalsa208sha256_opslimit_interactive(void); #define crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_INTERACTIVE 16777216U SODIUM_EXPORT @@ -70,7 +70,7 @@ size_t crypto_pwhash_scryptsalsa208sha256_memlimit_interactive(void); #define crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_SENSITIVE 33554432U SODIUM_EXPORT -size_t crypto_pwhash_scryptsalsa208sha256_opslimit_sensitive(void); +unsigned long long crypto_pwhash_scryptsalsa208sha256_opslimit_sensitive(void); #define crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_SENSITIVE 1073741824U SODIUM_EXPORT @@ -95,7 +95,7 @@ int crypto_pwhash_scryptsalsa208sha256_str(char out[crypto_pwhash_scryptsalsa208 __attribute__ ((warn_unused_result)) __attribute__ ((nonnull)); SODIUM_EXPORT -int crypto_pwhash_scryptsalsa208sha256_str_verify(const char str[crypto_pwhash_scryptsalsa208sha256_STRBYTES], +int crypto_pwhash_scryptsalsa208sha256_str_verify(const char * str, const char * const passwd, unsigned long long passwdlen) __attribute__ ((warn_unused_result)) __attribute__ ((nonnull)); @@ -108,7 +108,7 @@ int crypto_pwhash_scryptsalsa208sha256_ll(const uint8_t * passwd, size_t passwdl __attribute__ ((warn_unused_result)) __attribute__ ((nonnull)); SODIUM_EXPORT -int crypto_pwhash_scryptsalsa208sha256_str_needs_rehash(const char str[crypto_pwhash_scryptsalsa208sha256_STRBYTES], +int crypto_pwhash_scryptsalsa208sha256_str_needs_rehash(const char * str, unsigned long long opslimit, size_t memlimit) __attribute__ ((warn_unused_result)) __attribute__ ((nonnull)); diff --git a/libs/libsodium/src/include/sodium/crypto_scalarmult.h b/libs/libsodium/src/include/sodium/crypto_scalarmult.h index 842281371f..f72ee55c81 100644 --- a/libs/libsodium/src/include/sodium/crypto_scalarmult.h +++ b/libs/libsodium/src/include/sodium/crypto_scalarmult.h @@ -27,7 +27,7 @@ int crypto_scalarmult_base(unsigned char *q, const unsigned char *n) __attribute__ ((nonnull)); /* - * NOTE: Do not use the result of this function directly. + * NOTE: Do not use the result of this function directly for key exchange. * * Hash the result with the public keys in order to compute a shared * secret key: H(q || client_pk || server_pk) diff --git a/libs/libsodium/src/include/sodium/crypto_scalarmult_curve25519.h b/libs/libsodium/src/include/sodium/crypto_scalarmult_curve25519.h index 8a59123303..d97c8db212 100644 --- a/libs/libsodium/src/include/sodium/crypto_scalarmult_curve25519.h +++ b/libs/libsodium/src/include/sodium/crypto_scalarmult_curve25519.h @@ -18,7 +18,7 @@ SODIUM_EXPORT size_t crypto_scalarmult_curve25519_scalarbytes(void); /* - * NOTE: Do not use the result of this function directly. + * NOTE: Do not use the result of this function directly for key exchange. * * Hash the result with the public keys in order to compute a shared * secret key: H(q || client_pk || server_pk) diff --git a/libs/libsodium/src/include/sodium/crypto_scalarmult_ed25519.h b/libs/libsodium/src/include/sodium/crypto_scalarmult_ed25519.h index a3d562b207..15f7258c06 100644 --- a/libs/libsodium/src/include/sodium/crypto_scalarmult_ed25519.h +++ b/libs/libsodium/src/include/sodium/crypto_scalarmult_ed25519.h @@ -19,7 +19,7 @@ SODIUM_EXPORT size_t crypto_scalarmult_ed25519_scalarbytes(void); /* - * NOTE: Do not use the result of this function directly. + * NOTE: Do not use the result of this function directly for key exchange. * * Hash the result with the public keys in order to compute a shared * secret key: H(q || client_pk || server_pk) diff --git a/libs/libsodium/src/include/sodium/crypto_scalarmult_ristretto255.h b/libs/libsodium/src/include/sodium/crypto_scalarmult_ristretto255.h new file mode 100644 index 0000000000..40a45ccef0 --- /dev/null +++ b/libs/libsodium/src/include/sodium/crypto_scalarmult_ristretto255.h @@ -0,0 +1,43 @@ + +#ifndef crypto_scalarmult_ristretto255_H +#define crypto_scalarmult_ristretto255_H + +#include + +#include "export.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define crypto_scalarmult_ristretto255_BYTES 32U +SODIUM_EXPORT +size_t crypto_scalarmult_ristretto255_bytes(void); + +#define crypto_scalarmult_ristretto255_SCALARBYTES 32U +SODIUM_EXPORT +size_t crypto_scalarmult_ristretto255_scalarbytes(void); + +/* + * NOTE: Do not use the result of this function directly for key exchange. + * + * Hash the result with the public keys in order to compute a shared + * secret key: H(q || client_pk || server_pk) + * + * Or unless this is not an option, use the crypto_kx() API instead. + */ +SODIUM_EXPORT +int crypto_scalarmult_ristretto255(unsigned char *q, const unsigned char *n, + const unsigned char *p) + __attribute__ ((warn_unused_result)) __attribute__ ((nonnull)); + +SODIUM_EXPORT +int crypto_scalarmult_ristretto255_base(unsigned char *q, + const unsigned char *n) + __attribute__ ((nonnull)); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libs/libsodium/src/include/sodium/crypto_secretbox.h b/libs/libsodium/src/include/sodium/crypto_secretbox.h index c5f653c0a2..d3d3e3005b 100644 --- a/libs/libsodium/src/include/sodium/crypto_secretbox.h +++ b/libs/libsodium/src/include/sodium/crypto_secretbox.h @@ -36,7 +36,7 @@ size_t crypto_secretbox_messagebytes_max(void); SODIUM_EXPORT int crypto_secretbox_easy(unsigned char *c, const unsigned char *m, unsigned long long mlen, const unsigned char *n, - const unsigned char *k) __attribute__ ((nonnull)); + const unsigned char *k) __attribute__ ((nonnull(1, 4, 5))); SODIUM_EXPORT int crypto_secretbox_open_easy(unsigned char *m, const unsigned char *c, @@ -50,7 +50,7 @@ int crypto_secretbox_detached(unsigned char *c, unsigned char *mac, unsigned long long mlen, const unsigned char *n, const unsigned char *k) - __attribute__ ((nonnull)); + __attribute__ ((nonnull(1, 2, 5, 6))); SODIUM_EXPORT int crypto_secretbox_open_detached(unsigned char *m, @@ -69,22 +69,23 @@ void crypto_secretbox_keygen(unsigned char k[crypto_secretbox_KEYBYTES]) #define crypto_secretbox_ZEROBYTES crypto_secretbox_xsalsa20poly1305_ZEROBYTES SODIUM_EXPORT -size_t crypto_secretbox_zerobytes(void); +size_t crypto_secretbox_zerobytes(void) __attribute__ ((deprecated)); #define crypto_secretbox_BOXZEROBYTES crypto_secretbox_xsalsa20poly1305_BOXZEROBYTES SODIUM_EXPORT -size_t crypto_secretbox_boxzerobytes(void); +size_t crypto_secretbox_boxzerobytes(void) __attribute__ ((deprecated)); SODIUM_EXPORT int crypto_secretbox(unsigned char *c, const unsigned char *m, unsigned long long mlen, const unsigned char *n, - const unsigned char *k) __attribute__ ((nonnull)); + const unsigned char *k) + __attribute__ ((deprecated)) __attribute__ ((nonnull(1, 4, 5))); SODIUM_EXPORT int crypto_secretbox_open(unsigned char *m, const unsigned char *c, unsigned long long clen, const unsigned char *n, const unsigned char *k) - __attribute__ ((warn_unused_result)) __attribute__ ((nonnull(2, 4, 5))); + __attribute__ ((deprecated)) __attribute__ ((warn_unused_result)) __attribute__ ((nonnull(2, 4, 5))); #ifdef __cplusplus } diff --git a/libs/libsodium/src/include/sodium/crypto_secretbox_xchacha20poly1305.h b/libs/libsodium/src/include/sodium/crypto_secretbox_xchacha20poly1305.h index eb1754e8a6..91576eb858 100644 --- a/libs/libsodium/src/include/sodium/crypto_secretbox_xchacha20poly1305.h +++ b/libs/libsodium/src/include/sodium/crypto_secretbox_xchacha20poly1305.h @@ -35,7 +35,7 @@ int crypto_secretbox_xchacha20poly1305_easy(unsigned char *c, unsigned long long mlen, const unsigned char *n, const unsigned char *k) - __attribute__ ((nonnull)); + __attribute__ ((nonnull(1, 4, 5))); SODIUM_EXPORT int crypto_secretbox_xchacha20poly1305_open_easy(unsigned char *m, @@ -52,7 +52,7 @@ int crypto_secretbox_xchacha20poly1305_detached(unsigned char *c, unsigned long long mlen, const unsigned char *n, const unsigned char *k) - __attribute__ ((nonnull)); + __attribute__ ((nonnull(1, 2, 5, 6))); SODIUM_EXPORT int crypto_secretbox_xchacha20poly1305_open_detached(unsigned char *m, diff --git a/libs/libsodium/src/include/sodium/crypto_secretbox_xsalsa20poly1305.h b/libs/libsodium/src/include/sodium/crypto_secretbox_xsalsa20poly1305.h index f4d83aa562..9b4f2dcb4f 100644 --- a/libs/libsodium/src/include/sodium/crypto_secretbox_xsalsa20poly1305.h +++ b/libs/libsodium/src/include/sodium/crypto_secretbox_xsalsa20poly1305.h @@ -30,22 +30,6 @@ size_t crypto_secretbox_xsalsa20poly1305_macbytes(void); SODIUM_EXPORT size_t crypto_secretbox_xsalsa20poly1305_messagebytes_max(void); -SODIUM_EXPORT -int crypto_secretbox_xsalsa20poly1305(unsigned char *c, - const unsigned char *m, - unsigned long long mlen, - const unsigned char *n, - const unsigned char *k) - __attribute__ ((nonnull)); - -SODIUM_EXPORT -int crypto_secretbox_xsalsa20poly1305_open(unsigned char *m, - const unsigned char *c, - unsigned long long clen, - const unsigned char *n, - const unsigned char *k) - __attribute__ ((warn_unused_result)) __attribute__ ((nonnull(2, 4, 5))); - SODIUM_EXPORT void crypto_secretbox_xsalsa20poly1305_keygen(unsigned char k[crypto_secretbox_xsalsa20poly1305_KEYBYTES]) __attribute__ ((nonnull)); @@ -54,13 +38,31 @@ void crypto_secretbox_xsalsa20poly1305_keygen(unsigned char k[crypto_secretbox_x #define crypto_secretbox_xsalsa20poly1305_BOXZEROBYTES 16U SODIUM_EXPORT -size_t crypto_secretbox_xsalsa20poly1305_boxzerobytes(void); +size_t crypto_secretbox_xsalsa20poly1305_boxzerobytes(void) + __attribute__ ((deprecated)); #define crypto_secretbox_xsalsa20poly1305_ZEROBYTES \ (crypto_secretbox_xsalsa20poly1305_BOXZEROBYTES + \ crypto_secretbox_xsalsa20poly1305_MACBYTES) SODIUM_EXPORT -size_t crypto_secretbox_xsalsa20poly1305_zerobytes(void); +size_t crypto_secretbox_xsalsa20poly1305_zerobytes(void) + __attribute__ ((deprecated)); + +SODIUM_EXPORT +int crypto_secretbox_xsalsa20poly1305(unsigned char *c, + const unsigned char *m, + unsigned long long mlen, + const unsigned char *n, + const unsigned char *k) + __attribute__ ((deprecated)) __attribute__ ((nonnull(1, 4, 5))); + +SODIUM_EXPORT +int crypto_secretbox_xsalsa20poly1305_open(unsigned char *m, + const unsigned char *c, + unsigned long long clen, + const unsigned char *n, + const unsigned char *k) + __attribute__ ((deprecated)) __attribute__ ((warn_unused_result)) __attribute__ ((nonnull(2, 4, 5))); #ifdef __cplusplus } diff --git a/libs/libsodium/src/include/sodium/crypto_shorthash.h b/libs/libsodium/src/include/sodium/crypto_shorthash.h index a55d98f170..15ed47c71d 100644 --- a/libs/libsodium/src/include/sodium/crypto_shorthash.h +++ b/libs/libsodium/src/include/sodium/crypto_shorthash.h @@ -28,7 +28,7 @@ const char *crypto_shorthash_primitive(void); SODIUM_EXPORT int crypto_shorthash(unsigned char *out, const unsigned char *in, unsigned long long inlen, const unsigned char *k) - __attribute__ ((nonnull)); + __attribute__ ((nonnull(1, 4))); SODIUM_EXPORT void crypto_shorthash_keygen(unsigned char k[crypto_shorthash_KEYBYTES]) diff --git a/libs/libsodium/src/include/sodium/crypto_shorthash_siphash24.h b/libs/libsodium/src/include/sodium/crypto_shorthash_siphash24.h index 0b4efd5156..e22633d529 100644 --- a/libs/libsodium/src/include/sodium/crypto_shorthash_siphash24.h +++ b/libs/libsodium/src/include/sodium/crypto_shorthash_siphash24.h @@ -24,7 +24,7 @@ size_t crypto_shorthash_siphash24_keybytes(void); SODIUM_EXPORT int crypto_shorthash_siphash24(unsigned char *out, const unsigned char *in, unsigned long long inlen, const unsigned char *k) - __attribute__ ((nonnull)); + __attribute__ ((nonnull(1, 4))); #ifndef SODIUM_LIBRARY_MINIMAL /* -- 128-bit output -- */ @@ -40,7 +40,7 @@ size_t crypto_shorthash_siphashx24_keybytes(void); SODIUM_EXPORT int crypto_shorthash_siphashx24(unsigned char *out, const unsigned char *in, unsigned long long inlen, const unsigned char *k) - __attribute__ ((nonnull)); + __attribute__ ((nonnull(1, 4))); #endif #ifdef __cplusplus diff --git a/libs/libsodium/src/include/sodium/crypto_sign.h b/libs/libsodium/src/include/sodium/crypto_sign.h index 7b2febbcb5..a20fbd3955 100644 --- a/libs/libsodium/src/include/sodium/crypto_sign.h +++ b/libs/libsodium/src/include/sodium/crypto_sign.h @@ -61,7 +61,7 @@ int crypto_sign_keypair(unsigned char *pk, unsigned char *sk) SODIUM_EXPORT int crypto_sign(unsigned char *sm, unsigned long long *smlen_p, const unsigned char *m, unsigned long long mlen, - const unsigned char *sk) __attribute__ ((nonnull(1, 3, 5))); + const unsigned char *sk) __attribute__ ((nonnull(1, 5))); SODIUM_EXPORT int crypto_sign_open(unsigned char *m, unsigned long long *mlen_p, @@ -72,14 +72,14 @@ int crypto_sign_open(unsigned char *m, unsigned long long *mlen_p, SODIUM_EXPORT int crypto_sign_detached(unsigned char *sig, unsigned long long *siglen_p, const unsigned char *m, unsigned long long mlen, - const unsigned char *sk) __attribute__ ((nonnull(1, 3, 5))); + const unsigned char *sk) __attribute__ ((nonnull(1, 5))); SODIUM_EXPORT int crypto_sign_verify_detached(const unsigned char *sig, const unsigned char *m, unsigned long long mlen, const unsigned char *pk) - __attribute__ ((warn_unused_result)) __attribute__ ((nonnull)); + __attribute__ ((warn_unused_result)) __attribute__ ((nonnull(1, 4))); SODIUM_EXPORT int crypto_sign_init(crypto_sign_state *state); @@ -87,7 +87,7 @@ int crypto_sign_init(crypto_sign_state *state); SODIUM_EXPORT int crypto_sign_update(crypto_sign_state *state, const unsigned char *m, unsigned long long mlen) - __attribute__ ((nonnull)); + __attribute__ ((nonnull(1))); SODIUM_EXPORT int crypto_sign_final_create(crypto_sign_state *state, unsigned char *sig, diff --git a/libs/libsodium/src/include/sodium/crypto_sign_ed25519.h b/libs/libsodium/src/include/sodium/crypto_sign_ed25519.h index c2024da017..cb230252ad 100644 --- a/libs/libsodium/src/include/sodium/crypto_sign_ed25519.h +++ b/libs/libsodium/src/include/sodium/crypto_sign_ed25519.h @@ -43,7 +43,7 @@ SODIUM_EXPORT int crypto_sign_ed25519(unsigned char *sm, unsigned long long *smlen_p, const unsigned char *m, unsigned long long mlen, const unsigned char *sk) - __attribute__ ((nonnull(1, 3, 5))); + __attribute__ ((nonnull(1, 5))); SODIUM_EXPORT int crypto_sign_ed25519_open(unsigned char *m, unsigned long long *mlen_p, @@ -57,14 +57,14 @@ int crypto_sign_ed25519_detached(unsigned char *sig, const unsigned char *m, unsigned long long mlen, const unsigned char *sk) - __attribute__ ((nonnull(1, 3))); + __attribute__ ((nonnull(1, 5))); SODIUM_EXPORT int crypto_sign_ed25519_verify_detached(const unsigned char *sig, const unsigned char *m, unsigned long long mlen, const unsigned char *pk) - __attribute__ ((warn_unused_result)); + __attribute__ ((warn_unused_result)) __attribute__ ((nonnull(1, 4))); SODIUM_EXPORT int crypto_sign_ed25519_keypair(unsigned char *pk, unsigned char *sk) @@ -102,14 +102,14 @@ SODIUM_EXPORT int crypto_sign_ed25519ph_update(crypto_sign_ed25519ph_state *state, const unsigned char *m, unsigned long long mlen) - __attribute__ ((nonnull)); + __attribute__ ((nonnull(1))); SODIUM_EXPORT int crypto_sign_ed25519ph_final_create(crypto_sign_ed25519ph_state *state, unsigned char *sig, unsigned long long *siglen_p, const unsigned char *sk) - __attribute__ ((nonnull)); + __attribute__ ((nonnull(1, 2, 4))); SODIUM_EXPORT int crypto_sign_ed25519ph_final_verify(crypto_sign_ed25519ph_state *state, diff --git a/libs/libsodium/src/include/sodium/crypto_sign_edwards25519sha512batch.h b/libs/libsodium/src/include/sodium/crypto_sign_edwards25519sha512batch.h deleted file mode 100644 index 208de4016c..0000000000 --- a/libs/libsodium/src/include/sodium/crypto_sign_edwards25519sha512batch.h +++ /dev/null @@ -1,55 +0,0 @@ -#ifndef crypto_sign_edwards25519sha512batch_H -#define crypto_sign_edwards25519sha512batch_H - -/* - * WARNING: This construction was a prototype, which should not be used - * any more in new projects. - * - * crypto_sign_edwards25519sha512batch is provided for applications - * initially built with NaCl, but as recommended by the author of this - * construction, new applications should use ed25519 instead. - * - * In Sodium, you should use the high-level crypto_sign_*() functions instead. - */ - -#include -#include "export.h" - -#ifdef __cplusplus -# ifdef __GNUC__ -# pragma GCC diagnostic ignored "-Wlong-long" -# endif -extern "C" { -#endif - -#define crypto_sign_edwards25519sha512batch_BYTES 64U -#define crypto_sign_edwards25519sha512batch_PUBLICKEYBYTES 32U -#define crypto_sign_edwards25519sha512batch_SECRETKEYBYTES (32U + 32U) -#define crypto_sign_edwards25519sha512batch_MESSAGEBYTES_MAX (SODIUM_SIZE_MAX - crypto_sign_edwards25519sha512batch_BYTES) - -SODIUM_EXPORT -int crypto_sign_edwards25519sha512batch(unsigned char *sm, - unsigned long long *smlen_p, - const unsigned char *m, - unsigned long long mlen, - const unsigned char *sk) - __attribute__ ((deprecated)) __attribute__ ((nonnull(1, 3, 5))); - -SODIUM_EXPORT -int crypto_sign_edwards25519sha512batch_open(unsigned char *m, - unsigned long long *mlen_p, - const unsigned char *sm, - unsigned long long smlen, - const unsigned char *pk) - __attribute__ ((deprecated)) __attribute__ ((nonnull(3, 5))); - -SODIUM_EXPORT -int crypto_sign_edwards25519sha512batch_keypair(unsigned char *pk, - unsigned char *sk) - __attribute__ ((deprecated)) __attribute__ ((nonnull)); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/libs/libsodium/src/include/sodium/crypto_vrf.h b/libs/libsodium/src/include/sodium/crypto_vrf.h new file mode 100644 index 0000000000..e3b65b94e9 --- /dev/null +++ b/libs/libsodium/src/include/sodium/crypto_vrf.h @@ -0,0 +1,75 @@ +#ifndef crypto_vrf_H +#define crypto_vrf_H + +/* + * THREAD SAFETY: crypto_vrf_keypair() is thread-safe, + * provided that sodium_init() was called before. + * + * Other functions, including crypto_vrf_keypair_from_seed(), are always thread-safe. + */ + +#include + +#include "crypto_vrf_rfc9381.h" +#include "export.h" + +#ifdef __cplusplus +# ifdef __GNUC__ +# pragma GCC diagnostic ignored "-Wlong-long" +# endif +extern "C" { +#endif + +#define crypto_vrf_PROOFBYTES crypto_vrf_rfc9381_BYTES +SODIUM_EXPORT +size_t crypto_vrf_bytes(void); + +#define crypto_vrf_OUTPUTBYTES crypto_vrf_rfc9381_OUTPUTBYTES +SODIUM_EXPORT +size_t crypto_vrf_outputbytes(void); + +#define crypto_vrf_SEEDBYTES crypto_vrf_rfc9381_SEEDBYTES +SODIUM_EXPORT +size_t crypto_vrf_seedbytes(void); + +#define crypto_vrf_PUBLICKEYBYTES crypto_vrf_rfc9381_PUBLICKEYBYTES +SODIUM_EXPORT +size_t crypto_vrf_publickeybytes(void); + +#define crypto_vrf_SECRETKEYBYTES crypto_vrf_rfc9381_SECRETKEYBYTES +SODIUM_EXPORT +size_t crypto_vrf_secretkeybytes(void); + +#define crypto_vrf_PRIMITIVE "rfc9381" +SODIUM_EXPORT +const char *crypto_vrf_primitive(void); + +SODIUM_EXPORT +int crypto_vrf_keypair(unsigned char *pk, unsigned char *sk) + __attribute__ ((nonnull)); + +SODIUM_EXPORT +int crypto_vrf_seed_keypair(unsigned char *pk, unsigned char *sk, + const unsigned char *seed) + __attribute__ ((nonnull)); + +SODIUM_EXPORT +int crypto_vrf_prove(unsigned char *proof, const unsigned char *m, + unsigned long long mlen, const unsigned char *sk) + __attribute__ ((nonnull)); + +SODIUM_EXPORT +int crypto_vrf_verify(unsigned char *output, + const unsigned char *pk, + const unsigned char *proof, + const unsigned char *m, unsigned long long mlen) + __attribute__ ((warn_unused_result)) __attribute__ ((nonnull)); + +SODIUM_EXPORT +int crypto_vrf_proof_to_hash(unsigned char *hash, const unsigned char *proof); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libs/libsodium/src/include/sodium/crypto_vrf_rfc9381.h b/libs/libsodium/src/include/sodium/crypto_vrf_rfc9381.h new file mode 100644 index 0000000000..14bf2d06ea --- /dev/null +++ b/libs/libsodium/src/include/sodium/crypto_vrf_rfc9381.h @@ -0,0 +1,78 @@ + +#ifndef crypto_vrf_rfc9381_H +#define crypto_vrf_rfc9381_H + +#include + +#include "export.h" + +#ifdef __cplusplus +# ifdef __GNUC__ +# pragma GCC diagnostic ignored "-Wlong-long" +# endif +extern "C" { +#endif + +#define crypto_vrf_rfc9381_BYTES 80U +SODIUM_EXPORT +size_t crypto_vrf_rfc9381_bytes(void); + +#define crypto_vrf_rfc9381_OUTPUTBYTES 64U +SODIUM_EXPORT +size_t crypto_vrf_rfc9381_outputbytes(void); + +#define crypto_vrf_rfc9381_SEEDBYTES 32U +SODIUM_EXPORT +size_t crypto_vrf_rfc9381_seedbytes(void); + +#define crypto_vrf_rfc9381_PUBLICKEYBYTES 32U +SODIUM_EXPORT +size_t crypto_vrf_rfc9381_publickeybytes(void); + +#define crypto_vrf_rfc9381_SECRETKEYBYTES 64U +SODIUM_EXPORT +size_t crypto_vrf_rfc9381_secretkeybytes(void); + +SODIUM_EXPORT +int crypto_vrf_rfc9381_prove(unsigned char *proof, + const unsigned char *m, + unsigned long long mlen, const unsigned char *sk); + +SODIUM_EXPORT +int crypto_vrf_rfc9381_verify(unsigned char *output, + const unsigned char *pk, + const unsigned char *proof, + const unsigned char *m, + unsigned long long mlen) + __attribute__ ((warn_unused_result)) __attribute__ ((nonnull)); + +SODIUM_EXPORT +int crypto_vrf_rfc9381_proof_to_hash(unsigned char *hash, + const unsigned char *proof) + __attribute__ ((nonnull)); + +SODIUM_EXPORT +int crypto_vrf_rfc9381_keypair(unsigned char *pk, unsigned char *sk) + __attribute__ ((nonnull)); + +SODIUM_EXPORT +int crypto_vrf_rfc9381_seed_keypair(unsigned char *pk, + unsigned char *sk, + const unsigned char *seed) + __attribute__ ((nonnull)); + +SODIUM_EXPORT +void crypto_vrf_rfc9381_sk_to_seed(unsigned char *seed, + const unsigned char *sk) + __attribute__ ((nonnull)); + +SODIUM_EXPORT +void crypto_vrf_rfc9381_sk_to_pk(unsigned char *pk, + const unsigned char *sk) + __attribute__ ((nonnull)); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libs/libsodium/src/include/sodium/private/asm_cet.h b/libs/libsodium/src/include/sodium/private/asm_cet.h new file mode 100644 index 0000000000..4428c97f32 --- /dev/null +++ b/libs/libsodium/src/include/sodium/private/asm_cet.h @@ -0,0 +1,11 @@ +#ifndef asm_cet_H +#define asm_cet_H 1 + +#if HAVE_CET_H +# include +#endif +#ifndef _CET_ENDBR +# define _CET_ENDBR +#endif + +#endif diff --git a/libs/libsodium/src/include/sodium/private/chacha20_ietf_ext.h b/libs/libsodium/src/include/sodium/private/chacha20_ietf_ext.h index d03cfd3329..d863013650 100644 --- a/libs/libsodium/src/include/sodium/private/chacha20_ietf_ext.h +++ b/libs/libsodium/src/include/sodium/private/chacha20_ietf_ext.h @@ -3,6 +3,8 @@ #include +#include "private/quirks.h" + /* The ietf_ext variant allows the internal counter to overflow into the IV */ int crypto_stream_chacha20_ietf_ext(unsigned char *c, unsigned long long clen, diff --git a/libs/libsodium/src/include/sodium/private/common.h b/libs/libsodium/src/include/sodium/private/common.h index aaf6030248..0ed3c63456 100644 --- a/libs/libsodium/src/include/sodium/private/common.h +++ b/libs/libsodium/src/include/sodium/private/common.h @@ -1,7 +1,7 @@ #ifndef common_H #define common_H 1 -#if !defined(_MSC_VER) && 0 +#if !defined(_MSC_VER) && !defined(DEV_MODE) && 1 # warning *** This is unstable, untested, development code. # warning It might not compile. It might not work as expected. # warning It might be totally insecure. @@ -20,6 +20,8 @@ #include #include +#include "private/quirks.h" + #define COMPILER_ASSERT(X) (void) sizeof(char[(X) ? 1 : -1]) #ifdef HAVE_TI_MODE @@ -226,24 +228,40 @@ xor_buf(unsigned char *out, const unsigned char *in, size_t n) # endif #endif -#if defined(_MSC_VER) && \ - (defined(_M_X64) || defined(_M_AMD64) || defined(_M_IX86)) +#ifdef _MSC_VER -# include +# if defined(_M_X64) || defined(_M_IX86) +# include + +# define HAVE_INTRIN_H 1 +# define HAVE_MMINTRIN_H 1 +# define HAVE_EMMINTRIN_H 1 +# define HAVE_PMMINTRIN_H 1 +# define HAVE_TMMINTRIN_H 1 +# define HAVE_SMMINTRIN_H 1 +# define HAVE_AVXINTRIN_H 1 +# if _MSC_VER >= 1600 +# define HAVE_WMMINTRIN_H 1 +# endif +# if _MSC_VER >= 1700 && defined(_M_X64) +# define HAVE_AVX2INTRIN_H 1 +# endif +# if _MSC_VER >= 1910 && defined(_M_X64) +# define HAVE_AVX512FINTRIN_H 1 +# endif + +# elif defined(_M_ARM64) + +# ifndef __ARM_ARCH +# define __ARM_ARCH 1 +# endif +# ifndef __ARM_NEON +# define __ARM_NEON 1 +# endif +# define HAVE_ARMCRYPTO 1 + +# endif /* _MSC_VER */ -# define HAVE_INTRIN_H 1 -# define HAVE_MMINTRIN_H 1 -# define HAVE_EMMINTRIN_H 1 -# define HAVE_PMMINTRIN_H 1 -# define HAVE_TMMINTRIN_H 1 -# define HAVE_SMMINTRIN_H 1 -# define HAVE_AVXINTRIN_H 1 -# if _MSC_VER >= 1600 -# define HAVE_WMMINTRIN_H 1 -# endif -# if _MSC_VER >= 1700 && defined(_M_X64) -# define HAVE_AVX2INTRIN_H 1 -# endif #elif defined(HAVE_INTRIN_H) # include #endif @@ -258,4 +276,12 @@ extern void ct_unpoison(const void *, size_t); # define UNPOISON(X, L) (void) 0 #endif +#ifdef HAVE_GCC_MEMORY_FENCES +# define ACQUIRE_FENCE __atomic_thread_fence(__ATOMIC_ACQUIRE) +#elif defined(HAVE_C11_MEMORY_FENCES) +# define ACQUIRE_FENCE atomic_thread_fence(memory_order_acquire) +#else +# define ACQUIRE_FENCE (void) 0 +#endif + #endif diff --git a/libs/libsodium/src/include/sodium/private/ed25519_ref10.h b/libs/libsodium/src/include/sodium/private/ed25519_ref10.h index cbf258e0c1..9477df3ca4 100644 --- a/libs/libsodium/src/include/sodium/private/ed25519_ref10.h +++ b/libs/libsodium/src/include/sodium/private/ed25519_ref10.h @@ -4,6 +4,8 @@ #include #include +#include "private/quirks.h" + /* fe means field element. Here the field is \Z/(2^255-19). @@ -25,7 +27,6 @@ void fe25519_tobytes(unsigned char *s, const fe25519 h); # include "ed25519_ref10_fe_25_5.h" #endif - /* ge means group element. @@ -81,35 +82,58 @@ int ge25519_frombytes(ge25519_p3 *h, const unsigned char *s); int ge25519_frombytes_negate_vartime(ge25519_p3 *h, const unsigned char *s); -void ge25519_p3_to_cached(ge25519_cached *r, const ge25519_p3 *p); - void ge25519_p1p1_to_p2(ge25519_p2 *r, const ge25519_p1p1 *p); void ge25519_p1p1_to_p3(ge25519_p3 *r, const ge25519_p1p1 *p); -void ge25519_add(ge25519_p1p1 *r, const ge25519_p3 *p, const ge25519_cached *q); +void ge25519_p2_to_p3(ge25519_p3 *r, const ge25519_p2 *p); -void ge25519_sub(ge25519_p1p1 *r, const ge25519_p3 *p, const ge25519_cached *q); +void ge25519_p3_add(ge25519_p3 *r, const ge25519_p3 *p, const ge25519_p3 *q); + +void ge25519_p3_sub(ge25519_p3 *r, const ge25519_p3 *p, const ge25519_p3 *q); void ge25519_scalarmult_base(ge25519_p3 *h, const unsigned char *a); void ge25519_double_scalarmult_vartime(ge25519_p2 *r, const unsigned char *a, const ge25519_p3 *A, - const unsigned char *b); + const unsigned char *b, + const ge25519_p3 *B); void ge25519_scalarmult(ge25519_p3 *h, const unsigned char *a, const ge25519_p3 *p); +void ge25519_clear_cofactor(ge25519_p3 *p3); + int ge25519_is_canonical(const unsigned char *s); int ge25519_is_on_curve(const ge25519_p3 *p); int ge25519_is_on_main_subgroup(const ge25519_p3 *p); -int ge25519_has_small_order(const unsigned char s[32]); +int ge25519_has_small_order(const ge25519_p3 *p); void ge25519_from_uniform(unsigned char s[32], const unsigned char r[32]); +void ge25519_from_hash(unsigned char s[32], const unsigned char h[64]); + +int ge25519_from_string(unsigned char p[32], + const char *ctx, const unsigned char *msg, + size_t msg_len, int hash_alg); + +int ge25519_from_string_ro(unsigned char p[32], + const char *ctx, const unsigned char *msg, + size_t msg_len, int hash_alg); + +/* + Ristretto group + */ + +int ristretto255_frombytes(ge25519_p3 *h, const unsigned char *s); + +void ristretto255_p3_tobytes(unsigned char *s, const ge25519_p3 *h); + +void ristretto255_from_hash(unsigned char s[32], const unsigned char h[64]); + /* The set of scalars is \Z/l where l = 2^252 + 27742317777372353535851937790883648493. @@ -117,11 +141,18 @@ void ge25519_from_uniform(unsigned char s[32], const unsigned char r[32]); void sc25519_invert(unsigned char recip[32], const unsigned char s[32]); +void sc25519_negate(unsigned char neg[32], const unsigned char s[32]); + void sc25519_reduce(unsigned char s[64]); +void sc25519_mul(unsigned char s[32], const unsigned char a[32], + const unsigned char b[32]); + void sc25519_muladd(unsigned char s[32], const unsigned char a[32], const unsigned char b[32], const unsigned char c[32]); int sc25519_is_canonical(const unsigned char s[32]); +void ge25519_clear_cofactor(ge25519_p3 *p3); + #endif diff --git a/libs/libsodium/src/include/sodium/private/ed25519_ref10_fe_25_5.h b/libs/libsodium/src/include/sodium/private/ed25519_ref10_fe_25_5.h index ffb689e4a4..4e933dba06 100644 --- a/libs/libsodium/src/include/sodium/private/ed25519_ref10_fe_25_5.h +++ b/libs/libsodium/src/include/sodium/private/ed25519_ref10_fe_25_5.h @@ -1,6 +1,7 @@ #include #include "private/common.h" +#include "private/quirks.h" #include "utils.h" /* @@ -147,29 +148,35 @@ fe25519_neg(fe25519 h, const fe25519 f) static void fe25519_cmov(fe25519 f, const fe25519 g, unsigned int b) { - const uint32_t mask = (uint32_t) (-(int32_t) b); - - int32_t f0 = f[0]; - int32_t f1 = f[1]; - int32_t f2 = f[2]; - int32_t f3 = f[3]; - int32_t f4 = f[4]; - int32_t f5 = f[5]; - int32_t f6 = f[6]; - int32_t f7 = f[7]; - int32_t f8 = f[8]; - int32_t f9 = f[9]; - - int32_t x0 = f0 ^ g[0]; - int32_t x1 = f1 ^ g[1]; - int32_t x2 = f2 ^ g[2]; - int32_t x3 = f3 ^ g[3]; - int32_t x4 = f4 ^ g[4]; - int32_t x5 = f5 ^ g[5]; - int32_t x6 = f6 ^ g[6]; - int32_t x7 = f7 ^ g[7]; - int32_t x8 = f8 ^ g[8]; - int32_t x9 = f9 ^ g[9]; + uint32_t mask = (uint32_t) (-(int32_t) b); + int32_t f0, f1, f2, f3, f4, f5, f6, f7, f8, f9; + int32_t x0, x1, x2, x3, x4, x5, x6, x7, x8, x9; + + f0 = f[0]; + f1 = f[1]; + f2 = f[2]; + f3 = f[3]; + f4 = f[4]; + f5 = f[5]; + f6 = f[6]; + f7 = f[7]; + f8 = f[8]; + f9 = f[9]; + + x0 = f0 ^ g[0]; + x1 = f1 ^ g[1]; + x2 = f2 ^ g[2]; + x3 = f3 ^ g[3]; + x4 = f4 ^ g[4]; + x5 = f5 ^ g[5]; + x6 = f6 ^ g[6]; + x7 = f7 ^ g[7]; + x8 = f8 ^ g[8]; + x9 = f9 ^ g[9]; + +#ifdef HAVE_INLINE_ASM + __asm__ __volatile__("" : "+r"(mask)); +#endif x0 &= mask; x1 &= mask; @@ -197,40 +204,47 @@ fe25519_cmov(fe25519 f, const fe25519 g, unsigned int b) static void fe25519_cswap(fe25519 f, fe25519 g, unsigned int b) { - const uint32_t mask = (uint32_t) (-(int64_t) b); - - int32_t f0 = f[0]; - int32_t f1 = f[1]; - int32_t f2 = f[2]; - int32_t f3 = f[3]; - int32_t f4 = f[4]; - int32_t f5 = f[5]; - int32_t f6 = f[6]; - int32_t f7 = f[7]; - int32_t f8 = f[8]; - int32_t f9 = f[9]; - - int32_t g0 = g[0]; - int32_t g1 = g[1]; - int32_t g2 = g[2]; - int32_t g3 = g[3]; - int32_t g4 = g[4]; - int32_t g5 = g[5]; - int32_t g6 = g[6]; - int32_t g7 = g[7]; - int32_t g8 = g[8]; - int32_t g9 = g[9]; - - int32_t x0 = f0 ^ g0; - int32_t x1 = f1 ^ g1; - int32_t x2 = f2 ^ g2; - int32_t x3 = f3 ^ g3; - int32_t x4 = f4 ^ g4; - int32_t x5 = f5 ^ g5; - int32_t x6 = f6 ^ g6; - int32_t x7 = f7 ^ g7; - int32_t x8 = f8 ^ g8; - int32_t x9 = f9 ^ g9; + uint32_t mask = (uint32_t) (-(int64_t) b); + int32_t f0, f1, f2, f3, f4, f5, f6, f7, f8, f9; + int32_t g0, g1, g2, g3, g4, g5, g6, g7, g8, g9; + int32_t x0, x1, x2, x3, x4, x5, x6, x7, x8, x9; + + f0 = f[0]; + f1 = f[1]; + f2 = f[2]; + f3 = f[3]; + f4 = f[4]; + f5 = f[5]; + f6 = f[6]; + f7 = f[7]; + f8 = f[8]; + f9 = f[9]; + + g0 = g[0]; + g1 = g[1]; + g2 = g[2]; + g3 = g[3]; + g4 = g[4]; + g5 = g[5]; + g6 = g[6]; + g7 = g[7]; + g8 = g[8]; + g9 = g[9]; + + x0 = f0 ^ g0; + x1 = f1 ^ g1; + x2 = f2 ^ g2; + x3 = f3 ^ g3; + x4 = f4 ^ g4; + x5 = f5 ^ g5; + x6 = f6 ^ g6; + x7 = f7 ^ g7; + x8 = f8 ^ g8; + x9 = f9 ^ g9; + +#ifdef HAVE_INLINE_ASM + __asm__ __volatile__("" : "+r"(mask)); +#endif x0 &= mask; x1 &= mask; @@ -273,27 +287,7 @@ fe25519_cswap(fe25519 f, fe25519 g, unsigned int b) static inline void fe25519_copy(fe25519 h, const fe25519 f) { - int32_t f0 = f[0]; - int32_t f1 = f[1]; - int32_t f2 = f[2]; - int32_t f3 = f[3]; - int32_t f4 = f[4]; - int32_t f5 = f[5]; - int32_t f6 = f[6]; - int32_t f7 = f[7]; - int32_t f8 = f[8]; - int32_t f9 = f[9]; - - h[0] = f0; - h[1] = f1; - h[2] = f2; - h[3] = f3; - h[4] = f4; - h[5] = f5; - h[6] = f6; - h[7] = f7; - h[8] = f8; - h[9] = f9; + memcpy(h, f, 10 * sizeof h[0]); } /* @@ -978,8 +972,8 @@ fe25519_sq2(fe25519 h, const fe25519 f) h[9] = (int32_t) h9; } -static void -fe25519_scalar_product(fe25519 h, const fe25519 f, uint32_t n) +static inline void +fe25519_mul32(fe25519 h, const fe25519 f, uint32_t n) { int64_t sn = (int64_t) n; int32_t f0 = f[0]; diff --git a/libs/libsodium/src/include/sodium/private/ed25519_ref10_fe_51.h b/libs/libsodium/src/include/sodium/private/ed25519_ref10_fe_51.h index 28363083d9..ec6f3f3c40 100644 --- a/libs/libsodium/src/include/sodium/private/ed25519_ref10_fe_51.h +++ b/libs/libsodium/src/include/sodium/private/ed25519_ref10_fe_51.h @@ -1,6 +1,7 @@ #include #include "private/common.h" +#include "private/quirks.h" #include "utils.h" /* @@ -108,19 +109,50 @@ fe25519_neg(fe25519 h, const fe25519 f) static void fe25519_cmov(fe25519 f, const fe25519 g, unsigned int b) { - const uint64_t mask = (uint64_t) (-(int64_t) b); +#ifdef HAVE_AMD64_ASM + uint64_t t0, t1, t2; + + __asm__ __volatile__ + ( + "test %[c], %[c]\n" + "movq (%[b]), %[t0]\n" + "cmoveq (%[a]), %[t0]\n" + "movq 8(%[b]), %[t1]\n" + "cmoveq 8(%[a]), %[t1]\n" + "movq 16(%[b]), %[t2]\n" + "cmoveq 16(%[a]), %[t2]\n" + "movq %[t0], (%[a])\n" + "movq %[t1], 8(%[a])\n" + "movq 24(%[b]), %[t0]\n" + "cmoveq 24(%[a]), %[t0]\n" + "movq 32(%[b]), %[t1]\n" + "cmoveq 32(%[a]), %[t1]\n" + "movq %[t2], 16(%[a])\n" + "movq %[t0], 24(%[a])\n" + "movq %[t1], 32(%[a])\n" + : [ t0 ] "=&r"(t0), [ t1 ] "=&r"(t1), [ t2 ] "=&r"(t2) + : [ a ] "r"(f), [ b ] "r"(g), [ c ] "r"(b) + : "cc", "memory"); +#else + uint64_t mask = (uint64_t) (-(int64_t) b); + uint64_t f0, f1, f2, f3, f4; + uint64_t x0, x1, x2, x3, x4; - uint64_t f0 = f[0]; - uint64_t f1 = f[1]; - uint64_t f2 = f[2]; - uint64_t f3 = f[3]; - uint64_t f4 = f[4]; + f0 = f[0]; + f1 = f[1]; + f2 = f[2]; + f3 = f[3]; + f4 = f[4]; + + x0 = f0 ^ g[0]; + x1 = f1 ^ g[1]; + x2 = f2 ^ g[2]; + x3 = f3 ^ g[3]; + x4 = f4 ^ g[4]; - uint64_t x0 = f0 ^ g[0]; - uint64_t x1 = f1 ^ g[1]; - uint64_t x2 = f2 ^ g[2]; - uint64_t x3 = f3 ^ g[3]; - uint64_t x4 = f4 ^ g[4]; +# ifdef HAVE_INLINE_ASM + __asm__ __volatile__("" : "+r"(mask)); +# endif x0 &= mask; x1 &= mask; @@ -133,6 +165,7 @@ fe25519_cmov(fe25519 f, const fe25519 g, unsigned int b) f[2] = f2 ^ x2; f[3] = f3 ^ x3; f[4] = f4 ^ x4; +#endif } /* @@ -145,25 +178,32 @@ Preconditions: b in {0,1}. static void fe25519_cswap(fe25519 f, fe25519 g, unsigned int b) { - const uint64_t mask = (uint64_t) (-(int64_t) b); - - uint64_t f0 = f[0]; - uint64_t f1 = f[1]; - uint64_t f2 = f[2]; - uint64_t f3 = f[3]; - uint64_t f4 = f[4]; - - uint64_t g0 = g[0]; - uint64_t g1 = g[1]; - uint64_t g2 = g[2]; - uint64_t g3 = g[3]; - uint64_t g4 = g[4]; - - uint64_t x0 = f0 ^ g0; - uint64_t x1 = f1 ^ g1; - uint64_t x2 = f2 ^ g2; - uint64_t x3 = f3 ^ g3; - uint64_t x4 = f4 ^ g4; + uint64_t mask = (uint64_t) (-(int64_t) b); + uint64_t f0, f1, f2, f3, f4; + uint64_t g0, g1, g2, g3, g4; + uint64_t x0, x1, x2, x3, x4; + + f0 = f[0]; + f1 = f[1]; + f2 = f[2]; + f3 = f[3]; + f4 = f[4]; + + g0 = g[0]; + g1 = g[1]; + g2 = g[2]; + g3 = g[3]; + g4 = g[4]; + + x0 = f0 ^ g0; + x1 = f1 ^ g1; + x2 = f2 ^ g2; + x3 = f3 ^ g3; + x4 = f4 ^ g4; + +# ifdef HAVE_INLINE_ASM + __asm__ __volatile__("" : "+r"(mask)); +# endif x0 &= mask; x1 &= mask; @@ -191,17 +231,7 @@ fe25519_cswap(fe25519 f, fe25519 g, unsigned int b) static inline void fe25519_copy(fe25519 h, const fe25519 f) { - uint64_t f0 = f[0]; - uint64_t f1 = f[1]; - uint64_t f2 = f[2]; - uint64_t f3 = f[3]; - uint64_t f4 = f[4]; - - h[0] = f0; - h[1] = f1; - h[2] = f2; - h[3] = f3; - h[4] = f4; + memcpy(h, f, 5 * sizeof h[0]); } /* @@ -243,80 +273,57 @@ static void fe25519_mul(fe25519 h, const fe25519 f, const fe25519 g) { const uint64_t mask = 0x7ffffffffffffULL; - uint128_t r0, r1, r2, r3, r4, carry; - uint64_t f0, f1, f2, f3, f4; - uint64_t f1_19, f2_19, f3_19, f4_19; - uint64_t g0, g1, g2, g3, g4; + uint128_t r0, r1, r2, r3, r4; + uint128_t f0, f1, f2, f3, f4; + uint128_t f1_19, f2_19, f3_19, f4_19; + uint128_t g0, g1, g2, g3, g4; uint64_t r00, r01, r02, r03, r04; + uint64_t carry; - f0 = f[0]; - f1 = f[1]; - f2 = f[2]; - f3 = f[3]; - f4 = f[4]; + f0 = (uint128_t) f[0]; + f1 = (uint128_t) f[1]; + f2 = (uint128_t) f[2]; + f3 = (uint128_t) f[3]; + f4 = (uint128_t) f[4]; - g0 = g[0]; - g1 = g[1]; - g2 = g[2]; - g3 = g[3]; - g4 = g[4]; + g0 = (uint128_t) g[0]; + g1 = (uint128_t) g[1]; + g2 = (uint128_t) g[2]; + g3 = (uint128_t) g[3]; + g4 = (uint128_t) g[4]; f1_19 = 19ULL * f1; f2_19 = 19ULL * f2; f3_19 = 19ULL * f3; f4_19 = 19ULL * f4; - r0 = ((uint128_t) f0 ) * ((uint128_t) g0); - r0 += ((uint128_t) f1_19) * ((uint128_t) g4); - r0 += ((uint128_t) f2_19) * ((uint128_t) g3); - r0 += ((uint128_t) f3_19) * ((uint128_t) g2); - r0 += ((uint128_t) f4_19) * ((uint128_t) g1); - - r1 = ((uint128_t) f0 ) * ((uint128_t) g1); - r1 += ((uint128_t) f1 ) * ((uint128_t) g0); - r1 += ((uint128_t) f2_19) * ((uint128_t) g4); - r1 += ((uint128_t) f3_19) * ((uint128_t) g3); - r1 += ((uint128_t) f4_19) * ((uint128_t) g2); - - r2 = ((uint128_t) f0 ) * ((uint128_t) g2); - r2 += ((uint128_t) f1 ) * ((uint128_t) g1); - r2 += ((uint128_t) f2 ) * ((uint128_t) g0); - r2 += ((uint128_t) f3_19) * ((uint128_t) g4); - r2 += ((uint128_t) f4_19) * ((uint128_t) g3); - - r3 = ((uint128_t) f0 ) * ((uint128_t) g3); - r3 += ((uint128_t) f1 ) * ((uint128_t) g2); - r3 += ((uint128_t) f2 ) * ((uint128_t) g1); - r3 += ((uint128_t) f3 ) * ((uint128_t) g0); - r3 += ((uint128_t) f4_19) * ((uint128_t) g4); - - r4 = ((uint128_t) f0 ) * ((uint128_t) g4); - r4 += ((uint128_t) f1 ) * ((uint128_t) g3); - r4 += ((uint128_t) f2 ) * ((uint128_t) g2); - r4 += ((uint128_t) f3 ) * ((uint128_t) g1); - r4 += ((uint128_t) f4 ) * ((uint128_t) g0); + r0 = f0 * g0 + f1_19 * g4 + f2_19 * g3 + f3_19 * g2 + f4_19 * g1; + r1 = f0 * g1 + f1 * g0 + f2_19 * g4 + f3_19 * g3 + f4_19 * g2; + r2 = f0 * g2 + f1 * g1 + f2 * g0 + f3_19 * g4 + f4_19 * g3; + r3 = f0 * g3 + f1 * g2 + f2 * g1 + f3 * g0 + f4_19 * g4; + r4 = f0 * g4 + f1 * g3 + f2 * g2 + f3 * g1 + f4 * g0; r00 = ((uint64_t) r0) & mask; - carry = r0 >> 51; + carry = (uint64_t) (r0 >> 51); r1 += carry; r01 = ((uint64_t) r1) & mask; - carry = r1 >> 51; + carry = (uint64_t) (r1 >> 51); r2 += carry; r02 = ((uint64_t) r2) & mask; - carry = r2 >> 51; + carry = (uint64_t) (r2 >> 51); r3 += carry; r03 = ((uint64_t) r3) & mask; - carry = r3 >> 51; + carry = (uint64_t) (r3 >> 51); r4 += carry; r04 = ((uint64_t) r4) & mask; - carry = r4 >> 51; - r00 += 19ULL * (uint64_t) carry; + carry = (uint64_t) (r4 >> 51); + r00 += 19ULL * carry; carry = r00 >> 51; r00 &= mask; - r01 += (uint64_t) carry; + r01 += carry; carry = r01 >> 51; r01 &= mask; - r02 += (uint64_t) carry; + r02 += carry; h[0] = r00; h[1] = r01; @@ -334,16 +341,17 @@ static void fe25519_sq(fe25519 h, const fe25519 f) { const uint64_t mask = 0x7ffffffffffffULL; - uint128_t r0, r1, r2, r3, r4, carry; - uint64_t f0, f1, f2, f3, f4; - uint64_t f0_2, f1_2, f1_38, f2_38, f3_38, f3_19, f4_19; + uint128_t r0, r1, r2, r3, r4; + uint128_t f0, f1, f2, f3, f4; + uint128_t f0_2, f1_2, f1_38, f2_38, f3_38, f3_19, f4_19; uint64_t r00, r01, r02, r03, r04; + uint64_t carry; - f0 = f[0]; - f1 = f[1]; - f2 = f[2]; - f3 = f[3]; - f4 = f[4]; + f0 = (uint128_t) f[0]; + f1 = (uint128_t) f[1]; + f2 = (uint128_t) f[2]; + f3 = (uint128_t) f[3]; + f4 = (uint128_t) f[4]; f0_2 = f0 << 1; f1_2 = f1 << 1; @@ -355,47 +363,33 @@ fe25519_sq(fe25519 h, const fe25519 f) f3_19 = 19ULL * f3; f4_19 = 19ULL * f4; - r0 = ((uint128_t) f0 ) * ((uint128_t) f0); - r0 += ((uint128_t) f1_38) * ((uint128_t) f4); - r0 += ((uint128_t) f2_38) * ((uint128_t) f3); - - r1 = ((uint128_t) f0_2 ) * ((uint128_t) f1); - r1 += ((uint128_t) f2_38) * ((uint128_t) f4); - r1 += ((uint128_t) f3_19) * ((uint128_t) f3); - - r2 = ((uint128_t) f0_2 ) * ((uint128_t) f2); - r2 += ((uint128_t) f1 ) * ((uint128_t) f1); - r2 += ((uint128_t) f3_38) * ((uint128_t) f4); - - r3 = ((uint128_t) f0_2 ) * ((uint128_t) f3); - r3 += ((uint128_t) f1_2 ) * ((uint128_t) f2); - r3 += ((uint128_t) f4_19) * ((uint128_t) f4); - - r4 = ((uint128_t) f0_2 ) * ((uint128_t) f4); - r4 += ((uint128_t) f1_2 ) * ((uint128_t) f3); - r4 += ((uint128_t) f2 ) * ((uint128_t) f2); + r0 = f0 * f0 + f1_38 * f4 + f2_38 * f3; + r1 = f0_2 * f1 + f2_38 * f4 + f3_19 * f3; + r2 = f0_2 * f2 + f1 * f1 + f3_38 * f4; + r3 = f0_2 * f3 + f1_2 * f2 + f4_19 * f4; + r4 = f0_2 * f4 + f1_2 * f3 + f2 * f2; r00 = ((uint64_t) r0) & mask; - carry = r0 >> 51; + carry = (uint64_t) (r0 >> 51); r1 += carry; r01 = ((uint64_t) r1) & mask; - carry = r1 >> 51; + carry = (uint64_t) (r1 >> 51); r2 += carry; r02 = ((uint64_t) r2) & mask; - carry = r2 >> 51; + carry = (uint64_t) (r2 >> 51); r3 += carry; r03 = ((uint64_t) r3) & mask; - carry = r3 >> 51; + carry = (uint64_t) (r3 >> 51); r4 += carry; r04 = ((uint64_t) r4) & mask; - carry = r4 >> 51; - r00 += 19ULL * (uint64_t) carry; + carry = (uint64_t) (r4 >> 51); + r00 += 19ULL * carry; carry = r00 >> 51; r00 &= mask; - r01 += (uint64_t) carry; + r01 += carry; carry = r01 >> 51; r01 &= mask; - r02 += (uint64_t) carry; + r02 += carry; h[0] = r00; h[1] = r01; @@ -413,16 +407,17 @@ static void fe25519_sq2(fe25519 h, const fe25519 f) { const uint64_t mask = 0x7ffffffffffffULL; - uint128_t r0, r1, r2, r3, r4, carry; - uint64_t f0, f1, f2, f3, f4; - uint64_t f0_2, f1_2, f1_38, f2_38, f3_38, f3_19, f4_19; + uint128_t r0, r1, r2, r3, r4; + uint128_t f0, f1, f2, f3, f4; + uint128_t f0_2, f1_2, f1_38, f2_38, f3_38, f3_19, f4_19; uint64_t r00, r01, r02, r03, r04; + uint64_t carry; - f0 = f[0]; - f1 = f[1]; - f2 = f[2]; - f3 = f[3]; - f4 = f[4]; + f0 = (uint128_t) f[0]; + f1 = (uint128_t) f[1]; + f2 = (uint128_t) f[2]; + f3 = (uint128_t) f[3]; + f4 = (uint128_t) f[4]; f0_2 = f0 << 1; f1_2 = f1 << 1; @@ -434,25 +429,11 @@ fe25519_sq2(fe25519 h, const fe25519 f) f3_19 = 19ULL * f3; f4_19 = 19ULL * f4; - r0 = ((uint128_t) f0 ) * ((uint128_t) f0); - r0 += ((uint128_t) f1_38) * ((uint128_t) f4); - r0 += ((uint128_t) f2_38) * ((uint128_t) f3); - - r1 = ((uint128_t) f0_2 ) * ((uint128_t) f1); - r1 += ((uint128_t) f2_38) * ((uint128_t) f4); - r1 += ((uint128_t) f3_19) * ((uint128_t) f3); - - r2 = ((uint128_t) f0_2 ) * ((uint128_t) f2); - r2 += ((uint128_t) f1 ) * ((uint128_t) f1); - r2 += ((uint128_t) f3_38) * ((uint128_t) f4); - - r3 = ((uint128_t) f0_2 ) * ((uint128_t) f3); - r3 += ((uint128_t) f1_2 ) * ((uint128_t) f2); - r3 += ((uint128_t) f4_19) * ((uint128_t) f4); - - r4 = ((uint128_t) f0_2 ) * ((uint128_t) f4); - r4 += ((uint128_t) f1_2 ) * ((uint128_t) f3); - r4 += ((uint128_t) f2 ) * ((uint128_t) f2); + r0 = f0 * f0 + f1_38 * f4 + f2_38 * f3; + r1 = f0_2 * f1 + f2_38 * f4 + f3_19 * f3; + r2 = f0_2 * f2 + f1 * f1 + f3_38 * f4; + r3 = f0_2 * f3 + f1_2 * f2 + f4_19 * f4; + r4 = f0_2 * f4 + f1_2 * f3 + f2 * f2; r0 <<= 1; r1 <<= 1; @@ -461,26 +442,26 @@ fe25519_sq2(fe25519 h, const fe25519 f) r4 <<= 1; r00 = ((uint64_t) r0) & mask; - carry = r0 >> 51; + carry = (uint64_t) (r0 >> 51); r1 += carry; r01 = ((uint64_t) r1) & mask; - carry = r1 >> 51; + carry = (uint64_t) (r1 >> 51); r2 += carry; r02 = ((uint64_t) r2) & mask; - carry = r2 >> 51; + carry = (uint64_t) (r2 >> 51); r3 += carry; r03 = ((uint64_t) r3) & mask; - carry = r3 >> 51; + carry = (uint64_t) (r3 >> 51); r4 += carry; r04 = ((uint64_t) r4) & mask; - carry = r4 >> 51; - r00 += 19ULL * (uint64_t) carry; + carry = (uint64_t) (r4 >> 51); + r00 += 19ULL * carry; carry = r00 >> 51; r00 &= mask; - r01 += (uint64_t) carry; + r01 += carry; carry = r01 >> 51; r01 &= mask; - r02 += (uint64_t) carry; + r02 += carry; h[0] = r00; h[1] = r01; @@ -489,8 +470,8 @@ fe25519_sq2(fe25519 h, const fe25519 f) h[4] = r04; } -static void -fe25519_scalar_product(fe25519 h, const fe25519 f, uint32_t n) +static inline void +fe25519_mul32(fe25519 h, const fe25519 f, uint32_t n) { const uint64_t mask = 0x7ffffffffffffULL; uint128_t a; diff --git a/libs/libsodium/src/include/sodium/private/implementations.h b/libs/libsodium/src/include/sodium/private/implementations.h index 926c3a61a6..b322dbadf3 100644 --- a/libs/libsodium/src/include/sodium/private/implementations.h +++ b/libs/libsodium/src/include/sodium/private/implementations.h @@ -1,11 +1,15 @@ #ifndef implementations_H #define implementations_H +#include "private/quirks.h" + int _crypto_generichash_blake2b_pick_best_implementation(void); int _crypto_onetimeauth_poly1305_pick_best_implementation(void); int _crypto_pwhash_argon2_pick_best_implementation(void); int _crypto_scalarmult_curve25519_pick_best_implementation(void); int _crypto_stream_chacha20_pick_best_implementation(void); int _crypto_stream_salsa20_pick_best_implementation(void); +int _crypto_aead_aegis128l_pick_best_implementation(void); +int _crypto_aead_aegis256_pick_best_implementation(void); #endif diff --git a/libs/libsodium/src/include/sodium/private/mutex.h b/libs/libsodium/src/include/sodium/private/mutex.h index 03433173eb..0e198c7aa0 100644 --- a/libs/libsodium/src/include/sodium/private/mutex.h +++ b/libs/libsodium/src/include/sodium/private/mutex.h @@ -1,6 +1,8 @@ #ifndef mutex_H #define mutex_H 1 +#include "private/quirks.h" + extern int sodium_crit_enter(void); extern int sodium_crit_leave(void); diff --git a/libs/libsodium/src/include/sodium/private/quirks.h b/libs/libsodium/src/include/sodium/private/quirks.h new file mode 100644 index 0000000000..ffd861ee43 --- /dev/null +++ b/libs/libsodium/src/include/sodium/private/quirks.h @@ -0,0 +1,87 @@ +/* This is an automatically generated file */ + +#ifndef quirks_H +#ifndef NO_QUIRKS + +#define argon2_ctx _sodium_argon2_ctx +#define argon2_decode_string _sodium_argon2_decode_string +#define argon2_encode_string _sodium_argon2_encode_string +#define argon2_fill_memory_blocks _sodium_argon2_fill_memory_blocks +#define argon2_fill_segment_avx2 _sodium_argon2_fill_segment_avx2 +#define argon2_fill_segment_avx512f _sodium_argon2_fill_segment_avx512f +#define argon2_fill_segment_ref _sodium_argon2_fill_segment_ref +#define argon2_fill_segment_ssse3 _sodium_argon2_fill_segment_ssse3 +#define argon2_finalize _sodium_argon2_finalize +#define argon2_hash _sodium_argon2_hash +#define argon2_initialize _sodium_argon2_initialize +#define argon2_validate_inputs _sodium_argon2_validate_inputs +#define argon2_verify _sodium_argon2_verify +#define argon2i_hash_encoded _sodium_argon2i_hash_encoded +#define argon2i_hash_raw _sodium_argon2i_hash_raw +#define argon2i_verify _sodium_argon2i_verify +#define argon2id_hash_encoded _sodium_argon2id_hash_encoded +#define argon2id_hash_raw _sodium_argon2id_hash_raw +#define argon2id_verify _sodium_argon2id_verify +#define blake2b _sodium_blake2b +#define blake2b_compress_avx2 _sodium_blake2b_compress_avx2 +#define blake2b_compress_ref _sodium_blake2b_compress_ref +#define blake2b_compress_sse41 _sodium_blake2b_compress_sse41 +#define blake2b_compress_ssse3 _sodium_blake2b_compress_ssse3 +#define blake2b_final _sodium_blake2b_final +#define blake2b_init _sodium_blake2b_init +#define blake2b_init_key _sodium_blake2b_init_key +#define blake2b_init_key_salt_personal _sodium_blake2b_init_key_salt_personal +#define blake2b_init_param _sodium_blake2b_init_param +#define blake2b_init_salt_personal _sodium_blake2b_init_salt_personal +#define blake2b_long _sodium_blake2b_long +#define blake2b_pick_best_implementation _sodium_blake2b_pick_best_implementation +#define blake2b_salt_personal _sodium_blake2b_salt_personal +#define blake2b_update _sodium_blake2b_update +#define core_h2c_string_to_hash _sodium_core_h2c_string_to_hash +#define escrypt_PBKDF2_SHA256 _sodium_escrypt_PBKDF2_SHA256 +#define escrypt_alloc_region _sodium_escrypt_alloc_region +#define escrypt_free_local _sodium_escrypt_free_local +#define escrypt_free_region _sodium_escrypt_free_region +#define escrypt_gensalt_r _sodium_escrypt_gensalt_r +#define escrypt_init_local _sodium_escrypt_init_local +#define escrypt_kdf_nosse _sodium_escrypt_kdf_nosse +#define escrypt_kdf_sse _sodium_escrypt_kdf_sse +#define escrypt_parse_setting _sodium_escrypt_parse_setting +#define escrypt_r _sodium_escrypt_r +#define fe25519_frombytes _sodium_fe25519_frombytes +#define fe25519_invert _sodium_fe25519_invert +#define fe25519_tobytes _sodium_fe25519_tobytes +#define ge25519_clear_cofactor _sodium_ge25519_clear_cofactor +#define ge25519_double_scalarmult_vartime _sodium_ge25519_double_scalarmult_vartime +#define ge25519_from_hash _sodium_ge25519_from_hash +#define ge25519_from_string _sodium_ge25519_from_string +#define ge25519_from_string_ro _sodium_ge25519_from_string_ro +#define ge25519_from_uniform _sodium_ge25519_from_uniform +#define ge25519_frombytes _sodium_ge25519_frombytes +#define ge25519_frombytes_negate_vartime _sodium_ge25519_frombytes_negate_vartime +#define ge25519_has_small_order _sodium_ge25519_has_small_order +#define ge25519_is_canonical _sodium_ge25519_is_canonical +#define ge25519_is_on_curve _sodium_ge25519_is_on_curve +#define ge25519_is_on_main_subgroup _sodium_ge25519_is_on_main_subgroup +#define ge25519_p1p1_to_p2 _sodium_ge25519_p1p1_to_p2 +#define ge25519_p1p1_to_p3 _sodium_ge25519_p1p1_to_p3 +#define ge25519_p2_to_p3 _sodium_ge25519_p2_to_p3 +#define ge25519_p3_add _sodium_ge25519_p3_add +#define ge25519_p3_sub _sodium_ge25519_p3_sub +#define ge25519_p3_tobytes _sodium_ge25519_p3_tobytes +#define ge25519_scalarmult _sodium_ge25519_scalarmult +#define ge25519_scalarmult_base _sodium_ge25519_scalarmult_base +#define ge25519_tobytes _sodium_ge25519_tobytes +#define ristretto255_from_hash _sodium_ristretto255_from_hash +#define ristretto255_frombytes _sodium_ristretto255_frombytes +#define ristretto255_p3_tobytes _sodium_ristretto255_p3_tobytes +#define sc25519_invert _sodium_sc25519_invert +#define sc25519_is_canonical _sodium_sc25519_is_canonical +#define sc25519_mul _sodium_sc25519_mul +#define sc25519_muladd _sodium_sc25519_muladd +#define sc25519_negate _sodium_sc25519_negate +#define sc25519_reduce _sodium_sc25519_reduce +#define softaes_block_encrypt _sodium_softaes_block_encrypt + +#endif +#endif diff --git a/libs/libsodium/src/include/sodium/private/softaes.h b/libs/libsodium/src/include/sodium/private/softaes.h new file mode 100644 index 0000000000..f7a2bd24e4 --- /dev/null +++ b/libs/libsodium/src/include/sodium/private/softaes.h @@ -0,0 +1,56 @@ +#ifndef softaes_H +#define softaes_H 1 + +#include + +#include "private/common.h" + +typedef struct SoftAesBlock { + uint32_t w0; + uint32_t w1; + uint32_t w2; + uint32_t w3; +} SoftAesBlock; + +SoftAesBlock softaes_block_encrypt(const SoftAesBlock block, const SoftAesBlock rk); + +static inline SoftAesBlock +softaes_block_load(const uint8_t in[16]) +{ + const SoftAesBlock out = { LOAD32_LE(in + 0), LOAD32_LE(in + 4), LOAD32_LE(in + 8), + LOAD32_LE(in + 12) }; + return out; +} + +static inline SoftAesBlock +softaes_block_load64x2(const uint64_t a, const uint64_t b) +{ + const SoftAesBlock out = { (uint32_t) b, (uint32_t) (b >> 32), (uint32_t) a, + (uint32_t) (a >> 32) }; + return out; +} + +static inline void +softaes_block_store(uint8_t out[16], const SoftAesBlock in) +{ + STORE32_LE(out + 0, in.w0); + STORE32_LE(out + 4, in.w1); + STORE32_LE(out + 8, in.w2); + STORE32_LE(out + 12, in.w3); +} + +static inline SoftAesBlock +softaes_block_xor(const SoftAesBlock a, const SoftAesBlock b) +{ + const SoftAesBlock out = { a.w0 ^ b.w0, a.w1 ^ b.w1, a.w2 ^ b.w2, a.w3 ^ b.w3 }; + return out; +} + +static inline SoftAesBlock +softaes_block_and(const SoftAesBlock a, const SoftAesBlock b) +{ + const SoftAesBlock out = { a.w0 & b.w0, a.w1 & b.w1, a.w2 & b.w2, a.w3 & b.w3 }; + return out; +} + +#endif diff --git a/libs/libsodium/src/include/sodium/private/sse2_64_32.h b/libs/libsodium/src/include/sodium/private/sse2_64_32.h index 8c4889a05e..bea6713d1b 100644 --- a/libs/libsodium/src/include/sodium/private/sse2_64_32.h +++ b/libs/libsodium/src/include/sodium/private/sse2_64_32.h @@ -1,7 +1,7 @@ #ifndef sse2_64_32_H #define sse2_64_32_H 1 -#include "common.h" +#include "private/common.h" #ifdef HAVE_INTRIN_H # include @@ -9,7 +9,7 @@ #if defined(HAVE_EMMINTRIN_H) && \ !(defined(__amd64) || defined(__amd64__) || defined(__x86_64__) || \ - defined(_M_X64) || defined(_M_AMD64)) + defined(_M_X64)) # include # include diff --git a/libs/libsodium/src/include/sodium/randombytes.h b/libs/libsodium/src/include/sodium/randombytes.h index 47dc62f63e..8bb4c62a6b 100644 --- a/libs/libsodium/src/include/sodium/randombytes.h +++ b/libs/libsodium/src/include/sodium/randombytes.h @@ -53,7 +53,7 @@ SODIUM_EXPORT int randombytes_close(void); SODIUM_EXPORT -int randombytes_set_implementation(randombytes_implementation *impl) +int randombytes_set_implementation(const randombytes_implementation *impl) __attribute__ ((nonnull)); SODIUM_EXPORT diff --git a/libs/libsodium/src/include/sodium/randombytes_internal_random.h b/libs/libsodium/src/include/sodium/randombytes_internal_random.h new file mode 100644 index 0000000000..2b2b7d6edc --- /dev/null +++ b/libs/libsodium/src/include/sodium/randombytes_internal_random.h @@ -0,0 +1,22 @@ + +#ifndef randombytes_internal_random_H +#define randombytes_internal_random_H + +#include "export.h" +#include "randombytes.h" + +#ifdef __cplusplus +extern "C" { +#endif + +SODIUM_EXPORT +extern struct randombytes_implementation randombytes_internal_implementation; + +/* Backwards compatibility with libsodium < 1.0.18 */ +#define randombytes_salsa20_implementation randombytes_internal_implementation + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libs/libsodium/src/include/sodium/randombytes_nativeclient.h b/libs/libsodium/src/include/sodium/randombytes_nativeclient.h deleted file mode 100644 index ba014929e4..0000000000 --- a/libs/libsodium/src/include/sodium/randombytes_nativeclient.h +++ /dev/null @@ -1,23 +0,0 @@ - -#ifndef randombytes_nativeclient_H -#define randombytes_nativeclient_H - -#ifdef __native_client__ - -# include "export.h" -# include "randombytes.h" - -# ifdef __cplusplus -extern "C" { -# endif - -SODIUM_EXPORT -extern struct randombytes_implementation randombytes_nativeclient_implementation; - -# ifdef __cplusplus -} -# endif - -#endif - -#endif diff --git a/libs/libsodium/src/include/sodium/randombytes_salsa20_random.h b/libs/libsodium/src/include/sodium/randombytes_salsa20_random.h deleted file mode 100644 index d3a1da6ad5..0000000000 --- a/libs/libsodium/src/include/sodium/randombytes_salsa20_random.h +++ /dev/null @@ -1,19 +0,0 @@ - -#ifndef randombytes_salsa20_random_H -#define randombytes_salsa20_random_H - -#include "export.h" -#include "randombytes.h" - -#ifdef __cplusplus -extern "C" { -#endif - -SODIUM_EXPORT -extern struct randombytes_implementation randombytes_salsa20_implementation; - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/libs/libsodium/src/include/sodium/runtime.h b/libs/libsodium/src/include/sodium/runtime.h index 4cd8c2c499..85228bd840 100644 --- a/libs/libsodium/src/include/sodium/runtime.h +++ b/libs/libsodium/src/include/sodium/runtime.h @@ -11,6 +11,9 @@ extern "C" { SODIUM_EXPORT_WEAK int sodium_runtime_has_neon(void); +SODIUM_EXPORT_WEAK +int sodium_runtime_has_armcrypto(void); + SODIUM_EXPORT_WEAK int sodium_runtime_has_sse2(void); diff --git a/libs/libsodium/src/include/sodium/utils.h b/libs/libsodium/src/include/sodium/utils.h index 8054e1ab4a..655431bf56 100644 --- a/libs/libsodium/src/include/sodium/utils.h +++ b/libs/libsodium/src/include/sodium/utils.h @@ -19,7 +19,7 @@ extern "C" { #endif SODIUM_EXPORT -void sodium_memzero(void * const pnt, const size_t len) __attribute__ ((nonnull)); +void sodium_memzero(void * const pnt, const size_t len); SODIUM_EXPORT void sodium_stackzero(const size_t len); @@ -32,7 +32,7 @@ void sodium_stackzero(const size_t len); */ SODIUM_EXPORT int sodium_memcmp(const void * const b1_, const void * const b2_, size_t len) - __attribute__ ((warn_unused_result)) __attribute__ ((nonnull)); + __attribute__ ((warn_unused_result)); /* * sodium_compare() returns -1 if b1_ < b2_, 1 if b1_ > b2_ and 0 if b1_ == b2_ @@ -42,8 +42,7 @@ int sodium_memcmp(const void * const b1_, const void * const b2_, size_t len) */ SODIUM_EXPORT int sodium_compare(const unsigned char *b1_, const unsigned char *b2_, - size_t len) - __attribute__ ((warn_unused_result)) __attribute__ ((nonnull)); + size_t len) __attribute__ ((warn_unused_result)); SODIUM_EXPORT int sodium_is_zero(const unsigned char *n, const size_t nlen); @@ -52,24 +51,22 @@ SODIUM_EXPORT void sodium_increment(unsigned char *n, const size_t nlen); SODIUM_EXPORT -void sodium_add(unsigned char *a, const unsigned char *b, const size_t len) - __attribute__ ((nonnull)); +void sodium_add(unsigned char *a, const unsigned char *b, const size_t len); SODIUM_EXPORT -void sodium_sub(unsigned char *a, const unsigned char *b, const size_t len) - __attribute__ ((nonnull)); +void sodium_sub(unsigned char *a, const unsigned char *b, const size_t len); SODIUM_EXPORT char *sodium_bin2hex(char * const hex, const size_t hex_maxlen, const unsigned char * const bin, const size_t bin_len) - __attribute__ ((nonnull)); + __attribute__ ((nonnull(1))); SODIUM_EXPORT int sodium_hex2bin(unsigned char * const bin, const size_t bin_maxlen, const char * const hex, const size_t hex_len, const char * const ignore, size_t * const bin_len, const char ** const hex_end) - __attribute__ ((nonnull(1, 3))); + __attribute__ ((nonnull(1))); #define sodium_base64_VARIANT_ORIGINAL 1 #define sodium_base64_VARIANT_ORIGINAL_NO_PADDING 3 @@ -91,14 +88,14 @@ size_t sodium_base64_encoded_len(const size_t bin_len, const int variant); SODIUM_EXPORT char *sodium_bin2base64(char * const b64, const size_t b64_maxlen, const unsigned char * const bin, const size_t bin_len, - const int variant) __attribute__ ((nonnull)); + const int variant) __attribute__ ((nonnull(1))); SODIUM_EXPORT int sodium_base642bin(unsigned char * const bin, const size_t bin_maxlen, const char * const b64, const size_t b64_len, const char * const ignore, size_t * const bin_len, const char ** const b64_end, const int variant) - __attribute__ ((nonnull(1, 3))); + __attribute__ ((nonnull(1))); SODIUM_EXPORT int sodium_mlock(void * const addr, const size_t len) @@ -137,7 +134,7 @@ int sodium_munlock(void * const addr, const size_t len) * either 357 or 361 bytes. For this reason, when using sodium_malloc() to * allocate a crypto_generichash_state structure, padding must be added in * order to ensure proper alignment. crypto_generichash_statebytes() - * returns the rounded up structure size, and should be prefered to sizeof(): + * returns the rounded up structure size, and should be preferred to sizeof(): * state = sodium_malloc(crypto_generichash_statebytes()); */ diff --git a/libs/libsodium/src/include/sodium/version.h b/libs/libsodium/src/include/sodium/version.h index 8dce217855..18ec63f3bc 100644 --- a/libs/libsodium/src/include/sodium/version.h +++ b/libs/libsodium/src/include/sodium/version.h @@ -4,10 +4,11 @@ #include "export.h" -#define SODIUM_VERSION_STRING "1.0.17" +#define SODIUM_VERSION_STRING "1.0.21" + +#define SODIUM_LIBRARY_VERSION_MAJOR 28 +#define SODIUM_LIBRARY_VERSION_MINOR 0 -#define SODIUM_LIBRARY_VERSION_MAJOR 10 -#define SODIUM_LIBRARY_VERSION_MINOR 2 #ifdef __cplusplus extern "C" { diff --git a/libs/libsodium/src/include/sodium/version.h.in b/libs/libsodium/src/include/sodium/version.h.in new file mode 100644 index 0000000000..8a72044b4b --- /dev/null +++ b/libs/libsodium/src/include/sodium/version.h.in @@ -0,0 +1,33 @@ + +#ifndef sodium_version_H +#define sodium_version_H + +#include "export.h" + +#define SODIUM_VERSION_STRING "@VERSION@" + +#define SODIUM_LIBRARY_VERSION_MAJOR @SODIUM_LIBRARY_VERSION_MAJOR@ +#define SODIUM_LIBRARY_VERSION_MINOR @SODIUM_LIBRARY_VERSION_MINOR@ +@SODIUM_LIBRARY_MINIMAL_DEF@ + +#ifdef __cplusplus +extern "C" { +#endif + +SODIUM_EXPORT +const char *sodium_version_string(void); + +SODIUM_EXPORT +int sodium_library_version_major(void); + +SODIUM_EXPORT +int sodium_library_version_minor(void); + +SODIUM_EXPORT +int sodium_library_minimal(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libs/libsodium/src/randombytes/internal/randombytes_internal_random.c b/libs/libsodium/src/randombytes/internal/randombytes_internal_random.c new file mode 100644 index 0000000000..00bb703380 --- /dev/null +++ b/libs/libsodium/src/randombytes/internal/randombytes_internal_random.c @@ -0,0 +1,667 @@ + +#include +#include +#include +#include +#include +#include +#include +#include +#if !defined(_MSC_VER) && !defined(__BORLANDC__) +# include +#endif + +#include +#ifndef _WIN32 +# include +# include +#endif +#ifdef __linux__ +# define _LINUX_SOURCE +#endif +#ifdef HAVE_SYS_RANDOM_H +# include +#endif +#ifdef __linux__ +# ifdef HAVE_GETRANDOM +# define HAVE_LINUX_COMPATIBLE_GETRANDOM +# else +# include +# if defined(SYS_getrandom) && defined(__NR_getrandom) +# define getrandom(B, S, F) syscall(SYS_getrandom, (B), (int) (S), (F)) +# define HAVE_LINUX_COMPATIBLE_GETRANDOM +# endif +# endif +#elif defined(__midipix__) +# define HAVE_LINUX_COMPATIBLE_GETRANDOM +#elif defined(__FreeBSD__) +# include +# if defined(__FreeBSD_version) && __FreeBSD_version >= 1200000 +# define HAVE_LINUX_COMPATIBLE_GETRANDOM +# endif +#endif +#ifdef HAVE_COMMONCRYPTO_COMMONRANDOM_H +# include +#endif +#if !defined(NO_BLOCKING_RANDOM_POLL) && defined(__linux__) +# define BLOCK_ON_DEV_RANDOM +#endif +#ifdef BLOCK_ON_DEV_RANDOM +# include +#endif +#ifdef HAVE_RDRAND +# ifdef __clang__ +# pragma clang attribute push(__attribute__((target("rdrnd"))), apply_to = function) +# elif defined(__GNUC__) +# pragma GCC target("rdrnd") +# endif +# include +#endif + +#include "core.h" +#include "crypto_core_hchacha20.h" +#include "crypto_stream_chacha20.h" +#include "private/common.h" +#include "randombytes.h" +#include "randombytes_internal_random.h" +#include "runtime.h" +#include "utils.h" + +#ifdef _WIN32 +# include +# include +# define RtlGenRandom SystemFunction036 +# if defined(__cplusplus) +extern "C" +# endif +BOOLEAN NTAPI RtlGenRandom(PVOID RandomBuffer, ULONG RandomBufferLength); +# pragma comment(lib, "advapi32.lib") +# ifdef __BORLANDC__ +# define _ftime ftime +# define _timeb timeb +# endif +#endif + +#define INTERNAL_RANDOM_BLOCK_SIZE crypto_core_hchacha20_OUTPUTBYTES + +#if defined(__OpenBSD__) || defined(__CloudABI__) || defined(__wasi__) +# define HAVE_SAFE_ARC4RANDOM 1 +#endif +#if defined(__CloudABI__) || defined(__wasm__) +# define NONEXISTENT_DEV_RANDOM 1 +#endif + +#ifndef SSIZE_MAX +# define SSIZE_MAX (SIZE_MAX / 2 - 1) +#endif +#ifndef S_ISNAM +# ifdef __COMPCERT__ +# define S_ISNAM(X) 1 +# else +# define S_ISNAM(X) 0 +# endif +#endif + +#if !defined(TLS) && !defined(__STDC_NO_THREADS__) && \ + defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L +# define TLS _Thread_local +#endif +#ifndef TLS +# ifdef _WIN32 +# define TLS __declspec(thread) +# else +# define TLS +# endif +#endif + +typedef struct InternalRandomGlobal_ { + int initialized; + int random_data_source_fd; + int getentropy_available; + int getrandom_available; + int rdrand_available; +#ifdef HAVE_GETPID + pid_t pid; +#endif +} InternalRandomGlobal; + +typedef struct InternalRandom_ { + int initialized; + size_t rnd32_outleft; + unsigned char key[crypto_stream_chacha20_KEYBYTES]; + unsigned char rnd32[16U * INTERNAL_RANDOM_BLOCK_SIZE]; + uint64_t nonce; +} InternalRandom; + +static InternalRandomGlobal global = { + SODIUM_C99(.initialized =) 0, + SODIUM_C99(.random_data_source_fd =) -1 +}; + +static TLS InternalRandom stream = { + SODIUM_C99(.initialized =) 0, + SODIUM_C99(.rnd32_outleft =) (size_t) 0U +}; + + +/* + * Get a high-resolution timestamp, as a uint64_t value + */ + +#ifdef _WIN32 +static uint64_t +sodium_hrtime(void) +{ + struct _timeb tb; +# pragma warning(push) +# pragma warning(disable: 4996) + _ftime(&tb); +# pragma warning(pop) + return ((uint64_t) tb.time) * 1000000U + ((uint64_t) tb.millitm) * 1000U; +} + +#else /* _WIN32 */ + +static uint64_t +sodium_hrtime(void) +{ + struct timeval tv; + + if (gettimeofday(&tv, NULL) != 0) { + sodium_misuse(); /* LCOV_EXCL_LINE */ + } + return ((uint64_t) tv.tv_sec) * 1000000U + (uint64_t) tv.tv_usec; +} +#endif /* _WIN32 */ + +/* + * Initialize the entropy source + */ + +#ifdef _WIN32 + +static void +randombytes_internal_random_init(void) +{ + global.rdrand_available = sodium_runtime_has_rdrand(); +} + +#else /* _WIN32 */ + +# ifdef HAVE_COMMONCRYPTO_COMMONRANDOM_H +static int +randombytes_getentropy(void * const buf, const size_t size) +{ + if (CCRandomGenerateBytes(buf, size) != kCCSuccess) { + return -1; + } + return 0; +} + +# elif defined(HAVE_GETENTROPY) + +static int +_randombytes_getentropy(void * const buf, const size_t size) +{ + assert(size <= 256U); + /* LCOV_EXCL_START */ + if (&getentropy == NULL) { + errno = ENOSYS; + return -1; + } + /* LCOV_EXCL_END */ + if (getentropy(buf, size) != 0) { + return -1; /* LCOV_EXCL_LINE */ + } + return 0; +} + +static int +randombytes_getentropy(void * const buf_, size_t size) +{ + unsigned char *buf = (unsigned char *) buf_; + size_t chunk_size = 256U; + + do { + if (size < chunk_size) { + chunk_size = size; + assert(chunk_size > (size_t) 0U); + } + if (_randombytes_getentropy(buf, chunk_size) != 0) { + return -1; /* LCOV_EXCL_LINE */ + } + size -= chunk_size; + buf += chunk_size; + } while (size > (size_t) 0U); + + return 0; +} + +# elif defined(HAVE_LINUX_COMPATIBLE_GETRANDOM) + +static int +_randombytes_linux_getrandom(void * const buf, const size_t size) +{ + int readnb; + + assert(size <= 256U); + do { + readnb = getrandom(buf, size, 0); + } while (readnb < 0 && (errno == EINTR || errno == EAGAIN)); + + return (readnb == (int) size) - 1; +} + +static int +randombytes_linux_getrandom(void * const buf_, size_t size) +{ + unsigned char *buf = (unsigned char *) buf_; + size_t chunk_size = 256U; + + do { + if (size < chunk_size) { + chunk_size = size; + assert(chunk_size > (size_t) 0U); + } + if (_randombytes_linux_getrandom(buf, chunk_size) != 0) { + return -1; + } + size -= chunk_size; + buf += chunk_size; + } while (size > (size_t) 0U); + + return 0; +} +# endif + +# ifndef NONEXISTENT_DEV_RANDOM + +# ifdef BLOCK_ON_DEV_RANDOM +static int +randombytes_block_on_dev_random(void) +{ + struct pollfd pfd; + int fd; + int pret; + + fd = open("/dev/random", O_RDONLY); + if (fd == -1) { + return 0; + } + pfd.fd = fd; + pfd.events = POLLIN; + pfd.revents = 0; + do { + pret = poll(&pfd, 1, -1); + } while (pret < 0 && (errno == EINTR || errno == EAGAIN)); + if (pret != 1) { + (void) close(fd); + errno = EIO; + return -1; + } + return close(fd); +} +# endif + +/* LCOV_EXCL_START */ +static int +randombytes_internal_random_random_dev_open(void) +{ + struct stat st; + static const char *devices[] = { +# ifndef USE_BLOCKING_RANDOM + "/dev/urandom", +# endif + "/dev/random", NULL + }; + const char **device = devices; + int fd; + +# ifdef BLOCK_ON_DEV_RANDOM + if (randombytes_block_on_dev_random() != 0) { + return -1; + } +# endif + do { + fd = open(*device, O_RDONLY); + if (fd != -1) { + if (fstat(fd, &st) == 0 && (S_ISNAM(st.st_mode) || S_ISCHR(st.st_mode))) { +# if defined(F_SETFD) && defined(FD_CLOEXEC) + (void) fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | FD_CLOEXEC); +# endif + return fd; + } + (void) close(fd); + } else if (errno == EINTR) { + continue; + } + device++; + } while (*device != NULL); + + errno = EIO; + return -1; +} +/* LCOV_EXCL_STOP */ + +static ssize_t +safe_read(const int fd, void * const buf_, size_t size) +{ + unsigned char *buf = (unsigned char *) buf_; + ssize_t readnb; + + assert(size > (size_t) 0U); + assert(size <= SSIZE_MAX); + do { + while ((readnb = read(fd, buf, size)) < (ssize_t) 0 && + (errno == EINTR || errno == EAGAIN)); /* LCOV_EXCL_LINE */ + if (readnb < (ssize_t) 0) { + return readnb; /* LCOV_EXCL_LINE */ + } + if (readnb == (ssize_t) 0) { + break; /* LCOV_EXCL_LINE */ + } + size -= (size_t) readnb; + buf += readnb; + } while (size > (ssize_t) 0); + + return (ssize_t) (buf - (unsigned char *) buf_); +} + +# endif /* !NONEXISTENT_DEV_RANDOM */ + +static void +randombytes_internal_random_init(void) +{ + const int errno_save = errno; + + global.rdrand_available = sodium_runtime_has_rdrand(); + global.getentropy_available = 0; + global.getrandom_available = 0; + +# ifdef HAVE_GETENTROPY + { + unsigned char fodder[16]; + + if (randombytes_getentropy(fodder, sizeof fodder) == 0) { + global.getentropy_available = 1; + errno = errno_save; + return; + } + } +# elif defined(HAVE_LINUX_COMPATIBLE_GETRANDOM) + { + unsigned char fodder[16]; + + if (randombytes_linux_getrandom(fodder, sizeof fodder) == 0) { + global.getrandom_available = 1; + errno = errno_save; + return; + } + } +# endif +/* LCOV_EXCL_START */ +# if !defined(NONEXISTENT_DEV_RANDOM) + assert((global.getentropy_available | global.getrandom_available) == 0); + if ((global.random_data_source_fd = + randombytes_internal_random_random_dev_open()) == -1) { + sodium_misuse(); /* LCOV_EXCL_LINE */ + } + errno = errno_save; + return; +# endif +/* LCOV_EXCL_STOP */ +# ifndef HAVE_SAFE_ARC4RANDOM + sodium_misuse(); +# endif +} + +#endif /* _WIN32 */ + +/* + * (Re)seed the generator using the entropy source + */ + +static void +randombytes_internal_random_stir(void) +{ + stream.nonce = sodium_hrtime(); + assert(stream.nonce != (uint64_t) 0U); + memset(stream.rnd32, 0, sizeof stream.rnd32); + stream.rnd32_outleft = (size_t) 0U; + if (global.initialized == 0) { + randombytes_internal_random_init(); + global.initialized = 1; + } +#ifdef HAVE_GETPID + global.pid = getpid(); +#endif + +#ifndef _WIN32 + +# ifdef HAVE_GETENTROPY + if (global.getentropy_available != 0) { + if (randombytes_getentropy(stream.key, sizeof stream.key) != 0) { + sodium_misuse(); /* LCOV_EXCL_LINE */ + } + } +# elif defined(HAVE_LINUX_COMPATIBLE_GETRANDOM) + if (global.getrandom_available != 0) { + if (randombytes_linux_getrandom(stream.key, sizeof stream.key) != 0) { + sodium_misuse(); /* LCOV_EXCL_LINE */ + } + } +# elif defined(NONEXISTENT_DEV_RANDOM) && defined(HAVE_SAFE_ARC4RANDOM) + arc4random_buf(stream.key, sizeof stream.key); +# elif !defined(NONEXISTENT_DEV_RANDOM) + if (global.random_data_source_fd == -1 || + safe_read(global.random_data_source_fd, stream.key, + sizeof stream.key) != (ssize_t) sizeof stream.key) { + sodium_misuse(); /* LCOV_EXCL_LINE */ + } +# else + sodium_misuse(); +# endif + +#else /* _WIN32 */ + if (! RtlGenRandom((PVOID) stream.key, (ULONG) sizeof stream.key)) { + sodium_misuse(); /* LCOV_EXCL_LINE */ + } +#endif + + stream.initialized = 1; +} + +/* + * Reseed the generator if it hasn't been initialized yet + */ + +static void +randombytes_internal_random_stir_if_needed(void) +{ +#ifdef HAVE_GETPID + if (stream.initialized == 0) { + randombytes_internal_random_stir(); + } else if (global.pid != getpid()) { + sodium_misuse(); /* LCOV_EXCL_LINE */ + } +#else + if (stream.initialized == 0) { + randombytes_internal_random_stir(); + } +#endif +} + +/* + * Close the stream, free global resources + */ + +#ifdef _WIN32 +static int +randombytes_internal_random_close(void) +{ + int ret = -1; + + if (global.initialized != 0) { + global.initialized = 0; + ret = 0; + } + sodium_memzero(&stream, sizeof stream); + + return ret; +} +#else +static int +randombytes_internal_random_close(void) +{ + int ret = -1; + +# ifdef HAVE_GETENTROPY + if (global.getentropy_available != 0) { + ret = 0; + } +# elif defined(HAVE_LINUX_COMPATIBLE_GETRANDOM) + if (global.getrandom_available != 0) { + ret = 0; + } +# elif !defined(NONEXISTENT_DEV_RANDOM) && defined(HAVE_SAFE_ARC4RANDOM) + ret = 0; +# else + if (global.random_data_source_fd != -1 && + close(global.random_data_source_fd) == 0) { + global.random_data_source_fd = -1; + global.initialized = 0; +# ifdef HAVE_GETPID + global.pid = (pid_t) 0; +# endif + ret = 0; + } +# endif + + sodium_memzero(&stream, sizeof stream); + + return ret; +} +#endif + +/* + * RDRAND is only used to mitigate prediction if a key is compromised + */ + +static void +randombytes_internal_random_xorhwrand(void) +{ +/* LCOV_EXCL_START */ +#ifdef HAVE_RDRAND + unsigned int r; + + if (global.rdrand_available == 0) { + return; + } + (void) _rdrand32_step(&r); + * (uint32_t *) (void *) + &stream.key[crypto_stream_chacha20_KEYBYTES - 4] ^= (uint32_t) r; +#endif +/* LCOV_EXCL_STOP */ +} + +/* + * XOR the key with another same-length secret + */ + +static inline void +randombytes_internal_random_xorkey(const unsigned char * const mix) +{ + unsigned char *key = stream.key; + size_t i; + + for (i = (size_t) 0U; i < sizeof stream.key; i++) { + key[i] ^= mix[i]; + } +} + +/* + * Put `size` random bytes into `buf` and overwrite the key + */ + +static void +randombytes_internal_random_buf(void * const buf, const size_t size) +{ + size_t i; + int ret; + + randombytes_internal_random_stir_if_needed(); + COMPILER_ASSERT(sizeof stream.nonce == crypto_stream_chacha20_NONCEBYTES); +#if defined(ULLONG_MAX) && defined(SIZE_MAX) +# if SIZE_MAX > ULLONG_MAX + /* coverity[result_independent_of_operands] */ + assert(size <= ULLONG_MAX); +# endif +#endif + ret = crypto_stream_chacha20((unsigned char *) buf, (unsigned long long) size, + (unsigned char *) &stream.nonce, stream.key); + assert(ret == 0); + for (i = 0U; i < sizeof size; i++) { + stream.key[i] ^= ((const unsigned char *) (const void *) &size)[i]; + } + randombytes_internal_random_xorhwrand(); + stream.nonce++; + crypto_stream_chacha20_xor(stream.key, stream.key, sizeof stream.key, + (unsigned char *) &stream.nonce, stream.key); +} + +/* + * Pop a 32-bit value from the random pool + * + * Overwrite the key after the pool gets refilled. + */ + +static uint32_t +randombytes_internal_random(void) +{ + uint32_t val; + int ret; + + COMPILER_ASSERT(sizeof stream.rnd32 >= (sizeof stream.key) + (sizeof val)); + COMPILER_ASSERT(((sizeof stream.rnd32) - (sizeof stream.key)) + % sizeof val == (size_t) 0U); + if (stream.rnd32_outleft <= (size_t) 0U) { + randombytes_internal_random_stir_if_needed(); + COMPILER_ASSERT(sizeof stream.nonce == crypto_stream_chacha20_NONCEBYTES); + ret = crypto_stream_chacha20((unsigned char *) stream.rnd32, + (unsigned long long) sizeof stream.rnd32, + (unsigned char *) &stream.nonce, + stream.key); + assert(ret == 0); + stream.rnd32_outleft = (sizeof stream.rnd32) - (sizeof stream.key); + randombytes_internal_random_xorhwrand(); + randombytes_internal_random_xorkey(&stream.rnd32[stream.rnd32_outleft]); + memset(&stream.rnd32[stream.rnd32_outleft], 0, sizeof stream.key); + stream.nonce++; + } + stream.rnd32_outleft -= sizeof val; + memcpy(&val, &stream.rnd32[stream.rnd32_outleft], sizeof val); + memset(&stream.rnd32[stream.rnd32_outleft], 0, sizeof val); + + return val; +} + +static const char * +randombytes_internal_implementation_name(void) +{ + return "internal"; +} + +struct randombytes_implementation randombytes_internal_implementation = { + SODIUM_C99(.implementation_name =) randombytes_internal_implementation_name, + SODIUM_C99(.random =) randombytes_internal_random, + SODIUM_C99(.stir =) randombytes_internal_random_stir, + SODIUM_C99(.uniform =) NULL, + SODIUM_C99(.buf =) randombytes_internal_random_buf, + SODIUM_C99(.close =) randombytes_internal_random_close +}; + +#ifdef HAVE_RDRAND +# ifdef __clang__ +# pragma clang attribute pop +# endif +#endif diff --git a/libs/libsodium/src/randombytes/nativeclient/randombytes_nativeclient.c b/libs/libsodium/src/randombytes/nativeclient/randombytes_nativeclient.c deleted file mode 100644 index 93eec1f601..0000000000 --- a/libs/libsodium/src/randombytes/nativeclient/randombytes_nativeclient.c +++ /dev/null @@ -1,61 +0,0 @@ - -#include -#include -#include - -#ifdef __native_client__ -# include - -# include "core.h" -# include "utils.h" -# include "randombytes.h" -# include "randombytes_nativeclient.h" - -static void -randombytes_nativeclient_buf(void * const buf, const size_t size) -{ - unsigned char *buf_ = (unsigned char *) buf; - struct nacl_irt_random rand_intf; - size_t readnb = (size_t) 0U; - size_t toread = size; - - if (nacl_interface_query(NACL_IRT_RANDOM_v0_1, &rand_intf, - sizeof rand_intf) != sizeof rand_intf) { - sodium_misuse(); - } - while (toread > (size_t) 0U) { - if (rand_intf.get_random_bytes(buf_, size, &readnb) != 0 || - readnb > size) { - sodium_misuse(); - } - toread -= readnb; - buf_ += readnb; - } -} - -static uint32_t -randombytes_nativeclient_random(void) -{ - uint32_t r; - - randombytes_nativeclient_buf(&r, sizeof r); - - return r; -} - -static const char * -randombytes_nativeclient_implementation_name(void) -{ - return "nativeclient"; -} - -struct randombytes_implementation randombytes_nativeclient_implementation = { - SODIUM_C99(.implementation_name =) randombytes_nativeclient_implementation_name, - SODIUM_C99(.random =) randombytes_nativeclient_random, - SODIUM_C99(.stir =) NULL, - SODIUM_C99(.uniform =) NULL, - SODIUM_C99(.buf =) randombytes_nativeclient_buf, - SODIUM_C99(.close =) NULL -}; - -#endif diff --git a/libs/libsodium/src/randombytes/randombytes.c b/libs/libsodium/src/randombytes/randombytes.c index 34d9ebb1cd..9e5664a30a 100644 --- a/libs/libsodium/src/randombytes/randombytes.c +++ b/libs/libsodium/src/randombytes/randombytes.c @@ -13,14 +13,11 @@ #include "core.h" #include "crypto_stream_chacha20.h" #include "randombytes.h" -#ifdef RANDOMBYTES_DEFAULT_IMPLEMENTATION -# include "randombytes_default.h" -#else -# ifdef __native_client__ -# include "randombytes_nativeclient.h" -# else -# include "randombytes_sysrandom.h" +#ifndef RANDOMBYTES_CUSTOM_IMPLEMENTATION +# ifdef RANDOMBYTES_DEFAULT_IMPLEMENTATION +# include "randombytes_internal.h" # endif +# include "randombytes_sysrandom.h" #endif #include "private/common.h" @@ -33,64 +30,28 @@ static const randombytes_implementation *implementation; # ifdef __EMSCRIPTEN__ # define RANDOMBYTES_DEFAULT_IMPLEMENTATION NULL # else -# ifdef __native_client__ -# define RANDOMBYTES_DEFAULT_IMPLEMENTATION &randombytes_nativeclient_implementation; -# else -# define RANDOMBYTES_DEFAULT_IMPLEMENTATION &randombytes_sysrandom_implementation; -# endif +# define RANDOMBYTES_DEFAULT_IMPLEMENTATION &randombytes_sysrandom_implementation # endif #endif -static void -randombytes_init_if_needed(void) -{ - if (implementation == NULL) { - implementation = RANDOMBYTES_DEFAULT_IMPLEMENTATION; - randombytes_stir(); - } -} - -int -randombytes_set_implementation(randombytes_implementation *impl) -{ - implementation = impl; - - return 0; -} - -const char * -randombytes_implementation_name(void) +#ifdef __EMSCRIPTEN__ +static const char * +javascript_implementation_name(void) { -#ifndef __EMSCRIPTEN__ - randombytes_init_if_needed(); - return implementation->implementation_name(); -#else return "js"; -#endif } -uint32_t -randombytes_random(void) +static uint32_t +javascript_random(void) { -#ifndef __EMSCRIPTEN__ - randombytes_init_if_needed(); - return implementation->random(); -#else return EM_ASM_INT_V({ return Module.getRandomValue(); }); -#endif } -void -randombytes_stir(void) +static void +javascript_stir(void) { -#ifndef __EMSCRIPTEN__ - randombytes_init_if_needed(); - if (implementation->stir != NULL) { - implementation->stir(); - } -#else EM_ASM({ if (Module.getRandomValue === undefined) { try { @@ -118,7 +79,66 @@ randombytes_stir(void) } } }); +} + +static void +javascript_buf(void * const buf, const size_t size) +{ + unsigned char *p = (unsigned char *) buf; + size_t i; + + for (i = (size_t) 0U; i < size; i++) { + p[i] = (unsigned char) randombytes_random(); + } +} #endif + +static void +randombytes_init_if_needed(void) +{ + if (implementation == NULL) { +#ifdef __EMSCRIPTEN__ + static randombytes_implementation javascript_implementation; + javascript_implementation.implementation_name = javascript_implementation_name; + javascript_implementation.random = javascript_random; + javascript_implementation.stir = javascript_stir; + javascript_implementation.buf = javascript_buf; + implementation = &javascript_implementation; +#else + implementation = RANDOMBYTES_DEFAULT_IMPLEMENTATION; +#endif + randombytes_stir(); + } +} + +int +randombytes_set_implementation(const randombytes_implementation *impl) +{ + implementation = impl; + return 0; +} + +const char * +randombytes_implementation_name(void) +{ + randombytes_init_if_needed(); + return implementation->implementation_name(); +} + +uint32_t +randombytes_random(void) +{ + randombytes_init_if_needed(); + return implementation->random(); +} + +void +randombytes_stir(void) +{ + randombytes_init_if_needed(); + if (implementation->stir != NULL) { + implementation->stir(); + } } uint32_t @@ -127,12 +147,10 @@ randombytes_uniform(const uint32_t upper_bound) uint32_t min; uint32_t r; -#ifndef __EMSCRIPTEN__ randombytes_init_if_needed(); if (implementation->uniform != NULL) { return implementation->uniform(upper_bound); } -#endif if (upper_bound < 2) { return 0; } @@ -149,19 +167,10 @@ randombytes_uniform(const uint32_t upper_bound) void randombytes_buf(void * const buf, const size_t size) { -#ifndef __EMSCRIPTEN__ randombytes_init_if_needed(); if (size > (size_t) 0U) { implementation->buf(buf, size); } -#else - unsigned char *p = (unsigned char *) buf; - size_t i; - - for (i = (size_t) 0U; i < size; i++) { - p[i] = (unsigned char) randombytes_random(); - } -#endif } void diff --git a/libs/libsodium/src/randombytes/salsa20/randombytes_salsa20_random.c b/libs/libsodium/src/randombytes/salsa20/randombytes_salsa20_random.c deleted file mode 100644 index fc4c9b3709..0000000000 --- a/libs/libsodium/src/randombytes/salsa20/randombytes_salsa20_random.c +++ /dev/null @@ -1,569 +0,0 @@ - -#include -#include -#include -#include -#include -#include -#include -#include -#if !defined(_MSC_VER) && !defined(__BORLANDC__) -# include -#endif - -#include -#ifndef _WIN32 -# include -# include -#endif -#ifdef __linux__ -# ifdef __dietlibc__ -# define _LINUX_SOURCE -# include -# define HAVE_LINUX_COMPATIBLE_GETRANDOM -# else /* __dietlibc__ */ -# include -# if defined(SYS_getrandom) && defined(__NR_getrandom) -# define getrandom(B, S, F) syscall(SYS_getrandom, (B), (int) (S), (F)) -# define HAVE_LINUX_COMPATIBLE_GETRANDOM -# endif -# endif /* __dietlibc__ */ -#elif defined(__FreeBSD__) -# include -# if defined(__FreeBSD_version) && __FreeBSD_version >= 1200000 -# include -# define HAVE_LINUX_COMPATIBLE_GETRANDOM -# endif -#endif -#if !defined(NO_BLOCKING_RANDOM_POLL) && defined(__linux__) -# define BLOCK_ON_DEV_RANDOM -#endif -#ifdef BLOCK_ON_DEV_RANDOM -# include -#endif -#ifdef HAVE_RDRAND -# pragma GCC target("rdrnd") -# include -#endif - -#include "core.h" -#include "crypto_core_salsa20.h" -#include "crypto_stream_salsa20.h" -#include "private/common.h" -#include "randombytes.h" -#include "randombytes_salsa20_random.h" -#include "runtime.h" -#include "utils.h" - -#ifdef _WIN32 -# include -# include -# define RtlGenRandom SystemFunction036 -# if defined(__cplusplus) -extern "C" -# endif -BOOLEAN NTAPI RtlGenRandom(PVOID RandomBuffer, ULONG RandomBufferLength); -# pragma comment(lib, "advapi32.lib") -# ifdef __BORLANDC__ -# define _ftime ftime -# define _timeb timeb -# endif -#endif - -#define SALSA20_RANDOM_BLOCK_SIZE crypto_core_salsa20_OUTPUTBYTES - -#if defined(__OpenBSD__) || defined(__CloudABI__) -# define HAVE_SAFE_ARC4RANDOM 1 -#endif - -#ifndef SSIZE_MAX -# define SSIZE_MAX (SIZE_MAX / 2 - 1) -#endif -#ifndef S_ISNAM -# ifdef __COMPCERT__ -# define S_ISNAM(X) 1 -# else -# define S_ISNAM(X) 0 -# endif -#endif - -#ifndef TLS -# ifdef _WIN32 -# define TLS __declspec(thread) -# else -# define TLS -# endif -#endif - -typedef struct Salsa20RandomGlobal_ { - int initialized; - int random_data_source_fd; - int getrandom_available; - int rdrand_available; -#ifdef HAVE_GETPID - pid_t pid; -#endif -} Salsa20RandomGlobal; - -typedef struct Salsa20Random_ { - int initialized; - size_t rnd32_outleft; - unsigned char key[crypto_stream_salsa20_KEYBYTES]; - unsigned char rnd32[16U * SALSA20_RANDOM_BLOCK_SIZE]; - uint64_t nonce; -} Salsa20Random; - -static Salsa20RandomGlobal global = { - SODIUM_C99(.initialized =) 0, - SODIUM_C99(.random_data_source_fd =) -1 -}; - -static TLS Salsa20Random stream = { - SODIUM_C99(.initialized =) 0, - SODIUM_C99(.rnd32_outleft =) (size_t) 0U -}; - - -/* - * Get a high-resolution timestamp, as a uint64_t value - */ - -#ifdef _WIN32 -static uint64_t -sodium_hrtime(void) -{ - struct _timeb tb; -# pragma warning(push) -# pragma warning(disable: 4996) - _ftime(&tb); -# pragma warning(pop) - return ((uint64_t) tb.time) * 1000000U + ((uint64_t) tb.millitm) * 1000U; -} - -#else /* _WIN32 */ - -static uint64_t -sodium_hrtime(void) -{ - struct timeval tv; - - if (gettimeofday(&tv, NULL) != 0) { - sodium_misuse(); /* LCOV_EXCL_LINE */ - } - return ((uint64_t) tv.tv_sec) * 1000000U + (uint64_t) tv.tv_usec; -} -#endif - -/* - * Initialize the entropy source - */ - -#ifdef _WIN32 - -static void -randombytes_salsa20_random_init(void) -{ - global.rdrand_available = sodium_runtime_has_rdrand(); -} - -#else /* _WIN32 */ - -static ssize_t -safe_read(const int fd, void * const buf_, size_t size) -{ - unsigned char *buf = (unsigned char *) buf_; - ssize_t readnb; - - assert(size > (size_t) 0U); - assert(size <= SSIZE_MAX); - do { - while ((readnb = read(fd, buf, size)) < (ssize_t) 0 && - (errno == EINTR || errno == EAGAIN)); /* LCOV_EXCL_LINE */ - if (readnb < (ssize_t) 0) { - return readnb; /* LCOV_EXCL_LINE */ - } - if (readnb == (ssize_t) 0) { - break; /* LCOV_EXCL_LINE */ - } - size -= (size_t) readnb; - buf += readnb; - } while (size > (ssize_t) 0); - - return (ssize_t) (buf - (unsigned char *) buf_); -} - -# ifdef BLOCK_ON_DEV_RANDOM -static int -randombytes_block_on_dev_random(void) -{ - struct pollfd pfd; - int fd; - int pret; - - fd = open("/dev/random", O_RDONLY); - if (fd == -1) { - return 0; - } - pfd.fd = fd; - pfd.events = POLLIN; - pfd.revents = 0; - do { - pret = poll(&pfd, 1, -1); - } while (pret < 0 && (errno == EINTR || errno == EAGAIN)); - if (pret != 1) { - (void) close(fd); - errno = EIO; - return -1; - } - return close(fd); -} -# endif - -# ifndef HAVE_SAFE_ARC4RANDOM -static int -randombytes_salsa20_random_random_dev_open(void) -{ -/* LCOV_EXCL_START */ - struct stat st; - static const char *devices[] = { -# ifndef USE_BLOCKING_RANDOM - "/dev/urandom", -# endif - "/dev/random", NULL - }; - const char **device = devices; - int fd; - -# ifdef BLOCK_ON_DEV_RANDOM - if (randombytes_block_on_dev_random() != 0) { - return -1; - } -# endif - do { - fd = open(*device, O_RDONLY); - if (fd != -1) { - if (fstat(fd, &st) == 0 && (S_ISNAM(st.st_mode) || S_ISCHR(st.st_mode))) { -# if defined(F_SETFD) && defined(FD_CLOEXEC) - (void) fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | FD_CLOEXEC); -# endif - return fd; - } - (void) close(fd); - } else if (errno == EINTR) { - continue; - } - device++; - } while (*device != NULL); - - errno = EIO; - return -1; -/* LCOV_EXCL_STOP */ -} -# endif - -# ifdef HAVE_LINUX_COMPATIBLE_GETRANDOM -static int -_randombytes_linux_getrandom(void * const buf, const size_t size) -{ - int readnb; - - assert(size <= 256U); - do { - readnb = getrandom(buf, size, 0); - } while (readnb < 0 && (errno == EINTR || errno == EAGAIN)); - - return (readnb == (int) size) - 1; -} - -static int -randombytes_linux_getrandom(void * const buf_, size_t size) -{ - unsigned char *buf = (unsigned char *) buf_; - size_t chunk_size = 256U; - - do { - if (size < chunk_size) { - chunk_size = size; - assert(chunk_size > (size_t) 0U); - } - if (_randombytes_linux_getrandom(buf, chunk_size) != 0) { - return -1; - } - size -= chunk_size; - buf += chunk_size; - } while (size > (size_t) 0U); - - return 0; -} -# endif - -static void -randombytes_salsa20_random_init(void) -{ - const int errno_save = errno; - - global.rdrand_available = sodium_runtime_has_rdrand(); - -# ifdef HAVE_SAFE_ARC4RANDOM - errno = errno_save; -# else - -# ifdef HAVE_LINUX_COMPATIBLE_GETRANDOM - { - unsigned char fodder[16]; - - if (randombytes_linux_getrandom(fodder, sizeof fodder) == 0) { - global.getrandom_available = 1; - errno = errno_save; - return; - } - global.getrandom_available = 0; - } -# endif /* HAVE_LINUX_COMPATIBLE_GETRANDOM */ - - if ((global.random_data_source_fd = - randombytes_salsa20_random_random_dev_open()) == -1) { - sodium_misuse(); /* LCOV_EXCL_LINE */ - } - errno = errno_save; -# endif /* HAVE_SAFE_ARC4RANDOM */ -} - -#endif /* _WIN32 */ - -/* - * (Re)seed the generator using the entropy source - */ - -static void -randombytes_salsa20_random_stir(void) -{ - stream.nonce = sodium_hrtime(); - assert(stream.nonce != (uint64_t) 0U); - memset(stream.rnd32, 0, sizeof stream.rnd32); - stream.rnd32_outleft = (size_t) 0U; - if (global.initialized == 0) { - randombytes_salsa20_random_init(); - global.initialized = 1; - } -#ifdef HAVE_GETPID - global.pid = getpid(); -#endif - -#ifndef _WIN32 - -# ifdef HAVE_SAFE_ARC4RANDOM - arc4random_buf(stream.key, sizeof stream.key); -# elif defined(HAVE_LINUX_COMPATIBLE_GETRANDOM) - if (global.getrandom_available != 0) { - if (randombytes_linux_getrandom(stream.key, sizeof stream.key) != 0) { - sodium_misuse(); /* LCOV_EXCL_LINE */ - } - } else if (global.random_data_source_fd == -1 || - safe_read(global.random_data_source_fd, stream.key, - sizeof stream.key) != (ssize_t) sizeof stream.key) { - sodium_misuse(); /* LCOV_EXCL_LINE */ - } -# else - if (global.random_data_source_fd == -1 || - safe_read(global.random_data_source_fd, stream.key, - sizeof stream.key) != (ssize_t) sizeof stream.key) { - sodium_misuse(); /* LCOV_EXCL_LINE */ - } -# endif - -#else /* _WIN32 */ - if (! RtlGenRandom((PVOID) stream.key, (ULONG) sizeof stream.key)) { - sodium_misuse(); /* LCOV_EXCL_LINE */ - } -#endif - - stream.initialized = 1; -} - -/* - * Reseed the generator if it hasn't been initialized yet - */ - -static void -randombytes_salsa20_random_stir_if_needed(void) -{ -#ifdef HAVE_GETPID - if (stream.initialized == 0) { - randombytes_salsa20_random_stir(); - } else if (global.pid != getpid()) { - sodium_misuse(); /* LCOV_EXCL_LINE */ - } -#else - if (stream.initialized == 0) { - randombytes_salsa20_random_stir(); - } -#endif -} - -/* - * Close the stream, free global resources - */ - -#ifdef _WIN32 -static int -randombytes_salsa20_random_close(void) -{ - int ret = -1; - - if (global.initialized != 0) { - global.initialized = 0; - ret = 0; - } - sodium_memzero(&stream, sizeof stream); - - return ret; -} -#else -static int -randombytes_salsa20_random_close(void) -{ - int ret = -1; - - if (global.random_data_source_fd != -1 && - close(global.random_data_source_fd) == 0) { - global.random_data_source_fd = -1; - global.initialized = 0; -# ifdef HAVE_GETPID - global.pid = (pid_t) 0; -# endif - ret = 0; - } - -# ifdef HAVE_SAFE_ARC4RANDOM - ret = 0; -# endif - -# ifdef HAVE_LINUX_COMPATIBLE_GETRANDOM - if (global.getrandom_available != 0) { - ret = 0; - } -# endif - - sodium_memzero(&stream, sizeof stream); - - return ret; -} -#endif - -/* - * RDRAND is only used to mitigate prediction if a key is compromised - */ - -static void -randombytes_salsa20_random_xorhwrand(void) -{ -/* LCOV_EXCL_START */ -#ifdef HAVE_RDRAND - unsigned int r; - - if (global.rdrand_available == 0) { - return; - } - (void) _rdrand32_step(&r); - * (uint32_t *) (void *) - &stream.key[crypto_stream_salsa20_KEYBYTES - 4] ^= (uint32_t) r; -#endif -/* LCOV_EXCL_STOP */ -} - -/* - * XOR the key with another same-length secret - */ - -static inline void -randombytes_salsa20_random_xorkey(const unsigned char * const mix) -{ - unsigned char *key = stream.key; - size_t i; - - for (i = (size_t) 0U; i < sizeof stream.key; i++) { - key[i] ^= mix[i]; - } -} - -/* - * Put `size` random bytes into `buf` and overwrite the key - */ - -static void -randombytes_salsa20_random_buf(void * const buf, const size_t size) -{ - size_t i; - int ret; - - randombytes_salsa20_random_stir_if_needed(); - COMPILER_ASSERT(sizeof stream.nonce == crypto_stream_salsa20_NONCEBYTES); -#if defined(ULLONG_MAX) && defined(SIZE_MAX) -# if SIZE_MAX > ULLONG_MAX - /* coverity[result_independent_of_operands] */ - assert(size <= ULLONG_MAX); -# endif -#endif - ret = crypto_stream_salsa20((unsigned char *) buf, (unsigned long long) size, - (unsigned char *) &stream.nonce, stream.key); - assert(ret == 0); - for (i = 0U; i < sizeof size; i++) { - stream.key[i] ^= ((const unsigned char *) (const void *) &size)[i]; - } - randombytes_salsa20_random_xorhwrand(); - stream.nonce++; - crypto_stream_salsa20_xor(stream.key, stream.key, sizeof stream.key, - (unsigned char *) &stream.nonce, stream.key); -} - -/* - * Pop a 32-bit value from the random pool - * - * Overwrite the key after the pool gets refilled. - */ - -static uint32_t -randombytes_salsa20_random(void) -{ - uint32_t val; - int ret; - - COMPILER_ASSERT(sizeof stream.rnd32 >= (sizeof stream.key) + (sizeof val)); - COMPILER_ASSERT(((sizeof stream.rnd32) - (sizeof stream.key)) - % sizeof val == (size_t) 0U); - if (stream.rnd32_outleft <= (size_t) 0U) { - randombytes_salsa20_random_stir_if_needed(); - COMPILER_ASSERT(sizeof stream.nonce == crypto_stream_salsa20_NONCEBYTES); - ret = crypto_stream_salsa20((unsigned char *) stream.rnd32, - (unsigned long long) sizeof stream.rnd32, - (unsigned char *) &stream.nonce, - stream.key); - assert(ret == 0); - stream.rnd32_outleft = (sizeof stream.rnd32) - (sizeof stream.key); - randombytes_salsa20_random_xorhwrand(); - randombytes_salsa20_random_xorkey(&stream.rnd32[stream.rnd32_outleft]); - memset(&stream.rnd32[stream.rnd32_outleft], 0, sizeof stream.key); - stream.nonce++; - } - stream.rnd32_outleft -= sizeof val; - memcpy(&val, &stream.rnd32[stream.rnd32_outleft], sizeof val); - memset(&stream.rnd32[stream.rnd32_outleft], 0, sizeof val); - - return val; -} - -static const char * -randombytes_salsa20_implementation_name(void) -{ - return "salsa20"; -} - -struct randombytes_implementation randombytes_salsa20_implementation = { - SODIUM_C99(.implementation_name =) randombytes_salsa20_implementation_name, - SODIUM_C99(.random =) randombytes_salsa20_random, - SODIUM_C99(.stir =) randombytes_salsa20_random_stir, - SODIUM_C99(.uniform =) NULL, - SODIUM_C99(.buf =) randombytes_salsa20_random_buf, - SODIUM_C99(.close =) randombytes_salsa20_random_close -}; diff --git a/libs/libsodium/src/randombytes/sysrandom/randombytes_sysrandom.c b/libs/libsodium/src/randombytes/sysrandom/randombytes_sysrandom.c index d1439bf7fc..75fbca9dab 100644 --- a/libs/libsodium/src/randombytes/sysrandom/randombytes_sysrandom.c +++ b/libs/libsodium/src/randombytes/sysrandom/randombytes_sysrandom.c @@ -1,4 +1,3 @@ - #include #include #include @@ -8,29 +7,35 @@ #ifndef _WIN32 # include #endif - #include + #include #ifndef _WIN32 # include # include #endif #ifdef __linux__ -# ifdef __dietlibc__ -# define _LINUX_SOURCE -# include +# define _LINUX_SOURCE +#endif +#ifdef HAVE_SYS_RANDOM_H +# include +#endif +#ifdef __linux__ +# ifdef HAVE_GETRANDOM # define HAVE_LINUX_COMPATIBLE_GETRANDOM -# else /* __dietlibc__ */ +# else # include # if defined(SYS_getrandom) && defined(__NR_getrandom) # define getrandom(B, S, F) syscall(SYS_getrandom, (B), (int) (S), (F)) # define HAVE_LINUX_COMPATIBLE_GETRANDOM # endif -# endif /* __dietlibc */ -#elif defined(__FreeBSD__) +# endif +#elif defined(__midipix__) +# define HAVE_LINUX_COMPATIBLE_GETRANDOM +#elif defined(__FreeBSD__) || defined(__DragonFly__) # include -# if defined(__FreeBSD_version) && __FreeBSD_version >= 1200000 -# include +# if (defined(__FreeBSD_version) && __FreeBSD_version >= 1200000) || \ + (defined(__DragonFly_version) && __DragonFly_version >= 500700) # define HAVE_LINUX_COMPATIBLE_GETRANDOM # endif #endif @@ -72,7 +77,7 @@ BOOLEAN NTAPI RtlGenRandom(PVOID RandomBuffer, ULONG RandomBufferLength); # pragma comment(lib, "advapi32.lib") #endif -#if defined(__OpenBSD__) || defined(__CloudABI__) +#if defined(__OpenBSD__) || defined(__CloudABI__) || defined(__wasi__) # define HAVE_SAFE_ARC4RANDOM 1 #endif @@ -105,7 +110,7 @@ randombytes_sysrandom_close(void) return 0; } -#else /* __OpenBSD__ */ +#else /* HAVE_SAFE_ARC4RANDOM */ typedef struct SysRandom_ { int random_data_source_fd; @@ -375,7 +380,7 @@ randombytes_sysrandom(void) return r; } -#endif /* __OpenBSD__ */ +#endif /* HAVE_SAFE_ARC4RANDOM */ static const char * randombytes_sysrandom_implementation_name(void) diff --git a/libs/libsodium/src/sodium/codecs.c b/libs/libsodium/src/sodium/codecs.c index a3c3fca44a..81b042a7c9 100644 --- a/libs/libsodium/src/sodium/codecs.c +++ b/libs/libsodium/src/sodium/codecs.c @@ -7,6 +7,7 @@ #include #include "core.h" +#include "private/common.h" #include "utils.h" /* Derived from original code by CodesInChaos */ @@ -250,6 +251,7 @@ _sodium_base642bin_skip_padding(const char * const b64, const size_t b64_len, errno = ERANGE; return -1; } + ACQUIRE_FENCE; c = b64[*b64_pos_p]; if (c == '=') { padding_len--; diff --git a/libs/libsodium/src/sodium/core.c b/libs/libsodium/src/sodium/core.c index bdd6a0f1ac..3be531a53b 100644 --- a/libs/libsodium/src/sodium/core.c +++ b/libs/libsodium/src/sodium/core.c @@ -45,6 +45,8 @@ sodium_init(void) _crypto_scalarmult_curve25519_pick_best_implementation(); _crypto_stream_chacha20_pick_best_implementation(); _crypto_stream_salsa20_pick_best_implementation(); + _crypto_aead_aegis128l_pick_best_implementation(); + _crypto_aead_aegis256_pick_best_implementation(); initialized = 1; if (sodium_crit_leave() != 0) { return -1; /* LCOV_EXCL_LINE */ @@ -57,7 +59,7 @@ sodium_init(void) static CRITICAL_SECTION _sodium_lock; static volatile LONG _sodium_lock_initialized; -int +static int _sodium_crit_init(void) { LONG status = 0L; @@ -136,7 +138,7 @@ sodium_crit_leave(void) return pthread_mutex_unlock(&_sodium_lock); } -#elif defined(HAVE_ATOMIC_OPS) && !defined(__EMSCRIPTEN__) && !defined(__native_client__) +#elif defined(HAVE_ATOMIC_OPS) && !defined(__EMSCRIPTEN__) static volatile int _sodium_lock; @@ -151,7 +153,9 @@ sodium_crit_enter(void) # ifdef HAVE_NANOSLEEP (void) nanosleep(&q, NULL); # elif defined(__x86_64__) || defined(__i386__) - __asm__ __volatile__ ("pause"); + __asm__ __volatile__ ("pause":::"memory"); +# elif defined(__aarch64__) || defined(_M_ARM64) + __asm__ __volatile__ ("yield":::"memory"); # endif } return 0; @@ -212,3 +216,15 @@ sodium_set_misuse_handler(void (*handler)(void)) } return 0; } + +#if defined(_WIN32) && !defined(SODIUM_STATIC) +BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved) { + (void) hinstDLL; + (void) lpReserved; + + if (fdwReason == DLL_PROCESS_DETACH && _sodium_lock_initialized == 2) { + DeleteCriticalSection(&_sodium_lock); + } + return TRUE; +} +#endif diff --git a/libs/libsodium/src/sodium/runtime.c b/libs/libsodium/src/sodium/runtime.c index ba8d17da42..d4b2dee109 100644 --- a/libs/libsodium/src/sodium/runtime.c +++ b/libs/libsodium/src/sodium/runtime.c @@ -3,6 +3,14 @@ #ifdef HAVE_ANDROID_GETCPUFEATURES # include #endif +#ifdef __APPLE__ +# include +# include +# include +#endif +#ifdef HAVE_SYS_AUXV_H +# include +#endif #include "private/common.h" #include "runtime.h" @@ -10,6 +18,7 @@ typedef struct CPUFeatures_ { int initialized; int has_neon; + int has_armcrypto; int has_sse2; int has_sse3; int has_ssse3; @@ -48,32 +57,100 @@ static CPUFeatures _cpu_features; static int _sodium_runtime_arm_cpu_features(CPUFeatures * const cpu_features) { -#ifndef __arm__ cpu_features->has_neon = 0; - return -1; -#else -# ifdef __APPLE__ -# ifdef __ARM_NEON__ + cpu_features->has_armcrypto = 0; + +#ifndef __ARM_ARCH + return -1; /* LCOV_EXCL_LINE */ +#endif + +#if defined(__ARM_NEON) || defined(__aarch64__) || defined(_M_ARM64) cpu_features->has_neon = 1; -# else - cpu_features->has_neon = 0; -# endif -# elif defined(HAVE_ANDROID_GETCPUFEATURES) && \ - defined(ANDROID_CPU_ARM_FEATURE_NEON) +#elif defined(HAVE_ANDROID_GETCPUFEATURES) cpu_features->has_neon = - (android_getCpuFeatures() & ANDROID_CPU_ARM_FEATURE_NEON) != 0x0; -# else - cpu_features->has_neon = 0; + (android_getCpuFeatures() & ANDROID_CPU_ARM64_FEATURE_ASIMD) != 0x0; +#elif (defined(__aarch64__) || defined(_M_ARM64)) && defined(AT_HWCAP) +# ifdef HAVE_GETAUXVAL + cpu_features->has_neon = (getauxval(AT_HWCAP) & (1L << 1)) != 0; +# elif defined(HAVE_ELF_AUX_INFO) + { + unsigned long buf; + if (elf_aux_info(AT_HWCAP, (void *) &buf, (int) sizeof buf) == 0) { + cpu_features->has_neon = (buf & (1L << 1)) != 0; + } + } +# endif +#elif defined(__arm__) && defined(AT_HWCAP) +# ifdef HAVE_GETAUXVAL + cpu_features->has_neon = (getauxval(AT_HWCAP) & (1L << 12)) != 0; +# elif defined(HAVE_ELF_AUX_INFO) + { + unsigned long buf; + if (elf_aux_info(AT_HWCAP, (void *) &buf, (int) sizeof buf) == 0) { + cpu_features->has_neon = (buf & (1L << 12)) != 0; + } + } # endif - return 0; #endif + + if (cpu_features->has_neon == 0) { + return 0; + } + +#if defined(__ARM_FEATURE_CRYPTO) && defined(__ARM_FEATURE_AES) + cpu_features->has_armcrypto = 1; +#elif defined(_M_ARM64) + cpu_features->has_armcrypto = 1; /* assuming all CPUs supported by ARM Windows have the crypto extensions */ +#elif defined(__APPLE__) && defined(CPU_TYPE_ARM64) && defined(CPU_SUBTYPE_ARM64E) + { + cpu_type_t cpu_type; + cpu_subtype_t cpu_subtype; + size_t cpu_type_len = sizeof cpu_type; + size_t cpu_subtype_len = sizeof cpu_subtype; + + if (sysctlbyname("hw.cputype", &cpu_type, &cpu_type_len, + NULL, 0) == 0 && cpu_type == CPU_TYPE_ARM64 && + sysctlbyname("hw.cpusubtype", &cpu_subtype, &cpu_subtype_len, + NULL, 0) == 0 && + (cpu_subtype == CPU_SUBTYPE_ARM64E || + cpu_subtype == CPU_SUBTYPE_ARM64_V8)) { + cpu_features->has_armcrypto = 1; + } + } +#elif defined(HAVE_ANDROID_GETCPUFEATURES) + cpu_features->has_armcrypto = + (android_getCpuFeatures() & ANDROID_CPU_ARM64_FEATURE_AES) != 0x0; +#elif (defined(__aarch64__) || defined(_M_ARM64)) && defined(AT_HWCAP) +# ifdef HAVE_GETAUXVAL + cpu_features->has_armcrypto = (getauxval(AT_HWCAP) & (1L << 3)) != 0; +# elif defined(HAVE_ELF_AUX_INFO) + { + unsigned long buf; + if (elf_aux_info(AT_HWCAP, (void *) &buf, (int) sizeof buf) == 0) { + cpu_features->has_armcrypto = (buf & (1L << 3)) != 0; + } + } +# endif +#elif defined(__arm__) && defined(AT_HWCAP2) +# ifdef HAVE_GETAUXVAL + cpu_features->has_armcrypto = (getauxval(AT_HWCAP2) & (1L << 0)) != 0; +# elif defined(HAVE_ELF_AUX_INFO) + { + unsigned long buf; + if (elf_aux_info(AT_HWCAP2, (void *) &buf, (int) sizeof buf) == 0) { + cpu_features->has_armcrypto = (buf & (1L << 0)) != 0; + } + } +# endif +#endif + + return 0; } static void _cpuid(unsigned int cpu_info[4U], const unsigned int cpu_info_type) { -#if defined(_MSC_VER) && \ - (defined(_M_X64) || defined(_M_AMD64) || defined(_M_IX86)) +#if defined(_MSC_VER) && (defined(_M_X64) || defined(_M_IX86)) __cpuid((int *) cpu_info, cpu_info_type); #elif defined(HAVE_CPUID) cpu_info[0] = cpu_info[1] = cpu_info[2] = cpu_info[3] = 0; @@ -116,11 +193,10 @@ static int _sodium_runtime_intel_cpu_features(CPUFeatures * const cpu_features) { unsigned int cpu_info[4]; - unsigned int id; uint32_t xcr0 = 0U; _cpuid(cpu_info, 0x0); - if ((id = cpu_info[0]) == 0U) { + if (cpu_info[0] == 0U) { return -1; /* LCOV_EXCL_LINE */ } _cpuid(cpu_info, 0x00000001); @@ -203,11 +279,13 @@ _sodium_runtime_intel_cpu_features(CPUFeatures * const cpu_features) unsigned int cpu_info7[4]; _cpuid(cpu_info7, 0x00000007); + /* LCOV_EXCL_START */ if ((cpu_info7[1] & CPUID_EBX_AVX512F) == CPUID_EBX_AVX512F && (xcr0 & (XCR0_OPMASK | XCR0_ZMM_HI256 | XCR0_HI16_ZMM)) == (XCR0_OPMASK | XCR0_ZMM_HI256 | XCR0_HI16_ZMM)) { cpu_features->has_avx512f = 1; } + /* LCOV_EXCL_STOP */ } #endif @@ -246,6 +324,12 @@ sodium_runtime_has_neon(void) return _cpu_features.has_neon; } +int +sodium_runtime_has_armcrypto(void) +{ + return _cpu_features.has_armcrypto; +} + int sodium_runtime_has_sse2(void) { diff --git a/libs/libsodium/src/sodium/utils.c b/libs/libsodium/src/sodium/utils.c index b14b5151e7..2227bb8a63 100644 --- a/libs/libsodium/src/sodium/utils.c +++ b/libs/libsodium/src/sodium/utils.c @@ -4,16 +4,23 @@ #include #include #include -#include #include #include #include #include +#if defined(HAVE_RAISE) && !defined(__wasm__) +# include +#endif + #ifdef HAVE_SYS_MMAN_H # include #endif +#ifdef HAVE_SYS_PARAM_H +# include +#endif + #ifdef _WIN32 # include # include @@ -43,7 +50,10 @@ void *alloca (size_t); #endif #include "core.h" +#include "crypto_generichash.h" +#include "crypto_stream.h" #include "randombytes.h" +#include "private/common.h" #include "utils.h" #ifndef ENOSYS @@ -59,7 +69,11 @@ void *alloca (size_t); #define GARBAGE_VALUE 0xdb #ifndef MAP_NOCORE -# define MAP_NOCORE 0 +# ifdef MAP_CONCEAL +# define MAP_NOCORE MAP_CONCEAL +# else +# define MAP_NOCORE 0 +# endif #endif #if !defined(MAP_ANON) && defined(MAP_ANONYMOUS) # define MAP_ANON MAP_ANONYMOUS @@ -68,6 +82,7 @@ void *alloca (size_t); defined(HAVE_POSIX_MEMALIGN) # define HAVE_ALIGNED_MALLOC #endif + #if defined(HAVE_MPROTECT) && \ !(defined(PROT_NONE) && defined(PROT_READ) && defined(PROT_WRITE)) # undef HAVE_MPROTECT @@ -81,7 +96,15 @@ void *alloca (size_t); # define MADV_DONTDUMP MADV_NOCORE #endif -static size_t page_size; +#ifndef DEFAULT_PAGE_SIZE +# ifdef PAGE_SIZE +# define DEFAULT_PAGE_SIZE PAGE_SIZE +# else +# define DEFAULT_PAGE_SIZE 0x10000 +# endif +#endif + +static size_t page_size = DEFAULT_PAGE_SIZE; static unsigned char canary[CANARY_SIZE]; /* LCOV_EXCL_START */ @@ -100,9 +123,9 @@ _sodium_dummy_symbol_to_prevent_memzero_lto(void *const pnt, /* LCOV_EXCL_STOP */ void -sodium_memzero(void *const pnt, const size_t len) +sodium_memzero(void * const pnt, const size_t len) { -#ifdef _WIN32 +#if defined(_WIN32) && !defined(__CRT_INLINE) SecureZeroMemory(pnt, len); #elif defined(HAVE_MEMSET_S) if (len > 0U && memset_s(pnt, (rsize_t) len, 0, (rsize_t) len) != 0) { @@ -110,11 +133,15 @@ sodium_memzero(void *const pnt, const size_t len) } #elif defined(HAVE_EXPLICIT_BZERO) explicit_bzero(pnt, len); +#elif defined(HAVE_MEMSET_EXPLICIT) + memset_explicit(pnt, 0, len); #elif defined(HAVE_EXPLICIT_MEMSET) explicit_memset(pnt, 0, len); #elif HAVE_WEAK_SYMBOLS - memset(pnt, 0, len); - _sodium_dummy_symbol_to_prevent_memzero_lto(pnt, len); + if (len > 0U) { + memset(pnt, 0, len); + _sodium_dummy_symbol_to_prevent_memzero_lto(pnt, len); + } # ifdef HAVE_INLINE_ASM __asm__ __volatile__ ("" : : "r"(pnt) : "memory"); # endif @@ -221,8 +248,8 @@ sodium_compare(const unsigned char *b1_, const unsigned char *b2_, size_t len) i--; x1 = b1[i]; x2 = b2[i]; - gt |= ((x2 - x1) >> 8) & eq; - eq &= ((x2 ^ x1) - 1) >> 8; + gt |= (((unsigned int) x2 - (unsigned int) x1) >> 8) & eq; + eq &= (((unsigned int) (x2 ^ x1)) - 1) >> 8; } return (int) (gt + gt + eq) - 1; } @@ -382,7 +409,7 @@ int _sodium_alloc_init(void) { #ifdef HAVE_ALIGNED_MALLOC -# if defined(_SC_PAGESIZE) +# if defined(_SC_PAGESIZE) && defined(HAVE_SYSCONF) long page_size_ = sysconf(_SC_PAGESIZE); if (page_size_ > 0L) { page_size = (size_t) page_size_; @@ -391,12 +418,14 @@ _sodium_alloc_init(void) SYSTEM_INFO si; GetSystemInfo(&si); page_size = (size_t) si.dwPageSize; +# elif !defined(PAGE_SIZE) +# warning Unknown page size # endif if (page_size < CANARY_SIZE || page_size < sizeof(size_t)) { sodium_misuse(); /* LCOV_EXCL_LINE */ } #endif - randombytes_buf(canary, sizeof canary); + randombytes_buf(canary, CANARY_SIZE); return 0; } @@ -481,10 +510,14 @@ _mprotect_readwrite(void *ptr, size_t size) __attribute__((noreturn)) static void _out_of_bounds(void) { -# ifdef SIGSEGV +# if defined(HAVE_RAISE) && !defined(__wasm__) +# ifdef SIGPROT + raise(SIGPROT); +# elif defined(SIGSEGV) raise(SIGSEGV); -# elif defined(SIGKILL) +# elif defined(SIGKILL) raise(SIGKILL); +# endif # endif abort(); /* not something we want any higher-level API to catch */ } /* LCOV_EXCL_LINE */ @@ -589,7 +622,7 @@ _sodium_malloc(const size_t size) memcpy(unprotected_ptr + unprotected_size, canary, sizeof canary); # endif _mprotect_noaccess(unprotected_ptr + unprotected_size, page_size); - sodium_mlock(unprotected_ptr, unprotected_size); + (void) sodium_mlock(unprotected_ptr, unprotected_size); /* not a hard error in the context of sodium_malloc() */ canary_ptr = unprotected_ptr + _page_round(size_with_canary) - size_with_canary; user_ptr = canary_ptr + sizeof canary; @@ -659,7 +692,7 @@ sodium_free(void *ptr) _out_of_bounds(); } # endif - sodium_munlock(unprotected_ptr, unprotected_size); + (void) sodium_munlock(unprotected_ptr, unprotected_size); _free_aligned(base_ptr, total_size); } #endif /* HAVE_ALIGNED_MALLOC */ -- cgit v1.2.3