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