1+ /*
2+ * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved.
3+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+ *
5+ * This code is free software; you can redistribute it and/or modify it
6+ * under the terms of the GNU General Public License version 2 only, as
7+ * published by the Free Software Foundation.
8+ *
9+ * This code is distributed in the hope that it will be useful, but WITHOUT
10+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12+ * version 2 for more details (a copy is included in the LICENSE file that
13+ * accompanied this code).
14+ *
15+ * You should have received a copy of the GNU General Public License version
16+ * 2 along with this work; if not, write to the Free Software Foundation,
17+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18+ *
19+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20+ * or visit www.oracle.com if you need additional information or have any
21+ * questions.
22+ */
23+
24+ import java .io .*;
25+ import java .math .BigInteger ;
26+ import java .nio .file .Files ;
27+ import java .nio .file .Path ;
28+ import java .security .*;
29+ import java .security .spec .*;
30+ import java .util .*;
31+ import javax .crypto .*;
32+
33+ import jdk .test .lib .Asserts ;
34+
35+ /*
36+ * @test
37+ * @bug 8189189
38+ * @summary Test ECDH primitive operations
39+ * @library /test/lib
40+ * @run main ECDHPrimitive
41+ */
42+ public class ECDHPrimitive {
43+
44+
45+ private static final Map <String , String > NAME_MAP = Map .of (
46+ "P-256" , "secp256r1" ,
47+ "P-384" , "secp384r1" ,
48+ "P-521" , "secp521r1"
49+ );
50+
51+ public static void main (String [] args ) throws Exception {
52+ Path testFile = Path .of (System .getProperty ("test.src" ), "KAS_ECC_CDH_PrimitiveTest.txt" );
53+
54+ ECParameterSpec ecParams = null ;
55+
56+ try (BufferedReader in = Files .newBufferedReader (testFile )) {
57+ Map <String , byte []> values = new HashMap <>();
58+ String line = in .readLine ();
59+ while (line != null ) {
60+ line = line .trim ();
61+ if (line .startsWith ("#" ) || line .length () == 0 ) {
62+ // ignore
63+ } else if (line .startsWith ("[" )) {
64+ // change curve name
65+ StringTokenizer tok = new StringTokenizer (line , "[]" );
66+ String name = tok .nextToken ();
67+ String curveName = lookupName (name );
68+
69+ if (curveName == null ) {
70+ System .out .println ("Unknown curve: " + name
71+ + ". Skipping test" );
72+ ecParams = null ;
73+ } else {
74+ AlgorithmParameters params
75+ = AlgorithmParameters .getInstance ("EC" );
76+
77+ params .init (new ECGenParameterSpec (curveName ));
78+ ecParams = params .getParameterSpec (
79+ ECParameterSpec .class );
80+ System .out .println ("Testing curve: " + curveName );
81+ }
82+
83+ } else if (line .startsWith ("ZIUT" )) {
84+ addKeyValue (line , values );
85+ if (ecParams != null ) {
86+ runTest (ecParams , values );
87+ }
88+ } else {
89+ addKeyValue (line , values );
90+ }
91+
92+ line = in .readLine ();
93+ }
94+ }
95+ }
96+
97+ private static void runTest (ECParameterSpec ecParams ,
98+ Map <String , byte []> values ) throws Exception {
99+
100+ byte [] xArr = values .get ("QCAVSx" );
101+ BigInteger x = new BigInteger (1 , xArr );
102+ byte [] yArr = values .get ("QCAVSy" );
103+ BigInteger y = new BigInteger (1 , yArr );
104+ ECPoint w = new ECPoint (x , y );
105+ ECPublicKeySpec pubSpec = new ECPublicKeySpec (w , ecParams );
106+
107+ byte [] dArr = values .get ("dIUT" );
108+ BigInteger d = new BigInteger (1 , dArr );
109+ ECPrivateKeySpec priSpec = new ECPrivateKeySpec (d , ecParams );
110+
111+ KeyFactory kf = KeyFactory .getInstance ("EC" );
112+ PublicKey pub = kf .generatePublic (pubSpec );
113+ PrivateKey pri = kf .generatePrivate (priSpec );
114+
115+ KeyAgreement ka = KeyAgreement .getInstance ("ECDH" );
116+ ka .init (pri );
117+ ka .doPhase (pub , true );
118+ byte [] secret = ka .generateSecret ();
119+
120+ byte [] expectedSecret = values .get ("ZIUT" );
121+ Asserts .assertEqualsByteArray (secret , expectedSecret , "Incorrect secret value" );
122+ int testIndex = values .get ("COUNT" )[0 ];
123+ System .out .println ("Test " + testIndex + " passed." );
124+ }
125+
126+ private static void addKeyValue (String line , Map <String , byte []> values ) {
127+ StringTokenizer tok = new StringTokenizer (line , " =" );
128+ String key = tok .nextToken ();
129+ String value = tok .nextToken ();
130+ byte [] valueArr ;
131+ if (value .length () <= 2 ) {
132+ valueArr = new byte [1 ];
133+ valueArr [0 ] = Byte .parseByte (value , 10 );
134+ } else {
135+ valueArr = HexFormat .of ().parseHex (value );
136+ }
137+
138+ values .put (key , valueArr );
139+ }
140+
141+ private static String lookupName (String name ) {
142+ return NAME_MAP .get (name );
143+ }
144+ }
0 commit comments