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