Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openjdk-multiarch-jdk8u
Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/test/sun/security/pkcs11/Cipher/TestGCMKeyAndIvCheck.java
38855 views
1
/*
2
* Copyright (c) 2018, 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
/*
25
* @test
26
* @bug 8080462
27
* @library ..
28
* @modules jdk.crypto.cryptoki
29
* @run main TestGCMKeyAndIvCheck
30
* @summary Ensure that same key+iv can't be repeated used for encryption.
31
*/
32
33
34
import java.security.*;
35
import java.security.spec.AlgorithmParameterSpec;
36
import javax.crypto.*;
37
import javax.crypto.spec.*;
38
import java.math.*;
39
40
import java.util.*;
41
42
public class TestGCMKeyAndIvCheck extends PKCS11Test {
43
44
private static final byte[] AAD = new byte[5];
45
private static final byte[] PT = new byte[18];
46
47
public static void main(String[] args) throws Exception {
48
main(new TestGCMKeyAndIvCheck(), args);
49
}
50
51
private static void checkISE(Cipher c) throws Exception {
52
// Subsequent encryptions should fail
53
try {
54
c.updateAAD(AAD);
55
throw new Exception("Should throw ISE for updateAAD()");
56
} catch (IllegalStateException ise) {
57
// expected
58
}
59
60
try {
61
c.update(PT);
62
throw new Exception("Should throw ISE for update()");
63
} catch (IllegalStateException ise) {
64
// expected
65
}
66
try {
67
c.doFinal(PT);
68
throw new Exception("Should throw ISE for doFinal()");
69
} catch (IllegalStateException ise) {
70
// expected
71
}
72
}
73
74
public void test(String mode, Provider p) throws Exception {
75
Cipher c;
76
try {
77
String transformation = "AES/" + mode + "/NoPadding";
78
c = Cipher.getInstance(transformation, p);
79
} catch (GeneralSecurityException e) {
80
System.out.println("Skip testing " + p.getName() +
81
", no support for " + mode);
82
return;
83
}
84
SecretKey key = new SecretKeySpec(new byte[16], "AES");
85
// First try parameter-less init.
86
c.init(Cipher.ENCRYPT_MODE, key);
87
c.updateAAD(AAD);
88
byte[] ctPlusTag = c.doFinal(PT);
89
90
// subsequent encryption should fail unless re-init w/ different key+iv
91
checkISE(c);
92
93
// Validate the retrieved parameters against the IV and tag length.
94
AlgorithmParameters params = c.getParameters();
95
if (params == null) {
96
throw new Exception("getParameters() should not return null");
97
}
98
byte[] iv = null;
99
int tagLength = 0; // in bits
100
if (mode.equalsIgnoreCase("GCM")) {
101
GCMParameterSpec spec = params.getParameterSpec(GCMParameterSpec.class);
102
tagLength = spec.getTLen();
103
iv = spec.getIV();
104
} else {
105
throw new RuntimeException("Error: Unsupported mode: " + mode);
106
}
107
if (tagLength != (ctPlusTag.length - PT.length)*8) {
108
throw new Exception("Parameters contains incorrect TLen value");
109
}
110
if (!Arrays.equals(iv, c.getIV())) {
111
throw new Exception("Parameters contains incorrect IV value");
112
}
113
114
// Should be ok to use the same key+iv for decryption
115
c.init(Cipher.DECRYPT_MODE, key, params);
116
c.updateAAD(AAD);
117
byte[] recovered = c.doFinal(ctPlusTag);
118
if (!Arrays.equals(recovered, PT)) {
119
throw new Exception("decryption result mismatch");
120
}
121
122
// Now try to encrypt again using the same key+iv; should fail also
123
try {
124
c.init(Cipher.ENCRYPT_MODE, key, params);
125
throw new Exception("Should throw exception when same key+iv is used");
126
} catch (InvalidAlgorithmParameterException iape) {
127
// expected
128
}
129
130
// Now try to encrypt again using parameter-less init; should work
131
c.init(Cipher.ENCRYPT_MODE, key);
132
c.doFinal(PT);
133
134
// make sure a different iv is used
135
byte[] ivNew = c.getIV();
136
if (Arrays.equals(iv, ivNew)) {
137
throw new Exception("IV should be different now");
138
}
139
140
// Now try to encrypt again using a different parameter; should work
141
AlgorithmParameterSpec spec2 = new GCMParameterSpec(128, new byte[30]);
142
c.init(Cipher.ENCRYPT_MODE, key, spec2);
143
c.updateAAD(AAD);
144
c.doFinal(PT);
145
// subsequent encryption should fail unless re-init w/ different key+iv
146
checkISE(c);
147
148
// Now try decryption twice in a row; no re-init required and
149
// same parameters is used.
150
c.init(Cipher.DECRYPT_MODE, key, params);
151
c.updateAAD(AAD);
152
recovered = c.doFinal(ctPlusTag);
153
154
c.updateAAD(AAD);
155
recovered = c.doFinal(ctPlusTag);
156
if (!Arrays.equals(recovered, PT)) {
157
throw new Exception("decryption result mismatch");
158
}
159
160
// Now try decryption again and re-init using the same parameters
161
c.init(Cipher.DECRYPT_MODE, key, params);
162
c.updateAAD(AAD);
163
recovered = c.doFinal(ctPlusTag);
164
165
// init to decrypt w/o parameters; should fail with IKE as
166
// javadoc specified
167
try {
168
c.init(Cipher.DECRYPT_MODE, key);
169
throw new Exception("Should throw IKE for dec w/o params");
170
} catch (InvalidKeyException ike) {
171
// expected
172
}
173
174
// Lastly, try encryption AND decryption w/ wrong type of parameters,
175
// e.g. IvParameterSpec
176
try {
177
c.init(Cipher.ENCRYPT_MODE, key, new IvParameterSpec(iv));
178
throw new Exception("Should throw IAPE");
179
} catch (InvalidAlgorithmParameterException iape) {
180
// expected
181
}
182
try {
183
c.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec(iv));
184
throw new Exception("Should throw IAPE");
185
} catch (InvalidAlgorithmParameterException iape) {
186
// expected
187
}
188
189
System.out.println("Test Passed!");
190
}
191
192
@Override
193
public void main(Provider p) throws Exception {
194
test("GCM", p);
195
}
196
}
197
198
199