Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 70 additions & 0 deletions tests/api/test_evp_pkey.c
Original file line number Diff line number Diff line change
Expand Up @@ -382,6 +382,76 @@ int test_wolfSSL_EVP_MD_hmac_signing(void)
return EXPECT_RESULT();
}

/* Verify that EVP_DigestVerifyFinal rejects zero-length HMAC tags. */
int test_wolfSSL_EVP_DigestVerify_HMAC_zero_len_forgery(void)
{
EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && !defined(NO_HMAC) && !defined(NO_SHA256)
static const unsigned char key[] = {
0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b
};
static const char message[] = "wolfSSL DigestVerifyFinal forgery probe";
static const unsigned char zeros[WC_MAX_DIGEST_SIZE] = { 0 };

WOLFSSL_EVP_PKEY* pkey = NULL;
WOLFSSL_EVP_MD_CTX mdCtx;
unsigned char tag[WC_MAX_DIGEST_SIZE];
size_t tagLen = sizeof(tag);

wolfSSL_EVP_MD_CTX_init(&mdCtx);

ExpectNotNull(pkey = wolfSSL_EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, NULL,
key, (int)sizeof(key)));

/* Compute the genuine HMAC-SHA256 tag for the message. */
ExpectIntEQ(wolfSSL_EVP_DigestSignInit(&mdCtx, NULL, wolfSSL_EVP_sha256(),
NULL, pkey), 1);
ExpectIntEQ(wolfSSL_EVP_DigestSignUpdate(&mdCtx, message,
(unsigned int)XSTRLEN(message)),
1);
ExpectIntEQ(wolfSSL_EVP_DigestSignFinal(&mdCtx, tag, &tagLen), 1);
ExpectIntEQ((int)tagLen, WC_SHA256_DIGEST_SIZE);
ExpectIntEQ(wolfSSL_EVP_MD_CTX_cleanup(&mdCtx), 1);

/* Full-length genuine tag verifies. */
wolfSSL_EVP_MD_CTX_init(&mdCtx);
ExpectIntEQ(wolfSSL_EVP_DigestVerifyInit(&mdCtx, NULL, wolfSSL_EVP_sha256(),
NULL, pkey), 1);
ExpectIntEQ(wolfSSL_EVP_DigestVerifyUpdate(&mdCtx, message,
(unsigned int)XSTRLEN(message)),
1);
ExpectIntEQ(wolfSSL_EVP_DigestVerifyFinal(&mdCtx, tag, tagLen), 1);
ExpectIntEQ(wolfSSL_EVP_MD_CTX_cleanup(&mdCtx), 1);

/* Wrong full-length tag is rejected. */
wolfSSL_EVP_MD_CTX_init(&mdCtx);
ExpectIntEQ(wolfSSL_EVP_DigestVerifyInit(&mdCtx, NULL, wolfSSL_EVP_sha256(),
NULL, pkey), 1);
ExpectIntEQ(wolfSSL_EVP_DigestVerifyUpdate(&mdCtx, message,
(unsigned int)XSTRLEN(message)),
1);
ExpectIntNE(wolfSSL_EVP_DigestVerifyFinal(&mdCtx, zeros,
WC_SHA256_DIGEST_SIZE), 1);
ExpectIntEQ(wolfSSL_EVP_MD_CTX_cleanup(&mdCtx), 1);

/* Zero-length tag must be rejected. */
wolfSSL_EVP_MD_CTX_init(&mdCtx);
ExpectIntEQ(wolfSSL_EVP_DigestVerifyInit(&mdCtx, NULL, wolfSSL_EVP_sha256(),
NULL, pkey), 1);
ExpectIntEQ(wolfSSL_EVP_DigestVerifyUpdate(&mdCtx, message,
(unsigned int)XSTRLEN(message)),
1);
ExpectIntNE(wolfSSL_EVP_DigestVerifyFinal(&mdCtx, zeros, 0), 1);
ExpectIntEQ(wolfSSL_EVP_MD_CTX_cleanup(&mdCtx), 1);

wolfSSL_EVP_PKEY_free(pkey);
#endif
return EXPECT_RESULT();
}

int test_wolfSSL_EVP_PKEY_new_mac_key(void)
{
EXPECT_DECLS;
Expand Down
3 changes: 3 additions & 0 deletions tests/api/test_evp_pkey.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ int test_wolfSSL_EVP_PKEY_base_id(void);
int test_wolfSSL_EVP_PKEY_id(void);
int test_wolfSSL_EVP_MD_pkey_type(void);
int test_wolfSSL_EVP_MD_hmac_signing(void);
int test_wolfSSL_EVP_DigestVerify_HMAC_zero_len_forgery(void);
int test_wolfSSL_EVP_PKEY_new_mac_key(void);
int test_wolfSSL_EVP_PKEY_hkdf(void);
int test_wolfSSL_EVP_PBE_scrypt(void);
Expand Down Expand Up @@ -70,6 +71,8 @@ int test_wolfSSL_EVP_PKEY_print_public(void);
TEST_DECL_GROUP("evp_pkey", test_wolfSSL_EVP_PKEY_id), \
TEST_DECL_GROUP("evp_pkey", test_wolfSSL_EVP_MD_pkey_type), \
TEST_DECL_GROUP("evp_pkey", test_wolfSSL_EVP_MD_hmac_signing), \
TEST_DECL_GROUP("evp_pkey", \
test_wolfSSL_EVP_DigestVerify_HMAC_zero_len_forgery), \
TEST_DECL_GROUP("evp_pkey", test_wolfSSL_EVP_PKEY_new_mac_key), \
TEST_DECL_GROUP("evp_pkey", test_wolfSSL_EVP_PKEY_hkdf), \
TEST_DECL_GROUP("evp_pkey", test_wolfSSL_EVP_PBE_scrypt), \
Expand Down
64 changes: 64 additions & 0 deletions tests/api/test_mlkem.c
Original file line number Diff line number Diff line change
Expand Up @@ -3950,3 +3950,67 @@
return EXPECT_RESULT();
} /* END test_wc_mlkem_decapsulate_pubonly_fails */

/* Verify that the FO re-encryption check catches ciphertext tampering

Check failure on line 3953 in tests/api/test_mlkem.c

View workflow job for this annotation

GitHub Actions / codespell

FO ==> OF, FOR, TO, DO, GO
* at various byte offsets and falls back to implicit rejection. */
int test_wc_mlkem_decap_fo_reject(void)
{
EXPECT_DECLS;
#if !defined(HAVE_FIPS) || FIPS_VERSION3_GE(7,0,0)
#if defined(WOLFSSL_HAVE_MLKEM) && defined(WOLFSSL_WC_MLKEM) && \
!defined(WOLFSSL_NO_ML_KEM) && !defined(WOLFSSL_MLKEM_NO_DECAPSULATE) && \
!defined(WOLFSSL_MLKEM_NO_ENCAPSULATE) && \
!defined(WOLFSSL_MLKEM_NO_MAKE_KEY)
MlKemKey* key = NULL;
WC_RNG rng;
byte ct[WC_ML_KEM_MAX_CIPHER_TEXT_SIZE];
byte ctTampered[WC_ML_KEM_MAX_CIPHER_TEXT_SIZE];
byte ss[WC_ML_KEM_SS_SZ];
byte ssDec[WC_ML_KEM_SS_SZ];
byte ssTampered[WC_ML_KEM_SS_SZ];
word32 ctLen = 0;

key = (MlKemKey*)XMALLOC(sizeof(*key), NULL, DYNAMIC_TYPE_TMP_BUFFER);
ExpectNotNull(key);

XMEMSET(&rng, 0, sizeof(rng));
ExpectIntEQ(wc_InitRng(&rng), 0);

#ifndef WOLFSSL_NO_ML_KEM_768
ExpectIntEQ(wc_MlKemKey_Init(key, WC_ML_KEM_768, NULL, INVALID_DEVID), 0);
#elif !defined(WOLFSSL_NO_ML_KEM_512)
ExpectIntEQ(wc_MlKemKey_Init(key, WC_ML_KEM_512, NULL, INVALID_DEVID), 0);
#else
ExpectIntEQ(wc_MlKemKey_Init(key, WC_ML_KEM_1024, NULL, INVALID_DEVID), 0);
#endif

ExpectIntEQ(wc_MlKemKey_CipherTextSize(key, &ctLen), 0);
ExpectIntEQ(wc_MlKemKey_MakeKey(key, &rng), 0);
ExpectIntEQ(wc_MlKemKey_Encapsulate(key, ct, ss, &rng), 0);

/* Untampered ciphertext recovers the original ss. */
XMEMSET(ssDec, 0, sizeof(ssDec));
ExpectIntEQ(wc_MlKemKey_Decapsulate(key, ssDec, ct, ctLen), 0);
ExpectIntEQ(XMEMCMP(ssDec, ss, WC_ML_KEM_SS_SZ), 0);

/* Tamper at byte 32: implicit rejection must fire. */
XMEMCPY(ctTampered, ct, ctLen);
ctTampered[32] ^= 0x01;
XMEMSET(ssTampered, 0, sizeof(ssTampered));
ExpectIntEQ(wc_MlKemKey_Decapsulate(key, ssTampered, ctTampered, ctLen), 0);
ExpectIntNE(XMEMCMP(ssTampered, ss, WC_ML_KEM_SS_SZ), 0);

/* Tamper at byte 0: also must be rejected. */
XMEMCPY(ctTampered, ct, ctLen);
ctTampered[0] ^= 0x01;
XMEMSET(ssTampered, 0, sizeof(ssTampered));
ExpectIntEQ(wc_MlKemKey_Decapsulate(key, ssTampered, ctTampered, ctLen), 0);
ExpectIntNE(XMEMCMP(ssTampered, ss, WC_ML_KEM_SS_SZ), 0);

DoExpectIntEQ(wc_FreeRng(&rng), 0);
wc_MlKemKey_Free(key);
XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER);
#endif
#endif
return EXPECT_RESULT();
} /* END test_wc_mlkem_decap_fo_reject */

12 changes: 7 additions & 5 deletions tests/api/test_mlkem.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,13 @@ int test_wc_mlkem_make_key_kats(void);
int test_wc_mlkem_encapsulate_kats(void);
int test_wc_mlkem_decapsulate_kats(void);
int test_wc_mlkem_decapsulate_pubonly_fails(void);
int test_wc_mlkem_decap_fo_reject(void);

#define TEST_MLKEM_DECLS \
TEST_DECL_GROUP("mlkem", test_wc_mlkem_make_key_kats), \
TEST_DECL_GROUP("mlkem", test_wc_mlkem_encapsulate_kats), \
TEST_DECL_GROUP("mlkem", test_wc_mlkem_decapsulate_kats), \
TEST_DECL_GROUP("mlkem", test_wc_mlkem_decapsulate_pubonly_fails)
#define TEST_MLKEM_DECLS \
TEST_DECL_GROUP("mlkem", test_wc_mlkem_make_key_kats), \
TEST_DECL_GROUP("mlkem", test_wc_mlkem_encapsulate_kats), \
TEST_DECL_GROUP("mlkem", test_wc_mlkem_decapsulate_kats), \
TEST_DECL_GROUP("mlkem", test_wc_mlkem_decapsulate_pubonly_fails), \
TEST_DECL_GROUP("mlkem", test_wc_mlkem_decap_fo_reject)

#endif /* WOLFCRYPT_TEST_MLKEM_H */
132 changes: 132 additions & 0 deletions tests/api/test_pkcs12.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#include <wolfcrypt/src/misc.c>
#endif

#include <wolfssl/wolfcrypt/hmac.h>
#include <wolfssl/wolfcrypt/pkcs12.h>
#include <wolfssl/wolfcrypt/pwdbased.h>
#include <wolfssl/wolfcrypt/types.h>
Expand Down Expand Up @@ -272,6 +273,137 @@ int test_wc_d2i_PKCS12_oid_underflow(void)
return EXPECT_RESULT();
}

/* Test that a crafted PKCS12 with a MAC OCTET STRING shorter than the
* algorithm's native digest size is rejected, rather than allowing the
* integrity check to be truncated to a brute-forceable length. */
int test_wc_PKCS12_truncated_mac_bypass(void)
{
EXPECT_DECLS;
#if !defined(NO_ASN) && !defined(NO_PWDBASED) && defined(HAVE_PKCS12) \
&& !defined(NO_HMAC) && !defined(NO_SHA256)
static const byte authSafe[] = { 0x30, 0x00 }; /* empty SEQUENCE OF CI */
static const char password[] = "wolfSSL test";
static const byte salt[8] = {
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08
};
const int iter = 1;
const word32 pwLen = (word32)(sizeof(password) - 1);

byte unicodePw[2 * sizeof(password) + 2];
int unicodePwLen = 0;
byte macKey[WC_SHA256_DIGEST_SIZE];
byte fullMac[WC_SHA256_DIGEST_SIZE];
Hmac hmac;
int hmacInited = 0;
word32 i;

WC_PKCS12* pkcs12 = NULL;
byte pfx[64];
word32 pfxLen = 0;

/* BMPString-style password (UTF-16BE) with trailing 0x00 0x00, matching
* the unicode conversion done internally by wc_PKCS12_create_mac. */
for (i = 0; i < pwLen; i++) {
unicodePw[unicodePwLen++] = 0x00;
unicodePw[unicodePwLen++] = (byte)password[i];
}
unicodePw[unicodePwLen++] = 0x00;
unicodePw[unicodePwLen++] = 0x00;

/* Derive the MAC key the same way wc_PKCS12_create_mac does:
* PKCS12-PBKDF SHA-256, id=3 (MAC key), kLen=32. */
ExpectIntEQ(wc_PKCS12_PBKDF_ex(macKey, unicodePw, unicodePwLen,
salt, (int)sizeof(salt),
iter, WC_SHA256_DIGEST_SIZE,
WC_SHA256, 3 /* id = MAC */, NULL),
0);

/* Compute the genuine HMAC-SHA256 over the authSafe content. */
ExpectIntEQ(wc_HmacInit(&hmac, NULL, INVALID_DEVID), 0);
if (EXPECT_SUCCESS())
hmacInited = 1;
ExpectIntEQ(wc_HmacSetKey(&hmac, WC_SHA256, macKey, sizeof(macKey)), 0);
ExpectIntEQ(wc_HmacUpdate(&hmac, authSafe, (word32)sizeof(authSafe)), 0);
ExpectIntEQ(wc_HmacFinal(&hmac, fullMac), 0);
if (hmacInited)
wc_HmacFree(&hmac);

/*
* Build a 59-byte PFX with a 1-byte truncated digest equal to fullMac[0]:
*
* 30 39 PFX SEQUENCE (57)
* 02 01 03 version = 3
* 30 11 AuthSafe ContentInfo (17)
* 06 09 2A 86 48 86 F7 0D 01 07 01 OID 1.2.840.113549.1.7.1 (data)
* A0 04 [0] EXPLICIT (4)
* 04 02 OCTET STRING (2)
* 30 00 authSafe = empty SEQUENCE
* 30 21 MacData (33)
* 30 12 DigestInfo (18)
* 30 0d AlgorithmIdentifier (13)
* 06 09 60 86 48 01 65 03 04 02 01 OID SHA-256
* 05 00 NULL
* 04 01 XX OCTET STRING (1)
* 04 08 01 02 03 04 05 06 07 08 salt
* 02 01 01 iterations = 1
*/
pfx[pfxLen++] = 0x30; pfx[pfxLen++] = 0x39;
pfx[pfxLen++] = 0x02; pfx[pfxLen++] = 0x01; pfx[pfxLen++] = 0x03;
pfx[pfxLen++] = 0x30; pfx[pfxLen++] = 0x11;
pfx[pfxLen++] = 0x06; pfx[pfxLen++] = 0x09;
pfx[pfxLen++] = 0x2A; pfx[pfxLen++] = 0x86; pfx[pfxLen++] = 0x48;
pfx[pfxLen++] = 0x86; pfx[pfxLen++] = 0xF7; pfx[pfxLen++] = 0x0D;
pfx[pfxLen++] = 0x01; pfx[pfxLen++] = 0x07; pfx[pfxLen++] = 0x01;
pfx[pfxLen++] = 0xA0; pfx[pfxLen++] = 0x04;
pfx[pfxLen++] = 0x04; pfx[pfxLen++] = 0x02;
pfx[pfxLen++] = 0x30; pfx[pfxLen++] = 0x00;
pfx[pfxLen++] = 0x30; pfx[pfxLen++] = 0x21;
pfx[pfxLen++] = 0x30; pfx[pfxLen++] = 0x12;
pfx[pfxLen++] = 0x30; pfx[pfxLen++] = 0x0D;
pfx[pfxLen++] = 0x06; pfx[pfxLen++] = 0x09;
pfx[pfxLen++] = 0x60; pfx[pfxLen++] = 0x86; pfx[pfxLen++] = 0x48;
pfx[pfxLen++] = 0x01; pfx[pfxLen++] = 0x65; pfx[pfxLen++] = 0x03;
pfx[pfxLen++] = 0x04; pfx[pfxLen++] = 0x02; pfx[pfxLen++] = 0x01;
pfx[pfxLen++] = 0x05; pfx[pfxLen++] = 0x00;
pfx[pfxLen++] = 0x04; pfx[pfxLen++] = 0x01;
pfx[pfxLen++] = fullMac[0];
pfx[pfxLen++] = 0x04; pfx[pfxLen++] = 0x08;
pfx[pfxLen++] = 0x01; pfx[pfxLen++] = 0x02; pfx[pfxLen++] = 0x03;
pfx[pfxLen++] = 0x04; pfx[pfxLen++] = 0x05; pfx[pfxLen++] = 0x06;
pfx[pfxLen++] = 0x07; pfx[pfxLen++] = 0x08;
pfx[pfxLen++] = 0x02; pfx[pfxLen++] = 0x01; pfx[pfxLen++] = 0x01;

{
byte* parsedPkey = NULL;
word32 parsedPkeySz = 0;
byte* parsedCert = NULL;
word32 parsedCertSz = 0;
int d2iRet;

ExpectNotNull(pkcs12 = wc_PKCS12_new());

/* Accept rejection at either parse time (wc_d2i_PKCS12) or
* verify time (wc_PKCS12_parse); the test fails only if both
* succeed. */
d2iRet = wc_d2i_PKCS12(pfx, pfxLen, pkcs12);
if (d2iRet == 0) {
ExpectIntNE(wc_PKCS12_parse(pkcs12, password,
&parsedPkey, &parsedPkeySz,
&parsedCert, &parsedCertSz, NULL),
0);
}
else {
ExpectIntNE(d2iRet, 0);
}

XFREE(parsedPkey, NULL, DYNAMIC_TYPE_PUBLIC_KEY);
XFREE(parsedCert, NULL, DYNAMIC_TYPE_PKCS);
wc_PKCS12_free(pkcs12);
}
#endif
return EXPECT_RESULT();
}

int test_wc_PKCS12_PBKDF(void)
{
EXPECT_DECLS;
Expand Down
2 changes: 2 additions & 0 deletions tests/api/test_pkcs12.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ int test_wc_i2d_PKCS12(void);
int test_wc_PKCS12_create(void);
int test_wc_d2i_PKCS12_bad_mac_salt(void);
int test_wc_d2i_PKCS12_oid_underflow(void);
int test_wc_PKCS12_truncated_mac_bypass(void);
int test_wc_PKCS12_PBKDF(void);
int test_wc_PKCS12_PBKDF_ex(void);
int test_wc_PKCS12_PBKDF_ex_sha1(void);
Expand All @@ -42,6 +43,7 @@ int test_wc_PKCS12_PBKDF_ex_sha512_256(void);
TEST_DECL_GROUP("pkcs12", test_wc_PKCS12_create), \
TEST_DECL_GROUP("pkcs12", test_wc_d2i_PKCS12_bad_mac_salt), \
TEST_DECL_GROUP("pkcs12", test_wc_d2i_PKCS12_oid_underflow), \
TEST_DECL_GROUP("pkcs12", test_wc_PKCS12_truncated_mac_bypass), \
TEST_DECL_GROUP("pkcs12", test_wc_PKCS12_PBKDF), \
TEST_DECL_GROUP("pkcs12", test_wc_PKCS12_PBKDF_ex), \
TEST_DECL_GROUP("pkcs12", test_wc_PKCS12_PBKDF_ex_sha1), \
Expand Down
3 changes: 1 addition & 2 deletions wolfcrypt/src/evp.c
Original file line number Diff line number Diff line change
Expand Up @@ -4992,9 +4992,8 @@ int wolfSSL_EVP_DigestVerifyFinal(WOLFSSL_EVP_MD_CTX *ctx,

hashLen = wolfssl_mac_len(ctx->hash.hmac.macType);

if (siglen > hashLen || siglen > INT_MAX)
if (hashLen == 0 || siglen != hashLen)
return WOLFSSL_FAILURE;
Comment on lines 4993 to 4996
Copy link

Copilot AI Apr 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new HMAC length check (siglen != hashLen) changes previous behavior that allowed truncated HMAC tags (the removed comment explicitly referenced truncation). If OpenSSL-compat is the goal, consider only rejecting unsafe lengths (e.g., siglen == 0, siglen > hashLen, and siglen > INT_MAX to avoid the later (int)siglen cast) rather than requiring an exact-length tag, so callers that legitimately use truncated tags keep working while still fixing the zero-length-forgery case.

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Contributor Author

@mattia-moffa mattia-moffa Apr 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is correct, but at the same time accepting lengths such as 1 would be attackable via brute forcing (and anything below hashLen is exponentially worse than hashLen). OpenSSL compatibility shouldn't be an issue here because OpenSSL doesn't allow HMAC at all in EVP_DigestVerify*.

/* May be a truncated signature. */
}

if (wolfssl_evp_digest_pk_final(ctx, digest, &hashLen) <= 0)
Expand Down
6 changes: 6 additions & 0 deletions wolfcrypt/src/pkcs12.c
Original file line number Diff line number Diff line change
Expand Up @@ -633,6 +633,12 @@ static int wc_PKCS12_verify(WC_PKCS12* pkcs12, byte* data, word32 dataSz,
return ret;
}

if ((word32)ret != mac->digestSz) {
WOLFSSL_MSG("PKCS12 MAC digest size mismatch");
ForceZero(digest, sizeof(digest));
return MAC_CMP_FAILED_E;
}

#ifdef WOLFSSL_DEBUG_PKCS12
{
byte* p;
Expand Down
2 changes: 1 addition & 1 deletion wolfcrypt/src/port/arm/armv8-mlkem-asm.S
Original file line number Diff line number Diff line change
Expand Up @@ -8927,7 +8927,7 @@ L_mlkem_aarch64_cmp_neon_done:
orr v8.16b, v8.16b, v9.16b
orr v10.16b, v10.16b, v11.16b
orr v8.16b, v8.16b, v10.16b
ins v9.b[0], v8.b[1]
ext v9.16b, v8.16b, v8.16b, #8
orr v8.16b, v8.16b, v9.16b
mov x0, v8.d[0]
subs x0, x0, xzr
Expand Down
2 changes: 1 addition & 1 deletion wolfcrypt/src/port/arm/armv8-mlkem-asm_c.c
Original file line number Diff line number Diff line change
Expand Up @@ -8404,7 +8404,7 @@ int mlkem_cmp_neon(const byte* a, const byte* b, int sz)
"orr v8.16b, v8.16b, v9.16b\n\t"
"orr v10.16b, v10.16b, v11.16b\n\t"
"orr v8.16b, v8.16b, v10.16b\n\t"
"ins v9.b[0], v8.b[1]\n\t"
"ext v9.16b, v8.16b, v8.16b, #8\n\t"
"orr v8.16b, v8.16b, v9.16b\n\t"
"mov x0, v8.d[0]\n\t"
"subs x0, x0, xzr\n\t"
Expand Down
Loading