Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/test/jdk/com/sun/crypto/provider/Cipher/TestCipher.java
41159 views
1
/*
2
* Copyright (c) 2015, 2016, 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 static java.lang.System.out;
25
26
import java.security.InvalidAlgorithmParameterException;
27
import java.security.InvalidKeyException;
28
import java.security.NoSuchAlgorithmException;
29
import java.security.NoSuchProviderException;
30
import java.security.spec.AlgorithmParameterSpec;
31
32
import javax.crypto.BadPaddingException;
33
import javax.crypto.Cipher;
34
import javax.crypto.IllegalBlockSizeException;
35
import javax.crypto.KeyGenerator;
36
import javax.crypto.NoSuchPaddingException;
37
import javax.crypto.SecretKey;
38
import javax.crypto.ShortBufferException;
39
import javax.crypto.spec.IvParameterSpec;
40
import javax.crypto.spec.SecretKeySpec;
41
42
/**
43
* This is a abstract class used to test various ciphers
44
*/
45
public abstract class TestCipher {
46
47
private final String SUNJCE = "SunJCE";
48
private final String ALGORITHM;
49
private final String[] MODES;
50
private final String[] PADDINGS;
51
52
/* Used to test variable-key-length ciphers:
53
Key size tested is increment of KEYCUTTER from minKeySize
54
to min(maxKeySize, Cipher.getMaxAllowedKeyLength(algo)).
55
*/
56
private final int KEYCUTTER = 8;
57
private final int minKeySize;
58
private final int maxKeySize;
59
60
// Used to assert that Encryption/Decryption works with same buffer
61
// TEXT_LEN is multiple of blocks in order to work against ciphers w/ NoPadding
62
private final int TEXT_LEN = 800;
63
private final int ENC_OFFSET = 6;
64
private final int STORAGE_OFFSET = 3;
65
private final int PAD_BYTES = 16;
66
67
private final byte[] IV;
68
private final byte[] INPUT_TEXT;
69
70
// for variable-key-length ciphers
71
TestCipher(String algo, String[] modes, String[] paddings,
72
int minKeySize, int maxKeySize) throws NoSuchAlgorithmException {
73
ALGORITHM = algo;
74
MODES = modes;
75
PADDINGS = paddings;
76
this.minKeySize = minKeySize;
77
int maxAllowedKeySize = Cipher.getMaxAllowedKeyLength(ALGORITHM);
78
if (maxKeySize > maxAllowedKeySize) {
79
maxKeySize = maxAllowedKeySize;
80
}
81
this.maxKeySize = maxKeySize;
82
IV = generateBytes(8);
83
INPUT_TEXT = generateBytes(TEXT_LEN + PAD_BYTES + ENC_OFFSET);
84
}
85
86
// for fixed-key-length ciphers
87
TestCipher(String algo, String[] modes, String[] paddings) {
88
ALGORITHM = algo;
89
MODES = modes;
90
PADDINGS = paddings;
91
this.minKeySize = this.maxKeySize = 0;
92
93
IV = generateBytes(8);
94
INPUT_TEXT = generateBytes(TEXT_LEN + PAD_BYTES + ENC_OFFSET);
95
}
96
97
private static byte[] generateBytes(int length) {
98
byte[] bytes = new byte[length];
99
for (int i = 0; i < length; i++) {
100
bytes[i] = (byte) (i & 0xff);
101
}
102
return bytes;
103
}
104
105
private boolean isMultipleKeyLengthSupported() {
106
return (maxKeySize != minKeySize);
107
}
108
109
public void runAll() throws InvalidKeyException,
110
NoSuchPaddingException, InvalidAlgorithmParameterException,
111
ShortBufferException, IllegalBlockSizeException,
112
BadPaddingException, NoSuchAlgorithmException,
113
NoSuchProviderException {
114
115
for (String mode : MODES) {
116
for (String padding : PADDINGS) {
117
if (!isMultipleKeyLengthSupported()) {
118
runTest(mode, padding, minKeySize);
119
} else {
120
int keySize = maxKeySize;
121
while (keySize >= minKeySize) {
122
out.println("With Key Strength: " + keySize);
123
runTest(mode, padding, keySize);
124
keySize -= KEYCUTTER;
125
}
126
}
127
}
128
}
129
}
130
131
private void runTest(String mo, String pad, int keySize)
132
throws NoSuchPaddingException, BadPaddingException,
133
ShortBufferException, IllegalBlockSizeException,
134
InvalidAlgorithmParameterException, InvalidKeyException,
135
NoSuchAlgorithmException, NoSuchProviderException {
136
137
String TRANSFORMATION = ALGORITHM + "/" + mo + "/" + pad;
138
out.println("Testing: " + TRANSFORMATION);
139
140
// Initialization
141
Cipher ci = Cipher.getInstance(TRANSFORMATION, SUNJCE);
142
KeyGenerator kg = KeyGenerator.getInstance(ALGORITHM, SUNJCE);
143
if (keySize != 0) {
144
kg.init(keySize);
145
}
146
147
SecretKey key = kg.generateKey();
148
SecretKeySpec skeySpec = new SecretKeySpec(key.getEncoded(), ALGORITHM);
149
150
AlgorithmParameterSpec aps = new IvParameterSpec(IV);
151
if (mo.equalsIgnoreCase("ECB")) {
152
ci.init(Cipher.ENCRYPT_MODE, key);
153
} else {
154
ci.init(Cipher.ENCRYPT_MODE, key, aps);
155
}
156
157
// Encryption
158
byte[] plainText = INPUT_TEXT.clone();
159
160
// Generate cipher and save to separate buffer
161
byte[] cipherText = ci.doFinal(INPUT_TEXT, ENC_OFFSET, TEXT_LEN);
162
163
// Generate cipher and save to same buffer
164
int enc_bytes = ci.update(
165
INPUT_TEXT, ENC_OFFSET, TEXT_LEN, INPUT_TEXT, STORAGE_OFFSET);
166
enc_bytes += ci.doFinal(INPUT_TEXT, enc_bytes + STORAGE_OFFSET);
167
168
if (!equalsBlock(
169
INPUT_TEXT, STORAGE_OFFSET, enc_bytes,
170
cipherText, 0, cipherText.length)) {
171
throw new RuntimeException(
172
"Different ciphers generated with same buffer");
173
}
174
175
// Decryption
176
if (mo.equalsIgnoreCase("ECB")) {
177
ci.init(Cipher.DECRYPT_MODE, skeySpec);
178
} else {
179
ci.init(Cipher.DECRYPT_MODE, skeySpec, aps);
180
}
181
182
// Recover text from cipher and save to separate buffer
183
byte[] recoveredText = ci.doFinal(cipherText, 0, cipherText.length);
184
185
if (!equalsBlock(
186
plainText, ENC_OFFSET, TEXT_LEN,
187
recoveredText, 0, recoveredText.length)) {
188
throw new RuntimeException(
189
"Recovered text not same as plain text");
190
} else {
191
out.println("Recovered and plain text are same");
192
}
193
194
// Recover text from cipher and save to same buffer
195
int dec_bytes = ci.update(
196
INPUT_TEXT, STORAGE_OFFSET, enc_bytes, INPUT_TEXT, ENC_OFFSET);
197
dec_bytes += ci.doFinal(INPUT_TEXT, dec_bytes + ENC_OFFSET);
198
199
if (!equalsBlock(
200
plainText, ENC_OFFSET, TEXT_LEN,
201
INPUT_TEXT, ENC_OFFSET, dec_bytes)) {
202
throw new RuntimeException(
203
"Recovered text not same as plain text with same buffer");
204
} else {
205
out.println("Recovered and plain text are same with same buffer");
206
}
207
208
out.println("Test Passed.");
209
}
210
211
private static boolean equalsBlock(byte[] b1, int off1, int len1,
212
byte[] b2, int off2, int len2) {
213
if (len1 != len2) {
214
return false;
215
}
216
for (int i = off1, j = off2, k = 0; k < len1; i++, j++, k++) {
217
if (b1[i] != b2[j]) {
218
return false;
219
}
220
}
221
return true;
222
}
223
}
224
225