From 247c98d9548fead121e5314727782a4694bc0de3 Mon Sep 17 00:00:00 2001 From: Mounir IDRASSI Date: Sun, 26 Jan 2025 16:21:13 +0100 Subject: [PATCH] Implement SHA256 acceleration on ARM64 platforms using CPU instructions --- src/Crypto/Crypto.vcxproj | 4 + src/Crypto/Crypto.vcxproj.filters | 3 + src/Crypto/Sha2.c | 17 ++ src/Crypto/config.h | 13 ++ src/Crypto/cpu.c | 29 +++ src/Crypto/cpu.h | 2 + src/Crypto/sha256_armv8.c | 184 ++++++++++++++++++++ src/Driver/Driver.vcxproj | 4 + src/Driver/Driver.vcxproj.filters | 3 + src/Release/Setup Files/veracrypt-arm64.sys | Bin 440472 -> 430592 bytes src/Release/Setup Files/veracrypt-x64.sys | Bin 639632 -> 629248 bytes src/Volume/Volume.make | 8 + 12 files changed, 267 insertions(+) create mode 100644 src/Crypto/sha256_armv8.c diff --git a/src/Crypto/Crypto.vcxproj b/src/Crypto/Crypto.vcxproj index c17bd607..cad50c06 100644 --- a/src/Crypto/Crypto.vcxproj +++ b/src/Crypto/Crypto.vcxproj @@ -255,6 +255,10 @@ + + true + true + diff --git a/src/Crypto/Crypto.vcxproj.filters b/src/Crypto/Crypto.vcxproj.filters index f2b1b54d..099c3ce4 100644 --- a/src/Crypto/Crypto.vcxproj.filters +++ b/src/Crypto/Crypto.vcxproj.filters @@ -96,6 +96,9 @@ Source Files + + Source Files + diff --git a/src/Crypto/Sha2.c b/src/Crypto/Sha2.c index 5ae9cae2..27e61c3d 100644 --- a/src/Crypto/Sha2.c +++ b/src/Crypto/Sha2.c @@ -315,6 +315,10 @@ extern "C" void VC_CDECL sha256_compress_nayuki(uint_32t state[8], const uint_8t block[64]); #endif +#if CRYPTOPP_ARM_SHA2_AVAILABLE + void sha256_compress_digest_armv8(const void* input_data, uint_32t digest[8], uint_64t num_blks); +#endif + #if defined(__cplusplus) } #endif @@ -757,6 +761,13 @@ void SSE2Sha256Transform(sha256_ctx* ctx, void* mp, uint_64t num_blks) } #endif +#if CRYPTOPP_ARM_SHA2_AVAILABLE +void ArmSha256Transform(sha256_ctx* ctx, void* mp, uint_64t num_blks) +{ + sha256_compress_digest_armv8(mp, ctx->hash, num_blks); +} +#endif + #if CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X32 void Sha256AsmTransform(sha256_ctx* ctx, void* mp, uint_64t num_blks) { @@ -805,6 +816,12 @@ void sha256_begin(sha256_ctx* ctx) else #endif +#if CRYPTOPP_ARM_SHA2_AVAILABLE + if (HasSHA256()) + sha256transfunc = ArmSha256Transform; + else +#endif + #if CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X32 sha256transfunc = Sha256AsmTransform; #else diff --git a/src/Crypto/config.h b/src/Crypto/config.h index dd8e3f06..f485c07e 100644 --- a/src/Crypto/config.h +++ b/src/Crypto/config.h @@ -240,6 +240,19 @@ # endif // Platforms #endif +// ARMv8 and SHA-1, SHA-256. -march=armv8-a+crypto or above must be present +// Requires GCC 4.8, Clang 3.3 or Visual Studio 2017 +#if !defined(CRYPTOPP_ARM_SHA_AVAILABLE) && !defined(CRYPTOPP_DISABLE_ARM_SHA) +# if defined(__aarch32__) || defined(__aarch64__) || defined(_M_ARM64) +# if defined(__ARM_FEATURE_CRYPTO) || (CRYPTOPP_GCC_VERSION >= 40800) || \ + (CRYPTOPP_LLVM_CLANG_VERSION >= 30300) || (CRYPTOPP_APPLE_CLANG_VERSION >= 40300) || \ + (CRYPTOPP_MSC_VERSION >= 1916) +# define CRYPTOPP_ARM_SHA1_AVAILABLE 1 +# define CRYPTOPP_ARM_SHA2_AVAILABLE 1 +# endif // Compilers +# endif // Platforms +#endif + // Undo the ASM and Intrinsic related defines due to X32. #if CRYPTOPP_BOOL_X32 # undef CRYPTOPP_BOOL_X64 diff --git a/src/Crypto/cpu.c b/src/Crypto/cpu.c index 0f1ba54d..a5b5bb19 100644 --- a/src/Crypto/cpu.c +++ b/src/Crypto/cpu.c @@ -475,9 +475,13 @@ void DisableCPUExtendedFeatures () #ifndef HWCAP_AES # define HWCAP_AES (1 << 3) #endif +#ifndef HWCAP_SHA2 +# define HWCAP_SHA2 (1 << 6) +#endif #endif volatile int g_hasAESARM = 0; +volatile int g_hasSHA256ARM = 0; inline int CPU_QueryAES() { @@ -503,9 +507,34 @@ inline int CPU_QueryAES() #endif } +inline int CPU_QuerySHA2() +{ +#if defined(CRYPTOPP_ARM_SHA2_AVAILABLE) +#if defined(__linux__) && defined(__aarch64__) + if ((getauxval(AT_HWCAP) & HWCAP_SHA2) != 0) + return 1; +#elif defined(__APPLE__) && defined(__aarch64__) + // Apple Sillcon (M1) and later + return 1; +#elif defined(_WIN32) && defined(_M_ARM64) +#ifdef TC_WINDOWS_DRIVER + if (ExIsProcessorFeaturePresent(PF_ARM_V8_CRYPTO_INSTRUCTIONS_AVAILABLE) != 0) + return 1; +#else + if (IsProcessorFeaturePresent(PF_ARM_V8_CRYPTO_INSTRUCTIONS_AVAILABLE) != 0) + return 1; +#endif +#endif + return 0; +#else + return 0; +#endif +} + void DetectArmFeatures() { g_hasAESARM = CPU_QueryAES(); + g_hasSHA256ARM = CPU_QuerySHA2(); } #endif \ No newline at end of file diff --git a/src/Crypto/cpu.h b/src/Crypto/cpu.h index 761258f2..cb34ad1f 100644 --- a/src/Crypto/cpu.h +++ b/src/Crypto/cpu.h @@ -298,9 +298,11 @@ extern "C" { #endif extern volatile int g_hasAESARM; +extern volatile int g_hasSHA256ARM; void DetectArmFeatures(); #define HasAESNI() g_hasAESARM +#define HasSHA256() g_hasSHA256ARM #if defined(__cplusplus) } diff --git a/src/Crypto/sha256_armv8.c b/src/Crypto/sha256_armv8.c new file mode 100644 index 00000000..1599350a --- /dev/null +++ b/src/Crypto/sha256_armv8.c @@ -0,0 +1,184 @@ +/* +* SHA-256 using CPU instructions in ARMv8 +* +* Contributed by Jeffrey Walton. Based on public domain code by +* Johannes Schneiders, Skip Hovsmith and Barry O'Rourke. +* +* Further changes (C) 2020 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +/* Modified and adapted for VeraCrypt */ + +#include "Common/Tcdefs.h" +#if !defined(_UEFI) +#include +#include +#endif +#include "cpu.h" +#include "misc.h" + +#if CRYPTOPP_ARM_SHA2_AVAILABLE + +#include + +CRYPTOPP_ALIGN_DATA(64) static const uint32 K[] = { + 0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5, 0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5, + 0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3, 0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174, + 0xE49B69C1, 0xEFBE4786, 0x0FC19DC6, 0x240CA1CC, 0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA, + 0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7, 0xC6E00BF3, 0xD5A79147, 0x06CA6351, 0x14292967, + 0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13, 0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85, + 0xA2BFE8A1, 0xA81A664B, 0xC24B8B70, 0xC76C51A3, 0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070, + 0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5, 0x391C0CB3, 0x4ED8AA4A, 0x5B9CCA4F, 0x682E6FF3, + 0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208, 0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2, +}; + +void sha256_compress_digest_armv8(void* input_data, uint32 digest[8], uint64 num_blks) { + + + // Load initial values + uint32x4_t STATE0 = vld1q_u32(&digest[0]); + uint32x4_t STATE1 = vld1q_u32(&digest[4]); + + // Intermediate void* cast due to https://llvm.org/bugs/show_bug.cgi?id=20670 + const uint32* input32 = (const uint32*)(const void*)input_data; + + while (num_blks > 0) { + // Save current state + const uint32x4_t ABCD_SAVE = STATE0; + const uint32x4_t EFGH_SAVE = STATE1; + + uint32x4_t MSG0 = vld1q_u32(input32 + 0); + uint32x4_t MSG1 = vld1q_u32(input32 + 4); + uint32x4_t MSG2 = vld1q_u32(input32 + 8); + uint32x4_t MSG3 = vld1q_u32(input32 + 12); + + MSG0 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(MSG0))); + MSG1 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(MSG1))); + MSG2 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(MSG2))); + MSG3 = vreinterpretq_u32_u8(vrev32q_u8(vreinterpretq_u8_u32(MSG3))); + + uint32x4_t MSG_K, TSTATE; + + // Rounds 0-3 + MSG_K = vaddq_u32(MSG0, vld1q_u32(&K[4 * 0])); + TSTATE = vsha256hq_u32(STATE0, STATE1, MSG_K); + STATE1 = vsha256h2q_u32(STATE1, STATE0, MSG_K); + STATE0 = TSTATE; + MSG0 = vsha256su1q_u32(vsha256su0q_u32(MSG0, MSG1), MSG2, MSG3); + + // Rounds 4-7 + MSG_K = vaddq_u32(MSG1, vld1q_u32(&K[4 * 1])); + TSTATE = vsha256hq_u32(STATE0, STATE1, MSG_K); + STATE1 = vsha256h2q_u32(STATE1, STATE0, MSG_K); + STATE0 = TSTATE; + MSG1 = vsha256su1q_u32(vsha256su0q_u32(MSG1, MSG2), MSG3, MSG0); + + // Rounds 8-11 + MSG_K = vaddq_u32(MSG2, vld1q_u32(&K[4 * 2])); + TSTATE = vsha256hq_u32(STATE0, STATE1, MSG_K); + STATE1 = vsha256h2q_u32(STATE1, STATE0, MSG_K); + STATE0 = TSTATE; + MSG2 = vsha256su1q_u32(vsha256su0q_u32(MSG2, MSG3), MSG0, MSG1); + + // Rounds 12-15 + MSG_K = vaddq_u32(MSG3, vld1q_u32(&K[4 * 3])); + TSTATE = vsha256hq_u32(STATE0, STATE1, MSG_K); + STATE1 = vsha256h2q_u32(STATE1, STATE0, MSG_K); + STATE0 = TSTATE; + MSG3 = vsha256su1q_u32(vsha256su0q_u32(MSG3, MSG0), MSG1, MSG2); + + // Rounds 16-19 + MSG_K = vaddq_u32(MSG0, vld1q_u32(&K[4 * 4])); + TSTATE = vsha256hq_u32(STATE0, STATE1, MSG_K); + STATE1 = vsha256h2q_u32(STATE1, STATE0, MSG_K); + STATE0 = TSTATE; + MSG0 = vsha256su1q_u32(vsha256su0q_u32(MSG0, MSG1), MSG2, MSG3); + + // Rounds 20-23 + MSG_K = vaddq_u32(MSG1, vld1q_u32(&K[4 * 5])); + TSTATE = vsha256hq_u32(STATE0, STATE1, MSG_K); + STATE1 = vsha256h2q_u32(STATE1, STATE0, MSG_K); + STATE0 = TSTATE; + MSG1 = vsha256su1q_u32(vsha256su0q_u32(MSG1, MSG2), MSG3, MSG0); + + // Rounds 24-27 + MSG_K = vaddq_u32(MSG2, vld1q_u32(&K[4 * 6])); + TSTATE = vsha256hq_u32(STATE0, STATE1, MSG_K); + STATE1 = vsha256h2q_u32(STATE1, STATE0, MSG_K); + STATE0 = TSTATE; + MSG2 = vsha256su1q_u32(vsha256su0q_u32(MSG2, MSG3), MSG0, MSG1); + + // Rounds 28-31 + MSG_K = vaddq_u32(MSG3, vld1q_u32(&K[4 * 7])); + TSTATE = vsha256hq_u32(STATE0, STATE1, MSG_K); + STATE1 = vsha256h2q_u32(STATE1, STATE0, MSG_K); + STATE0 = TSTATE; + MSG3 = vsha256su1q_u32(vsha256su0q_u32(MSG3, MSG0), MSG1, MSG2); + + // Rounds 32-35 + MSG_K = vaddq_u32(MSG0, vld1q_u32(&K[4 * 8])); + TSTATE = vsha256hq_u32(STATE0, STATE1, MSG_K); + STATE1 = vsha256h2q_u32(STATE1, STATE0, MSG_K); + STATE0 = TSTATE; + MSG0 = vsha256su1q_u32(vsha256su0q_u32(MSG0, MSG1), MSG2, MSG3); + + // Rounds 36-39 + MSG_K = vaddq_u32(MSG1, vld1q_u32(&K[4 * 9])); + TSTATE = vsha256hq_u32(STATE0, STATE1, MSG_K); + STATE1 = vsha256h2q_u32(STATE1, STATE0, MSG_K); + STATE0 = TSTATE; + MSG1 = vsha256su1q_u32(vsha256su0q_u32(MSG1, MSG2), MSG3, MSG0); + + // Rounds 40-43 + MSG_K = vaddq_u32(MSG2, vld1q_u32(&K[4 * 10])); + TSTATE = vsha256hq_u32(STATE0, STATE1, MSG_K); + STATE1 = vsha256h2q_u32(STATE1, STATE0, MSG_K); + STATE0 = TSTATE; + MSG2 = vsha256su1q_u32(vsha256su0q_u32(MSG2, MSG3), MSG0, MSG1); + + // Rounds 44-47 + MSG_K = vaddq_u32(MSG3, vld1q_u32(&K[4 * 11])); + TSTATE = vsha256hq_u32(STATE0, STATE1, MSG_K); + STATE1 = vsha256h2q_u32(STATE1, STATE0, MSG_K); + STATE0 = TSTATE; + MSG3 = vsha256su1q_u32(vsha256su0q_u32(MSG3, MSG0), MSG1, MSG2); + + // Rounds 48-51 + MSG_K = vaddq_u32(MSG0, vld1q_u32(&K[4 * 12])); + TSTATE = vsha256hq_u32(STATE0, STATE1, MSG_K); + STATE1 = vsha256h2q_u32(STATE1, STATE0, MSG_K); + STATE0 = TSTATE; + + // Rounds 52-55 + MSG_K = vaddq_u32(MSG1, vld1q_u32(&K[4 * 13])); + TSTATE = vsha256hq_u32(STATE0, STATE1, MSG_K); + STATE1 = vsha256h2q_u32(STATE1, STATE0, MSG_K); + STATE0 = TSTATE; + + // Rounds 56-59 + MSG_K = vaddq_u32(MSG2, vld1q_u32(&K[4 * 14])); + TSTATE = vsha256hq_u32(STATE0, STATE1, MSG_K); + STATE1 = vsha256h2q_u32(STATE1, STATE0, MSG_K); + STATE0 = TSTATE; + + // Rounds 60-63 + MSG_K = vaddq_u32(MSG3, vld1q_u32(&K[4 * 15])); + TSTATE = vsha256hq_u32(STATE0, STATE1, MSG_K); + STATE1 = vsha256h2q_u32(STATE1, STATE0, MSG_K); + STATE0 = TSTATE; + + // Add back to state + STATE0 = vaddq_u32(STATE0, ABCD_SAVE); + STATE1 = vaddq_u32(STATE1, EFGH_SAVE); + + input32 += 64 / 4; + num_blks--; + } + + // Save state + vst1q_u32(&digest[0], STATE0); + vst1q_u32(&digest[4], STATE1); +} +#endif diff --git a/src/Driver/Driver.vcxproj b/src/Driver/Driver.vcxproj index f6aacf9a..76ca90ed 100644 --- a/src/Driver/Driver.vcxproj +++ b/src/Driver/Driver.vcxproj @@ -272,6 +272,10 @@ copy $(OutDir)veracrypt.inf "$(SolutionDir)Debug\Setup Files\veracrypt.inf"false + + true + true + diff --git a/src/Driver/Driver.vcxproj.filters b/src/Driver/Driver.vcxproj.filters index 6f43b0e8..3c427dad 100644 --- a/src/Driver/Driver.vcxproj.filters +++ b/src/Driver/Driver.vcxproj.filters @@ -168,6 +168,9 @@ Crypto\Source Files + + Crypto\Source Files + diff --git a/src/Release/Setup Files/veracrypt-arm64.sys b/src/Release/Setup Files/veracrypt-arm64.sys index 8925f81286fdd8242badf8571049165934b6b38c..707fa0d633b00247268a614742738ecd83003aad 100644 GIT binary patch delta 18040 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 Ms%7m)?Q;IV0Am61^8f$< delta 28137 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 diff --git a/src/Release/Setup Files/veracrypt-x64.sys b/src/Release/Setup Files/veracrypt-x64.sys index 42e677f7514471dd06e9769f25eec026a6d71a19..ae31c516de3794eeec0ea5bf36ffcd2f0d843264 100644 GIT binary patch delta 148 zcmbQxs@||gZ371*^ESU}lermvnHbn6M=|=dGJrtyI>z>Oj3CSe#LPg<0>rF9%m&2l zK+Lgy9V2HLi#$+wI!Ff-5Jv)WgA^x20~;quhyf@!U73xukdbNoR5s54z1$28!VFRj dj6f;j>GP*>{$;eBK6fhTb4JVUt=rVYG8Jw07P(nfp1tmHtp`k<%C5EapIHNU61ZwRGgZ>au zvV~Hl5F;!S%}6VPL3Qb3XvRP|yy^s+apf2@9L5C`g2ADGuJkj<8JFOy>Deb3$Kk3~ zu_qbBkYKVD)Cz%s0aU4IG~?#D9dYkj;q-`HsuTq(3P8Z&SayIF&FCDr1MY!DA>ec{ zzyZx9gNCEvR22jqm1_zZ1N>`B*a1c)9F~hZi-?2)*q_>>FhRUEAX{!?oRMaZU9%PF zS-bdBTpiOF?EOCc?6az_5|Lag>n(ta4g{zu+gv09jzDlLLN@wyNyieI9{YZ#y(Y|` z*6&wq;mnXtQHfY)fDw({jY4xHc3Wb(0Zv+mft$(3h3rM}_oNX0u^a#!t&pCZ-onG( zkLd4?1vdceX+=!jye0%U5|K>YN5O0(k^+b%7YYGtq6#R}>XFjhr@22ixIe6OpWGN?(0}+Q87miiUWn;YtE|E42zc@2j$LQGD-TN%$Aq&u%Po4>f6%Ku zylyJNz@25|G+ftFP_0lWOC|58v@&2r#O$j^Cpbv-Tedu2#M!)`mMVM2 zVQC*@io!KTgyp{70@~ddy5nwe;P|90GR#ci^GP`G;zkU!kjvi2QFL}@DlWeF>QNptOo>H5))rog!usu@&piiskL}>wA3e=&M@^z}2|7vma z0X(#+rsHPCDdMn7Dl&Kg`cwu)Xx)gR1OUEBo(}cXMMlkHvl0>2k4mI1*{opAc>sm> z1rd}V0QvxgT+dvOI5#f}B|u$4AtWS3-tU_y$h#5!6ast*!~n8_8_D;F3rOIAuTB8n zt-1m9x#|ee=XY12-RnRXnmfot?SZJMZ({+6qk;f35D0!N01$B=zcs;wL?Qn_8bJYA zXz$Jqhp(Uz01RBa*r9y{Nkzb6ssUrsNITM?d#qpNll_W!H7-8bC0MeU-`BpwX4`PQ z6M;htGh&$9w=1cJPP*QdZ(huh18t-(;3l0ZeO*qwG%kZT-|ID-BV1BSbYty=Nrm2n z$#j#ZU?EIoQEd=IA9@$=%0L*x?f!rYXc2mN(Mh1T(zHoPUn76-?zr?69q-MDxIZuM zJ(T0Yd+dh2agE28Qz-|Ihf6t|zx83Yo)<1SFv!qWy+!Y%Lv+TIO}56ZnjeE)BAr8p zADpm73saAe`;URJTqR>+^^#1`3EudmS1P)4L_Z(Cn7(^C|!%E&~u= z5JUvWd7pIWWe*|6EZlD02#ZeUv0Dg6f*cN0_#`#`?a%5@1|Gtvkd$75ecUEzuF-jT z@=y8jPVWJ{I*fhcC3EW=M?}V39;EF~egQxD;f^)_$=v`earXOkXZRA6Uke$|nzGZu zlm>E)&e>+VKZv}~cK(vhLoSDlgG!s3W%-yCP7Fji>%YiuY`pr>dZY&#dC%F>+cpSf z8-Wpq4oZHw(=ko1@Z-x$niA<@YMW*OsPtw4l}>dH0SsN65vPTWo*UhUvtUJ$KM98q`UT^Bjs8W`Dev^k?4S4Z} zVP^u`Q?zv=b)8@mB2dJ>ks^*Rod}gG_KGghtyK_@h?)T<-ID@5y_!j%2z_JIY_g)D z;`4Rw>-r>26g~%k!XBJGbtX~7JHxr;<_wO#b4hVWwyndSi%&JB_e%kk4!r5?+mixz zgU;vc$Colo7aKI6g_|06F?)<`EC_rqDjGd&>1>f`9;J@YeL4BLF=#Zl3B64=jqPET z>m>_GJXw2?v%qli#fx}q zmKPs7+LBelo9}YCzvb=NUA<2iDHF)EeuRd!qTri+0|(5noaab}55+5MnU@3(beo<|SBwvcXVf^ld%Bm559C?)VYBAF>Z5d%LiZ+D!|#JXmh0*E`JLlchODnVZs&nw zF$H1vGf$V?3HPpwtg}DkH60|npLkyF_Vn`ebDq`A27$|=5kcHqHczb0vcExZF$BGZ z00)}!E6Vc1Q4mptt%28HqMkc#=f|KN0eb+AMnShQ05nIleC@Ob1}5S-_5>SsMqi zLmBW3643!j2$22-w|n1N-%gr1>)`6ut$94zzVBY9Knq|^YcGP@1(*Oka}9I1$LW7H z5JJ~K!}cm>2at&FL2h4g6WTVQO#|91oM^j*9H1-*;uKer+3wp*L%>WU^hV$E5H4%| z-5@BqeFNn`cfQ&;<)?je6=6?SHfvyK!+i2U5!+#ktcrViZEo7)oZ|M$MaNm;gn65s zXWAV3wq^o!8a&cE*NWKeqt4!`i_vXtsqc8VfnJK$?=Za>bk!H}uO<_HmQBc2an zMbXB#z&Ouq>>+YE+=>S zZiPV7Lye2LE9IHj{phxRT480!QibFIkSZh%#h5_UxgVJH--IOaZz8zAj62uF!nsim zG=KjZi83OwEZ@TbC^m*-%O8<4GnNhFoInx(Sh!b^EO9H z(cG5&OG@wIFBe2s2!X;_kQT?T^-w6_Ls8+dj9U72&WGZLr6kqsQtNK*XG1bgh?VZ} z&Ug1OWC^h`HoicWE)FCXSQyosviJu(G#8T&Tx)wppKNxR?RZ70^oVEgKp`VbOvqTV zxOi7!uVA~4ulj-42Aq3(?dqOT^6p+|%4-EmF(Cibqj#vL<;B%2@mDXXT&}p(G`_{n zf4|N$XJK4YlfPS6&%$Xz2Hl#RQ*#{JAN;%;4?m$ixo7LS@7ywD*~Dz*)R}pfqDJqt z_T%nJS;>NXUaNKCyc(`0&$p*}?A< zP7_M_{h%TO0*?H%P(p=UpqanTFbAZSP~kez=xRdnr3S5fsB4g>qr})UA>qG}N@NGC z55_*bcY~Nc<+iEzvr_rp4bL)=0OHQ4PJa1#&=Z07JT!wTKO(>l#aMU%i&X*eiYho2 zdAyRc9e|2Nz~^(Lx(lN20a3UAf}4VWFOU3=@6p0uh?_EVum8bKb^JU?5Glp%3h?-% zp^&kXfW()tZSc4BB6#?^W2`JKG5VIK>Y$FAB3=$q)Cc7B)Ra`PUpqvu?a+$g=OJfF zaq$blSbC6x32q*_RL++WLB~J@o#6*ThflHx0uhcgT*{Ez1%pqnUDh;-=-@BL0Q|i~ z^t&QcuSXCuFPI*-i0zgFo|26;Dlk|T$N8rCR zN&nFtLB##<34LkiQLGNg>s%D`fPCPgPiYBk*3%|egK$!E7yE4cuzZhF{M^9Xa3q=d z#_1GS?YWdslWGa~uss0@*>j0om$L@k(rUM0{9k+5x1V_YGQ+IuXuxj$^;=_RQY|xj z1?vvxc*b`~w!F3r!x}3d^JPiAjZ3|ZDPU;~7^SBZ~B*!GICC!z&MxHTd>&a6DF zSTb+V>2>_nq|t1_B;we1=TZ)xgZ&#XZc2x&G_8p4(%yJ|7ZLkjd?%ua9np4C<%lb_!=WZAFYHfQDYQyJt z78mz2WbJw;J8zY2A?TF%>YM{X*R<{A15w;2ucxhj&8CT-3uj=Dt~Gd72c`3rwT#K} z%B??dn%mS8cs;}KML~~LL03<&t7qbEK3)66GcT3_Twz+bcFgFW&EVa`;m=jq`wy!% z)i*R}p7NZo*WEBRfJ;}ar5okhs=(ZKnWJ-ug@{5dfjxwU(Mjhp;H*Iw42^k(j5K)~ zD;6%lkPyharQ!PJ&WCkF*$;W2o{JuSm5wa6QrfH-UGp?Qr1dCliG;jB6`B=vk{cF>Ip~q*6 zcpYJTT^*z6#~yeTt+T`nPLcqpFZ6g1U=3L1TI8C=nf@JhrKwur&$8AJ&!s6^-{dPm z3M;+JlYPJOVu&X@1A8GU{HwSJ@no~#J?uMG{-QHO53mBi?`^+$+)r8+z(;#M37T@n z0x*4hFp^WffYkGUHq2117qF1fh$ZU>6Frf2+^5DbpZI*_Nd3e%f~DO7@UVz`7_Il*62b zc$N*Js;!xQxRa`9HYI6R^*Q62LqlE;(Owou)s7X5NzH(uXXI=9)se315>tp z(eJ_8Xo)R;{fRGQ+az5@J7LYlqcO+Gd#{L&mxON84SSwb$3N*FKX64n(iq+c&*QQlEi^5$R6>Xe9jef+JyhWZTgQEJ5Lt#9tC|+?PfO=N z)3pAHqy_%K%zs1E!eIe5MF6Xc!{P7{ekuZAvWm3qFX8>S=nno?e*1Uf{daKp{K+}v z@e0yL<^yMM_lX~}wj-(TTTt2M2wPMxWMIYwD2qU}Y>&l+724XCg$GE#fa19&+6VBn@7SVcD=MoKk=y~Q^gBRk=h8p!c0v*h; zD!ELm{>P^J*!wqG9#nHdgtlB*A`vbLmz2JPfM=8Yqf;6+LSc#*Bkd!=qa5qAEtaoM zxJnFpvv)bpFDF`d{qZ{1+T`tU?XiMqDM?q~mE{5wu^o7+x@Q&f;?1MC zk|HXtl7>Fg?LOt_rIBe+H&sv;Dy>p_`&G35xPgBsuD2l$aM&gL)b+~U>ZivJJwI6r zH@ZHPRZYRU#-%_R`iMGn`=Gzhxe;-oapmGH+>AtpTH^FWUN$TgC}V7OCc z&ESOy<=4u_?_~VXbD2-vq(kO+lh2u`P>!!xqOwnO%vNm|m@1mcIH+wrcxi9bTyH;F zbDL?SqMC6cqE^>Sp5tYVxxv%!I&T3x7dW}o^X%R}sbIuYMFCP@5oQ`}`pCu9=SF0? zrR;vhKKESoMn@-rl5+fbf3?{nbArp9G8!)svwd)AUH8(Jp7pIh?;I@59k~W2YA%`4 zh5EK~3X|R*TeN72}7059Fev7&%_vj!)B z34;zaoWP)V1D3$=Zx42hf=qC*NC!*IH%?tehA$qORyrA)iPUikQqF46r z@XwnsK9Lpigk#0+pX88sel7-yFCBQUX_; z+rM9XM-Y5K;ISW-Wx-F(>iK@lAaR@O;WKlInr(AlBOdPxtS`JjaZPHsBzRxEZfovM z!E0PxoQ|53qgzj^mcCzzibt&d-XF*&Jn?c@o8r7sHP}ET|tYW!^%y<%`Rkl zS)VX}ZCS?sJd-I`itR@X^C>K~uTvr)XudGg+NZJWM%+i7(7?(0q<1OsclX*TOYe+H zM2?ampjGK|XusJq)1Kk2TiUHazic(Vh687%OesJG7xYEXo zv77+ci#V9);!9p;y75|PpC)1HcB77AL_}Ks?GGByt9Wl#+|w$=n#a`M1QCtYvtj(g zya~qwmd7jaO9>?~Cn-OwF<#7CVVYF>AddHx8D+ix;%LSnPefl%OX_M$9DhNf*n4;9 zXiY`rVim({Z%>BZR1MJUPM+x~Q9rEC;0g`|xLKMUdqedrq~mA|M0;~o2=7+hb2Tqu z-)tTgX#zz?_*KnoF)s@I`|$k#F!K8n_<=L5)ILgX?5473iA^m&-PZ};%H+@B~K^y>^bEMPOkMWHC+Kg@CW zhqBB($2IR5J?cobFG9p82H(2Ls1?0)bl2kE^vkg#k918=hHUsVG+H2Sbdj zewFs`uPI3XS@Ub4|0StsRXF~Y8nsq9roxQ?AvCx~I%fSBt&pY;f0GVZ#o-YxbDo~- zZ#=bxYLfN+o_gf(8Lv+Ms2ZxCAp=HjIx}21@9>@7I_S68-%5A2izHL`>UT*B1K0}#osBIYi1vf+ z94hMu^gb+Lx_5w2B`eaC43}61s%~9;UC+7fJ$2OZ6Dmq{j|1mD`A3_`glNY=`BKao zg_P_uo#H!BFd2w@1``b9B1-8Gecu=8zN><%#b_-oPMh`7i};=veH_ms0lutG7{P}4 z3oEdLQD*Xc5x~Q)XDP5p*Y9wtJRT(U+~|2FUiNZ@wF!TFCytI{nmMYlcE>>IQ5~9OgMp(O2ryZ3g zT9x>cNb638?c1x8c{5!+JZAaBdCv=ttnVE!yjls80dLiEa#_8aIToSX@K|D0EmLKZ s4`*|U&2SdRjz8aM*!wDU8`=|>?&I^Sg;y%{L+|GT103?mc?#@*03?%6RsaA1 diff --git a/src/Volume/Volume.make b/src/Volume/Volume.make index e38542bb..a4f62562 100644 --- a/src/Volume/Volume.make +++ b/src/Volume/Volume.make @@ -50,6 +50,7 @@ ifneq "$(COMPILE_ASM)" "false" OBJSEX += ../Crypto/Camellia_aesni_asm.oo OBJSEX += ../Crypto/sha256-nayuki.oo OBJSEX += ../Crypto/sha512-nayuki.oo + OBJSEX += ../Crypto/sha256_armv8.oo OBJSEX += ../Crypto/sha256_avx1.oo OBJSEX += ../Crypto/sha256_avx2.oo OBJSEX += ../Crypto/sha256_sse4.oo @@ -82,6 +83,7 @@ else ifeq "$(CPU_ARCH)" "x64" else ifeq "$(CPU_ARCH)" "arm64" OBJARMV8CRYPTO += ../Crypto/Aes_hw_armv8.oarmv8crypto OBJS += ../Crypto/Aescrypt.o + OBJARMV8CRYPTO += ../Crypto/sha256_armv8.oarmv8crypto else OBJS += ../Crypto/Aescrypt.o endif @@ -150,6 +152,12 @@ ifneq "$(COMPILE_ASM)" "false" $(CC) $(CFLAGS_X64) -c ../Crypto/Aes_hw_armv8.c -o ../Crypto/Aes_hw_armv8_x64.o lipo -create ../Crypto/Aes_hw_armv8_arm64.o ../Crypto/Aes_hw_armv8_x64.o -output ../Crypto/Aes_hw_armv8.oo rm -fr ../Crypto/Aes_hw_armv8_arm64.o ../Crypto/Aes_hw_armv8_x64.o +../Crypto/sha256_armv8.oo: ../Crypto/sha256_armv8.c + @echo Compiling $(