From 41c123a022b8747c6d39cf8e944115b6072aeb82 Mon Sep 17 00:00:00 2001 From: Will Childs-Klein Date: Fri, 31 Jan 2025 16:18:56 -0500 Subject: [PATCH] Move computeMLDSAMu helper to TestUtil --- CMakeLists.txt | 2 +- csrc/public_utils.cpp | 68 ------------------- .../corretto/crypto/provider/PublicUtils.java | 28 -------- .../crypto/provider/test/MLDSATest.java | 21 +++++- .../crypto/provider/test/PublicUtilsTest.java | 56 --------------- .../crypto/provider/test/TestUtil.java | 19 ++++++ 6 files changed, 39 insertions(+), 155 deletions(-) delete mode 100644 csrc/public_utils.cpp delete mode 100644 src/com/amazon/corretto/crypto/provider/PublicUtils.java delete mode 100644 tst/com/amazon/corretto/crypto/provider/test/PublicUtilsTest.java diff --git a/CMakeLists.txt b/CMakeLists.txt index d527d4e7..02f74796 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -274,7 +274,6 @@ set(C_SRC csrc/libcrypto_rng.cpp csrc/loader.cpp csrc/md5.cpp - csrc/public_utils.cpp csrc/rsa_cipher.cpp csrc/rsa_gen.cpp csrc/sha1.cpp @@ -282,6 +281,7 @@ set(C_SRC csrc/sha384.cpp csrc/sha512.cpp csrc/sign.cpp + csrc/test_util.cpp csrc/testhooks.cpp csrc/util.cpp csrc/util_class.cpp diff --git a/csrc/public_utils.cpp b/csrc/public_utils.cpp deleted file mode 100644 index c305d590..00000000 --- a/csrc/public_utils.cpp +++ /dev/null @@ -1,68 +0,0 @@ -// Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. -// SPDX-License-Identifier: Apache-2.0 -#include -#include -#include - -#include "auto_free.h" -#include "env.h" - -namespace AmazonCorrettoCryptoProvider { - -/* - * Class: com_amazon_corretto_crypto_provider_Utils - * Method: computeMLDSAMuInternal - * Signature: ([B[B)[B - */ -extern "C" JNIEXPORT jbyteArray JNICALL Java_com_amazon_corretto_crypto_provider_PublicUtils_computeMLDSAMuInternal( - JNIEnv* pEnv, jclass, jbyteArray pubKeyEncodedArr, jbyteArray messageArr) -{ - try { - raii_env env(pEnv); - jsize pub_key_der_len = env->GetArrayLength(pubKeyEncodedArr); - jsize message_len = env->GetArrayLength(messageArr); - uint8_t* pub_key_der = (uint8_t*)env->GetByteArrayElements(pubKeyEncodedArr, nullptr); - CHECK_OPENSSL(pub_key_der); - uint8_t* message = (uint8_t*)env->GetByteArrayElements(messageArr, nullptr); - CHECK_OPENSSL(message); - - CBS cbs; - CBS_init(&cbs, pub_key_der, pub_key_der_len); - EVP_PKEY_auto pkey = EVP_PKEY_auto::from((EVP_parse_public_key(&cbs))); - EVP_PKEY_CTX_auto ctx = EVP_PKEY_CTX_auto::from(EVP_PKEY_CTX_new(pkey.get(), nullptr)); - EVP_MD_CTX_auto md_ctx_mu = EVP_MD_CTX_auto::from(EVP_MD_CTX_new()); - EVP_MD_CTX_auto md_ctx_pk = EVP_MD_CTX_auto::from(EVP_MD_CTX_new()); - - size_t pk_len; // fetch the public key length - CHECK_OPENSSL(EVP_PKEY_get_raw_public_key(pkey.get(), nullptr, &pk_len)); - std::vector pk(pk_len); - CHECK_OPENSSL(EVP_PKEY_get_raw_public_key(pkey.get(), pk.data(), &pk_len)); - uint8_t tr[64] = { 0 }; - uint8_t mu[64] = { 0 }; - uint8_t pre[2] = { 0 }; - - // get raw public key and hash it - CHECK_OPENSSL(EVP_DigestInit_ex(md_ctx_pk.get(), EVP_shake256(), nullptr)); - CHECK_OPENSSL(EVP_DigestUpdate(md_ctx_pk.get(), pk.data(), pk_len)); - CHECK_OPENSSL(EVP_DigestFinalXOF(md_ctx_pk.get(), tr, sizeof(tr))); - - // compute mu - CHECK_OPENSSL(EVP_DigestInit_ex(md_ctx_mu.get(), EVP_shake256(), nullptr)); - CHECK_OPENSSL(EVP_DigestUpdate(md_ctx_mu.get(), tr, sizeof(tr))); - CHECK_OPENSSL(EVP_DigestUpdate(md_ctx_mu.get(), pre, sizeof(pre))); - CHECK_OPENSSL(EVP_DigestUpdate(md_ctx_mu.get(), message, message_len)); - CHECK_OPENSSL(EVP_DigestFinalXOF(md_ctx_mu.get(), mu, sizeof(mu))); - - env->ReleaseByteArrayElements(pubKeyEncodedArr, (jbyte*)pub_key_der, 0); - env->ReleaseByteArrayElements(messageArr, (jbyte*)message, 0); - - jbyteArray ret = env->NewByteArray(sizeof(mu)); - env->SetByteArrayRegion(ret, 0, sizeof(mu), (const jbyte*)mu); - return ret; - } catch (java_ex& ex) { - ex.throw_to_java(pEnv); - return 0; - } -} - -} // namespace diff --git a/src/com/amazon/corretto/crypto/provider/PublicUtils.java b/src/com/amazon/corretto/crypto/provider/PublicUtils.java deleted file mode 100644 index 3d7c75e7..00000000 --- a/src/com/amazon/corretto/crypto/provider/PublicUtils.java +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. -// SPDX-License-Identifier: Apache-2.0 -package com.amazon.corretto.crypto.provider; - -import java.security.PublicKey; - -/** Public utility methods */ -public class PublicUtils { - private PublicUtils() {} // private constructor to prevent instantiation - - private static native byte[] computeMLDSAMuInternal(byte[] pubKeyEncoded, byte[] message); - - /** - * Computes mu as defined on line 6 of Algorithm 7 and line 7 of Algorithm 8 in NIST FIPS 204. - * - *

See FIPS 204 - * - * @param publicKey ML-DSA public key - * @param message byte array of the message over which to compute mu - * @return a byte[] of length 64 containing mu - */ - public static byte[] computeMLDSAMu(PublicKey publicKey, byte[] message) { - if (publicKey == null || !publicKey.getAlgorithm().startsWith("ML-DSA") || message == null) { - throw new IllegalArgumentException(); - } - return computeMLDSAMuInternal(publicKey.getEncoded(), message); - } -} diff --git a/tst/com/amazon/corretto/crypto/provider/test/MLDSATest.java b/tst/com/amazon/corretto/crypto/provider/test/MLDSATest.java index b920edd2..714fa73d 100644 --- a/tst/com/amazon/corretto/crypto/provider/test/MLDSATest.java +++ b/tst/com/amazon/corretto/crypto/provider/test/MLDSATest.java @@ -11,7 +11,6 @@ import static org.junit.jupiter.api.Assertions.assertTrue; import com.amazon.corretto.crypto.provider.AmazonCorrettoCryptoProvider; -import com.amazon.corretto.crypto.provider.PublicUtils; import java.security.InvalidKeyException; import java.security.KeyFactory; import java.security.KeyPair; @@ -271,7 +270,7 @@ public void testExtMu(TestParams params) throws Exception { PublicKey pub = params.pub; byte[] message = Arrays.copyOf(params.message, params.message.length); - byte[] mu = PublicUtils.computeMLDSAMu(pub, message); + byte[] mu = TestUtil.computeMLDSAMu(pub, message); assertEquals(64, mu.length); byte[] fakeMu = new byte[64]; Arrays.fill(fakeMu, (byte) 0); @@ -317,4 +316,22 @@ public void testExtMu(TestParams params) throws Exception { extMuVerifier.update(mu); assertFalse(extMuVerifier.verify(signatureBytes)); } + + @ParameterizedTest + @ValueSource(strings = {"ML-DSA-44", "ML-DSA-65", "ML-DSA-87"}) + public void testComputeMLDSAExtMu(String algorithm) throws Exception { + KeyPair keyPair = KeyPairGenerator.getInstance(algorithm, NATIVE_PROVIDER).generateKeyPair(); + PublicKey nativePub = keyPair.getPublic(); + KeyFactory bcKf = KeyFactory.getInstance("ML-DSA", TestUtil.BC_PROVIDER); + PublicKey bcPub = bcKf.generatePublic(new X509EncodedKeySpec(nativePub.getEncoded())); + + byte[] message = new byte[256]; + Arrays.fill(message, (byte) 0x41); + byte[] mu = TestUtil.computeMLDSAMu(nativePub, message); + assertEquals(64, mu.length); + // We don't have any other implementations of mu calculation to test against, so just assert + // that mu is equivalent + // generated from both ACCP and BouncyCastle keys. + assertArrayEquals(mu, TestUtil.computeMLDSAMu(bcPub, message)); + } } diff --git a/tst/com/amazon/corretto/crypto/provider/test/PublicUtilsTest.java b/tst/com/amazon/corretto/crypto/provider/test/PublicUtilsTest.java deleted file mode 100644 index e6a185d4..00000000 --- a/tst/com/amazon/corretto/crypto/provider/test/PublicUtilsTest.java +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. -// SPDX-License-Identifier: Apache-2.0 -package com.amazon.corretto.crypto.provider.test; - -import static org.junit.jupiter.api.Assertions.assertArrayEquals; -import static org.junit.jupiter.api.Assertions.assertEquals; - -import com.amazon.corretto.crypto.provider.AmazonCorrettoCryptoProvider; -import com.amazon.corretto.crypto.provider.PublicUtils; -import java.security.KeyFactory; -import java.security.KeyPair; -import java.security.KeyPairGenerator; -import java.security.Provider; -import java.security.PublicKey; -import java.security.spec.X509EncodedKeySpec; -import java.util.Arrays; -import org.junit.jupiter.api.condition.DisabledIf; -import org.junit.jupiter.api.extension.ExtendWith; -import org.junit.jupiter.api.parallel.Execution; -import org.junit.jupiter.api.parallel.ExecutionMode; -import org.junit.jupiter.api.parallel.ResourceAccessMode; -import org.junit.jupiter.api.parallel.ResourceLock; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.ValueSource; - -@Execution(ExecutionMode.CONCURRENT) -@ExtendWith(TestResultLogger.class) -@ResourceLock(value = TestUtil.RESOURCE_GLOBAL, mode = ResourceAccessMode.READ) -public class PublicUtilsTest { - private static final Provider NATIVE_PROVIDER = AmazonCorrettoCryptoProvider.INSTANCE; - - // TODO: remove this disablement when ACCP consumes an AWS-LC-FIPS release with ML-DSA - private static boolean mlDsaDisabled() { - return AmazonCorrettoCryptoProvider.INSTANCE.isFips() - && !AmazonCorrettoCryptoProvider.INSTANCE.isExperimentalFips(); - } - - @ParameterizedTest - @ValueSource(strings = {"ML-DSA-44", "ML-DSA-65", "ML-DSA-87"}) - @DisabledIf("mlDsaDisabled") - public void testComputeMLDSAExtMu(String algorithm) throws Exception { - KeyPair keyPair = KeyPairGenerator.getInstance(algorithm, NATIVE_PROVIDER).generateKeyPair(); - PublicKey nativePub = keyPair.getPublic(); - KeyFactory bcKf = KeyFactory.getInstance("ML-DSA", TestUtil.BC_PROVIDER); - PublicKey bcPub = bcKf.generatePublic(new X509EncodedKeySpec(nativePub.getEncoded())); - - byte[] message = new byte[256]; - Arrays.fill(message, (byte) 0x41); - byte[] mu = PublicUtils.computeMLDSAMu(nativePub, message); - assertEquals(64, mu.length); - // We don't have any other implementations of mu calculation to test against, so just assert - // that mu is equivalent - // generated from both ACCP and BouncyCastle keys. - assertArrayEquals(mu, PublicUtils.computeMLDSAMu(bcPub, message)); - } -} diff --git a/tst/com/amazon/corretto/crypto/provider/test/TestUtil.java b/tst/com/amazon/corretto/crypto/provider/test/TestUtil.java index e8f07f9a..d98ab74f 100644 --- a/tst/com/amazon/corretto/crypto/provider/test/TestUtil.java +++ b/tst/com/amazon/corretto/crypto/provider/test/TestUtil.java @@ -17,6 +17,7 @@ import java.nio.ByteBuffer; import java.security.NoSuchAlgorithmException; import java.security.Provider; +import java.security.PublicKey; import java.security.SecureRandom; import java.security.Security; import java.util.ArrayList; @@ -841,4 +842,22 @@ static boolean edKeyFactoryRegistered() { return "true" .equals(System.getProperty("com.amazon.corretto.crypto.provider.registerEdKeyFactory")); } + + private static native byte[] computeMLDSAMuInternal(byte[] pubKeyEncoded, byte[] message); + + /** + * Computes mu as defined on line 6 of Algorithm 7 and line 7 of Algorithm 8 in NIST FIPS 204. + * + *

See FIPS 204 + * + * @param publicKey ML-DSA public key + * @param message byte array of the message over which to compute mu + * @return a byte[] of length 64 containing mu + */ + static byte[] computeMLDSAMu(PublicKey publicKey, byte[] message) { + if (publicKey == null || !publicKey.getAlgorithm().startsWith("ML-DSA") || message == null) { + throw new IllegalArgumentException(); + } + return computeMLDSAMuInternal(publicKey.getEncoded(), message); + } }