Skip to content

Fix Ascon-80pq key sign extension in AsconEngine so high-bit keys match the specification - #2500

Open
Arpan0995 wants to merge 1 commit into
bcgit:mainfrom
Arpan0995:ascon80pq-key-sign-extension
Open

Arpan0995 wants to merge 1 commit into
bcgit:mainfrom
Arpan0995:ascon80pq-key-sign-extension

Conversation

@Arpan0995

Copy link
Copy Markdown
Contributor

For Ascon-80pq, AsconEngine loads key bytes 0 to 3 with K0 = Pack.bigEndianToInt(key, 0); (core/src/main/java/.../engines/AsconEngine.java:220), which sign-extends when key[0] has its high bit set. At finalisation :194 and :195 use K1 >> 32 and K2 >> 32, carrying the sign bits of key[4] and key[12] into the upper half. The ascon-c v1.2.8 reference crypto_aead/ascon80pqv12/ref/aead.c uses zero-extended uint64_t and logical shifts. So for seven keys in eight the tag differs from the specification, and with key[0] set the ciphertext too. LWC_AEAD_KAT_160_128.txt, read by testVectorsEngine_ascon80pq, has the one key 000102...13, which sets none of those bits.

Reproduced on released bcprov-jdk18on-1.86.jar and the 1.87-SNAPSHOT beta (1.87.0.20737), which ship the same AsconEngine.class; main (c314b9c) has the same source. Of ten vectors, the three with none of the bits set match and the other seven fail: ciphertext and tag for Wycheproof tcId 2, 6 and 45 (key[0] set), the tag only for the rest, e.g. tcId 1 gives tag 9c8ca536..., not a781b81a.... Decrypting the expected ct || tag of each of the seven throws InvalidCipherTextException "Ascon-80pq AEAD mac does not match". Ascon-128, Ascon-128a and AsconAEAD128 are unaffected.

This change:

  • masks the load at :220 with & 0xffffffffL and uses >>> at :194 and :195, doing the same in the jdk1.4 copy (core/src/main/jdk1.4/.../AsconEngine.java:443, :372, :373). They are no-ops when none of those bits is set; and
  • adds testVectorsEngine_ascon80pq_highBitKeys to AsconTest, called from performTest(), encrypting and decrypting ten inline vectors: eight from Wycheproof ascon80pq_test.json and Counts 1 and 537 of the ascon-c KAT, sources and licences in a comment.

The new test fails without the change on both jars and passes with it. Other RegressionTest.tests entries give the same result either way (21 need absent bc-test-data). Given the eleven crypto/ascon files of bc-test-data, the whole AsconTest prints Ascon: Okay with the change and on the beta fails only in the new method.

I compiled the jdk1.4 copy only with --release 8. With the change it passes the seven new rows with a 0, 1 or 16 byte plaintext; tcId 3, 5 and 6 (2, 4 and 5 bytes) fail before and after from a separate defect left for its own change: its ProcessFinalDecrypt and ProcessFinalEncrypt (:308 to :353) handle a final partial word with Pack.littleEndianToLong_High and longToLittleEndian_High, where base uses big-endian. The jdk1.4 RegressionTest does not register AsconTest, so that build never runs it.

Ciphertext an earlier release made under an affected key will no longer decrypt; it never did with a conformant implementation.

No jar has a META-INF/versions copy of AsconEngine; no module-info or OSGi change is needed. :core:checkstyleMain is clean. A release-note entry is included, happy to move it to another block.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant