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