src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11AEADCipher.java
author chegar
Thu, 17 Oct 2019 20:54:25 +0100
branchdatagramsocketimpl-branch
changeset 58679 9c3209ff7550
parent 58678 9cf78a70fa4f
parent 58489 2faeaa5933a6
permissions -rw-r--r--
datagramsocketimpl-branch: merge with default
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
55332
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
     1
/* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
     2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
     3
 *
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
     4
 * This code is free software; you can redistribute it and/or modify it
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
     5
 * under the terms of the GNU General Public License version 2 only, as
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
     6
 * published by the Free Software Foundation.  Oracle designates this
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
     7
 * particular file as subject to the "Classpath" exception as provided
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
     8
 * by Oracle in the LICENSE file that accompanied this code.
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
     9
 *
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
    10
 * This code is distributed in the hope that it will be useful, but WITHOUT
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
    11
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
    12
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
    13
 * version 2 for more details (a copy is included in the LICENSE file that
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
    14
 * accompanied this code).
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
    15
 *
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
    16
 * You should have received a copy of the GNU General Public License version
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
    17
 * 2 along with this work; if not, write to the Free Software Foundation,
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
    18
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
    19
 *
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
    20
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
    21
 * or visit www.oracle.com if you need additional information or have any
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
    22
 * questions.
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
    23
 */
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
    24
package sun.security.pkcs11;
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
    25
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
    26
import java.io.ByteArrayOutputStream;
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
    27
import java.nio.ByteBuffer;
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
    28
import java.util.Arrays;
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
    29
import java.util.Locale;
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
    30
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
    31
import java.security.*;
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
    32
import java.security.spec.*;
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
    33
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
    34
import javax.crypto.*;
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
    35
import javax.crypto.spec.*;
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
    36
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
    37
import sun.nio.ch.DirectBuffer;
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
    38
import sun.security.jca.JCAUtil;
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
    39
import sun.security.pkcs11.wrapper.*;
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
    40
import static sun.security.pkcs11.wrapper.PKCS11Constants.*;
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
    41
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
    42
/**
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
    43
 * P11 AEAD Cipher implementation class. This class currently supports
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
    44
 * AES with GCM mode.
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
    45
 *
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
    46
 * Note that AEAD modes do not use padding, so this class does not have
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
    47
 * its own padding impl. In addition, NSS CKM_AES_GCM only supports single-part
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
    48
 * encryption/decryption, thus the current impl uses PKCS#11 C_Encrypt/C_Decrypt
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
    49
 * calls and buffers data until doFinal is called.
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
    50
 *
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
    51
 * Note that PKCS#11 standard currently only supports GCM and CCM AEAD modes.
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
    52
 * There are no provisions for other AEAD modes yet.
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
    53
 *
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
    54
 * @since   13
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
    55
 */
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
    56
final class P11AEADCipher extends CipherSpi {
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
    57
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
    58
    // mode constant for GCM mode
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
    59
    private static final int MODE_GCM = 10;
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
    60
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
    61
    // default constants for GCM
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
    62
    private static final int GCM_DEFAULT_TAG_LEN = 16;
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
    63
    private static final int GCM_DEFAULT_IV_LEN = 16;
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
    64
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
    65
    private static final String ALGO = "AES";
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
    66
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
    67
    // token instance
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
    68
    private final Token token;
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
    69
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
    70
    // mechanism id
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
    71
    private final long mechanism;
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
    72
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
    73
    // mode, one of MODE_* above
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
    74
    private final int blockMode;
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
    75
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
    76
    // acceptable key size, -1 if more than 1 key sizes are accepted
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
    77
    private final int fixedKeySize;
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
    78
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
    79
    // associated session, if any
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
    80
    private Session session = null;
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
    81
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
    82
    // key, if init() was called
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
    83
    private P11Key p11Key = null;
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
    84
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
    85
    // flag indicating whether an operation is initialized
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
    86
    private boolean initialized = false;
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
    87
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
    88
    // falg indicating encrypt or decrypt mode
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
    89
    private boolean encrypt = true;
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
    90
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
    91
    // parameters
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
    92
    private byte[] iv = null;
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
    93
    private int tagLen = -1;
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
    94
    private SecureRandom random = JCAUtil.getSecureRandom();
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
    95
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
    96
    // dataBuffer is cleared upon doFinal calls
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
    97
    private ByteArrayOutputStream dataBuffer = new ByteArrayOutputStream();
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
    98
    // aadBuffer is cleared upon successful init calls
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
    99
    private ByteArrayOutputStream aadBuffer = new ByteArrayOutputStream();
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   100
    private boolean updateCalled = false;
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   101
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   102
    private boolean requireReinit = false;
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   103
    private P11Key lastEncKey = null;
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   104
    private byte[] lastEncIv = null;
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   105
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   106
    P11AEADCipher(Token token, String algorithm, long mechanism)
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   107
            throws PKCS11Exception, NoSuchAlgorithmException {
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   108
        super();
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   109
        this.token = token;
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   110
        this.mechanism = mechanism;
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   111
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   112
        String[] algoParts = algorithm.split("/");
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   113
        if (algoParts.length != 3) {
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   114
            throw new ProviderException("Unsupported Transformation format: " +
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   115
                    algorithm);
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   116
        }
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   117
        if (!algoParts[0].startsWith("AES")) {
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   118
            throw new ProviderException("Only support AES for AEAD cipher mode");
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   119
        }
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   120
        int index = algoParts[0].indexOf('_');
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   121
        if (index != -1) {
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   122
            // should be well-formed since we specify what we support
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   123
            fixedKeySize = Integer.parseInt(algoParts[0].substring(index+1)) >> 3;
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   124
        } else {
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   125
            fixedKeySize = -1;
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   126
        }
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   127
        this.blockMode = parseMode(algoParts[1]);
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   128
        if (!algoParts[2].equals("NoPadding")) {
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   129
            throw new ProviderException("Only NoPadding is supported for AEAD cipher mode");
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   130
        }
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   131
    }
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   132
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   133
    protected void engineSetMode(String mode) throws NoSuchAlgorithmException {
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   134
        // Disallow change of mode for now since currently it's explicitly
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   135
        // defined in transformation strings
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   136
        throw new NoSuchAlgorithmException("Unsupported mode " + mode);
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   137
    }
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   138
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   139
    private int parseMode(String mode) throws NoSuchAlgorithmException {
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   140
        mode = mode.toUpperCase(Locale.ENGLISH);
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   141
        int result;
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   142
        if (mode.equals("GCM")) {
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   143
            result = MODE_GCM;
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   144
        } else {
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   145
            throw new NoSuchAlgorithmException("Unsupported mode " + mode);
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   146
        }
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   147
        return result;
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   148
    }
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   149
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   150
    // see JCE spec
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   151
    protected void engineSetPadding(String padding)
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   152
            throws NoSuchPaddingException {
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   153
        // Disallow change of padding for now since currently it's explicitly
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   154
        // defined in transformation strings
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   155
        throw new NoSuchPaddingException("Unsupported padding " + padding);
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   156
    }
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   157
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   158
    // see JCE spec
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   159
    protected int engineGetBlockSize() {
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   160
        return 16; // constant; only AES is supported
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   161
    }
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   162
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   163
    // see JCE spec
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   164
    protected int engineGetOutputSize(int inputLen) {
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   165
        return doFinalLength(inputLen);
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   166
    }
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   167
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   168
    // see JCE spec
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   169
    protected byte[] engineGetIV() {
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   170
        return (iv == null) ? null : iv.clone();
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   171
    }
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   172
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   173
    // see JCE spec
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   174
    protected AlgorithmParameters engineGetParameters() {
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   175
        if (encrypt && iv == null && tagLen == -1) {
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   176
            switch (blockMode) {
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   177
                case MODE_GCM:
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   178
                    iv = new byte[GCM_DEFAULT_IV_LEN];
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   179
                    tagLen = GCM_DEFAULT_TAG_LEN;
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   180
                    break;
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   181
                default:
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   182
                    throw new ProviderException("Unsupported mode");
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   183
            }
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   184
            random.nextBytes(iv);
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   185
        }
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   186
        try {
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   187
            AlgorithmParameterSpec spec;
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   188
            String apAlgo;
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   189
            switch (blockMode) {
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   190
                case MODE_GCM:
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   191
                    apAlgo = "GCM";
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   192
                    spec = new GCMParameterSpec(tagLen << 3, iv);
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   193
                    break;
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   194
                default:
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   195
                    throw new ProviderException("Unsupported mode");
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   196
            }
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   197
            AlgorithmParameters params =
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   198
                AlgorithmParameters.getInstance(apAlgo);
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   199
            params.init(spec);
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   200
            return params;
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   201
        } catch (GeneralSecurityException e) {
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   202
            // NoSuchAlgorithmException, NoSuchProviderException
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   203
            // InvalidParameterSpecException
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   204
            throw new ProviderException("Could not encode parameters", e);
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   205
        }
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   206
    }
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   207
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   208
    // see JCE spec
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   209
    protected void engineInit(int opmode, Key key, SecureRandom sr)
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   210
            throws InvalidKeyException {
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   211
        if (opmode == Cipher.DECRYPT_MODE) {
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   212
            throw new InvalidKeyException("Parameters required for decryption");
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   213
        }
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   214
        updateCalled = false;
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   215
        try {
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   216
            implInit(opmode, key, null, -1, sr);
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   217
        } catch (InvalidAlgorithmParameterException e) {
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   218
            throw new InvalidKeyException("init() failed", e);
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   219
        }
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   220
    }
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   221
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   222
    // see JCE spec
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   223
    protected void engineInit(int opmode, Key key,
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   224
            AlgorithmParameterSpec params, SecureRandom sr)
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   225
            throws InvalidKeyException, InvalidAlgorithmParameterException {
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   226
        if (opmode == Cipher.DECRYPT_MODE && params == null) {
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   227
            throw new InvalidAlgorithmParameterException
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   228
                    ("Parameters required for decryption");
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   229
        }
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   230
        updateCalled = false;
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   231
        byte[] ivValue = null;
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   232
        int tagLen = -1;
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   233
        if (params != null) {
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   234
            switch (blockMode) {
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   235
            case MODE_GCM:
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   236
                if (!(params instanceof GCMParameterSpec)) {
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   237
                    throw new InvalidAlgorithmParameterException
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   238
                        ("Only GCMParameterSpec is supported");
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   239
                }
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   240
                ivValue = ((GCMParameterSpec) params).getIV();
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   241
                tagLen = ((GCMParameterSpec) params).getTLen() >> 3;
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   242
            break;
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   243
            default:
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   244
                throw new ProviderException("Unsupported mode");
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   245
            }
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   246
        }
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   247
        implInit(opmode, key, ivValue, tagLen, sr);
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   248
    }
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   249
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   250
    // see JCE spec
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   251
    protected void engineInit(int opmode, Key key, AlgorithmParameters params,
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   252
            SecureRandom sr)
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   253
            throws InvalidKeyException, InvalidAlgorithmParameterException {
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   254
        if (opmode == Cipher.DECRYPT_MODE && params == null) {
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   255
            throw new InvalidAlgorithmParameterException
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   256
                    ("Parameters required for decryption");
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   257
        }
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   258
        updateCalled = false;
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   259
        try {
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   260
            AlgorithmParameterSpec paramSpec = null;
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   261
            if (params != null) {
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   262
                switch (blockMode) {
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   263
                    case MODE_GCM:
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   264
                        paramSpec =
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   265
                            params.getParameterSpec(GCMParameterSpec.class);
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   266
                        break;
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   267
                    default:
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   268
                        throw new ProviderException("Unsupported mode");
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   269
                }
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   270
            }
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   271
            engineInit(opmode, key, paramSpec, sr);
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   272
        } catch (InvalidParameterSpecException ex) {
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   273
            throw new InvalidAlgorithmParameterException(ex);
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   274
        }
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   275
    }
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   276
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   277
    // actual init() implementation
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   278
    private void implInit(int opmode, Key key, byte[] iv, int tagLen,
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   279
        SecureRandom sr)
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   280
        throws InvalidKeyException, InvalidAlgorithmParameterException {
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   281
        reset(true);
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   282
        if (fixedKeySize != -1 && key.getEncoded().length != fixedKeySize) {
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   283
            throw new InvalidKeyException("Key size is invalid");
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   284
        }
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   285
        P11Key newKey = P11SecretKeyFactory.convertKey(token, key, ALGO);
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   286
        switch (opmode) {
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   287
            case Cipher.ENCRYPT_MODE:
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   288
                encrypt = true;
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   289
                requireReinit = Arrays.equals(iv, lastEncIv) &&
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   290
                        (newKey == lastEncKey);
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   291
                if (requireReinit) {
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   292
                    throw new InvalidAlgorithmParameterException
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   293
                        ("Cannot reuse iv for GCM encryption");
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   294
                }
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   295
                break;
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   296
            case Cipher.DECRYPT_MODE:
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   297
                encrypt = false;
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   298
                requireReinit = false;
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   299
                break;
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   300
            default:
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   301
                throw new InvalidAlgorithmParameterException
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   302
                        ("Unsupported mode: " + opmode);
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   303
        }
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   304
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   305
        // decryption without parameters is checked in all engineInit() calls
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   306
        if (sr != null) {
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   307
            this.random = sr;
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   308
        }
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   309
        if (iv == null && tagLen == -1) {
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   310
            // generate default values
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   311
            switch (blockMode) {
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   312
                case MODE_GCM:
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   313
                    iv = new byte[GCM_DEFAULT_IV_LEN];
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   314
                    this.random.nextBytes(iv);
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   315
                    tagLen = GCM_DEFAULT_TAG_LEN;
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   316
                    break;
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   317
                default:
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   318
                    throw new ProviderException("Unsupported mode");
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   319
            }
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   320
        }
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   321
        this.iv = iv;
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   322
        this.tagLen = tagLen;
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   323
        this.p11Key = newKey;
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   324
        try {
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   325
            initialize();
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   326
        } catch (PKCS11Exception e) {
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   327
            throw new InvalidKeyException("Could not initialize cipher", e);
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   328
        }
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   329
    }
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   330
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   331
    private void cancelOperation() {
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   332
        try {
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   333
            if (session.hasObjects() == false) {
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   334
                session = token.killSession(session);
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   335
                return;
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   336
            } else {
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   337
                // cancel operation by finishing it
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   338
                int bufLen = doFinalLength(0);
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   339
                byte[] buffer = new byte[bufLen];
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   340
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   341
                if (encrypt) {
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   342
                    token.p11.C_Encrypt(session.id(), 0, buffer, 0, bufLen,
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   343
                            0, buffer, 0, bufLen);
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   344
                } else {
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   345
                    token.p11.C_Decrypt(session.id(), 0, buffer, 0, bufLen,
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   346
                            0, buffer, 0, bufLen);
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   347
                }
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   348
            }
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   349
        } catch (PKCS11Exception e) {
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   350
            throw new ProviderException("Cancel failed", e);
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   351
        }
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   352
    }
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   353
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   354
    private void ensureInitialized() throws PKCS11Exception {
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   355
        if (initialized && aadBuffer.size() > 0) {
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   356
            // need to cancel first to avoid CKR_OPERATION_ACTIVE
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   357
            reset(true);
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   358
        }
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   359
        if (!initialized) {
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   360
            initialize();
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   361
        }
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   362
    }
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   363
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   364
    private void initialize() throws PKCS11Exception {
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   365
        if (p11Key == null) {
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   366
            throw new ProviderException(
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   367
                    "Operation cannot be performed without"
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   368
                    + " calling engineInit first");
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   369
        }
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   370
        if (requireReinit) {
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   371
            throw new IllegalStateException
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   372
                ("Must use either different key or iv for GCM encryption");
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   373
        }
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   374
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   375
        token.ensureValid();
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   376
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   377
        byte[] aad = (aadBuffer.size() > 0? aadBuffer.toByteArray() : null);
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   378
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   379
        long p11KeyID = p11Key.getKeyID();
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   380
        try {
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   381
            CK_MECHANISM mechWithParams;
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   382
            switch (blockMode) {
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   383
                case MODE_GCM:
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   384
                    mechWithParams = new CK_MECHANISM(mechanism,
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   385
                        new CK_GCM_PARAMS(tagLen << 3, iv, aad));
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   386
                    break;
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   387
                default:
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   388
                    throw new ProviderException("Unsupported mode: " + blockMode);
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   389
            }
58489
2faeaa5933a6 8229243: SunPKCS11-Solaris provider tests failing on Solaris 11.4
valeriep
parents: 55332
diff changeset
   390
            if (session == null) {
2faeaa5933a6 8229243: SunPKCS11-Solaris provider tests failing on Solaris 11.4
valeriep
parents: 55332
diff changeset
   391
                session = token.getOpSession();
2faeaa5933a6 8229243: SunPKCS11-Solaris provider tests failing on Solaris 11.4
valeriep
parents: 55332
diff changeset
   392
            }
55332
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   393
            if (encrypt) {
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   394
                token.p11.C_EncryptInit(session.id(), mechWithParams,
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   395
                    p11KeyID);
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   396
            } else {
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   397
                token.p11.C_DecryptInit(session.id(), mechWithParams,
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   398
                    p11KeyID);
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   399
            }
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   400
        } catch (PKCS11Exception e) {
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   401
            p11Key.releaseKeyID();
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   402
            session = token.releaseSession(session);
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   403
            throw e;
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   404
        } finally {
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   405
            dataBuffer.reset();
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   406
            aadBuffer.reset();
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   407
        }
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   408
        initialized = true;
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   409
    }
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   410
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   411
    // if doFinal(inLen) is called, how big does the output buffer have to be?
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   412
    private int doFinalLength(int inLen) {
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   413
        if (inLen < 0) {
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   414
            throw new ProviderException("Invalid negative input length");
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   415
        }
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   416
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   417
        int result = inLen + dataBuffer.size();
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   418
        if (encrypt) {
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   419
            result += tagLen;
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   420
        } else {
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   421
            // PKCS11Exception: CKR_BUFFER_TOO_SMALL
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   422
            //result -= tagLen;
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   423
        }
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   424
        return result;
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   425
    }
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   426
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   427
    // reset the states to the pre-initialized values
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   428
    private void reset(boolean doCancel) {
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   429
        if (!initialized) {
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   430
            return;
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   431
        }
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   432
        try {
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   433
            if (session == null) {
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   434
                return;
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   435
            }
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   436
            if (doCancel && token.explicitCancel) {
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   437
                cancelOperation();
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   438
            }
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   439
        } finally {
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   440
            p11Key.releaseKeyID();
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   441
            session = token.releaseSession(session);
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   442
        }
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   443
        initialized = false;
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   444
    }
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   445
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   446
    // see JCE spec
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   447
    protected byte[] engineUpdate(byte[] in, int inOfs, int inLen) {
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   448
        updateCalled = true;
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   449
        int n = implUpdate(in, inOfs, inLen);
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   450
        return new byte[0];
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   451
    }
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   452
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   453
    // see JCE spec
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   454
    protected int engineUpdate(byte[] in, int inOfs, int inLen, byte[] out,
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   455
            int outOfs) throws ShortBufferException {
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   456
        updateCalled = true;
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   457
        implUpdate(in, inOfs, inLen);
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   458
        return 0;
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   459
    }
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   460
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   461
    // see JCE spec
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   462
    @Override
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   463
    protected int engineUpdate(ByteBuffer inBuffer, ByteBuffer outBuffer)
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   464
            throws ShortBufferException {
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   465
        updateCalled = true;
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   466
        implUpdate(inBuffer);
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   467
        return 0;
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   468
    }
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   469
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   470
    // see JCE spec
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   471
    @Override
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   472
    protected synchronized void engineUpdateAAD(byte[] src, int srcOfs, int srcLen)
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   473
            throws IllegalStateException {
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   474
        if ((src == null) || (srcOfs < 0) || (srcOfs + srcLen > src.length)) {
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   475
            throw new IllegalArgumentException("Invalid AAD");
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   476
        }
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   477
        if (requireReinit) {
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   478
            throw new IllegalStateException
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   479
                ("Must use either different key or iv for GCM encryption");
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   480
        }
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   481
        if (p11Key == null) {
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   482
            throw new IllegalStateException("Need to initialize Cipher first");
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   483
        }
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   484
        if (updateCalled) {
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   485
            throw new IllegalStateException
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   486
                ("Update has been called; no more AAD data");
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   487
        }
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   488
        aadBuffer.write(src, srcOfs, srcLen);
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   489
    }
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   490
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   491
    // see JCE spec
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   492
    @Override
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   493
    protected void engineUpdateAAD(ByteBuffer src)
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   494
            throws IllegalStateException {
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   495
        if (src == null) {
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   496
            throw new IllegalArgumentException("Invalid AAD");
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   497
        }
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   498
        byte[] srcBytes = new byte[src.remaining()];
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   499
        src.get(srcBytes);
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   500
        engineUpdateAAD(srcBytes, 0, srcBytes.length);
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   501
    }
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   502
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   503
    // see JCE spec
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   504
    protected byte[] engineDoFinal(byte[] in, int inOfs, int inLen)
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   505
            throws IllegalBlockSizeException, BadPaddingException {
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   506
        int minOutLen = doFinalLength(inLen);
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   507
        try {
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   508
            byte[] out = new byte[minOutLen];
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   509
            int n = engineDoFinal(in, inOfs, inLen, out, 0);
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   510
            return P11Util.convert(out, 0, n);
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   511
        } catch (ShortBufferException e) {
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   512
            // convert since the output length is calculated by doFinalLength()
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   513
            throw new ProviderException(e);
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   514
        } finally {
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   515
            updateCalled = false;
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   516
        }
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   517
    }
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   518
    // see JCE spec
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   519
    protected int engineDoFinal(byte[] in, int inOfs, int inLen, byte[] out,
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   520
            int outOfs) throws ShortBufferException, IllegalBlockSizeException,
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   521
            BadPaddingException {
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   522
        try {
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   523
            return implDoFinal(in, inOfs, inLen, out, outOfs, out.length - outOfs);
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   524
        } finally {
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   525
            updateCalled = false;
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   526
        }
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   527
    }
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   528
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   529
    // see JCE spec
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   530
    @Override
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   531
    protected int engineDoFinal(ByteBuffer inBuffer, ByteBuffer outBuffer)
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   532
            throws ShortBufferException, IllegalBlockSizeException,
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   533
            BadPaddingException {
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   534
        try {
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   535
            return implDoFinal(inBuffer, outBuffer);
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   536
        } finally {
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   537
            updateCalled = false;
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   538
        }
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   539
    }
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   540
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   541
    private int implUpdate(byte[] in, int inOfs, int inLen) {
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   542
        if (inLen > 0) {
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   543
            updateCalled = true;
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   544
            try {
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   545
                ensureInitialized();
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   546
            } catch (PKCS11Exception e) {
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   547
                //e.printStackTrace();
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   548
                reset(false);
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   549
                throw new ProviderException("update() failed", e);
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   550
            }
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   551
            dataBuffer.write(in, inOfs, inLen);
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   552
        }
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   553
        // always 0 as NSS only supports single-part encryption/decryption
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   554
        return 0;
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   555
    }
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   556
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   557
    private int implUpdate(ByteBuffer inBuf) {
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   558
        int inLen = inBuf.remaining();
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   559
        if (inLen > 0) {
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   560
            try {
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   561
                ensureInitialized();
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   562
            } catch (PKCS11Exception e) {
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   563
                reset(false);
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   564
                throw new ProviderException("update() failed", e);
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   565
            }
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   566
            byte[] data = new byte[inLen];
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   567
            inBuf.get(data);
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   568
            dataBuffer.write(data, 0, data.length);
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   569
        }
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   570
        // always 0 as NSS only supports single-part encryption/decryption
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   571
        return 0;
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   572
    }
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   573
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   574
    private int implDoFinal(byte[] in, int inOfs, int inLen,
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   575
            byte[] out, int outOfs, int outLen)
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   576
            throws ShortBufferException, IllegalBlockSizeException,
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   577
            BadPaddingException {
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   578
        int requiredOutLen = doFinalLength(inLen);
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   579
        if (outLen < requiredOutLen) {
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   580
            throw new ShortBufferException();
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   581
        }
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   582
        boolean doCancel = true;
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   583
        try {
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   584
            ensureInitialized();
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   585
            if (dataBuffer.size() > 0) {
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   586
                if (in != null && inOfs > 0 && inLen > 0 &&
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   587
                    inOfs < (in.length - inLen)) {
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   588
                    dataBuffer.write(in, inOfs, inLen);
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   589
                }
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   590
                in = dataBuffer.toByteArray();
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   591
                inOfs = 0;
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   592
                inLen = in.length;
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   593
            }
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   594
            int k = 0;
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   595
            if (encrypt) {
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   596
                k = token.p11.C_Encrypt(session.id(), 0, in, inOfs, inLen,
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   597
                        0, out, outOfs, outLen);
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   598
                doCancel = false;
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   599
            } else {
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   600
                // Special handling to match SunJCE provider behavior
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   601
                if (inLen == 0) {
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   602
                    return 0;
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   603
                }
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   604
                k = token.p11.C_Decrypt(session.id(), 0, in, inOfs, inLen,
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   605
                        0, out, outOfs, outLen);
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   606
                doCancel = false;
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   607
            }
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   608
            return k;
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   609
        } catch (PKCS11Exception e) {
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   610
            doCancel = false;
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   611
            handleException(e);
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   612
            throw new ProviderException("doFinal() failed", e);
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   613
        } finally {
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   614
            if (encrypt) {
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   615
                lastEncKey = this.p11Key;
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   616
                lastEncIv = this.iv;
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   617
                requireReinit = true;
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   618
            }
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   619
            reset(doCancel);
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   620
        }
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   621
    }
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   622
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   623
    private int implDoFinal(ByteBuffer inBuffer, ByteBuffer outBuffer)
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   624
            throws ShortBufferException, IllegalBlockSizeException,
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   625
            BadPaddingException {
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   626
        int outLen = outBuffer.remaining();
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   627
        int inLen = inBuffer.remaining();
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   628
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   629
        int requiredOutLen = doFinalLength(inLen);
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   630
        if (outLen < requiredOutLen) {
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   631
            throw new ShortBufferException();
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   632
        }
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   633
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   634
        boolean doCancel = true;
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   635
        try {
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   636
            ensureInitialized();
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   637
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   638
            long inAddr = 0;
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   639
            byte[] in = null;
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   640
            int inOfs = 0;
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   641
            if (dataBuffer.size() > 0) {
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   642
                if (inLen > 0) {
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   643
                    byte[] temp = new byte[inLen];
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   644
                    inBuffer.get(temp);
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   645
                    dataBuffer.write(temp, 0, temp.length);
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   646
                }
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   647
                in = dataBuffer.toByteArray();
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   648
                inOfs = 0;
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   649
                inLen = in.length;
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   650
            } else {
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   651
                if (inBuffer instanceof DirectBuffer) {
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   652
                    inAddr = ((DirectBuffer) inBuffer).address();
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   653
                    inOfs = inBuffer.position();
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   654
                } else {
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   655
                    if (inBuffer.hasArray()) {
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   656
                        in = inBuffer.array();
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   657
                        inOfs = inBuffer.position() + inBuffer.arrayOffset();
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   658
                    } else {
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   659
                        in = new byte[inLen];
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   660
                        inBuffer.get(in);
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   661
                    }
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   662
                }
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   663
            }
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   664
            long outAddr = 0;
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   665
            byte[] outArray = null;
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   666
            int outOfs = 0;
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   667
            if (outBuffer instanceof DirectBuffer) {
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   668
                outAddr = ((DirectBuffer) outBuffer).address();
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   669
                outOfs = outBuffer.position();
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   670
            } else {
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   671
                if (outBuffer.hasArray()) {
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   672
                    outArray = outBuffer.array();
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   673
                    outOfs = outBuffer.position() + outBuffer.arrayOffset();
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   674
                } else {
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   675
                    outArray = new byte[outLen];
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   676
                }
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   677
            }
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   678
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   679
            int k = 0;
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   680
            if (encrypt) {
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   681
                k = token.p11.C_Encrypt(session.id(), inAddr, in, inOfs, inLen,
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   682
                        outAddr, outArray, outOfs, outLen);
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   683
                doCancel = false;
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   684
            } else {
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   685
                // Special handling to match SunJCE provider behavior
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   686
                if (inLen == 0) {
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   687
                    return 0;
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   688
                }
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   689
                k = token.p11.C_Decrypt(session.id(), inAddr, in, inOfs, inLen,
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   690
                        outAddr, outArray, outOfs, outLen);
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   691
                doCancel = false;
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   692
            }
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   693
            outBuffer.position(outBuffer.position() + k);
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   694
            return k;
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   695
        } catch (PKCS11Exception e) {
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   696
            doCancel = false;
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   697
            handleException(e);
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   698
            throw new ProviderException("doFinal() failed", e);
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   699
        } finally {
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   700
            if (encrypt) {
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   701
                lastEncKey = this.p11Key;
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   702
                lastEncIv = this.iv;
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   703
                requireReinit = true;
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   704
            }
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   705
            reset(doCancel);
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   706
        }
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   707
    }
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   708
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   709
    private void handleException(PKCS11Exception e)
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   710
            throws ShortBufferException, IllegalBlockSizeException,
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   711
            BadPaddingException {
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   712
        long errorCode = e.getErrorCode();
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   713
        if (errorCode == CKR_BUFFER_TOO_SMALL) {
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   714
            throw (ShortBufferException)
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   715
                    (new ShortBufferException().initCause(e));
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   716
        } else if (errorCode == CKR_DATA_LEN_RANGE ||
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   717
                   errorCode == CKR_ENCRYPTED_DATA_LEN_RANGE) {
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   718
            throw (IllegalBlockSizeException)
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   719
                    (new IllegalBlockSizeException(e.toString()).initCause(e));
58489
2faeaa5933a6 8229243: SunPKCS11-Solaris provider tests failing on Solaris 11.4
valeriep
parents: 55332
diff changeset
   720
        } else if (errorCode == CKR_ENCRYPTED_DATA_INVALID ||
2faeaa5933a6 8229243: SunPKCS11-Solaris provider tests failing on Solaris 11.4
valeriep
parents: 55332
diff changeset
   721
                // Solaris-specific
2faeaa5933a6 8229243: SunPKCS11-Solaris provider tests failing on Solaris 11.4
valeriep
parents: 55332
diff changeset
   722
                errorCode == CKR_GENERAL_ERROR) {
55332
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   723
            throw (BadPaddingException)
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   724
                    (new BadPaddingException(e.toString()).initCause(e));
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   725
        }
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   726
    }
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   727
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   728
    // see JCE spec
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   729
    protected byte[] engineWrap(Key key) throws IllegalBlockSizeException,
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   730
            InvalidKeyException {
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   731
        // XXX key wrapping
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   732
        throw new UnsupportedOperationException("engineWrap()");
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   733
    }
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   734
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   735
    // see JCE spec
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   736
    protected Key engineUnwrap(byte[] wrappedKey, String wrappedKeyAlgorithm,
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   737
            int wrappedKeyType)
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   738
            throws InvalidKeyException, NoSuchAlgorithmException {
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   739
        // XXX key unwrapping
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   740
        throw new UnsupportedOperationException("engineUnwrap()");
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   741
    }
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   742
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   743
    // see JCE spec
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   744
    @Override
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   745
    protected int engineGetKeySize(Key key) throws InvalidKeyException {
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   746
        int n = P11SecretKeyFactory.convertKey
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   747
                (token, key, ALGO).length();
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   748
        return n;
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   749
    }
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   750
}
f492567244ab 8080462: Update SunPKCS11 provider with PKCS11 v2.40 support
valeriep
parents:
diff changeset
   751