/* * Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ import jdk.test.lib.artifacts.Artifact; import jdk.test.lib.artifacts.ArtifactResolver; import jdk.test.lib.json.JSONValue; import jtreg.SkippedException; import java.io.IOException; import java.io.InputStream; import java.nio.file.Path; import java.security.Provider; import java.security.Security; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; /* * @test * @bug 8342442 8345057 * @summary Test default implementation. Use othervm because * ML_DSA_Impls.version might be modified * @library /test/lib * @modules java.base/sun.security.provider * java.base/sun.security.util * java.base/com.sun.crypto.provider * @run main/othervm/timeout=480 Launcher */ /* * @test * @bug 8342442 8345057 * @summary Test verifying the intrinsic implementation. * @library /test/lib * @modules java.base/sun.security.provider * java.base/sun.security.util * java.base/com.sun.crypto.provider * @run main/othervm/timeout=480 -Xcomp Launcher */ /// This test runs on `internalProjection.json`-style files generated by NIST's /// ACVP Server ([GitHub repository](https://github.com/usnistgov/ACVP-Server)). /// These files are included in ZIP archives available under the /// [tags section](https://github.com/usnistgov/ACVP-Server/tags) /// of the repository. /// /// The zip archive is either hosted on artifactory server or /// specified with local path to the test. /// The test looks for test data files in the archive listed with `TEST_FILES`. /// /// These tests are currently compatible with ACVP version 1.1.0.38. /// /// By default, the test uses system-preferred implementations. /// If you want to test a specific provider, set the /// `test.acvp.provider` test property. The provider must be /// registered. /// /// Tests for each algorithm must be compliant to its specification linked from /// [https://github.com/usnistgov/ACVP?tab=readme-ov-file#supported-algorithms]. /// /// Example: /// /// Run locally with ArtifactResolver /// ``` /// jtreg -Djdk.test.lib.artifacts.ACVP-Server= /// ``` /// OR host the zip archive on artifactory server. /// public class Launcher { private static final Provider PROVIDER; private static final String ACVP_BUNDLE_LOC = "jpg.tests.jdk"; private static final String ACVP_BUNDLE_NAME = "ACVP-Server"; private static final String ACVP_BUNDLE_VERSION = "1.1.0.38"; // Zip archive entry name, do not update to use File.separator private static final String[] TEST_FILES = { "gen-val/json-files/ML-DSA-keyGen-FIPS204/internalProjection.json", "gen-val/json-files/ML-DSA-sigGen-FIPS204/internalProjection.json", "gen-val/json-files/ML-DSA-sigVer-FIPS204/internalProjection.json", "gen-val/json-files/ML-KEM-encapDecap-FIPS203/internalProjection.json", "gen-val/json-files/ML-KEM-keyGen-FIPS203/internalProjection.json" }; private static int count = 0; private static int invalidTest = 0; private static int unsupportedTest = 0; static { var provProp = System.getProperty("test.acvp.provider"); if (provProp != null) { var p = Security.getProvider(provProp); if (p == null) { System.err.println(provProp + " is not a registered provider name"); throw new RuntimeException(provProp + " is not a registered provider name"); } PROVIDER = p; } else { PROVIDER = null; } } public static void main(String[] args) throws Exception { Path archivePath = null; try { archivePath = ArtifactResolver.fetchOne(ACVP_SERVER_TESTS.class); } catch (IOException e) { if (e.getMessage().contains("Cannot find the artifact ACVP-Server")) { throw new SkippedException("ACVP-Server not available."); } } System.out.println("Data path: " + archivePath); if (PROVIDER != null) { System.out.println("Provider: " + PROVIDER.getName()); } // Read test data files from zip archive try (ZipFile zf = new ZipFile(archivePath.toFile())) { for (String testFile : TEST_FILES) { // Zip archive entry name, do not update to use File.separator String fullEntryName = ACVP_BUNDLE_NAME + "-" + ACVP_BUNDLE_VERSION + "/" + testFile; System.out.println("Find and test with: " + fullEntryName); ZipEntry ze = zf.getEntry(fullEntryName); if (ze != null) { run(zf.getInputStream(ze)); } else { throw new RuntimeException("Entry not found: " + fullEntryName); } } } if (count > 0) { System.out.println(); System.out.println("Test completed: " + count); System.out.println("Invalid tests: " + invalidTest); System.out.println("Unsupported tests: " + unsupportedTest); } else { throw new RuntimeException("No supported test found"); } if (invalidTest != 0 || unsupportedTest != 0){ throw new RuntimeException("Invalid or Unsupported tests found"); } } static void run(InputStream test) { try { JSONValue kat; try (test) { kat = JSONValue.parse(new String(test.readAllBytes())); } catch (Exception e) { System.out.println("Warning: cannot parse " + test + ". Skipped"); invalidTest++; return; } var alg = kat.get("algorithm").asString(); switch (alg) { case "ML-DSA" -> { ML_DSA_Test.run(kat, PROVIDER); count++; } case "ML-KEM" -> { ML_KEM_Test.run(kat, PROVIDER); count++; } case "SHA2-256", "SHA2-224", "SHA3-256", "SHA3-224" -> { SHA_Test.run(kat, PROVIDER); count++; } default -> { System.out.println("Skipped unsupported algorithm: " + alg); unsupportedTest++; } } } catch (RuntimeException re) { throw re; } catch (Exception e) { throw new RuntimeException(e); } } @Artifact( organization = ACVP_BUNDLE_LOC, name = ACVP_BUNDLE_NAME, revision = ACVP_BUNDLE_VERSION, extension = "zip", unpack = false) private static class ACVP_SERVER_TESTS { } }