Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/test/jdk/javax/crypto/CipherSpi/DirectBBRemaining.java
41149 views
1
/*
2
* Copyright (c) 2012, 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 7142509
27
* @summary Cipher.doFinal(ByteBuffer,ByteBuffer) fails to
28
* process when in.remaining() == 0
29
* @key randomness
30
*/
31
32
import java.nio.ByteBuffer;
33
import java.security.SecureRandom;
34
import java.util.Arrays;
35
import java.util.Random;
36
37
import javax.crypto.Cipher;
38
import javax.crypto.SecretKey;
39
import javax.crypto.spec.SecretKeySpec;
40
41
/*
42
* Simple test case to show that Cipher.doFinal(ByteBuffer, ByteBuffer) fails to
43
* process the data internally buffered inBB the cipher when input.remaining()
44
* == 0 and at least one buffer is a direct buffer.
45
*/
46
public class DirectBBRemaining {
47
48
private static Random random = new SecureRandom();
49
private static int testSizes = 40;
50
private static int outputFrequency = 5;
51
52
public static void main(String args[]) throws Exception {
53
boolean failedOnce = false;
54
Exception failedReason = null;
55
56
byte[] keyBytes = new byte[8];
57
random.nextBytes(keyBytes);
58
SecretKey key = new SecretKeySpec(keyBytes, "DES");
59
60
Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding", "SunJCE");
61
cipher.init(Cipher.ENCRYPT_MODE, key);
62
63
/*
64
* Iterate through various sizes to make sure that the code does empty
65
* blocks, single partial blocks, 1 full block, full + partial blocks,
66
* multiple full blocks, etc. 5 blocks (using DES) is probably overkill
67
* but will feel more confident the fix isn't breaking anything.
68
*/
69
System.out.println("Output test results for every "
70
+ outputFrequency + " tests...");
71
72
for (int size = 0; size <= testSizes; size++) {
73
boolean output = (size % outputFrequency) == 0;
74
if (output) {
75
System.out.print("\nTesting buffer size: " + size + ":");
76
}
77
78
int outSize = cipher.getOutputSize(size);
79
80
try {
81
encrypt(cipher, size,
82
ByteBuffer.allocate(size),
83
ByteBuffer.allocate(outSize),
84
ByteBuffer.allocateDirect(size),
85
ByteBuffer.allocateDirect(outSize),
86
output);
87
} catch (Exception e) {
88
System.out.print("\n Failed with size " + size);
89
failedOnce = true;
90
failedReason = e;
91
92
// If we got an exception, let's be safe for future
93
// testing and reset the cipher to a known good state.
94
cipher.init(Cipher.ENCRYPT_MODE, key);
95
}
96
}
97
if (failedOnce) {
98
throw failedReason;
99
}
100
System.out.println("\nTest Passed...");
101
}
102
103
private enum TestVariant {
104
105
HEAP_HEAP, HEAP_DIRECT, DIRECT_HEAP, DIRECT_DIRECT
106
};
107
108
private static void encrypt(Cipher cipher, int size,
109
ByteBuffer heapIn, ByteBuffer heapOut,
110
ByteBuffer directIn, ByteBuffer directOut,
111
boolean output) throws Exception {
112
113
ByteBuffer inBB = null;
114
ByteBuffer outBB = null;
115
116
// Set up data and encrypt to known/expected values.
117
byte[] testdata = new byte[size];
118
random.nextBytes(testdata);
119
byte[] expected = cipher.doFinal(testdata);
120
121
for (TestVariant tv : TestVariant.values()) {
122
if (output) {
123
System.out.print(" " + tv);
124
}
125
126
switch (tv) {
127
case HEAP_HEAP:
128
inBB = heapIn;
129
outBB = heapOut;
130
break;
131
case HEAP_DIRECT:
132
inBB = heapIn;
133
outBB = directOut;
134
break;
135
case DIRECT_HEAP:
136
inBB = directIn;
137
outBB = heapOut;
138
break;
139
case DIRECT_DIRECT:
140
inBB = directIn;
141
outBB = directOut;
142
break;
143
}
144
145
inBB.clear();
146
outBB.clear();
147
148
inBB.put(testdata);
149
inBB.flip();
150
151
// Process all data in one shot, but don't call doFinal() yet.
152
// May store up to n-1 bytes (w/block size n) internally.
153
cipher.update(inBB, outBB);
154
if (inBB.hasRemaining()) {
155
throw new Exception("buffer not empty");
156
}
157
158
// finish encryption and process all data buffered
159
cipher.doFinal(inBB, outBB);
160
outBB.flip();
161
162
// validate output size
163
if (outBB.remaining() != expected.length) {
164
throw new Exception(
165
"incomplete encryption output, expected "
166
+ expected.length + " bytes but was only "
167
+ outBB.remaining() + " bytes");
168
}
169
170
// validate output data
171
byte[] encrypted = new byte[outBB.remaining()];
172
outBB.get(encrypted);
173
if (!Arrays.equals(expected, encrypted)) {
174
throw new Exception("bad encryption output");
175
}
176
177
if (!Arrays.equals(cipher.doFinal(), cipher.doFinal())) {
178
throw new Exception("Internal buffers still held data!");
179
}
180
}
181
}
182
}
183
184