|
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 package org.openjdk.bench.javax.crypto.full; |
|
24 |
|
25 import org.openjdk.jmh.annotations.Benchmark; |
|
26 import org.openjdk.jmh.annotations.Param; |
|
27 import org.openjdk.jmh.annotations.Setup; |
|
28 |
|
29 import javax.crypto.*; |
|
30 import javax.crypto.spec.*; |
|
31 import java.security.*; |
|
32 import java.security.spec.*; |
|
33 |
|
34 |
|
35 public abstract class CipherBench extends CryptoBase { |
|
36 |
|
37 @Param({}) |
|
38 private String permutation; |
|
39 |
|
40 @Param({}) |
|
41 private String mode; |
|
42 |
|
43 @Param({}) |
|
44 private String padding; |
|
45 |
|
46 @Param({}) |
|
47 private int keyLength; |
|
48 |
|
49 @Param({}) |
|
50 private int dataSize; |
|
51 |
|
52 private int decryptCount = 0; |
|
53 private byte[] data; |
|
54 private byte[][] encryptedData = new byte[2][]; |
|
55 private byte[] outBuffer; |
|
56 private Cipher[] encryptCipher = new Cipher[2]; |
|
57 private Cipher decryptCipher; |
|
58 protected SecretKeySpec ks; |
|
59 protected byte[] iv; |
|
60 |
|
61 protected abstract int ivLength(); |
|
62 protected abstract AlgorithmParameterSpec makeParameterSpec(); |
|
63 |
|
64 protected void init(Cipher c, int mode, SecretKeySpec ks) |
|
65 throws GeneralSecurityException { |
|
66 |
|
67 if (iv == null) { |
|
68 iv = fillSecureRandom(new byte[ivLength()]); |
|
69 } |
|
70 |
|
71 // toggle some bits in the IV to get around IV reuse defenses |
|
72 iv[0] ^= 0xFF; |
|
73 AlgorithmParameterSpec paramSpec = makeParameterSpec(); |
|
74 |
|
75 c.init(mode, ks, paramSpec); |
|
76 } |
|
77 |
|
78 protected void init(Cipher c, int mode, SecretKeySpec ks, Cipher fromCipher) |
|
79 throws GeneralSecurityException { |
|
80 |
|
81 AlgorithmParameters params = fromCipher.getParameters(); |
|
82 c.init(mode, ks, fromCipher.getParameters()); |
|
83 } |
|
84 |
|
85 @Setup |
|
86 public void setup() throws GeneralSecurityException { |
|
87 setupProvider(); |
|
88 |
|
89 String transform = permutation + "/" + mode + "/" + padding; |
|
90 byte[] keystring = fillSecureRandom(new byte[keyLength / 8]); |
|
91 ks = new SecretKeySpec(keystring, permutation); |
|
92 data = fillRandom(new byte[dataSize]); |
|
93 for (int i = 0; i < 2; i++) { |
|
94 encryptCipher[i] = makeCipher(prov, transform); |
|
95 init(encryptCipher[i], Cipher.ENCRYPT_MODE, ks); |
|
96 encryptedData[i] = encryptCipher[i].doFinal(data); |
|
97 } |
|
98 outBuffer = new byte[dataSize + 128]; // extra space for tag, etc |
|
99 decryptCipher = makeCipher(prov, transform); |
|
100 } |
|
101 |
|
102 @Benchmark |
|
103 public void encrypt() throws GeneralSecurityException { |
|
104 init(encryptCipher[1], Cipher.ENCRYPT_MODE, ks); |
|
105 encryptCipher[1].doFinal(data, 0, data.length, outBuffer); |
|
106 } |
|
107 |
|
108 @Benchmark |
|
109 public void decrypt() throws GeneralSecurityException { |
|
110 init(decryptCipher, Cipher.DECRYPT_MODE, ks, |
|
111 encryptCipher[decryptCount]); |
|
112 decryptCipher.doFinal(encryptedData[decryptCount], 0, |
|
113 encryptedData[decryptCount].length, outBuffer); |
|
114 decryptCount = (decryptCount + 1) % 2; |
|
115 } |
|
116 |
|
117 public static class GCM extends CipherBench { |
|
118 |
|
119 @Param({"AES"}) |
|
120 private String permutation; |
|
121 |
|
122 @Param({"GCM"}) |
|
123 private String mode; |
|
124 |
|
125 @Param({"NoPadding", "PKCS5Padding"}) |
|
126 private String padding; |
|
127 |
|
128 @Param({"128", "256"}) |
|
129 private int keyLength; |
|
130 |
|
131 @Param({"1024", "" + 16 * 1024}) |
|
132 private int dataSize; |
|
133 |
|
134 protected int ivLength() { |
|
135 return 32; |
|
136 } |
|
137 protected AlgorithmParameterSpec makeParameterSpec() { |
|
138 return new GCMParameterSpec(96, iv, 0, 16); |
|
139 } |
|
140 |
|
141 private byte[] aad; |
|
142 |
|
143 protected void init(Cipher c, int mode, SecretKeySpec ks) |
|
144 throws GeneralSecurityException { |
|
145 |
|
146 if (aad == null) { |
|
147 aad = fillSecureRandom(new byte[5]); |
|
148 } |
|
149 |
|
150 super.init(c, mode, ks); |
|
151 c.updateAAD(aad); |
|
152 } |
|
153 |
|
154 protected void init(Cipher c, int mode, SecretKeySpec ks, |
|
155 Cipher fromCipher) throws GeneralSecurityException { |
|
156 |
|
157 super.init(c, mode, ks, fromCipher); |
|
158 c.updateAAD(aad); |
|
159 } |
|
160 } |
|
161 |
|
162 public static class CTR extends CipherBench { |
|
163 |
|
164 @Param({"AES"}) |
|
165 private String permutation; |
|
166 |
|
167 @Param({"CTR"}) |
|
168 private String mode; |
|
169 |
|
170 @Param({"NoPadding"}) |
|
171 private String padding; |
|
172 |
|
173 @Param({"128", "256"}) |
|
174 private int keyLength; |
|
175 |
|
176 @Param({"1024", "" + 16 * 1024}) |
|
177 private int dataSize; |
|
178 |
|
179 protected int ivLength() { |
|
180 return 16; |
|
181 } |
|
182 protected AlgorithmParameterSpec makeParameterSpec() { |
|
183 return new IvParameterSpec(iv); |
|
184 } |
|
185 } |
|
186 |
|
187 public static class ChaCha20Poly1305 extends CipherBench { |
|
188 |
|
189 @Param({"ChaCha20-Poly1305"}) |
|
190 private String permutation; |
|
191 |
|
192 @Param({"None"}) |
|
193 private String mode; |
|
194 |
|
195 @Param({"NoPadding"}) |
|
196 private String padding; |
|
197 |
|
198 @Param({"256"}) |
|
199 private int keyLength; |
|
200 |
|
201 @Param({"1024", "" + 16 * 1024}) |
|
202 private int dataSize; |
|
203 |
|
204 protected int ivLength() { |
|
205 return 12; |
|
206 } |
|
207 protected AlgorithmParameterSpec makeParameterSpec() { |
|
208 return new IvParameterSpec(iv); |
|
209 } |
|
210 } |
|
211 |
|
212 public static class ChaCha20 extends CipherBench { |
|
213 |
|
214 @Param({"ChaCha20"}) |
|
215 private String permutation; |
|
216 |
|
217 @Param({"None"}) |
|
218 private String mode; |
|
219 |
|
220 @Param({"NoPadding"}) |
|
221 private String padding; |
|
222 |
|
223 @Param({"256"}) |
|
224 private int keyLength; |
|
225 |
|
226 @Param({"1024", "" + 16 * 1024}) |
|
227 private int dataSize; |
|
228 |
|
229 protected int ivLength() { |
|
230 return 12; |
|
231 } |
|
232 protected AlgorithmParameterSpec makeParameterSpec() { |
|
233 return new ChaCha20ParameterSpec(iv, 0); |
|
234 } |
|
235 |
|
236 protected void init(Cipher c, int mode, SecretKeySpec ks, |
|
237 Cipher fromCipher) throws GeneralSecurityException { |
|
238 |
|
239 AlgorithmParameterSpec paramSpec = |
|
240 new ChaCha20ParameterSpec(fromCipher.getIV(), 0); |
|
241 c.init(mode, ks, paramSpec); |
|
242 } |
|
243 } |
|
244 } |