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