Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/test/jdk/com/sun/crypto/provider/Cipher/AEAD/GCMBufferTest.java
41161 views
1
/*
2
* Copyright (c) 2020, 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
* @summary Use Cipher update and doFinal with a mixture of byte[], bytebuffer,
27
* and offset while verifying return values. Also using different and
28
* in-place buffers.
29
*
30
* in-place is not tested with different buffer types as it is not a logical
31
* scenario and is complicated by getOutputSize calculations.
32
*/
33
34
import javax.crypto.Cipher;
35
import javax.crypto.SecretKey;
36
import javax.crypto.spec.GCMParameterSpec;
37
import javax.crypto.spec.SecretKeySpec;
38
import java.io.ByteArrayOutputStream;
39
import java.math.BigInteger;
40
import java.nio.ByteBuffer;
41
import java.security.SecureRandom;
42
import java.util.Arrays;
43
import java.util.HashMap;
44
import java.util.List;
45
46
public class GCMBufferTest implements Cloneable {
47
48
// Data type for the operation
49
enum dtype { BYTE, HEAP, DIRECT };
50
// Data map
51
static HashMap<String, List<Data>> datamap = new HashMap<>();
52
// List of enum values for order of operation
53
List<dtype> ops;
54
55
static final int AESBLOCK = 16;
56
// The remaining input data length is inserted at the particular index
57
// in sizes[] during execution.
58
static final int REMAINDER = -1;
59
60
String algo;
61
boolean same = true;
62
int[] sizes;
63
boolean incremental = false;
64
// In some cases the theoretical check is too complicated to verify
65
boolean theoreticalCheck;
66
List<Data> dataSet;
67
int inOfs = 0, outOfs = 0;
68
69
static class Data {
70
int id;
71
SecretKey key;
72
byte[] iv;
73
byte[] pt;
74
byte[] aad;
75
byte[] ct;
76
byte[] tag;
77
78
Data(String keyalgo, int id, String key, String iv, byte[] pt, String aad,
79
String ct, String tag) {
80
this.id = id;
81
this.key = new SecretKeySpec(HexToBytes(key), keyalgo);
82
this.iv = HexToBytes(iv);
83
this.pt = pt;
84
this.aad = HexToBytes(aad);
85
this.ct = HexToBytes(ct);
86
this.tag = HexToBytes(tag);
87
}
88
89
Data(String keyalgo, int id, String key, String iv, String pt, String aad,
90
String ct, String tag) {
91
this(keyalgo, id, key, iv, HexToBytes(pt), aad, ct, tag);
92
}
93
94
Data(String keyalgo, int id, String key, int ptlen) {
95
this.id = id;
96
this.key = new SecretKeySpec(HexToBytes(key), keyalgo);
97
iv = new byte[16];
98
pt = new byte[ptlen];
99
tag = new byte[12];
100
aad = new byte[0];
101
byte[] tct = null;
102
try {
103
SecureRandom r = new SecureRandom();
104
r.nextBytes(iv);
105
r.nextBytes(pt);
106
Cipher c = Cipher.getInstance("AES/GCM/NoPadding");
107
c.init(Cipher.ENCRYPT_MODE, this.key,
108
new GCMParameterSpec(tag.length * 8, this.iv));
109
tct = c.doFinal(pt);
110
} catch (Exception e) {
111
System.out.println("Error in generating data for length " +
112
ptlen);
113
}
114
ct = new byte[ptlen];
115
System.arraycopy(tct, 0, ct, 0, ct.length);
116
System.arraycopy(tct, ct.length, tag, 0, tag.length);
117
}
118
119
}
120
121
/**
122
* Construct a test with an algorithm and a list of dtype.
123
* @param algo Algorithm string
124
* @param ops List of dtypes. If only one dtype is specified, only a
125
* doFinal operation will occur. If multiple dtypes are
126
* specified, the last is a doFinal, the others are updates.
127
*/
128
GCMBufferTest(String algo, List<dtype> ops) {
129
this.algo = algo;
130
this.ops = ops;
131
theoreticalCheck = true;
132
dataSet = datamap.get(algo);
133
}
134
135
public GCMBufferTest clone() throws CloneNotSupportedException{
136
return (GCMBufferTest)super.clone();
137
}
138
139
/**
140
* Define particular data sizes to be tested. "REMAINDER", which has a
141
* value of -1, can be used to insert the remaining input text length at
142
* that index during execution.
143
* @param sizes Data sizes for each dtype in the list.
144
*/
145
GCMBufferTest dataSegments(int[] sizes) {
146
this.sizes = sizes;
147
return this;
148
}
149
150
/**
151
* Do not perform in-place operations
152
*/
153
GCMBufferTest differentBufferOnly() {
154
this.same = false;
155
return this;
156
}
157
158
/**
159
* Enable incrementing through each data size available. This can only be
160
* used when the List has more than one dtype entry.
161
*/
162
GCMBufferTest incrementalSegments() {
163
this.incremental = true;
164
return this;
165
}
166
167
/**
168
* Specify a particular test dataset.
169
*
170
* @param id id value for the test data to used in this test.
171
*/
172
GCMBufferTest dataSet(int id) throws Exception {
173
for (Data d : datamap.get(algo)) {
174
if (d.id == id) {
175
dataSet = List.of(d);
176
return this;
177
}
178
}
179
throw new Exception("Unaeble to find dataSet id = " + id);
180
}
181
182
/**
183
* Set both input and output offsets to the same offset
184
* @param offset value for inOfs and outOfs
185
* @return
186
*/
187
GCMBufferTest offset(int offset) {
188
this.inOfs = offset;
189
this.outOfs = offset;
190
return this;
191
}
192
193
/**
194
* Set the input offset
195
* @param offset value for input offset
196
* @return
197
*/
198
GCMBufferTest inOfs(int offset) {
199
this.inOfs = offset;
200
return this;
201
}
202
203
/**
204
* Set the output offset
205
* @param offset value for output offset
206
* @return
207
*/
208
GCMBufferTest outOfs(int offset) {
209
this.outOfs = offset;
210
return this;
211
}
212
213
/**
214
* Reverse recursive loop that starts at the end-1 index, going to 0, in
215
* the size array to calculate all the possible sizes.
216
* It returns the remaining data size not used in the loop. This remainder
217
* is used for the end index which is the doFinal op.
218
*/
219
int inc(int index, int max, int total) {
220
if (sizes[index] == max - total) {
221
sizes[index + 1]++;
222
total++;
223
sizes[index] = 0;
224
} else if (index == 0) {
225
sizes[index]++;
226
}
227
228
total += sizes[index];
229
if (index > 0) {
230
return inc(index - 1, max, total);
231
}
232
return total;
233
}
234
235
// Call recursive loop and take returned remainder value for last index
236
boolean incrementSizes(int max) {
237
sizes[ops.size() - 1] = max - inc(ops.size() - 2, max, 0);
238
if (sizes[ops.size() - 2] == max) {
239
// We are at the end, exit test loop
240
return false;
241
}
242
return true;
243
}
244
245
void test() throws Exception {
246
int i = 1;
247
System.out.println("Algo: " + algo + " \tOps: " + ops.toString());
248
for (Data data : dataSet) {
249
250
// If incrementalSegments is enabled, run through that test only
251
if (incremental) {
252
if (ops.size() < 2) {
253
throw new Exception("To do incrementalSegments you must" +
254
"have more that 1 dtype in the list");
255
}
256
sizes = new int[ops.size()];
257
258
while (incrementSizes(data.pt.length)) {
259
System.out.print("Encrypt: Data Index: " + i + " \tSizes[ ");
260
for (int v : sizes) {
261
System.out.print(v + " ");
262
}
263
System.out.println("]");
264
encrypt(data);
265
}
266
Arrays.fill(sizes, 0);
267
268
while (incrementSizes(data.ct.length + data.tag.length)) {
269
System.out.print("Decrypt: Data Index: " + i + " \tSizes[ ");
270
for (int v : sizes) {
271
System.out.print(v + " ");
272
}
273
System.out.println("]");
274
decrypt(data);
275
}
276
277
} else {
278
// Default test of 0 and 2 offset doing in place and different
279
// i/o buffers
280
System.out.println("Encrypt: Data Index: " + i);
281
encrypt(data);
282
283
System.out.println("Decrypt: Data Index: " + i);
284
decrypt(data);
285
}
286
i++;
287
}
288
}
289
290
// Setup data for encryption
291
void encrypt(Data data) throws Exception {
292
byte[] input, output;
293
294
input = data.pt;
295
output = new byte[data.ct.length + data.tag.length];
296
System.arraycopy(data.ct, 0, output, 0, data.ct.length);
297
System.arraycopy(data.tag, 0, output, data.ct.length,
298
data.tag.length);
299
300
// Test different input/output buffers
301
System.out.println("\tinput len: " + input.length + " inOfs " +
302
inOfs + " outOfs " + outOfs + " in/out buffer: different");
303
crypto(true, data, input, output);
304
305
// Test with in-place buffers
306
if (same) {
307
System.out.println("\tinput len: " + input.length + " inOfs " +
308
inOfs + " outOfs " + outOfs + " in/out buffer: in-place");
309
cryptoSameBuffer(true, data, input, output);
310
}
311
}
312
313
// Setup data for decryption
314
void decrypt(Data data) throws Exception {
315
byte[] input, output;
316
317
input = new byte[data.ct.length + data.tag.length];
318
System.arraycopy(data.ct, 0, input, 0, data.ct.length);
319
System.arraycopy(data.tag, 0, input, data.ct.length, data.tag.length);
320
output = data.pt;
321
322
// Test different input/output buffers
323
System.out.println("\tinput len: " + input.length + " inOfs " +
324
inOfs + " outOfs " + outOfs + " in-place: different");
325
crypto(false, data, input, output);
326
327
// Test with in-place buffers
328
if (same) {
329
System.out.println("\tinput len: " + input.length + " inOfs " +
330
inOfs + " outOfs " + outOfs + " in-place: same");
331
cryptoSameBuffer(false, data, input, output);
332
}
333
}
334
335
/**
336
* Perform cipher operation using different input and output buffers.
337
* This method allows mixing of data types (byte, heap, direct).
338
*/
339
void crypto(boolean encrypt, Data d, byte[] input, byte[] output)
340
throws Exception {
341
byte[] pt = new byte[input.length + inOfs];
342
System.arraycopy(input, 0, pt, inOfs, input.length);
343
byte[] expectedOut = new byte[output.length + outOfs];
344
System.arraycopy(output, 0, expectedOut, outOfs, output.length);
345
int plen = input.length / ops.size(); // partial input length
346
int theoreticallen;// expected output length
347
int dataoffset = 0; // offset of unconsumed data in pt
348
int index = 0; // index of which op we are on
349
int rlen; // result length
350
int pbuflen = 0; // plen remaining in the GCM internal buffers
351
352
Cipher cipher = Cipher.getInstance(algo);
353
cipher.init((encrypt ? Cipher.ENCRYPT_MODE : Cipher.DECRYPT_MODE),
354
d.key, new GCMParameterSpec(d.tag.length * 8, d.iv));
355
cipher.updateAAD(d.aad);
356
357
ByteArrayOutputStream ba = new ByteArrayOutputStream();
358
ba.write(new byte[outOfs], 0, outOfs);
359
for (dtype v : ops) {
360
if (index < ops.size() - 1) {
361
if (sizes != null && input.length > 0) {
362
if (sizes[index] == -1) {
363
plen = input.length - dataoffset;
364
} else {
365
if (sizes[index] > input.length) {
366
plen = input.length;
367
} else {
368
plen = sizes[index];
369
}
370
}
371
}
372
373
int olen = cipher.getOutputSize(plen) + outOfs;
374
375
/*
376
* The theoretical limit is the length of the data sent to
377
* update() + any data might be setting in CipherCore or GCM
378
* internal buffers % the block size.
379
*/
380
theoreticallen = (plen + pbuflen) - ((plen + pbuflen) % AESBLOCK);
381
382
// Update operations
383
switch (v) {
384
case BYTE -> {
385
byte[] out = new byte[olen];
386
rlen = cipher.update(pt, dataoffset + inOfs, plen, out,
387
outOfs);
388
ba.write(out, outOfs, rlen);
389
}
390
case HEAP -> {
391
ByteBuffer b = ByteBuffer.allocate(plen + outOfs);
392
b.position(outOfs);
393
b.put(pt, dataoffset + inOfs, plen);
394
b.flip();
395
b.position(outOfs);
396
ByteBuffer out = ByteBuffer.allocate(olen);
397
out.position(outOfs);
398
rlen = cipher.update(b, out);
399
ba.write(out.array(), outOfs, rlen);
400
}
401
case DIRECT -> {
402
ByteBuffer b = ByteBuffer.allocateDirect(plen + outOfs);
403
b.position(outOfs);
404
b.put(pt, dataoffset + inOfs, plen);
405
b.flip();
406
b.position(outOfs);
407
ByteBuffer out = ByteBuffer.allocateDirect(olen);
408
out.position(outOfs);
409
rlen = cipher.update(b, out);
410
byte[] o = new byte[rlen];
411
out.flip();
412
out.position(outOfs);
413
out.get(o, 0, rlen);
414
ba.write(o);
415
}
416
default -> throw new Exception("Unknown op: " + v.name());
417
}
418
419
if (theoreticalCheck) {
420
pbuflen += plen - rlen;
421
if (encrypt && rlen != theoreticallen) {
422
throw new Exception("Wrong update return len (" +
423
v.name() + "): " + "rlen=" + rlen +
424
", expected output len=" + theoreticallen);
425
}
426
}
427
428
dataoffset += plen;
429
index++;
430
431
} else {
432
// doFinal operation
433
plen = input.length - dataoffset;
434
435
int olen = cipher.getOutputSize(plen) + outOfs;
436
switch (v) {
437
case BYTE -> {
438
byte[] out = new byte[olen];
439
rlen = cipher.doFinal(pt, dataoffset + inOfs,
440
plen, out, outOfs);
441
ba.write(out, outOfs, rlen);
442
}
443
case HEAP -> {
444
ByteBuffer b = ByteBuffer.allocate(plen + inOfs);
445
b.limit(b.capacity());
446
b.position(inOfs);
447
b.put(pt, dataoffset + inOfs, plen);
448
b.flip();
449
b.position(inOfs);
450
ByteBuffer out = ByteBuffer.allocate(olen);
451
out.limit(out.capacity());
452
out.position(outOfs);
453
rlen = cipher.doFinal(b, out);
454
ba.write(out.array(), outOfs, rlen);
455
}
456
case DIRECT -> {
457
ByteBuffer b = ByteBuffer.allocateDirect(plen + inOfs);
458
b.limit(b.capacity());
459
b.position(inOfs);
460
b.put(pt, dataoffset + inOfs, plen);
461
b.flip();
462
b.position(inOfs);
463
ByteBuffer out = ByteBuffer.allocateDirect(olen);
464
out.limit(out.capacity());
465
out.position(outOfs);
466
rlen = cipher.doFinal(b, out);
467
byte[] o = new byte[rlen];
468
out.flip();
469
out.position(outOfs);
470
out.get(o, 0, rlen);
471
ba.write(o);
472
}
473
default -> throw new Exception("Unknown op: " + v.name());
474
}
475
476
if (theoreticalCheck && rlen != olen - outOfs) {
477
throw new Exception("Wrong doFinal return len (" +
478
v.name() + "): " + "rlen=" + rlen +
479
", expected output len=" + (olen - outOfs));
480
}
481
482
// Verify results
483
byte[] ctresult = ba.toByteArray();
484
if (ctresult.length != expectedOut.length ||
485
Arrays.compare(ctresult, expectedOut) != 0) {
486
String s = "Ciphertext mismatch (" + v.name() +
487
"):\nresult (len=" + ctresult.length + "):" +
488
String.format("%0" + (ctresult.length << 1) + "x",
489
new BigInteger(1, ctresult)) +
490
"\nexpected (len=" + output.length + "):" +
491
String.format("%0" + (output.length << 1) + "x",
492
new BigInteger(1, output));
493
System.err.println(s);
494
throw new Exception(s);
495
496
}
497
}
498
}
499
}
500
501
/**
502
* Perform cipher operation using in-place buffers. This method does not
503
* allow mixing of data types (byte, heap, direct).
504
*
505
* Mixing data types makes no sense for in-place operations and would
506
* greatly complicate the test code.
507
*/
508
void cryptoSameBuffer(boolean encrypt, Data d, byte[] input, byte[] output) throws Exception {
509
510
byte[] data, out;
511
if (encrypt) {
512
data = new byte[output.length + Math.max(inOfs, outOfs)];
513
} else {
514
data = new byte[input.length + Math.max(inOfs, outOfs)];
515
}
516
517
ByteBuffer bbin = null, bbout = null;
518
System.arraycopy(input, 0, data, inOfs, input.length);
519
byte[] expectedOut = new byte[output.length + outOfs];
520
System.arraycopy(output, 0, expectedOut, outOfs, output.length);
521
int plen = input.length / ops.size(); // partial input length
522
int theorticallen = plen - (plen % AESBLOCK); // output length
523
int dataoffset = 0;
524
int index = 0;
525
int rlen = 0; // result length
526
int len = 0;
527
528
Cipher cipher = Cipher.getInstance(algo);
529
cipher.init((encrypt ? Cipher.ENCRYPT_MODE : Cipher.DECRYPT_MODE),
530
d.key, new GCMParameterSpec(d.tag.length * 8, d.iv));
531
cipher.updateAAD(d.aad);
532
533
// Prepare data
534
switch (ops.get(0)) {
535
case HEAP -> {
536
bbin = ByteBuffer.wrap(data);
537
bbin.limit(input.length + inOfs);
538
bbout = bbin.duplicate();
539
}
540
case DIRECT -> {
541
bbin = ByteBuffer.allocateDirect(data.length);
542
bbout = bbin.duplicate();
543
bbin.put(data, 0, input.length + inOfs);
544
bbin.flip();
545
}
546
}
547
548
// Set data limits for bytebuffers
549
if (bbin != null) {
550
bbin.position(inOfs);
551
bbout.limit(output.length + outOfs);
552
bbout.position(outOfs);
553
}
554
555
// Iterate through each operation
556
for (dtype v : ops) {
557
if (index < ops.size() - 1) {
558
switch (v) {
559
case BYTE -> {
560
rlen = cipher.update(data, dataoffset + inOfs, plen,
561
data, len + outOfs);
562
}
563
case HEAP, DIRECT -> {
564
theorticallen = bbin.remaining() -
565
(bbin.remaining() % AESBLOCK);
566
rlen = cipher.update(bbin, bbout);
567
}
568
default -> throw new Exception("Unknown op: " + v.name());
569
}
570
571
// Check that the theoretical return value matches the actual.
572
if (theoreticalCheck && encrypt && rlen != theorticallen) {
573
throw new Exception("Wrong update return len (" +
574
v.name() + "): " + "rlen=" + rlen +
575
", expected output len=" + theorticallen);
576
}
577
578
dataoffset += plen;
579
len += rlen;
580
index++;
581
582
} else {
583
// Run doFinal op
584
plen = input.length - dataoffset;
585
586
switch (v) {
587
case BYTE -> {
588
rlen = cipher.doFinal(data, dataoffset + inOfs,
589
plen, data, len + outOfs);
590
out = Arrays.copyOfRange(data, 0,len + rlen + outOfs);
591
}
592
case HEAP, DIRECT -> {
593
rlen = cipher.doFinal(bbin, bbout);
594
bbout.flip();
595
out = new byte[bbout.remaining()];
596
bbout.get(out);
597
}
598
default -> throw new Exception("Unknown op: " + v.name());
599
}
600
len += rlen;
601
602
// Verify results
603
if (len != output.length ||
604
Arrays.compare(out, 0, len, expectedOut, 0,
605
output.length) != 0) {
606
String s = "Ciphertext mismatch (" + v.name() +
607
"):\nresult (len=" + len + "):\n" +
608
byteToHex(out) +
609
"\nexpected (len=" + output.length + "):\n" +
610
String.format("%0" + (output.length << 1) + "x",
611
new BigInteger(1, output));
612
System.err.println(s);
613
throw new Exception(s);
614
}
615
}
616
}
617
}
618
static void offsetTests(GCMBufferTest t) throws Exception {
619
t.clone().offset(2).test();
620
t.clone().inOfs(2).test();
621
// Test not designed for overlap situations
622
t.clone().outOfs(2).differentBufferOnly().test();
623
}
624
625
public static void main(String args[]) throws Exception {
626
initTest();
627
// Test single byte array
628
new GCMBufferTest("AES/GCM/NoPadding", List.of(dtype.BYTE)).test();
629
offsetTests(new GCMBufferTest("AES/GCM/NoPadding", List.of(dtype.BYTE)));
630
// Test update-doFinal with byte arrays
631
new GCMBufferTest("AES/GCM/NoPadding", List.of(dtype.BYTE, dtype.BYTE)).test();
632
offsetTests(new GCMBufferTest("AES/GCM/NoPadding", List.of(dtype.BYTE, dtype.BYTE)));
633
// Test update-update-doFinal with byte arrays
634
new GCMBufferTest("AES/GCM/NoPadding",
635
List.of(dtype.BYTE, dtype.BYTE, dtype.BYTE)).test();
636
offsetTests(new GCMBufferTest("AES/GCM/NoPadding", List.of(dtype.BYTE, dtype.BYTE, dtype.BYTE)));
637
638
// Test single heap bytebuffer
639
new GCMBufferTest("AES/GCM/NoPadding", List.of(dtype.HEAP)).test();
640
offsetTests(new GCMBufferTest("AES/GCM/NoPadding", List.of(dtype.HEAP)));
641
// Test update-doFinal with heap bytebuffer
642
new GCMBufferTest("AES/GCM/NoPadding",
643
List.of(dtype.HEAP, dtype.HEAP)).test();
644
offsetTests(new GCMBufferTest("AES/GCM/NoPadding", List.of(dtype.HEAP, dtype.HEAP)));
645
// Test update-update-doFinal with heap bytebuffer
646
new GCMBufferTest("AES/GCM/NoPadding",
647
List.of(dtype.HEAP, dtype.HEAP, dtype.HEAP)).test();
648
offsetTests(new GCMBufferTest("AES/GCM/NoPadding", List.of(dtype.HEAP, dtype.HEAP, dtype.HEAP)));
649
650
// Test single direct bytebuffer
651
new GCMBufferTest("AES/GCM/NoPadding", List.of(dtype.DIRECT)).test();
652
offsetTests(new GCMBufferTest("AES/GCM/NoPadding", List.of(dtype.DIRECT)));
653
// Test update-doFinal with direct bytebuffer
654
new GCMBufferTest("AES/GCM/NoPadding",
655
List.of(dtype.DIRECT, dtype.DIRECT)).test();
656
offsetTests(new GCMBufferTest("AES/GCM/NoPadding",
657
List.of(dtype.DIRECT, dtype.DIRECT)));
658
// Test update-update-doFinal with direct bytebuffer
659
new GCMBufferTest("AES/GCM/NoPadding",
660
List.of(dtype.DIRECT, dtype.DIRECT, dtype.DIRECT)).test();
661
offsetTests(new GCMBufferTest("AES/GCM/NoPadding",
662
List.of(dtype.DIRECT, dtype.DIRECT, dtype.DIRECT)));
663
664
// Test update-update-doFinal with byte arrays and preset data sizes
665
GCMBufferTest t = new GCMBufferTest("AES/GCM/NoPadding",
666
List.of(dtype.BYTE, dtype.BYTE, dtype.BYTE)).dataSegments(
667
new int[] { 1, 1, GCMBufferTest.REMAINDER});
668
t.clone().test();
669
offsetTests(t.clone());
670
671
// Test update-doFinal with a byte array and a direct bytebuffer
672
t = new GCMBufferTest("AES/GCM/NoPadding",
673
List.of(dtype.BYTE, dtype.DIRECT)).differentBufferOnly();
674
t.clone().test();
675
offsetTests(t.clone());
676
// Test update-doFinal with a byte array and heap and direct bytebuffer
677
t = new GCMBufferTest("AES/GCM/NoPadding",
678
List.of(dtype.BYTE, dtype.HEAP, dtype.DIRECT)).differentBufferOnly();
679
t.clone().test();
680
offsetTests(t.clone());
681
// Test update-doFinal with a direct bytebuffer and a byte array.
682
t = new GCMBufferTest("AES/GCM/NoPadding",
683
List.of(dtype.DIRECT, dtype.BYTE)).differentBufferOnly();
684
t.clone().test();
685
offsetTests(t.clone());
686
687
// Test update-doFinal with a direct bytebuffer and a byte array with
688
// preset data sizes.
689
t = new GCMBufferTest("AES/GCM/NoPadding",
690
List.of(dtype.DIRECT, dtype.BYTE)).differentBufferOnly().
691
dataSegments(new int[] { 20, GCMBufferTest.REMAINDER });
692
t.clone().test();
693
offsetTests(t.clone());
694
// Test update-update-doFinal with a direct and heap bytebuffer and a
695
// byte array with preset data sizes.
696
t = new GCMBufferTest("AES/GCM/NoPadding",
697
List.of(dtype.DIRECT, dtype.BYTE, dtype.HEAP)).
698
differentBufferOnly().dataSet(5).
699
dataSegments(new int[] { 5000, 1000, GCMBufferTest.REMAINDER });
700
t.clone().test();
701
offsetTests(t.clone());
702
703
// Test update-update-doFinal with byte arrays, incrementing through
704
// every data size combination for the Data set 0
705
new GCMBufferTest("AES/GCM/NoPadding",
706
List.of(dtype.BYTE, dtype.BYTE, dtype.BYTE)).incrementalSegments().
707
dataSet(0).test();
708
// Test update-update-doFinal with direct bytebuffers, incrementing through
709
// every data size combination for the Data set 0
710
new GCMBufferTest("AES/GCM/NoPadding",
711
List.of(dtype.DIRECT, dtype.DIRECT, dtype.DIRECT)).
712
incrementalSegments().dataSet(0).test();
713
}
714
715
private static byte[] HexToBytes(String hexVal) {
716
if (hexVal == null) {
717
return new byte[0];
718
}
719
byte[] result = new byte[hexVal.length()/2];
720
for (int i = 0; i < result.length; i++) {
721
String byteVal = hexVal.substring(2*i, 2*i +2);
722
result[i] = Integer.valueOf(byteVal, 16).byteValue();
723
}
724
return result;
725
}
726
727
private static String byteToHex(byte[] barray) {
728
StringBuilder s = new StringBuilder();
729
for (byte b : barray) {
730
s.append(String.format("%02x", b));
731
}
732
return s.toString();
733
}
734
735
// Test data
736
static void initTest() {
737
datamap.put("AES/GCM/NoPadding", List.of(
738
// GCM KAT
739
new Data("AES", 0,
740
"141f1ce91989b07e7eb6ae1dbd81ea5e",
741
"49451da24bd6074509d3cebc2c0394c972e6934b45a1d91f3ce1d3ca69e19" +
742
"4aa1958a7c21b6f21d530ce6d2cc5256a3f846b6f9d2f38df0102c4791e5" +
743
"7df038f6e69085646007df999751e248e06c47245f4cd3b8004585a7470d" +
744
"ee1690e9d2d63169a58d243c0b57b3e5b4a481a3e4e8c60007094ef3adea" +
745
"2e8f05dd3a1396f",
746
"d384305af2388699aa302f510913fed0f2cb63ba42efa8c5c9de2922a2ec" +
747
"2fe87719dadf1eb0aef212b51e74c9c5b934104a43",
748
"630cf18a91cc5a6481ac9eefd65c24b1a3c93396bd7294d6b8ba3239517" +
749
"27666c947a21894a079ef061ee159c05beeb4",
750
"f4c34e5fbe74c0297313268296cd561d59ccc95bbfcdfcdc71b0097dbd83" +
751
"240446b28dc088abd42b0fc687f208190ff24c0548",
752
"dbb93bbb56d0439cd09f620a57687f5d"),
753
// GCM KAT
754
new Data("AES", 1, "11754cd72aec309bf52f7687212e8957",
755
"3c819d9a9bed087615030b65",
756
(String)null, null, null,
757
"250327c674aaf477aef2675748cf6971"),
758
// GCM KAT
759
new Data("AES", 2, "272f16edb81a7abbea887357a58c1917",
760
"794ec588176c703d3d2a7a07",
761
(String)null, null, null,
762
"b6e6f197168f5049aeda32dafbdaeb"),
763
// zero'd test data
764
new Data("AES", 3, "272f16edb81a7abbea887357a58c1917",
765
"794ec588176c703d3d2a7a07",
766
new byte[256], null,
767
"15b461672153270e8ba1e6789f7641c5411f3e642abda731b6086f535c216457" +
768
"e87305bc59a1ff1f7e1e0bbdf302b75549b136606c67d7e5f71277aeca4bc670" +
769
"07a98f78e0cfa002ed183e62f07893ad31fe67aad1bb37e15b957a14d145f14f" +
770
"7483d041f2c3612ad5033155984470bdfc64d18df73c2745d92f28461bb09832" +
771
"33524811321ba87d213692825815dd13f528dba601a3c319cac6be9b48686c23" +
772
"a0ce23d5062916ea8827bbb243f585e446131489e951354c8ab24661f625c02e" +
773
"15536c5bb602244e98993ff745f3e523399b2059f0e062d8933fad2366e7e147" +
774
"510a931282bb0e3f635efe7bf05b1dd715f95f5858261b00735224256b6b3e80",
775
"08b3593840d4ed005f5234ae062a5c"),
776
// Random test data
777
new Data("AES", 4, "272f16edb81a7abbea887357a58c1917",
778
"794ec588176c703d3d2a7a07",
779
new byte[2075], null,
780
"15b461672153270e8ba1e6789f7641c5411f3e642abda731b6086f535c216457" +
781
"e87305bc59a1ff1f7e1e0bbdf302b75549b136606c67d7e5f71277aeca4bc670" +
782
"07a98f78e0cfa002ed183e62f07893ad31fe67aad1bb37e15b957a14d145f14f" +
783
"7483d041f2c3612ad5033155984470bdfc64d18df73c2745d92f28461bb09832" +
784
"33524811321ba87d213692825815dd13f528dba601a3c319cac6be9b48686c23" +
785
"a0ce23d5062916ea8827bbb243f585e446131489e951354c8ab24661f625c02e" +
786
"15536c5bb602244e98993ff745f3e523399b2059f0e062d8933fad2366e7e147" +
787
"510a931282bb0e3f635efe7bf05b1dd715f95f5858261b00735224256b6b3e80" +
788
"7364cb53ff6d4e88f928cf67ac70da127718a8a35542efbae9dd7567c818a074" +
789
"9a0c74bd69014639f59768bc55056d1166ea5523e8c66f9d78d980beb8f0d83b" +
790
"a9e2c5544b94dc3a1a4b6f0f95f897b010150e89ebcacf0daee3c2793d6501a0" +
791
"b58b411de273dee987e8e8cf8bb29ef2e7f655b46b55fabf64c6a4295e0d080b" +
792
"6a570ace90eb0fe0f5b5d878bdd90eddaa1150e4d5a6505b350aac814fe99615" +
793
"317ecd0516a464c7904011ef5922409c0d65b1e43b69d7c3293a8f7d3e9fbee9" +
794
"eb91ec0007a7d6f72e64deb675d459c5ba07dcfd58d08e6820b100465e6e04f0" +
795
"663e310584a00d36d23699c1bffc6afa094c75184fc7cde7ad35909c0f49f2f3" +
796
"fe1e6d745ab628d74ea56b757047de57ce18b4b3c71e8af31a6fac16189cb0a3" +
797
"a97a1bea447042ce382fcf726560476d759c24d5c735525ea26a332c2094408e" +
798
"671c7deb81d5505bbfd178f866a6f3a011b3cfdbe089b4957a790688028dfdf7" +
799
"9a096b3853f9d0d6d3feef230c7f5f46ffbf7486ebdaca5804dc5bf9d202415e" +
800
"e0d67b365c2f92a17ea740807e4f0b198b42b54f15faa9dff2c7c35d2cf8d72e" +
801
"b8f8b18875a2e7b5c43d1e0aa5139c461e8153c7f632895aa46ffe2b134e6a0d" +
802
"dfbf6a336e709adfe951bd52c4dfc7b07a15fb3888fc35b7e758922f87a104c4" +
803
"563c5c7839cfe5a7edbdb97264a7c4ebc90367b10cbe09dbf2390767ad7afaa8" +
804
"8fb46b39d3f55f216d2104e5cf040bf3d39b758bea28e2dbce576c808d17a8eb" +
805
"e2fd183ef42a774e39119dff1f539efeb6ad15d889dfcb0d54d0d4d4cc03c8d9" +
806
"aa6c9ebd157f5e7170183298d6a30ada8792dcf793d931e2a1eafccbc63c11c0" +
807
"c5c5ed60837f30017d693ccb294df392a8066a0594a56954aea7b78a16e9a11f" +
808
"4a8bc2104070a7319f5fab0d2c4ccad8ec5cd8f47c839179bfd54a7bf225d502" +
809
"cd0a318752fe763e8c09eb88fa57fc5399ad1f797d0595c7b8afdd23f13603e9" +
810
"6802192bb51433b7723f4e512bd4f799feb94b458e7f9792f5f9bd6733828f70" +
811
"a6b7ffbbc0bb7575021f081ec2a0d37fecd7cda2daec9a3a9d9dfe1c8034cead" +
812
"e4b56b581cc82bd5b74b2b30817967d9da33850336f171a4c68e2438e03f4b11" +
813
"96da92f01b3b7aeab795180ccf40a4b090b1175a1fc0b67c95f93105c3aef00e" +
814
"13d76cc402539192274fee703730cd0d1c5635257719cc96cacdbad00c6255e2" +
815
"bd40c775b43ad09599e84f2c3205d75a6661ca3f151183be284b354ce21457d1" +
816
"3ba65b9b2cdb81874bd14469c2008b3ddec78f7225ecc710cc70de7912ca6a6d" +
817
"348168322ab59fdafcf5c833bfa0ad4046f4b6da90e9f263db7079af592eda07" +
818
"5bf16c6b1a8346da9c292a48bf660860a4fc89eaef40bc132779938eca294569" +
819
"787c740af2b5a8de7f5e10ac750d1e3d0ef3ed168ba408a676e10b8a20bd4be8" +
820
"3e8336b45e54481726d73e1bd19f165a98e242aca0d8387f2dd22d02d74e23db" +
821
"4cef9a523587413e0a44d7e3260019a34d3a6b38426ae9fa4655be338d721970" +
822
"cb9fe76c073f26f9303093a033022cd2c62b2790bce633ba9026a1c93b6535f1" +
823
"1882bf5880e511b9e1b0b7d8f23a993aae5fd275faac3a5b4ccaf7c06b0b266a" +
824
"ee970a1e3a4cd7a41094f516960630534e692545b25a347c30e3f328bba4825f" +
825
"ed754e5525d846131ecba7ca120a6aeabc7bab9f59c890c80b7e31f9bc741591" +
826
"55d292433ce9558e104102f2cc63ee267c1c8333e841522707ea6d595cb802b9" +
827
"61697da77bbc4cb404ea62570ab335ebffa2023730732ac5ddba1c3dbb5be408" +
828
"3c50aea462c1ffa166d7cc3db4b742b747e81b452db2363e91374dee8c6b40f0" +
829
"e7fbf50e60eaf5cc5649f6bb553aae772c185026ceb052af088c545330a1ffbf" +
830
"50615b8c7247c6cd386afd7440654f4e15bcfae0c45442ec814fe88433a9d616" +
831
"ee6cc3f163f0d3d325526d05f25d3b37ad5eeb3ca77248ad86c9042b16c65554" +
832
"aebb6ad3e17b981492b13f42c5a5dc088e991da303e5a273fdbb8601aece4267" +
833
"47b01f6cb972e6da1743a0d7866cf206e95f23c6f8e337c901b9cd34a9a1fbbe" +
834
"1694f2c26b00dfa4d02c0d54540163e798fbdc9c25f30d6406f5b4c13f7ed619" +
835
"34e350f4059c13aa5e973307a9e3058917cda96fdd082e9c629ccfb2a9f98d12" +
836
"5c6e4703a7b0f348f5cdeb63cef2133d1c6c1a087591e0a2bca29d09c6565e66" +
837
"e91042f83b0e74e60a5d57562c23e2fbcd6599c29d7c19e47cf625c2ce24bb8a" +
838
"13f8e54041498437eec2cedd1e3d8e57a051baa962c0a62d70264d99c5ee716d" +
839
"5c8b9078db08c8b2c5613f464198a7aff43f76c5b4612b46a4f1cd2a494386c5" +
840
"7fd28f3d199f0ba8d8e39116cc7db16ce6188205ee49a9dce3d4fa32ea394919" +
841
"f6e91ef58b84d00b99596b4306c2d9f432d917bb4ac73384c42ae12adb4920d8" +
842
"c33a816febcb299dcddf3ec7a8eb6e04cdc90891c6e145bd9fc5f41dc4061a46" +
843
"9feba38545b64ec8203f386ceef52785619e991d274ae80af7e54af535e0b011" +
844
"5effdf847472992875e09398457604d04e0bb965db692c0cdcf11a",
845
"687cc09c89298491deb51061d709af"),
846
// Randomly generated data at the time of execution.
847
new Data("AES", 5, "11754cd72aec309bf52f7687212e8957", 12345)
848
)
849
);
850
}
851
}
852
853