1 /*
2 * Copyright (c) 2004, 2013, 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
123 }
124
125 /**
126 * Returns the length in bytes that an output buffer would need to be
127 * given the input length <code>inputLen</code> (in bytes).
128 *
129 * <p>The actual output length of the next <code>update</code> or
130 * <code>doFinal</code> call may be smaller than the length returned
131 * by this method.
132 *
133 * @param inputLen the input length (in bytes).
134 *
135 * @return the required output buffer size (in bytes).
136 */
137 protected int engineGetOutputSize(int inputLen) {
138 // can only return an upper-limit if not initialized yet.
139 int result = 0;
140 if (decrypting) {
141 result = inputLen - 16; // CHECKSUM_LEN + IV_LEN;
142 } else {
143 result = inputLen + 16;
144 }
145 return (result < 0? 0:result);
146 }
147
148 /**
149 * Returns the initialization vector (IV) in a new buffer.
150 *
151 * @return the initialization vector, or null if the underlying
152 * algorithm does not use an IV, or if the IV has not yet
153 * been set.
154 */
155 protected byte[] engineGetIV() {
156 return (iv == null) ? null : iv.clone();
157 }
158
159 /**
160 * Initializes this cipher with a key and a source of randomness.
161 *
162 * <p>The cipher only supports the following two operation modes:<b>
163 * Cipher.WRAP_MODE, and <b>
435 * @return the wrapped key.
436 *
437 * @exception IllegalBlockSizeException if this cipher is a block
438 * cipher, no padding has been requested, and the length of the
439 * encoding of the key to be wrapped is not a
440 * multiple of the block size.
441 *
442 * @exception InvalidKeyException if it is impossible or unsafe to
443 * wrap the key with this cipher (e.g., a hardware protected key is
444 * being passed to a software only cipher).
445 */
446 protected byte[] engineWrap(Key key)
447 throws IllegalBlockSizeException, InvalidKeyException {
448 byte[] keyVal = key.getEncoded();
449 if ((keyVal == null) || (keyVal.length == 0)) {
450 throw new InvalidKeyException("Cannot get an encoding of " +
451 "the key to be wrapped");
452 }
453
454 byte[] cks = getChecksum(keyVal);
455 byte[] in = new byte[keyVal.length + CHECKSUM_LEN];
456 System.arraycopy(keyVal, 0, in, 0, keyVal.length);
457 System.arraycopy(cks, 0, in, keyVal.length, CHECKSUM_LEN);
458
459 byte[] out = new byte[iv.length + in.length];
460 System.arraycopy(iv, 0, out, 0, iv.length);
461
462 cipher.encrypt(in, 0, in.length, out, iv.length);
463
464 // reverse the array content
465 for (int i = 0; i < out.length/2; i++) {
466 byte temp = out[i];
467 out[i] = out[out.length-1-i];
468 out[out.length-1-i] = temp;
469 }
470 try {
471 cipher.init(false, cipherKey.getAlgorithm(),
472 cipherKey.getEncoded(), IV2);
473 } catch (InvalidKeyException ike) {
474 // should never happen
475 throw new RuntimeException("Internal cipher key is corrupted");
476 }
477 byte[] out2 = new byte[out.length];
478 cipher.encrypt(out, 0, out.length, out2, 0);
479
|
1 /*
2 * Copyright (c) 2004, 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
123 }
124
125 /**
126 * Returns the length in bytes that an output buffer would need to be
127 * given the input length <code>inputLen</code> (in bytes).
128 *
129 * <p>The actual output length of the next <code>update</code> or
130 * <code>doFinal</code> call may be smaller than the length returned
131 * by this method.
132 *
133 * @param inputLen the input length (in bytes).
134 *
135 * @return the required output buffer size (in bytes).
136 */
137 protected int engineGetOutputSize(int inputLen) {
138 // can only return an upper-limit if not initialized yet.
139 int result = 0;
140 if (decrypting) {
141 result = inputLen - 16; // CHECKSUM_LEN + IV_LEN;
142 } else {
143 result = Math.addExact(inputLen, 16);
144 }
145 return (result < 0? 0:result);
146 }
147
148 /**
149 * Returns the initialization vector (IV) in a new buffer.
150 *
151 * @return the initialization vector, or null if the underlying
152 * algorithm does not use an IV, or if the IV has not yet
153 * been set.
154 */
155 protected byte[] engineGetIV() {
156 return (iv == null) ? null : iv.clone();
157 }
158
159 /**
160 * Initializes this cipher with a key and a source of randomness.
161 *
162 * <p>The cipher only supports the following two operation modes:<b>
163 * Cipher.WRAP_MODE, and <b>
435 * @return the wrapped key.
436 *
437 * @exception IllegalBlockSizeException if this cipher is a block
438 * cipher, no padding has been requested, and the length of the
439 * encoding of the key to be wrapped is not a
440 * multiple of the block size.
441 *
442 * @exception InvalidKeyException if it is impossible or unsafe to
443 * wrap the key with this cipher (e.g., a hardware protected key is
444 * being passed to a software only cipher).
445 */
446 protected byte[] engineWrap(Key key)
447 throws IllegalBlockSizeException, InvalidKeyException {
448 byte[] keyVal = key.getEncoded();
449 if ((keyVal == null) || (keyVal.length == 0)) {
450 throw new InvalidKeyException("Cannot get an encoding of " +
451 "the key to be wrapped");
452 }
453
454 byte[] cks = getChecksum(keyVal);
455 byte[] in = new byte[Math.addExact(keyVal.length, CHECKSUM_LEN)];
456 System.arraycopy(keyVal, 0, in, 0, keyVal.length);
457 System.arraycopy(cks, 0, in, keyVal.length, CHECKSUM_LEN);
458
459 byte[] out = new byte[Math.addExact(iv.length, in.length)];
460 System.arraycopy(iv, 0, out, 0, iv.length);
461
462 cipher.encrypt(in, 0, in.length, out, iv.length);
463
464 // reverse the array content
465 for (int i = 0; i < out.length/2; i++) {
466 byte temp = out[i];
467 out[i] = out[out.length-1-i];
468 out[out.length-1-i] = temp;
469 }
470 try {
471 cipher.init(false, cipherKey.getAlgorithm(),
472 cipherKey.getEncoded(), IV2);
473 } catch (InvalidKeyException ike) {
474 // should never happen
475 throw new RuntimeException("Internal cipher key is corrupted");
476 }
477 byte[] out2 = new byte[out.length];
478 cipher.encrypt(out, 0, out.length, out2, 0);
479
|