jdk/src/share/classes/com/sun/crypto/provider/CipherCore.java
author valeriep
Tue, 08 May 2012 17:57:48 -0700
changeset 12685 8a448b5b9006
parent 10336 0bb1999251f8
child 15008 6a494f8ba5b5
permissions -rw-r--r--
4963723: Implement SHA-224 Summary: Add support for SHA-224, SHA224withRSA, SHA224withECDSA, HmacSHA224 and OAEPwithSHA-224AndMGF1Padding. Reviewed-by: vinnie
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     1
/*
10336
0bb1999251f8 7064075: Security libraries don't build with javac -Xlint:all,-deprecation -Werror
jjg
parents: 5506
diff changeset
     2
 * Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
90ce3da70b43 Initial load
duke
parents:
diff changeset
     4
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
90ce3da70b43 Initial load
duke
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2
diff changeset
     7
 * published by the Free Software Foundation.  Oracle designates this
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2
diff changeset
     9
 * by Oracle in the LICENSE file that accompanied this code.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    10
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
90ce3da70b43 Initial load
duke
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
90ce3da70b43 Initial load
duke
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
90ce3da70b43 Initial load
duke
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
90ce3da70b43 Initial load
duke
parents:
diff changeset
    15
 * accompanied this code).
90ce3da70b43 Initial load
duke
parents:
diff changeset
    16
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
90ce3da70b43 Initial load
duke
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    20
 *
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2
diff changeset
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2
diff changeset
    22
 * or visit www.oracle.com if you need additional information or have any
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2
diff changeset
    23
 * questions.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    24
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    25
90ce3da70b43 Initial load
duke
parents:
diff changeset
    26
package com.sun.crypto.provider;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    27
90ce3da70b43 Initial load
duke
parents:
diff changeset
    28
import java.util.Locale;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    29
90ce3da70b43 Initial load
duke
parents:
diff changeset
    30
import java.security.*;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    31
import java.security.spec.*;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    32
import javax.crypto.*;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    33
import javax.crypto.spec.*;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    34
import javax.crypto.BadPaddingException;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    35
90ce3da70b43 Initial load
duke
parents:
diff changeset
    36
/**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    37
 * This class represents the symmetric algorithms in its various modes
90ce3da70b43 Initial load
duke
parents:
diff changeset
    38
 * (<code>ECB</code>, <code>CFB</code>, <code>OFB</code>, <code>CBC</code>,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    39
 * <code>PCBC</code>, <code>CTR</code>, and <code>CTS</code>) and
90ce3da70b43 Initial load
duke
parents:
diff changeset
    40
 * padding schemes (<code>PKCS5Padding</code>, <code>NoPadding</code>,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    41
 * <code>ISO10126Padding</code>).
90ce3da70b43 Initial load
duke
parents:
diff changeset
    42
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    43
 * @author Gigi Ankeny
90ce3da70b43 Initial load
duke
parents:
diff changeset
    44
 * @author Jan Luehe
90ce3da70b43 Initial load
duke
parents:
diff changeset
    45
 * @see ElectronicCodeBook
90ce3da70b43 Initial load
duke
parents:
diff changeset
    46
 * @see CipherFeedback
90ce3da70b43 Initial load
duke
parents:
diff changeset
    47
 * @see OutputFeedback
90ce3da70b43 Initial load
duke
parents:
diff changeset
    48
 * @see CipherBlockChaining
90ce3da70b43 Initial load
duke
parents:
diff changeset
    49
 * @see PCBC
90ce3da70b43 Initial load
duke
parents:
diff changeset
    50
 * @see CounterMode
90ce3da70b43 Initial load
duke
parents:
diff changeset
    51
 * @see CipherTextStealing
90ce3da70b43 Initial load
duke
parents:
diff changeset
    52
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    53
90ce3da70b43 Initial load
duke
parents:
diff changeset
    54
final class CipherCore {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    55
90ce3da70b43 Initial load
duke
parents:
diff changeset
    56
    /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
    57
     * internal buffer
90ce3da70b43 Initial load
duke
parents:
diff changeset
    58
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    59
    private byte[] buffer = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    60
90ce3da70b43 Initial load
duke
parents:
diff changeset
    61
    /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
    62
     * internal buffer
90ce3da70b43 Initial load
duke
parents:
diff changeset
    63
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    64
    private int blockSize = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    65
90ce3da70b43 Initial load
duke
parents:
diff changeset
    66
    /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
    67
     * unit size (number of input bytes that can be processed at a time)
90ce3da70b43 Initial load
duke
parents:
diff changeset
    68
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    69
    private int unitBytes = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    70
90ce3da70b43 Initial load
duke
parents:
diff changeset
    71
    /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
    72
     * index of the content size left in the buffer
90ce3da70b43 Initial load
duke
parents:
diff changeset
    73
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    74
    private int buffered = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    75
90ce3da70b43 Initial load
duke
parents:
diff changeset
    76
    /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
    77
     * minimum number of bytes in the buffer required for
90ce3da70b43 Initial load
duke
parents:
diff changeset
    78
     * FeedbackCipher.encryptFinal()/decryptFinal() call.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    79
     * update() must buffer this many bytes before before starting
90ce3da70b43 Initial load
duke
parents:
diff changeset
    80
     * to encrypt/decrypt data.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    81
     * currently, only CTS mode has a non-zero value due to its special
90ce3da70b43 Initial load
duke
parents:
diff changeset
    82
     * handling on the last two blocks (the last one may be incomplete).
90ce3da70b43 Initial load
duke
parents:
diff changeset
    83
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    84
    private int minBytes = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    85
90ce3da70b43 Initial load
duke
parents:
diff changeset
    86
    /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
    87
     * number of bytes needed to make the total input length a multiple
90ce3da70b43 Initial load
duke
parents:
diff changeset
    88
     * of the blocksize (this is used in feedback mode, when the number of
90ce3da70b43 Initial load
duke
parents:
diff changeset
    89
     * input bytes that are processed at a time is different from the block
90ce3da70b43 Initial load
duke
parents:
diff changeset
    90
     * size)
90ce3da70b43 Initial load
duke
parents:
diff changeset
    91
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    92
    private int diffBlocksize = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    93
90ce3da70b43 Initial load
duke
parents:
diff changeset
    94
    /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
    95
     * padding class
90ce3da70b43 Initial load
duke
parents:
diff changeset
    96
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    97
    private Padding padding = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    98
90ce3da70b43 Initial load
duke
parents:
diff changeset
    99
    /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   100
     * internal cipher engine
90ce3da70b43 Initial load
duke
parents:
diff changeset
   101
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   102
    private FeedbackCipher cipher = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   103
90ce3da70b43 Initial load
duke
parents:
diff changeset
   104
    /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   105
     * the cipher mode
90ce3da70b43 Initial load
duke
parents:
diff changeset
   106
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   107
    private int cipherMode = ECB_MODE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   108
90ce3da70b43 Initial load
duke
parents:
diff changeset
   109
    /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   110
     * are we encrypting or decrypting?
90ce3da70b43 Initial load
duke
parents:
diff changeset
   111
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   112
    private boolean decrypting = false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   113
90ce3da70b43 Initial load
duke
parents:
diff changeset
   114
    /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   115
     * Block Mode constants
90ce3da70b43 Initial load
duke
parents:
diff changeset
   116
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   117
    private static final int ECB_MODE = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   118
    private static final int CBC_MODE = 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   119
    private static final int CFB_MODE = 2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   120
    private static final int OFB_MODE = 3;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   121
    private static final int PCBC_MODE = 4;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   122
    private static final int CTR_MODE = 5;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   123
    private static final int CTS_MODE = 6;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   124
90ce3da70b43 Initial load
duke
parents:
diff changeset
   125
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   126
     * Creates an instance of CipherCore with default ECB mode and
90ce3da70b43 Initial load
duke
parents:
diff changeset
   127
     * PKCS5Padding.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   128
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   129
    CipherCore(SymmetricCipher impl, int blkSize) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   130
        blockSize = blkSize;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   131
        unitBytes = blkSize;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   132
        diffBlocksize = blkSize;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   133
90ce3da70b43 Initial load
duke
parents:
diff changeset
   134
        /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   135
         * The buffer should be usable for all cipher mode and padding
90ce3da70b43 Initial load
duke
parents:
diff changeset
   136
         * schemes. Thus, it has to be at least (blockSize+1) for CTS.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   137
         * In decryption mode, it also hold the possible padding block.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   138
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   139
        buffer = new byte[blockSize*2];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   140
90ce3da70b43 Initial load
duke
parents:
diff changeset
   141
        // set mode and padding
90ce3da70b43 Initial load
duke
parents:
diff changeset
   142
        cipher = new ElectronicCodeBook(impl);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   143
        padding = new PKCS5Padding(blockSize);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   144
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   145
90ce3da70b43 Initial load
duke
parents:
diff changeset
   146
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   147
     * Sets the mode of this cipher.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   148
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   149
     * @param mode the cipher mode
90ce3da70b43 Initial load
duke
parents:
diff changeset
   150
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   151
     * @exception NoSuchAlgorithmException if the requested cipher mode does
90ce3da70b43 Initial load
duke
parents:
diff changeset
   152
     * not exist
90ce3da70b43 Initial load
duke
parents:
diff changeset
   153
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   154
    void setMode(String mode) throws NoSuchAlgorithmException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   155
        if (mode == null)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   156
            throw new NoSuchAlgorithmException("null mode");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   157
90ce3da70b43 Initial load
duke
parents:
diff changeset
   158
        String modeUpperCase = mode.toUpperCase(Locale.ENGLISH);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   159
90ce3da70b43 Initial load
duke
parents:
diff changeset
   160
        if (modeUpperCase.equals("ECB")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   161
            return;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   162
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   163
90ce3da70b43 Initial load
duke
parents:
diff changeset
   164
        SymmetricCipher rawImpl = cipher.getEmbeddedCipher();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   165
        if (modeUpperCase.equals("CBC")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   166
            cipherMode = CBC_MODE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   167
            cipher = new CipherBlockChaining(rawImpl);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   168
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   169
        else if (modeUpperCase.equals("CTS")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   170
            cipherMode = CTS_MODE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   171
            cipher = new CipherTextStealing(rawImpl);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   172
            minBytes = blockSize+1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   173
            padding = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   174
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   175
        else if (modeUpperCase.equals("CTR")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   176
            cipherMode = CTR_MODE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   177
            cipher = new CounterMode(rawImpl);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   178
            unitBytes = 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   179
            padding = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   180
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   181
        else if (modeUpperCase.startsWith("CFB")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   182
            cipherMode = CFB_MODE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   183
            unitBytes = getNumOfUnit(mode, "CFB".length(), blockSize);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   184
            cipher = new CipherFeedback(rawImpl, unitBytes);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   185
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   186
        else if (modeUpperCase.startsWith("OFB")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   187
            cipherMode = OFB_MODE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   188
            unitBytes = getNumOfUnit(mode, "OFB".length(), blockSize);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   189
            cipher = new OutputFeedback(rawImpl, unitBytes);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   190
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   191
        else if (modeUpperCase.equals("PCBC")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   192
            cipherMode = PCBC_MODE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   193
            cipher = new PCBC(rawImpl);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   194
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   195
        else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   196
            throw new NoSuchAlgorithmException("Cipher mode: " + mode
90ce3da70b43 Initial load
duke
parents:
diff changeset
   197
                                               + " not found");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   198
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   199
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   200
90ce3da70b43 Initial load
duke
parents:
diff changeset
   201
    private static int getNumOfUnit(String mode, int offset, int blockSize)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   202
        throws NoSuchAlgorithmException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   203
        int result = blockSize; // use blockSize as default value
90ce3da70b43 Initial load
duke
parents:
diff changeset
   204
        if (mode.length() > offset) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   205
            int numInt;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   206
            try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   207
                Integer num = Integer.valueOf(mode.substring(offset));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   208
                numInt = num.intValue();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   209
                result = numInt >> 3;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   210
            } catch (NumberFormatException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   211
                throw new NoSuchAlgorithmException
90ce3da70b43 Initial load
duke
parents:
diff changeset
   212
                    ("Algorithm mode: " + mode + " not implemented");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   213
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   214
            if ((numInt % 8 != 0) || (result > blockSize)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   215
                throw new NoSuchAlgorithmException
90ce3da70b43 Initial load
duke
parents:
diff changeset
   216
                    ("Invalid algorithm mode: " + mode);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   217
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   218
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   219
        return result;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   220
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   221
90ce3da70b43 Initial load
duke
parents:
diff changeset
   222
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   223
     * Sets the padding mechanism of this cipher.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   224
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   225
     * @param padding the padding mechanism
90ce3da70b43 Initial load
duke
parents:
diff changeset
   226
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   227
     * @exception NoSuchPaddingException if the requested padding mechanism
90ce3da70b43 Initial load
duke
parents:
diff changeset
   228
     * does not exist
90ce3da70b43 Initial load
duke
parents:
diff changeset
   229
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   230
    void setPadding(String paddingScheme)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   231
        throws NoSuchPaddingException
90ce3da70b43 Initial load
duke
parents:
diff changeset
   232
    {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   233
        if (paddingScheme == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   234
            throw new NoSuchPaddingException("null padding");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   235
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   236
        if (paddingScheme.equalsIgnoreCase("NoPadding")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   237
            padding = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   238
        } else if (paddingScheme.equalsIgnoreCase("ISO10126Padding")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   239
            padding = new ISO10126Padding(blockSize);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   240
        } else if (!paddingScheme.equalsIgnoreCase("PKCS5Padding")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   241
            throw new NoSuchPaddingException("Padding: " + paddingScheme
90ce3da70b43 Initial load
duke
parents:
diff changeset
   242
                                             + " not implemented");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   243
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   244
        if ((padding != null) &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
   245
            ((cipherMode == CTR_MODE) || (cipherMode == CTS_MODE))) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   246
            padding = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   247
            throw new NoSuchPaddingException
90ce3da70b43 Initial load
duke
parents:
diff changeset
   248
                ((cipherMode == CTR_MODE? "CTR":"CTS") +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   249
                 " mode must be used with NoPadding");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   250
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   251
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   252
90ce3da70b43 Initial load
duke
parents:
diff changeset
   253
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   254
     * Returns the length in bytes that an output buffer would need to be in
90ce3da70b43 Initial load
duke
parents:
diff changeset
   255
     * order to hold the result of the next <code>update</code> or
90ce3da70b43 Initial load
duke
parents:
diff changeset
   256
     * <code>doFinal</code> operation, given the input length
90ce3da70b43 Initial load
duke
parents:
diff changeset
   257
     * <code>inputLen</code> (in bytes).
90ce3da70b43 Initial load
duke
parents:
diff changeset
   258
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   259
     * <p>This call takes into account any unprocessed (buffered) data from a
90ce3da70b43 Initial load
duke
parents:
diff changeset
   260
     * previous <code>update</code> call, and padding.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   261
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   262
     * <p>The actual output length of the next <code>update</code> or
90ce3da70b43 Initial load
duke
parents:
diff changeset
   263
     * <code>doFinal</code> call may be smaller than the length returned by
90ce3da70b43 Initial load
duke
parents:
diff changeset
   264
     * this method.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   265
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   266
     * @param inputLen the input length (in bytes)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   267
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   268
     * @return the required output buffer size (in bytes)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   269
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   270
    int getOutputSize(int inputLen) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   271
        int totalLen = buffered + inputLen;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   272
90ce3da70b43 Initial load
duke
parents:
diff changeset
   273
        if (padding == null)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   274
            return totalLen;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   275
90ce3da70b43 Initial load
duke
parents:
diff changeset
   276
        if (decrypting)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   277
            return totalLen;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   278
90ce3da70b43 Initial load
duke
parents:
diff changeset
   279
        if (unitBytes != blockSize) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   280
            if (totalLen < diffBlocksize)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   281
                return diffBlocksize;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   282
            else
90ce3da70b43 Initial load
duke
parents:
diff changeset
   283
                return (totalLen + blockSize -
90ce3da70b43 Initial load
duke
parents:
diff changeset
   284
                        ((totalLen - diffBlocksize) % blockSize));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   285
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   286
            return totalLen + padding.padLength(totalLen);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   287
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   288
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   289
90ce3da70b43 Initial load
duke
parents:
diff changeset
   290
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   291
     * Returns the initialization vector (IV) in a new buffer.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   292
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   293
     * <p>This is useful in the case where a random IV has been created
90ce3da70b43 Initial load
duke
parents:
diff changeset
   294
     * (see <a href = "#init">init</a>),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   295
     * or in the context of password-based encryption or
90ce3da70b43 Initial load
duke
parents:
diff changeset
   296
     * decryption, where the IV is derived from a user-provided password.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   297
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   298
     * @return the initialization vector in a new buffer, or null if the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   299
     * underlying algorithm does not use an IV, or if the IV has not yet
90ce3da70b43 Initial load
duke
parents:
diff changeset
   300
     * been set.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   301
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   302
    byte[] getIV() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   303
        byte[] iv = cipher.getIV();
10336
0bb1999251f8 7064075: Security libraries don't build with javac -Xlint:all,-deprecation -Werror
jjg
parents: 5506
diff changeset
   304
        return (iv == null) ? null : iv.clone();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   305
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   306
90ce3da70b43 Initial load
duke
parents:
diff changeset
   307
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   308
     * Returns the parameters used with this cipher.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   309
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   310
     * <p>The returned parameters may be the same that were used to initialize
90ce3da70b43 Initial load
duke
parents:
diff changeset
   311
     * this cipher, or may contain the default set of parameters or a set of
90ce3da70b43 Initial load
duke
parents:
diff changeset
   312
     * randomly generated parameters used by the underlying cipher
90ce3da70b43 Initial load
duke
parents:
diff changeset
   313
     * implementation (provided that the underlying cipher implementation
90ce3da70b43 Initial load
duke
parents:
diff changeset
   314
     * uses a default set of parameters or creates new parameters if it needs
90ce3da70b43 Initial load
duke
parents:
diff changeset
   315
     * parameters but was not initialized with any).
90ce3da70b43 Initial load
duke
parents:
diff changeset
   316
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   317
     * @return the parameters used with this cipher, or null if this cipher
90ce3da70b43 Initial load
duke
parents:
diff changeset
   318
     * does not use any parameters.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   319
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   320
    AlgorithmParameters getParameters(String algName) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   321
        AlgorithmParameters params = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   322
        if (cipherMode == ECB_MODE) return null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   323
        byte[] iv = getIV();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   324
        if (iv != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   325
            AlgorithmParameterSpec ivSpec;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   326
            if (algName.equals("RC2")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   327
                RC2Crypt rawImpl = (RC2Crypt) cipher.getEmbeddedCipher();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   328
                ivSpec = new RC2ParameterSpec(rawImpl.getEffectiveKeyBits(),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   329
                                              iv);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   330
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   331
                ivSpec = new IvParameterSpec(iv);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   332
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   333
            try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   334
                params = AlgorithmParameters.getInstance(algName, "SunJCE");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   335
            } catch (NoSuchAlgorithmException nsae) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   336
                // should never happen
90ce3da70b43 Initial load
duke
parents:
diff changeset
   337
                throw new RuntimeException("Cannot find " + algName +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   338
                    " AlgorithmParameters implementation in SunJCE provider");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   339
            } catch (NoSuchProviderException nspe) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   340
                // should never happen
90ce3da70b43 Initial load
duke
parents:
diff changeset
   341
                throw new RuntimeException("Cannot find SunJCE provider");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   342
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   343
            try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   344
                params.init(ivSpec);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   345
            } catch (InvalidParameterSpecException ipse) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   346
                // should never happen
90ce3da70b43 Initial load
duke
parents:
diff changeset
   347
                throw new RuntimeException("IvParameterSpec not supported");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   348
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   349
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   350
        return params;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   351
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   352
90ce3da70b43 Initial load
duke
parents:
diff changeset
   353
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   354
     * Initializes this cipher with a key and a source of randomness.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   355
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   356
     * <p>The cipher is initialized for one of the following four operations:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   357
     * encryption, decryption, key wrapping or key unwrapping, depending on
90ce3da70b43 Initial load
duke
parents:
diff changeset
   358
     * the value of <code>opmode</code>.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   359
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   360
     * <p>If this cipher requires an initialization vector (IV), it will get
90ce3da70b43 Initial load
duke
parents:
diff changeset
   361
     * it from <code>random</code>.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   362
     * This behaviour should only be used in encryption or key wrapping
90ce3da70b43 Initial load
duke
parents:
diff changeset
   363
     * mode, however.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   364
     * When initializing a cipher that requires an IV for decryption or
90ce3da70b43 Initial load
duke
parents:
diff changeset
   365
     * key unwrapping, the IV
90ce3da70b43 Initial load
duke
parents:
diff changeset
   366
     * (same IV that was used for encryption or key wrapping) must be provided
90ce3da70b43 Initial load
duke
parents:
diff changeset
   367
     * explicitly as a
90ce3da70b43 Initial load
duke
parents:
diff changeset
   368
     * parameter, in order to get the correct result.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   369
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   370
     * <p>This method also cleans existing buffer and other related state
90ce3da70b43 Initial load
duke
parents:
diff changeset
   371
     * information.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   372
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   373
     * @param opmode the operation mode of this cipher (this is one of
90ce3da70b43 Initial load
duke
parents:
diff changeset
   374
     * the following:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   375
     * <code>ENCRYPT_MODE</code>, <code>DECRYPT_MODE</code>,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   376
     * <code>WRAP_MODE</code> or <code>UNWRAP_MODE</code>)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   377
     * @param key the secret key
90ce3da70b43 Initial load
duke
parents:
diff changeset
   378
     * @param random the source of randomness
90ce3da70b43 Initial load
duke
parents:
diff changeset
   379
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   380
     * @exception InvalidKeyException if the given key is inappropriate for
90ce3da70b43 Initial load
duke
parents:
diff changeset
   381
     * initializing this cipher
90ce3da70b43 Initial load
duke
parents:
diff changeset
   382
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   383
    void init(int opmode, Key key, SecureRandom random)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   384
            throws InvalidKeyException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   385
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   386
            init(opmode, key, (AlgorithmParameterSpec)null, random);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   387
        } catch (InvalidAlgorithmParameterException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   388
            throw new InvalidKeyException(e.getMessage());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   389
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   390
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   391
90ce3da70b43 Initial load
duke
parents:
diff changeset
   392
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   393
     * Initializes this cipher with a key, a set of
90ce3da70b43 Initial load
duke
parents:
diff changeset
   394
     * algorithm parameters, and a source of randomness.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   395
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   396
     * <p>The cipher is initialized for one of the following four operations:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   397
     * encryption, decryption, key wrapping or key unwrapping, depending on
90ce3da70b43 Initial load
duke
parents:
diff changeset
   398
     * the value of <code>opmode</code>.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   399
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   400
     * <p>If this cipher (including its underlying feedback or padding scheme)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   401
     * requires any random bytes, it will get them from <code>random</code>.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   402
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   403
     * @param opmode the operation mode of this cipher (this is one of
90ce3da70b43 Initial load
duke
parents:
diff changeset
   404
     * the following:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   405
     * <code>ENCRYPT_MODE</code>, <code>DECRYPT_MODE</code>,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   406
     * <code>WRAP_MODE</code> or <code>UNWRAP_MODE</code>)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   407
     * @param key the encryption key
90ce3da70b43 Initial load
duke
parents:
diff changeset
   408
     * @param params the algorithm parameters
90ce3da70b43 Initial load
duke
parents:
diff changeset
   409
     * @param random the source of randomness
90ce3da70b43 Initial load
duke
parents:
diff changeset
   410
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   411
     * @exception InvalidKeyException if the given key is inappropriate for
90ce3da70b43 Initial load
duke
parents:
diff changeset
   412
     * initializing this cipher
90ce3da70b43 Initial load
duke
parents:
diff changeset
   413
     * @exception InvalidAlgorithmParameterException if the given algorithm
90ce3da70b43 Initial load
duke
parents:
diff changeset
   414
     * parameters are inappropriate for this cipher
90ce3da70b43 Initial load
duke
parents:
diff changeset
   415
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   416
    void init(int opmode, Key key, AlgorithmParameterSpec params,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   417
            SecureRandom random)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   418
            throws InvalidKeyException, InvalidAlgorithmParameterException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   419
        decrypting = (opmode == Cipher.DECRYPT_MODE)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   420
                  || (opmode == Cipher.UNWRAP_MODE);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   421
90ce3da70b43 Initial load
duke
parents:
diff changeset
   422
        byte[] keyBytes = getKeyBytes(key);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   423
90ce3da70b43 Initial load
duke
parents:
diff changeset
   424
        byte[] ivBytes;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   425
        if (params == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   426
            ivBytes = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   427
        } else if (params instanceof IvParameterSpec) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   428
            ivBytes = ((IvParameterSpec)params).getIV();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   429
            if ((ivBytes == null) || (ivBytes.length != blockSize)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   430
                throw new InvalidAlgorithmParameterException
90ce3da70b43 Initial load
duke
parents:
diff changeset
   431
                    ("Wrong IV length: must be " + blockSize +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   432
                    " bytes long");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   433
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   434
        } else if (params instanceof RC2ParameterSpec) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   435
            ivBytes = ((RC2ParameterSpec)params).getIV();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   436
            if ((ivBytes != null) && (ivBytes.length != blockSize)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   437
                throw new InvalidAlgorithmParameterException
90ce3da70b43 Initial load
duke
parents:
diff changeset
   438
                    ("Wrong IV length: must be " + blockSize +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   439
                    " bytes long");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   440
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   441
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   442
            throw new InvalidAlgorithmParameterException("Wrong parameter "
90ce3da70b43 Initial load
duke
parents:
diff changeset
   443
                                                         + "type: IV "
90ce3da70b43 Initial load
duke
parents:
diff changeset
   444
                                                         + "expected");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   445
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   446
90ce3da70b43 Initial load
duke
parents:
diff changeset
   447
        if (cipherMode == ECB_MODE) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   448
            if (ivBytes != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   449
                throw new InvalidAlgorithmParameterException
90ce3da70b43 Initial load
duke
parents:
diff changeset
   450
                                                ("ECB mode cannot use IV");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   451
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   452
        } else if (ivBytes == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   453
            if (decrypting) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   454
                throw new InvalidAlgorithmParameterException("Parameters "
90ce3da70b43 Initial load
duke
parents:
diff changeset
   455
                                                             + "missing");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   456
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   457
            if (random == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   458
                random = SunJCE.RANDOM;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   459
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   460
            ivBytes = new byte[blockSize];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   461
            random.nextBytes(ivBytes);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   462
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   463
90ce3da70b43 Initial load
duke
parents:
diff changeset
   464
        buffered = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   465
        diffBlocksize = blockSize;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   466
90ce3da70b43 Initial load
duke
parents:
diff changeset
   467
        String algorithm = key.getAlgorithm();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   468
90ce3da70b43 Initial load
duke
parents:
diff changeset
   469
        cipher.init(decrypting, algorithm, keyBytes, ivBytes);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   470
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   471
90ce3da70b43 Initial load
duke
parents:
diff changeset
   472
    void init(int opmode, Key key, AlgorithmParameters params,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   473
              SecureRandom random)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   474
        throws InvalidKeyException, InvalidAlgorithmParameterException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   475
        IvParameterSpec ivSpec = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   476
        if (params != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   477
            try {
10336
0bb1999251f8 7064075: Security libraries don't build with javac -Xlint:all,-deprecation -Werror
jjg
parents: 5506
diff changeset
   478
                ivSpec = params.getParameterSpec(IvParameterSpec.class);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   479
            } catch (InvalidParameterSpecException ipse) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   480
                throw new InvalidAlgorithmParameterException("Wrong parameter "
90ce3da70b43 Initial load
duke
parents:
diff changeset
   481
                                                             + "type: IV "
90ce3da70b43 Initial load
duke
parents:
diff changeset
   482
                                                             + "expected");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   483
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   484
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   485
        init(opmode, key, ivSpec, random);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   486
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   487
90ce3da70b43 Initial load
duke
parents:
diff changeset
   488
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   489
     * Return the key bytes of the specified key. Throw an InvalidKeyException
90ce3da70b43 Initial load
duke
parents:
diff changeset
   490
     * if the key is not usable.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   491
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   492
    static byte[] getKeyBytes(Key key) throws InvalidKeyException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   493
        if (key == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   494
            throw new InvalidKeyException("No key given");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   495
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   496
        // note: key.getFormat() may return null
90ce3da70b43 Initial load
duke
parents:
diff changeset
   497
        if (!"RAW".equalsIgnoreCase(key.getFormat())) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   498
            throw new InvalidKeyException("Wrong format: RAW bytes needed");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   499
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   500
        byte[] keyBytes = key.getEncoded();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   501
        if (keyBytes == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   502
            throw new InvalidKeyException("RAW key bytes missing");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   503
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   504
        return keyBytes;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   505
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   506
90ce3da70b43 Initial load
duke
parents:
diff changeset
   507
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   508
     * Continues a multiple-part encryption or decryption operation
90ce3da70b43 Initial load
duke
parents:
diff changeset
   509
     * (depending on how this cipher was initialized), processing another data
90ce3da70b43 Initial load
duke
parents:
diff changeset
   510
     * part.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   511
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   512
     * <p>The first <code>inputLen</code> bytes in the <code>input</code>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   513
     * buffer, starting at <code>inputOffset</code>, are processed, and the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   514
     * result is stored in a new buffer.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   515
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   516
     * @param input the input buffer
90ce3da70b43 Initial load
duke
parents:
diff changeset
   517
     * @param inputOffset the offset in <code>input</code> where the input
90ce3da70b43 Initial load
duke
parents:
diff changeset
   518
     * starts
90ce3da70b43 Initial load
duke
parents:
diff changeset
   519
     * @param inputLen the input length
90ce3da70b43 Initial load
duke
parents:
diff changeset
   520
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   521
     * @return the new buffer with the result
90ce3da70b43 Initial load
duke
parents:
diff changeset
   522
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   523
     * @exception IllegalStateException if this cipher is in a wrong state
90ce3da70b43 Initial load
duke
parents:
diff changeset
   524
     * (e.g., has not been initialized)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   525
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   526
    byte[] update(byte[] input, int inputOffset, int inputLen) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   527
        byte[] output = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   528
        byte[] out = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   529
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   530
            output = new byte[getOutputSize(inputLen)];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   531
            int len = update(input, inputOffset, inputLen, output,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   532
                             0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   533
            if (len == output.length) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   534
                out = output;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   535
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   536
                out = new byte[len];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   537
                System.arraycopy(output, 0, out, 0, len);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   538
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   539
        } catch (ShortBufferException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   540
            // never thrown
90ce3da70b43 Initial load
duke
parents:
diff changeset
   541
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   542
        return out;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   543
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   544
90ce3da70b43 Initial load
duke
parents:
diff changeset
   545
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   546
     * Continues a multiple-part encryption or decryption operation
90ce3da70b43 Initial load
duke
parents:
diff changeset
   547
     * (depending on how this cipher was initialized), processing another data
90ce3da70b43 Initial load
duke
parents:
diff changeset
   548
     * part.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   549
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   550
     * <p>The first <code>inputLen</code> bytes in the <code>input</code>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   551
     * buffer, starting at <code>inputOffset</code>, are processed, and the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   552
     * result is stored in the <code>output</code> buffer, starting at
90ce3da70b43 Initial load
duke
parents:
diff changeset
   553
     * <code>outputOffset</code>.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   554
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   555
     * @param input the input buffer
90ce3da70b43 Initial load
duke
parents:
diff changeset
   556
     * @param inputOffset the offset in <code>input</code> where the input
90ce3da70b43 Initial load
duke
parents:
diff changeset
   557
     * starts
90ce3da70b43 Initial load
duke
parents:
diff changeset
   558
     * @param inputLen the input length
90ce3da70b43 Initial load
duke
parents:
diff changeset
   559
     * @param output the buffer for the result
90ce3da70b43 Initial load
duke
parents:
diff changeset
   560
     * @param outputOffset the offset in <code>output</code> where the result
90ce3da70b43 Initial load
duke
parents:
diff changeset
   561
     * is stored
90ce3da70b43 Initial load
duke
parents:
diff changeset
   562
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   563
     * @return the number of bytes stored in <code>output</code>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   564
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   565
     * @exception ShortBufferException if the given output buffer is too small
90ce3da70b43 Initial load
duke
parents:
diff changeset
   566
     * to hold the result
90ce3da70b43 Initial load
duke
parents:
diff changeset
   567
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   568
    int update(byte[] input, int inputOffset, int inputLen, byte[] output,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   569
               int outputOffset) throws ShortBufferException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   570
        // figure out how much can be sent to crypto function
90ce3da70b43 Initial load
duke
parents:
diff changeset
   571
        int len = buffered + inputLen - minBytes;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   572
        if (padding != null && decrypting) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   573
            // do not include the padding bytes when decrypting
90ce3da70b43 Initial load
duke
parents:
diff changeset
   574
            len -= blockSize;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   575
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   576
        // do not count the trailing bytes which do not make up a unit
90ce3da70b43 Initial load
duke
parents:
diff changeset
   577
        len = (len > 0 ? (len - (len%unitBytes)) : 0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   578
90ce3da70b43 Initial load
duke
parents:
diff changeset
   579
        // check output buffer capacity
90ce3da70b43 Initial load
duke
parents:
diff changeset
   580
        if ((output == null) || ((output.length - outputOffset) < len)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   581
            throw new ShortBufferException("Output buffer must be "
90ce3da70b43 Initial load
duke
parents:
diff changeset
   582
                                           + "(at least) " + len
90ce3da70b43 Initial load
duke
parents:
diff changeset
   583
                                           + " bytes long");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   584
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   585
        if (len != 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   586
            // there is some work to do
90ce3da70b43 Initial load
duke
parents:
diff changeset
   587
            byte[] in = new byte[len];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   588
90ce3da70b43 Initial load
duke
parents:
diff changeset
   589
            int inputConsumed = len - buffered;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   590
            int bufferedConsumed = buffered;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   591
            if (inputConsumed < 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   592
                inputConsumed = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   593
                bufferedConsumed = len;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   594
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   595
90ce3da70b43 Initial load
duke
parents:
diff changeset
   596
            if (buffered != 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   597
                System.arraycopy(buffer, 0, in, 0, bufferedConsumed);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   598
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   599
            if (inputConsumed > 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   600
                System.arraycopy(input, inputOffset, in,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   601
                                 bufferedConsumed, inputConsumed);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   602
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   603
90ce3da70b43 Initial load
duke
parents:
diff changeset
   604
            if (decrypting) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   605
                cipher.decrypt(in, 0, len, output, outputOffset);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   606
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   607
                cipher.encrypt(in, 0, len, output, outputOffset);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   608
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   609
90ce3da70b43 Initial load
duke
parents:
diff changeset
   610
            // Let's keep track of how many bytes are needed to make
90ce3da70b43 Initial load
duke
parents:
diff changeset
   611
            // the total input length a multiple of blocksize when
90ce3da70b43 Initial load
duke
parents:
diff changeset
   612
            // padding is applied
90ce3da70b43 Initial load
duke
parents:
diff changeset
   613
            if (unitBytes != blockSize) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   614
                if (len < diffBlocksize)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   615
                    diffBlocksize -= len;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   616
                else
90ce3da70b43 Initial load
duke
parents:
diff changeset
   617
                    diffBlocksize = blockSize -
90ce3da70b43 Initial load
duke
parents:
diff changeset
   618
                        ((len - diffBlocksize) % blockSize);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   619
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   620
90ce3da70b43 Initial load
duke
parents:
diff changeset
   621
            inputLen -= inputConsumed;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   622
            inputOffset += inputConsumed;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   623
            outputOffset += len;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   624
            buffered -= bufferedConsumed;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   625
            if (buffered > 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   626
                System.arraycopy(buffer, bufferedConsumed, buffer, 0,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   627
                                 buffered);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   628
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   629
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   630
        // left over again
90ce3da70b43 Initial load
duke
parents:
diff changeset
   631
        if (inputLen > 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   632
            System.arraycopy(input, inputOffset, buffer, buffered,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   633
                             inputLen);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   634
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   635
        buffered += inputLen;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   636
        return len;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   637
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   638
90ce3da70b43 Initial load
duke
parents:
diff changeset
   639
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   640
     * Encrypts or decrypts data in a single-part operation,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   641
     * or finishes a multiple-part operation.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   642
     * The data is encrypted or decrypted, depending on how this cipher was
90ce3da70b43 Initial load
duke
parents:
diff changeset
   643
     * initialized.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   644
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   645
     * <p>The first <code>inputLen</code> bytes in the <code>input</code>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   646
     * buffer, starting at <code>inputOffset</code>, and any input bytes that
90ce3da70b43 Initial load
duke
parents:
diff changeset
   647
     * may have been buffered during a previous <code>update</code> operation,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   648
     * are processed, with padding (if requested) being applied.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   649
     * The result is stored in a new buffer.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   650
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   651
     * <p>The cipher is reset to its initial state (uninitialized) after this
90ce3da70b43 Initial load
duke
parents:
diff changeset
   652
     * call.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   653
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   654
     * @param input the input buffer
90ce3da70b43 Initial load
duke
parents:
diff changeset
   655
     * @param inputOffset the offset in <code>input</code> where the input
90ce3da70b43 Initial load
duke
parents:
diff changeset
   656
     * starts
90ce3da70b43 Initial load
duke
parents:
diff changeset
   657
     * @param inputLen the input length
90ce3da70b43 Initial load
duke
parents:
diff changeset
   658
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   659
     * @return the new buffer with the result
90ce3da70b43 Initial load
duke
parents:
diff changeset
   660
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   661
     * @exception IllegalBlockSizeException if this cipher is a block cipher,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   662
     * no padding has been requested (only in encryption mode), and the total
90ce3da70b43 Initial load
duke
parents:
diff changeset
   663
     * input length of the data processed by this cipher is not a multiple of
90ce3da70b43 Initial load
duke
parents:
diff changeset
   664
     * block size
90ce3da70b43 Initial load
duke
parents:
diff changeset
   665
     * @exception BadPaddingException if this cipher is in decryption mode,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   666
     * and (un)padding has been requested, but the decrypted data is not
90ce3da70b43 Initial load
duke
parents:
diff changeset
   667
     * bounded by the appropriate padding bytes
90ce3da70b43 Initial load
duke
parents:
diff changeset
   668
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   669
    byte[] doFinal(byte[] input, int inputOffset, int inputLen)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   670
        throws IllegalBlockSizeException, BadPaddingException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   671
        byte[] output = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   672
        byte[] out = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   673
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   674
            output = new byte[getOutputSize(inputLen)];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   675
            int len = doFinal(input, inputOffset, inputLen, output, 0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   676
            if (len < output.length) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   677
                out = new byte[len];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   678
                if (len != 0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   679
                    System.arraycopy(output, 0, out, 0, len);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   680
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   681
                out = output;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   682
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   683
        } catch (ShortBufferException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   684
            // never thrown
90ce3da70b43 Initial load
duke
parents:
diff changeset
   685
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   686
        return out;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   687
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   688
90ce3da70b43 Initial load
duke
parents:
diff changeset
   689
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   690
     * Encrypts or decrypts data in a single-part operation,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   691
     * or finishes a multiple-part operation.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   692
     * The data is encrypted or decrypted, depending on how this cipher was
90ce3da70b43 Initial load
duke
parents:
diff changeset
   693
     * initialized.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   694
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   695
     * <p>The first <code>inputLen</code> bytes in the <code>input</code>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   696
     * buffer, starting at <code>inputOffset</code>, and any input bytes that
90ce3da70b43 Initial load
duke
parents:
diff changeset
   697
     * may have been buffered during a previous <code>update</code> operation,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   698
     * are processed, with padding (if requested) being applied.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   699
     * The result is stored in the <code>output</code> buffer, starting at
90ce3da70b43 Initial load
duke
parents:
diff changeset
   700
     * <code>outputOffset</code>.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   701
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   702
     * <p>The cipher is reset to its initial state (uninitialized) after this
90ce3da70b43 Initial load
duke
parents:
diff changeset
   703
     * call.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   704
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   705
     * @param input the input buffer
90ce3da70b43 Initial load
duke
parents:
diff changeset
   706
     * @param inputOffset the offset in <code>input</code> where the input
90ce3da70b43 Initial load
duke
parents:
diff changeset
   707
     * starts
90ce3da70b43 Initial load
duke
parents:
diff changeset
   708
     * @param inputLen the input length
90ce3da70b43 Initial load
duke
parents:
diff changeset
   709
     * @param output the buffer for the result
90ce3da70b43 Initial load
duke
parents:
diff changeset
   710
     * @param outputOffset the offset in <code>output</code> where the result
90ce3da70b43 Initial load
duke
parents:
diff changeset
   711
     * is stored
90ce3da70b43 Initial load
duke
parents:
diff changeset
   712
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   713
     * @return the number of bytes stored in <code>output</code>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   714
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   715
     * @exception IllegalBlockSizeException if this cipher is a block cipher,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   716
     * no padding has been requested (only in encryption mode), and the total
90ce3da70b43 Initial load
duke
parents:
diff changeset
   717
     * input length of the data processed by this cipher is not a multiple of
90ce3da70b43 Initial load
duke
parents:
diff changeset
   718
     * block size
90ce3da70b43 Initial load
duke
parents:
diff changeset
   719
     * @exception ShortBufferException if the given output buffer is too small
90ce3da70b43 Initial load
duke
parents:
diff changeset
   720
     * to hold the result
90ce3da70b43 Initial load
duke
parents:
diff changeset
   721
     * @exception BadPaddingException if this cipher is in decryption mode,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   722
     * and (un)padding has been requested, but the decrypted data is not
90ce3da70b43 Initial load
duke
parents:
diff changeset
   723
     * bounded by the appropriate padding bytes
90ce3da70b43 Initial load
duke
parents:
diff changeset
   724
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   725
    int doFinal(byte[] input, int inputOffset, int inputLen, byte[] output,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   726
                int outputOffset)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   727
        throws IllegalBlockSizeException, ShortBufferException,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   728
               BadPaddingException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   729
90ce3da70b43 Initial load
duke
parents:
diff changeset
   730
        // calculate the total input length
90ce3da70b43 Initial load
duke
parents:
diff changeset
   731
        int totalLen = buffered + inputLen;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   732
        int paddedLen = totalLen;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   733
        int paddingLen = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   734
90ce3da70b43 Initial load
duke
parents:
diff changeset
   735
        // will the total input length be a multiple of blockSize?
90ce3da70b43 Initial load
duke
parents:
diff changeset
   736
        if (unitBytes != blockSize) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   737
            if (totalLen < diffBlocksize) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   738
                paddingLen = diffBlocksize - totalLen;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   739
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   740
                paddingLen = blockSize -
90ce3da70b43 Initial load
duke
parents:
diff changeset
   741
                    ((totalLen - diffBlocksize) % blockSize);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   742
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   743
        } else if (padding != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   744
            paddingLen = padding.padLength(totalLen);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   745
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   746
90ce3da70b43 Initial load
duke
parents:
diff changeset
   747
        if ((paddingLen > 0) && (paddingLen != blockSize) &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
   748
            (padding != null) && decrypting) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   749
            throw new IllegalBlockSizeException
90ce3da70b43 Initial load
duke
parents:
diff changeset
   750
                ("Input length must be multiple of " + blockSize +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   751
                 " when decrypting with padded cipher");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   752
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   753
90ce3da70b43 Initial load
duke
parents:
diff changeset
   754
        // if encrypting and padding not null, add padding
90ce3da70b43 Initial load
duke
parents:
diff changeset
   755
        if (!decrypting && padding != null)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   756
            paddedLen += paddingLen;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   757
90ce3da70b43 Initial load
duke
parents:
diff changeset
   758
        // check output buffer capacity.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   759
        // if we are decrypting with padding applied, we can perform this
90ce3da70b43 Initial load
duke
parents:
diff changeset
   760
        // check only after we have determined how many padding bytes there
90ce3da70b43 Initial load
duke
parents:
diff changeset
   761
        // are.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   762
        if (output == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   763
            throw new ShortBufferException("Output buffer is null");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   764
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   765
        int outputCapacity = output.length - outputOffset;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   766
        if (((!decrypting) || (padding == null)) &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
   767
            (outputCapacity < paddedLen) ||
90ce3da70b43 Initial load
duke
parents:
diff changeset
   768
            (decrypting && (outputCapacity < (paddedLen - blockSize)))) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   769
            throw new ShortBufferException("Output buffer too short: "
90ce3da70b43 Initial load
duke
parents:
diff changeset
   770
                                           + outputCapacity + " bytes given, "
90ce3da70b43 Initial load
duke
parents:
diff changeset
   771
                                           + paddedLen + " bytes needed");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   772
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   773
90ce3da70b43 Initial load
duke
parents:
diff changeset
   774
        // prepare the final input avoiding copying if possible
90ce3da70b43 Initial load
duke
parents:
diff changeset
   775
        byte[] finalBuf = input;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   776
        int finalOffset = inputOffset;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   777
        if ((buffered != 0) || (!decrypting && padding != null)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   778
            finalOffset = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   779
            finalBuf = new byte[paddedLen];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   780
            if (buffered != 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   781
                System.arraycopy(buffer, 0, finalBuf, 0, buffered);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   782
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   783
            if (inputLen != 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   784
                System.arraycopy(input, inputOffset, finalBuf,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   785
                                 buffered, inputLen);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   786
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   787
            if (!decrypting && padding != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   788
                padding.padWithLen(finalBuf, totalLen, paddingLen);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   789
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   790
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   791
90ce3da70b43 Initial load
duke
parents:
diff changeset
   792
        if (decrypting) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   793
            // if the size of specified output buffer is less than
90ce3da70b43 Initial load
duke
parents:
diff changeset
   794
            // the length of the cipher text, then the current
90ce3da70b43 Initial load
duke
parents:
diff changeset
   795
            // content of cipher has to be preserved in order for
90ce3da70b43 Initial load
duke
parents:
diff changeset
   796
            // users to retry the call with a larger buffer in the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   797
            // case of ShortBufferException.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   798
            if (outputCapacity < paddedLen) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   799
                cipher.save();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   800
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   801
            // create temporary output buffer so that only "real"
90ce3da70b43 Initial load
duke
parents:
diff changeset
   802
            // data bytes are passed to user's output buffer.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   803
            byte[] outWithPadding = new byte[totalLen];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   804
            totalLen = finalNoPadding(finalBuf, finalOffset, outWithPadding,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   805
                                      0, totalLen);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   806
90ce3da70b43 Initial load
duke
parents:
diff changeset
   807
            if (padding != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   808
                int padStart = padding.unpad(outWithPadding, 0, totalLen);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   809
                if (padStart < 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   810
                    throw new BadPaddingException("Given final block not "
90ce3da70b43 Initial load
duke
parents:
diff changeset
   811
                                                  + "properly padded");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   812
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   813
                totalLen = padStart;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   814
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   815
            if ((output.length - outputOffset) < totalLen) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   816
                // restore so users can retry with a larger buffer
90ce3da70b43 Initial load
duke
parents:
diff changeset
   817
                cipher.restore();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   818
                throw new ShortBufferException("Output buffer too short: "
90ce3da70b43 Initial load
duke
parents:
diff changeset
   819
                                               + (output.length-outputOffset)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   820
                                               + " bytes given, " + totalLen
90ce3da70b43 Initial load
duke
parents:
diff changeset
   821
                                               + " bytes needed");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   822
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   823
            for (int i = 0; i < totalLen; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   824
                output[outputOffset + i] = outWithPadding[i];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   825
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   826
        } else { // encrypting
90ce3da70b43 Initial load
duke
parents:
diff changeset
   827
            totalLen = finalNoPadding(finalBuf, finalOffset, output,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   828
                                      outputOffset, paddedLen);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   829
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   830
90ce3da70b43 Initial load
duke
parents:
diff changeset
   831
        buffered = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   832
        diffBlocksize = blockSize;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   833
        if (cipherMode != ECB_MODE) {
10336
0bb1999251f8 7064075: Security libraries don't build with javac -Xlint:all,-deprecation -Werror
jjg
parents: 5506
diff changeset
   834
            cipher.reset();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   835
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   836
        return totalLen;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   837
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   838
90ce3da70b43 Initial load
duke
parents:
diff changeset
   839
    private int finalNoPadding(byte[] in, int inOff, byte[] out, int outOff,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   840
                               int len)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   841
        throws IllegalBlockSizeException
90ce3da70b43 Initial load
duke
parents:
diff changeset
   842
    {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   843
        if (in == null || len == 0)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   844
            return 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   845
90ce3da70b43 Initial load
duke
parents:
diff changeset
   846
        if ((cipherMode != CFB_MODE) && (cipherMode != OFB_MODE)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   847
            && ((len % unitBytes) != 0) && (cipherMode != CTS_MODE)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   848
            if (padding != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   849
                throw new IllegalBlockSizeException
90ce3da70b43 Initial load
duke
parents:
diff changeset
   850
                    ("Input length (with padding) not multiple of " +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   851
                     unitBytes + " bytes");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   852
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   853
                throw new IllegalBlockSizeException
90ce3da70b43 Initial load
duke
parents:
diff changeset
   854
                    ("Input length not multiple of " + unitBytes
90ce3da70b43 Initial load
duke
parents:
diff changeset
   855
                     + " bytes");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   856
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   857
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   858
90ce3da70b43 Initial load
duke
parents:
diff changeset
   859
        if (decrypting) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   860
            cipher.decryptFinal(in, inOff, len, out, outOff);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   861
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   862
            cipher.encryptFinal(in, inOff, len, out, outOff);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   863
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   864
90ce3da70b43 Initial load
duke
parents:
diff changeset
   865
        return len;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   866
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   867
90ce3da70b43 Initial load
duke
parents:
diff changeset
   868
    // Note: Wrap() and Unwrap() are the same in
90ce3da70b43 Initial load
duke
parents:
diff changeset
   869
    // each of SunJCE CipherSpi implementation classes.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   870
    // They are duplicated due to export control requirements:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   871
    // All CipherSpi implementation must be final.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   872
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   873
     * Wrap a key.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   874
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   875
     * @param key the key to be wrapped.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   876
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   877
     * @return the wrapped key.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   878
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   879
     * @exception IllegalBlockSizeException if this cipher is a block
90ce3da70b43 Initial load
duke
parents:
diff changeset
   880
     * cipher, no padding has been requested, and the length of the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   881
     * encoding of the key to be wrapped is not a
90ce3da70b43 Initial load
duke
parents:
diff changeset
   882
     * multiple of the block size.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   883
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   884
     * @exception InvalidKeyException if it is impossible or unsafe to
90ce3da70b43 Initial load
duke
parents:
diff changeset
   885
     * wrap the key with this cipher (e.g., a hardware protected key is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   886
     * being passed to a software only cipher).
90ce3da70b43 Initial load
duke
parents:
diff changeset
   887
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   888
    byte[] wrap(Key key)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   889
        throws IllegalBlockSizeException, InvalidKeyException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   890
        byte[] result = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   891
90ce3da70b43 Initial load
duke
parents:
diff changeset
   892
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   893
            byte[] encodedKey = key.getEncoded();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   894
            if ((encodedKey == null) || (encodedKey.length == 0)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   895
                throw new InvalidKeyException("Cannot get an encoding of " +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   896
                                              "the key to be wrapped");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   897
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   898
            result = doFinal(encodedKey, 0, encodedKey.length);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   899
        } catch (BadPaddingException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   900
            // Should never happen
90ce3da70b43 Initial load
duke
parents:
diff changeset
   901
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   902
        return result;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   903
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   904
90ce3da70b43 Initial load
duke
parents:
diff changeset
   905
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   906
     * Unwrap a previously wrapped key.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   907
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   908
     * @param wrappedKey the key to be unwrapped.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   909
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   910
     * @param wrappedKeyAlgorithm the algorithm the wrapped key is for.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   911
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   912
     * @param wrappedKeyType the type of the wrapped key.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   913
     * This is one of <code>Cipher.SECRET_KEY</code>,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   914
     * <code>Cipher.PRIVATE_KEY</code>, or <code>Cipher.PUBLIC_KEY</code>.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   915
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   916
     * @return the unwrapped key.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   917
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   918
     * @exception NoSuchAlgorithmException if no installed providers
90ce3da70b43 Initial load
duke
parents:
diff changeset
   919
     * can create keys of type <code>wrappedKeyType</code> for the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   920
     * <code>wrappedKeyAlgorithm</code>.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   921
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   922
     * @exception InvalidKeyException if <code>wrappedKey</code> does not
90ce3da70b43 Initial load
duke
parents:
diff changeset
   923
     * represent a wrapped key of type <code>wrappedKeyType</code> for
90ce3da70b43 Initial load
duke
parents:
diff changeset
   924
     * the <code>wrappedKeyAlgorithm</code>.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   925
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   926
    Key unwrap(byte[] wrappedKey, String wrappedKeyAlgorithm,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   927
               int wrappedKeyType)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   928
        throws InvalidKeyException, NoSuchAlgorithmException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   929
        byte[] encodedKey;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   930
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   931
            encodedKey = doFinal(wrappedKey, 0, wrappedKey.length);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   932
        } catch (BadPaddingException ePadding) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   933
            throw new InvalidKeyException("The wrapped key is not padded " +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   934
                                          "correctly");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   935
        } catch (IllegalBlockSizeException eBlockSize) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   936
            throw new InvalidKeyException("The wrapped key does not have " +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   937
                                          "the correct length");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   938
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   939
        return ConstructKeys.constructKey(encodedKey, wrappedKeyAlgorithm,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   940
                                          wrappedKeyType);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   941
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   942
}