Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/java.base/share/classes/com/sun/crypto/provider/BlowfishCipher.java
41161 views
1
/*
2
* Copyright (c) 1998, 2021, 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. Oracle designates this
8
* particular file as subject to the "Classpath" exception as provided
9
* by Oracle in the LICENSE file that accompanied this code.
10
*
11
* This code is distributed in the hope that it will be useful, but WITHOUT
12
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14
* version 2 for more details (a copy is included in the LICENSE file that
15
* accompanied this code).
16
*
17
* You should have received a copy of the GNU General Public License version
18
* 2 along with this work; if not, write to the Free Software Foundation,
19
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20
*
21
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22
* or visit www.oracle.com if you need additional information or have any
23
* questions.
24
*/
25
26
package com.sun.crypto.provider;
27
28
import java.security.*;
29
import java.security.spec.*;
30
import java.util.Arrays;
31
32
import sun.security.util.*;
33
import javax.crypto.*;
34
import javax.crypto.spec.*;
35
import javax.crypto.BadPaddingException;
36
37
/**
38
* This class implements the Blowfish algorithm in its various modes
39
* (<code>ECB</code>, <code>CFB</code>, <code>OFB</code>, <code>CBC</code>,
40
* <code>PCBC</code>) and padding schemes (<code>PKCS5Padding</code>,
41
* <code>NoPadding</code>, <code>ISO10126Padding</code>).
42
*
43
* <p> Blowfish is a 64-bit block cipher with a variable-length key.
44
*
45
* @author Jan Luehe
46
*
47
*
48
* @see BlowfishCrypt
49
* @see CipherBlockChaining
50
* @see ElectronicCodeBook
51
* @see CipherFeedback
52
* @see OutputFeedback
53
*/
54
55
public final class BlowfishCipher extends CipherSpi {
56
57
/*
58
* internal CipherCore object which does the real work.
59
*/
60
private CipherCore core = null;
61
62
/**
63
* Creates an instance of Blowfish cipher with default ECB mode and
64
* PKCS5Padding.
65
*/
66
public BlowfishCipher() {
67
core = new CipherCore(new BlowfishCrypt(),
68
BlowfishConstants.BLOWFISH_BLOCK_SIZE);
69
}
70
71
/**
72
* Sets the mode of this cipher.
73
*
74
* @param mode the cipher mode
75
*
76
* @exception NoSuchAlgorithmException if the requested cipher mode does
77
* not exist
78
*/
79
protected void engineSetMode(String mode)
80
throws NoSuchAlgorithmException {
81
core.setMode(mode);
82
}
83
84
/**
85
* Sets the padding mechanism of this cipher.
86
*
87
* @param paddingScheme the padding mechanism
88
*
89
* @exception NoSuchPaddingException if the requested padding mechanism
90
* does not exist
91
*/
92
protected void engineSetPadding(String paddingScheme)
93
throws NoSuchPaddingException {
94
core.setPadding(paddingScheme);
95
}
96
97
/**
98
* Returns the block size (in bytes).
99
*
100
* @return the block size (in bytes), or 0 if the underlying algorithm is
101
* not a block cipher
102
*/
103
protected int engineGetBlockSize() {
104
return BlowfishConstants.BLOWFISH_BLOCK_SIZE;
105
}
106
107
/**
108
* Returns the length in bytes that an output buffer would need to be in
109
* order to hold the result of the next <code>update</code> or
110
* <code>doFinal</code> operation, given the input length
111
* <code>inputLen</code> (in bytes).
112
*
113
* <p>This call takes into account any unprocessed (buffered) data from a
114
* previous <code>update</code> call, and padding.
115
*
116
* <p>The actual output length of the next <code>update</code> or
117
* <code>doFinal</code> call may be smaller than the length returned by
118
* this method.
119
*
120
* @param inputLen the input length (in bytes)
121
*
122
* @return the required output buffer size (in bytes)
123
*/
124
protected int engineGetOutputSize(int inputLen) {
125
return core.getOutputSize(inputLen);
126
}
127
128
/**
129
* Returns the initialization vector (IV) in a new buffer.
130
*
131
* <p>This is useful in the case where a random IV has been created
132
* (see <a href = "#init">init</a>),
133
* or in the context of password-based encryption or
134
* decryption, where the IV is derived from a user-supplied password.
135
*
136
* @return the initialization vector in a new buffer, or null if the
137
* underlying algorithm does not use an IV, or if the IV has not yet
138
* been set.
139
*/
140
protected byte[] engineGetIV() {
141
return core.getIV();
142
}
143
144
/**
145
* Returns the parameters used with this cipher.
146
*
147
* <p>The returned parameters may be the same that were used to initialize
148
* this cipher, or may contain the default set of parameters or a set of
149
* randomly generated parameters used by the underlying cipher
150
* implementation (provided that the underlying cipher implementation
151
* uses a default set of parameters or creates new parameters if it needs
152
* parameters but was not initialized with any).
153
*
154
* @return the parameters used with this cipher, or null if this cipher
155
* does not use any parameters.
156
*/
157
protected AlgorithmParameters engineGetParameters() {
158
return core.getParameters("Blowfish");
159
}
160
161
/**
162
* Initializes this cipher with a key and a source of randomness.
163
*
164
* <p>The cipher is initialized for one of the following four operations:
165
* encryption, decryption, key wrapping or key unwrapping, depending on
166
* the value of <code>opmode</code>.
167
*
168
* <p>If this cipher requires an initialization vector (IV), it will get
169
* it from <code>random</code>.
170
* This behaviour should only be used in encryption or key wrapping
171
* mode, however.
172
* When initializing a cipher that requires an IV for decryption or
173
* key unwrapping, the IV
174
* (same IV that was used for encryption or key wrapping) must be provided
175
* explicitly as a
176
* parameter, in order to get the correct result.
177
*
178
* <p>This method also cleans existing buffer and other related state
179
* information.
180
*
181
* @param opmode the operation mode of this cipher (this is one of
182
* the following:
183
* <code>ENCRYPT_MODE</code>, <code>DECRYPT_MODE</code>,
184
* <code>WRAP_MODE</code> or <code>UNWRAP_MODE</code>)
185
* @param key the secret key
186
* @param random the source of randomness
187
*
188
* @exception InvalidKeyException if the given key is inappropriate for
189
* initializing this cipher
190
*/
191
protected void engineInit(int opmode, Key key, SecureRandom random)
192
throws InvalidKeyException {
193
core.init(opmode, key, random);
194
}
195
196
/**
197
* Initializes this cipher with a key, a set of
198
* algorithm parameters, and a source of randomness.
199
*
200
* <p>The cipher is initialized for one of the following four operations:
201
* encryption, decryption, key wrapping or key unwrapping, depending on
202
* the value of <code>opmode</code>.
203
*
204
* <p>If this cipher (including its underlying feedback or padding scheme)
205
* requires any random bytes, it will get them from <code>random</code>.
206
*
207
* @param opmode the operation mode of this cipher (this is one of
208
* the following:
209
* <code>ENCRYPT_MODE</code>, <code>DECRYPT_MODE</code>,
210
* <code>WRAP_MODE</code> or <code>UNWRAP_MODE</code>)
211
* @param key the encryption key
212
* @param params the algorithm parameters
213
* @param random the source of randomness
214
*
215
* @exception InvalidKeyException if the given key is inappropriate for
216
* initializing this cipher
217
* @exception InvalidAlgorithmParameterException if the given algorithm
218
* parameters are inappropriate for this cipher
219
*/
220
protected void engineInit(int opmode, Key key,
221
AlgorithmParameterSpec params,
222
SecureRandom random)
223
throws InvalidKeyException, InvalidAlgorithmParameterException {
224
core.init(opmode, key, params, random);
225
}
226
227
protected void engineInit(int opmode, Key key,
228
AlgorithmParameters params,
229
SecureRandom random)
230
throws InvalidKeyException, InvalidAlgorithmParameterException {
231
core.init(opmode, key, params, random);
232
}
233
234
/**
235
* Continues a multiple-part encryption or decryption operation
236
* (depending on how this cipher was initialized), processing another data
237
* part.
238
*
239
* <p>The first <code>inputLen</code> bytes in the <code>input</code>
240
* buffer, starting at <code>inputOffset</code>, are processed, and the
241
* result is stored in a new buffer.
242
*
243
* @param input the input buffer
244
* @param inputOffset the offset in <code>input</code> where the input
245
* starts
246
* @param inputLen the input length
247
*
248
* @return the new buffer with the result
249
*
250
* @exception IllegalStateException if this cipher is in a wrong state
251
* (e.g., has not been initialized)
252
*/
253
protected byte[] engineUpdate(byte[] input, int inputOffset,
254
int inputLen) {
255
return core.update(input, inputOffset, inputLen);
256
}
257
258
/**
259
* Continues a multiple-part encryption or decryption operation
260
* (depending on how this cipher was initialized), processing another data
261
* part.
262
*
263
* <p>The first <code>inputLen</code> bytes in the <code>input</code>
264
* buffer, starting at <code>inputOffset</code>, are processed, and the
265
* result is stored in the <code>output</code> buffer, starting at
266
* <code>outputOffset</code>.
267
*
268
* @param input the input buffer
269
* @param inputOffset the offset in <code>input</code> where the input
270
* starts
271
* @param inputLen the input length
272
* @param output the buffer for the result
273
* @param outputOffset the offset in <code>output</code> where the result
274
* is stored
275
*
276
* @return the number of bytes stored in <code>output</code>
277
*
278
* @exception ShortBufferException if the given output buffer is too small
279
* to hold the result
280
*/
281
protected int engineUpdate(byte[] input, int inputOffset, int inputLen,
282
byte[] output, int outputOffset)
283
throws ShortBufferException {
284
return core.update(input, inputOffset, inputLen, output,
285
outputOffset);
286
}
287
288
/**
289
* Encrypts or decrypts data in a single-part operation,
290
* or finishes a multiple-part operation.
291
* The data is encrypted or decrypted, depending on how this cipher was
292
* initialized.
293
*
294
* <p>The first <code>inputLen</code> bytes in the <code>input</code>
295
* buffer, starting at <code>inputOffset</code>, and any input bytes that
296
* may have been buffered during a previous <code>update</code> operation,
297
* are processed, with padding (if requested) being applied.
298
* The result is stored in a new buffer.
299
*
300
* <p>The cipher is reset to its initial state (uninitialized) after this
301
* call.
302
*
303
* @param input the input buffer
304
* @param inputOffset the offset in <code>input</code> where the input
305
* starts
306
* @param inputLen the input length
307
*
308
* @return the new buffer with the result
309
*
310
* @exception IllegalBlockSizeException if this cipher is a block cipher,
311
* no padding has been requested (only in encryption mode), and the total
312
* input length of the data processed by this cipher is not a multiple of
313
* block size
314
* @exception BadPaddingException if this cipher is in decryption mode,
315
* and (un)padding has been requested, but the decrypted data is not
316
* bounded by the appropriate padding bytes
317
*/
318
protected byte[] engineDoFinal(byte[] input, int inputOffset,
319
int inputLen)
320
throws IllegalBlockSizeException, BadPaddingException {
321
return core.doFinal(input, inputOffset, inputLen);
322
}
323
324
/**
325
* Encrypts or decrypts data in a single-part operation,
326
* or finishes a multiple-part operation.
327
* The data is encrypted or decrypted, depending on how this cipher was
328
* initialized.
329
*
330
* <p>The first <code>inputLen</code> bytes in the <code>input</code>
331
* buffer, starting at <code>inputOffset</code>, and any input bytes that
332
* may have been buffered during a previous <code>update</code> operation,
333
* are processed, with padding (if requested) being applied.
334
* The result is stored in the <code>output</code> buffer, starting at
335
* <code>outputOffset</code>.
336
*
337
* <p>The cipher is reset to its initial state (uninitialized) after this
338
* call.
339
*
340
* @param input the input buffer
341
* @param inputOffset the offset in <code>input</code> where the input
342
* starts
343
* @param inputLen the input length
344
* @param output the buffer for the result
345
* @param outputOffset the offset in <code>output</code> where the result
346
* is stored
347
*
348
* @return the number of bytes stored in <code>output</code>
349
*
350
* @exception IllegalBlockSizeException if this cipher is a block cipher,
351
* no padding has been requested (only in encryption mode), and the total
352
* input length of the data processed by this cipher is not a multiple of
353
* block size
354
* @exception ShortBufferException if the given output buffer is too small
355
* to hold the result
356
* @exception BadPaddingException if this cipher is in decryption mode,
357
* and (un)padding has been requested, but the decrypted data is not
358
* bounded by the appropriate padding bytes
359
*/
360
protected int engineDoFinal(byte[] input, int inputOffset, int inputLen,
361
byte[] output, int outputOffset)
362
throws IllegalBlockSizeException, ShortBufferException,
363
BadPaddingException {
364
return core.doFinal(input, inputOffset, inputLen, output,
365
outputOffset);
366
}
367
368
/**
369
* Returns the key size of the given key object.
370
*
371
* @param key the key object.
372
*
373
* @return the key size of the given key object.
374
*
375
* @exception InvalidKeyException if <code>key</code> is invalid.
376
*/
377
protected int engineGetKeySize(Key key) throws InvalidKeyException {
378
byte[] encodedKey = key.getEncoded();
379
Arrays.fill(encodedKey, (byte)0);
380
return Math.multiplyExact(encodedKey.length, 8);
381
}
382
383
/**
384
* Wrap a key.
385
*
386
* @param key the key to be wrapped.
387
*
388
* @return the wrapped key.
389
*
390
* @exception IllegalBlockSizeException if this cipher is a block
391
* cipher, no padding has been requested, and the length of the
392
* encoding of the key to be wrapped is not a
393
* multiple of the block size.
394
*
395
* @exception InvalidKeyException if it is impossible or unsafe to
396
* wrap the key with this cipher (e.g., a hardware protected key is
397
* being passed to a software only cipher).
398
*/
399
protected byte[] engineWrap(Key key)
400
throws IllegalBlockSizeException, InvalidKeyException {
401
return core.wrap(key);
402
}
403
404
/**
405
* Unwrap a previously wrapped key.
406
*
407
* @param wrappedKey the key to be unwrapped.
408
*
409
* @param wrappedKeyAlgorithm the algorithm the wrapped key is for.
410
*
411
* @param wrappedKeyType the type of the wrapped key.
412
* This is one of <code>Cipher.SECRET_KEY</code>,
413
* <code>Cipher.PRIVATE_KEY</code>, or <code>Cipher.PUBLIC_KEY</code>.
414
*
415
* @return the unwrapped key.
416
*
417
* @exception NoSuchAlgorithmException if no installed providers
418
* can create keys of type <code>wrappedKeyType</code> for the
419
* <code>wrappedKeyAlgorithm</code>.
420
*
421
* @exception InvalidKeyException if <code>wrappedKey</code> does not
422
* represent a wrapped key of type <code>wrappedKeyType</code> for
423
* the <code>wrappedKeyAlgorithm</code>.
424
*/
425
protected Key engineUnwrap(byte[] wrappedKey,
426
String wrappedKeyAlgorithm,
427
int wrappedKeyType)
428
throws InvalidKeyException, NoSuchAlgorithmException {
429
return core.unwrap(wrappedKey, wrappedKeyAlgorithm,
430
wrappedKeyType);
431
}
432
}
433
434