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