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