jdk/src/share/classes/sun/security/rsa/RSAPadding.java
author wetmore
Wed, 22 Jan 2014 14:59:33 -0800
changeset 23911 f93d74f7d6fe
parent 22309 1990211a42e5
permissions -rw-r--r--
8027766: Enhance RSA processing Summary: Refactored code Reviewed-by: mullan, xuelei
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     1
/*
22309
1990211a42e5 8023069: Enhance TLS connections
xuelei
parents: 19436
diff changeset
     2
 * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
90ce3da70b43 Initial load
duke
parents:
diff changeset
     4
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
90ce3da70b43 Initial load
duke
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2
diff changeset
     7
 * published by the Free Software Foundation.  Oracle designates this
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2
diff changeset
     9
 * by Oracle in the LICENSE file that accompanied this code.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    10
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
90ce3da70b43 Initial load
duke
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
90ce3da70b43 Initial load
duke
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
90ce3da70b43 Initial load
duke
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
90ce3da70b43 Initial load
duke
parents:
diff changeset
    15
 * accompanied this code).
90ce3da70b43 Initial load
duke
parents:
diff changeset
    16
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
90ce3da70b43 Initial load
duke
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    20
 *
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2
diff changeset
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2
diff changeset
    22
 * or visit www.oracle.com if you need additional information or have any
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2
diff changeset
    23
 * questions.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    24
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    25
90ce3da70b43 Initial load
duke
parents:
diff changeset
    26
package sun.security.rsa;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    27
90ce3da70b43 Initial load
duke
parents:
diff changeset
    28
import java.util.*;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    29
90ce3da70b43 Initial load
duke
parents:
diff changeset
    30
import java.security.*;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    31
import java.security.spec.*;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    32
90ce3da70b43 Initial load
duke
parents:
diff changeset
    33
import javax.crypto.BadPaddingException;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    34
import javax.crypto.spec.PSource;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    35
import javax.crypto.spec.OAEPParameterSpec;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    36
90ce3da70b43 Initial load
duke
parents:
diff changeset
    37
import sun.security.jca.JCAUtil;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    38
90ce3da70b43 Initial load
duke
parents:
diff changeset
    39
/**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    40
 * RSA padding and unpadding.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    41
 *
23911
f93d74f7d6fe 8027766: Enhance RSA processing
wetmore
parents: 22309
diff changeset
    42
 * The various PKCS#1 versions can be found in the EMC/RSA Labs
f93d74f7d6fe 8027766: Enhance RSA processing
wetmore
parents: 22309
diff changeset
    43
 * web site, which is currently:
f93d74f7d6fe 8027766: Enhance RSA processing
wetmore
parents: 22309
diff changeset
    44
 *
f93d74f7d6fe 8027766: Enhance RSA processing
wetmore
parents: 22309
diff changeset
    45
 *     http://www.emc.com/emc-plus/rsa-labs/index.htm
f93d74f7d6fe 8027766: Enhance RSA processing
wetmore
parents: 22309
diff changeset
    46
 *
f93d74f7d6fe 8027766: Enhance RSA processing
wetmore
parents: 22309
diff changeset
    47
 * or in the IETF RFCs derived from the above PKCS#1 standards.
f93d74f7d6fe 8027766: Enhance RSA processing
wetmore
parents: 22309
diff changeset
    48
 *
f93d74f7d6fe 8027766: Enhance RSA processing
wetmore
parents: 22309
diff changeset
    49
 *     RFC 2313: v1.5
f93d74f7d6fe 8027766: Enhance RSA processing
wetmore
parents: 22309
diff changeset
    50
 *     RFC 2437: v2.0
f93d74f7d6fe 8027766: Enhance RSA processing
wetmore
parents: 22309
diff changeset
    51
 *     RFC 3447: v2.1
f93d74f7d6fe 8027766: Enhance RSA processing
wetmore
parents: 22309
diff changeset
    52
 *
f93d74f7d6fe 8027766: Enhance RSA processing
wetmore
parents: 22309
diff changeset
    53
 * The format of PKCS#1 v1.5 padding is:
f93d74f7d6fe 8027766: Enhance RSA processing
wetmore
parents: 22309
diff changeset
    54
 *
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    55
 *   0x00 | BT | PS...PS | 0x00 | data...data
23911
f93d74f7d6fe 8027766: Enhance RSA processing
wetmore
parents: 22309
diff changeset
    56
 *
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    57
 * where BT is the blocktype (1 or 2). The length of the entire string
90ce3da70b43 Initial load
duke
parents:
diff changeset
    58
 * must be the same as the size of the modulus (i.e. 128 byte for a 1024 bit
90ce3da70b43 Initial load
duke
parents:
diff changeset
    59
 * key). Per spec, the padding string must be at least 8 bytes long. That
90ce3da70b43 Initial load
duke
parents:
diff changeset
    60
 * leaves up to (length of key in bytes) - 11 bytes for the data.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    61
 *
23911
f93d74f7d6fe 8027766: Enhance RSA processing
wetmore
parents: 22309
diff changeset
    62
 * OAEP padding was introduced in PKCS#1 v2.0 and is a bit more complicated
f93d74f7d6fe 8027766: Enhance RSA processing
wetmore
parents: 22309
diff changeset
    63
 * and has a number of options. We support:
f93d74f7d6fe 8027766: Enhance RSA processing
wetmore
parents: 22309
diff changeset
    64
 *
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    65
 *   . arbitrary hash functions ('Hash' in the specification), MessageDigest
90ce3da70b43 Initial load
duke
parents:
diff changeset
    66
 *     implementation must be available
90ce3da70b43 Initial load
duke
parents:
diff changeset
    67
 *   . MGF1 as the mask generation function
90ce3da70b43 Initial load
duke
parents:
diff changeset
    68
 *   . the empty string as the default value for label L and whatever
90ce3da70b43 Initial load
duke
parents:
diff changeset
    69
 *     specified in javax.crypto.spec.OAEPParameterSpec
90ce3da70b43 Initial load
duke
parents:
diff changeset
    70
 *
23911
f93d74f7d6fe 8027766: Enhance RSA processing
wetmore
parents: 22309
diff changeset
    71
 * The algorithms (representations) are forwards-compatible: that is,
f93d74f7d6fe 8027766: Enhance RSA processing
wetmore
parents: 22309
diff changeset
    72
 * the algorithm described in previous releases are in later releases.
f93d74f7d6fe 8027766: Enhance RSA processing
wetmore
parents: 22309
diff changeset
    73
 * However, additional comments/checks/clarifications were added to the
f93d74f7d6fe 8027766: Enhance RSA processing
wetmore
parents: 22309
diff changeset
    74
 * later versions based on real-world experience (e.g. stricter v1.5
f93d74f7d6fe 8027766: Enhance RSA processing
wetmore
parents: 22309
diff changeset
    75
 * format checking.)
f93d74f7d6fe 8027766: Enhance RSA processing
wetmore
parents: 22309
diff changeset
    76
 *
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    77
 * Note: RSA keys should be at least 512 bits long
90ce3da70b43 Initial load
duke
parents:
diff changeset
    78
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    79
 * @since   1.5
90ce3da70b43 Initial load
duke
parents:
diff changeset
    80
 * @author  Andreas Sterbenz
90ce3da70b43 Initial load
duke
parents:
diff changeset
    81
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    82
public final class RSAPadding {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    83
90ce3da70b43 Initial load
duke
parents:
diff changeset
    84
    // NOTE: the constants below are embedded in the JCE RSACipher class
90ce3da70b43 Initial load
duke
parents:
diff changeset
    85
    // file. Do not change without coordinating the update
90ce3da70b43 Initial load
duke
parents:
diff changeset
    86
90ce3da70b43 Initial load
duke
parents:
diff changeset
    87
    // PKCS#1 v1.5 padding, blocktype 1 (signing)
90ce3da70b43 Initial load
duke
parents:
diff changeset
    88
    public final static int PAD_BLOCKTYPE_1    = 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    89
    // PKCS#1 v1.5 padding, blocktype 2 (encryption)
90ce3da70b43 Initial load
duke
parents:
diff changeset
    90
    public final static int PAD_BLOCKTYPE_2    = 2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    91
    // nopadding. Does not do anything, but allows simpler RSACipher code
90ce3da70b43 Initial load
duke
parents:
diff changeset
    92
    public final static int PAD_NONE           = 3;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    93
    // PKCS#1 v2.1 OAEP padding
90ce3da70b43 Initial load
duke
parents:
diff changeset
    94
    public final static int PAD_OAEP_MGF1 = 4;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    95
90ce3da70b43 Initial load
duke
parents:
diff changeset
    96
    // type, one of PAD_*
90ce3da70b43 Initial load
duke
parents:
diff changeset
    97
    private final int type;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    98
90ce3da70b43 Initial load
duke
parents:
diff changeset
    99
    // size of the padded block (i.e. size of the modulus)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   100
    private final int paddedSize;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   101
90ce3da70b43 Initial load
duke
parents:
diff changeset
   102
    // PRNG used to generate padding bytes (PAD_BLOCKTYPE_2, PAD_OAEP_MGF1)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   103
    private SecureRandom random;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   104
90ce3da70b43 Initial load
duke
parents:
diff changeset
   105
    // maximum size of the data
90ce3da70b43 Initial load
duke
parents:
diff changeset
   106
    private final int maxDataSize;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   107
90ce3da70b43 Initial load
duke
parents:
diff changeset
   108
    // OAEP: main messagedigest
90ce3da70b43 Initial load
duke
parents:
diff changeset
   109
    private MessageDigest md;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   110
90ce3da70b43 Initial load
duke
parents:
diff changeset
   111
    // OAEP: message digest for MGF1
90ce3da70b43 Initial load
duke
parents:
diff changeset
   112
    private MessageDigest mgfMd;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   113
90ce3da70b43 Initial load
duke
parents:
diff changeset
   114
    // OAEP: value of digest of data (user-supplied or zero-length) using md
90ce3da70b43 Initial load
duke
parents:
diff changeset
   115
    private byte[] lHash;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   116
90ce3da70b43 Initial load
duke
parents:
diff changeset
   117
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   118
     * Get a RSAPadding instance of the specified type.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   119
     * Keys used with this padding must be paddedSize bytes long.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   120
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   121
    public static RSAPadding getInstance(int type, int paddedSize)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   122
            throws InvalidKeyException, InvalidAlgorithmParameterException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   123
        return new RSAPadding(type, paddedSize, null, null);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   124
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   125
90ce3da70b43 Initial load
duke
parents:
diff changeset
   126
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   127
     * Get a RSAPadding instance of the specified type.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   128
     * Keys used with this padding must be paddedSize bytes long.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   129
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   130
    public static RSAPadding getInstance(int type, int paddedSize,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   131
            SecureRandom random) throws InvalidKeyException,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   132
            InvalidAlgorithmParameterException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   133
        return new RSAPadding(type, paddedSize, random, null);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   134
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   135
90ce3da70b43 Initial load
duke
parents:
diff changeset
   136
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   137
     * Get a RSAPadding instance of the specified type, which must be
90ce3da70b43 Initial load
duke
parents:
diff changeset
   138
     * OAEP. Keys used with this padding must be paddedSize bytes long.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   139
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   140
    public static RSAPadding getInstance(int type, int paddedSize,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   141
            SecureRandom random, OAEPParameterSpec spec)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   142
        throws InvalidKeyException, InvalidAlgorithmParameterException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   143
        return new RSAPadding(type, paddedSize, random, spec);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   144
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   145
90ce3da70b43 Initial load
duke
parents:
diff changeset
   146
    // internal constructor
90ce3da70b43 Initial load
duke
parents:
diff changeset
   147
    private RSAPadding(int type, int paddedSize, SecureRandom random,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   148
            OAEPParameterSpec spec) throws InvalidKeyException,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   149
            InvalidAlgorithmParameterException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   150
        this.type = type;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   151
        this.paddedSize = paddedSize;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   152
        this.random = random;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   153
        if (paddedSize < 64) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   154
            // sanity check, already verified in RSASignature/RSACipher
90ce3da70b43 Initial load
duke
parents:
diff changeset
   155
            throw new InvalidKeyException("Padded size must be at least 64");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   156
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   157
        switch (type) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   158
        case PAD_BLOCKTYPE_1:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   159
        case PAD_BLOCKTYPE_2:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   160
            maxDataSize = paddedSize - 11;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   161
            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   162
        case PAD_NONE:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   163
            maxDataSize = paddedSize;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   164
            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   165
        case PAD_OAEP_MGF1:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   166
            String mdName = "SHA-1";
90ce3da70b43 Initial load
duke
parents:
diff changeset
   167
            String mgfMdName = "SHA-1";
90ce3da70b43 Initial load
duke
parents:
diff changeset
   168
            byte[] digestInput = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   169
            try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   170
                if (spec != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   171
                    mdName = spec.getDigestAlgorithm();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   172
                    String mgfName = spec.getMGFAlgorithm();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   173
                    if (!mgfName.equalsIgnoreCase("MGF1")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   174
                        throw new InvalidAlgorithmParameterException
90ce3da70b43 Initial load
duke
parents:
diff changeset
   175
                            ("Unsupported MGF algo: " + mgfName);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   176
                    }
23911
f93d74f7d6fe 8027766: Enhance RSA processing
wetmore
parents: 22309
diff changeset
   177
                    mgfMdName = ((MGF1ParameterSpec)spec.getMGFParameters())
f93d74f7d6fe 8027766: Enhance RSA processing
wetmore
parents: 22309
diff changeset
   178
                            .getDigestAlgorithm();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   179
                    PSource pSrc = spec.getPSource();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   180
                    String pSrcAlgo = pSrc.getAlgorithm();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   181
                    if (!pSrcAlgo.equalsIgnoreCase("PSpecified")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   182
                        throw new InvalidAlgorithmParameterException
90ce3da70b43 Initial load
duke
parents:
diff changeset
   183
                            ("Unsupported pSource algo: " + pSrcAlgo);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   184
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   185
                    digestInput = ((PSource.PSpecified) pSrc).getValue();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   186
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   187
                md = MessageDigest.getInstance(mdName);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   188
                mgfMd = MessageDigest.getInstance(mgfMdName);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   189
            } catch (NoSuchAlgorithmException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   190
                throw new InvalidKeyException
90ce3da70b43 Initial load
duke
parents:
diff changeset
   191
                        ("Digest " + mdName + " not available", e);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   192
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   193
            lHash = getInitialHash(md, digestInput);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   194
            int digestLen = lHash.length;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   195
            maxDataSize = paddedSize - 2 - 2 * digestLen;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   196
            if (maxDataSize <= 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   197
                throw new InvalidKeyException
90ce3da70b43 Initial load
duke
parents:
diff changeset
   198
                        ("Key is too short for encryption using OAEPPadding" +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   199
                         " with " + mdName + " and MGF1" + mgfMdName);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   200
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   201
            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   202
        default:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   203
            throw new InvalidKeyException("Invalid padding: " + type);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   204
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   205
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   206
90ce3da70b43 Initial load
duke
parents:
diff changeset
   207
    // cache of hashes of zero length data
90ce3da70b43 Initial load
duke
parents:
diff changeset
   208
    private static final Map<String,byte[]> emptyHashes =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   209
        Collections.synchronizedMap(new HashMap<String,byte[]>());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   210
90ce3da70b43 Initial load
duke
parents:
diff changeset
   211
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   212
     * Return the value of the digest using the specified message digest
90ce3da70b43 Initial load
duke
parents:
diff changeset
   213
     * <code>md</code> and the digest input <code>digestInput</code>.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   214
     * if <code>digestInput</code> is null or 0-length, zero length
90ce3da70b43 Initial load
duke
parents:
diff changeset
   215
     * is used to generate the initial digest.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   216
     * Note: the md object must be in reset state
90ce3da70b43 Initial load
duke
parents:
diff changeset
   217
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   218
    private static byte[] getInitialHash(MessageDigest md,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   219
        byte[] digestInput) {
23911
f93d74f7d6fe 8027766: Enhance RSA processing
wetmore
parents: 22309
diff changeset
   220
        byte[] result;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   221
        if ((digestInput == null) || (digestInput.length == 0)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   222
            String digestName = md.getAlgorithm();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   223
            result = emptyHashes.get(digestName);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   224
            if (result == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   225
                result = md.digest();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   226
                emptyHashes.put(digestName, result);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   227
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   228
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   229
            result = md.digest(digestInput);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   230
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   231
        return result;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   232
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   233
90ce3da70b43 Initial load
duke
parents:
diff changeset
   234
    /**
23911
f93d74f7d6fe 8027766: Enhance RSA processing
wetmore
parents: 22309
diff changeset
   235
     * Return the maximum size of the plaintext data that can be processed
f93d74f7d6fe 8027766: Enhance RSA processing
wetmore
parents: 22309
diff changeset
   236
     * using this object.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   237
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   238
    public int getMaxDataSize() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   239
        return maxDataSize;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   240
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   241
90ce3da70b43 Initial load
duke
parents:
diff changeset
   242
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   243
     * Pad the data and return the padded block.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   244
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   245
    public byte[] pad(byte[] data, int ofs, int len)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   246
            throws BadPaddingException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   247
        return pad(RSACore.convert(data, ofs, len));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   248
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   249
90ce3da70b43 Initial load
duke
parents:
diff changeset
   250
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   251
     * Pad the data and return the padded block.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   252
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   253
    public byte[] pad(byte[] data) throws BadPaddingException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   254
        if (data.length > maxDataSize) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   255
            throw new BadPaddingException("Data must be shorter than "
90ce3da70b43 Initial load
duke
parents:
diff changeset
   256
                + (maxDataSize + 1) + " bytes");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   257
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   258
        switch (type) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   259
        case PAD_NONE:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   260
            return data;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   261
        case PAD_BLOCKTYPE_1:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   262
        case PAD_BLOCKTYPE_2:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   263
            return padV15(data);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   264
        case PAD_OAEP_MGF1:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   265
            return padOAEP(data);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   266
        default:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   267
            throw new AssertionError();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   268
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   269
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   270
90ce3da70b43 Initial load
duke
parents:
diff changeset
   271
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   272
     * Unpad the padded block and return the data.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   273
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   274
    public byte[] unpad(byte[] padded, int ofs, int len)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   275
            throws BadPaddingException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   276
        return unpad(RSACore.convert(padded, ofs, len));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   277
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   278
90ce3da70b43 Initial load
duke
parents:
diff changeset
   279
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   280
     * Unpad the padded block and return the data.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   281
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   282
    public byte[] unpad(byte[] padded) throws BadPaddingException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   283
        if (padded.length != paddedSize) {
23911
f93d74f7d6fe 8027766: Enhance RSA processing
wetmore
parents: 22309
diff changeset
   284
            throw new BadPaddingException("Decryption error");
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   285
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   286
        switch (type) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   287
        case PAD_NONE:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   288
            return padded;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   289
        case PAD_BLOCKTYPE_1:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   290
        case PAD_BLOCKTYPE_2:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   291
            return unpadV15(padded);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   292
        case PAD_OAEP_MGF1:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   293
            return unpadOAEP(padded);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   294
        default:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   295
            throw new AssertionError();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   296
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   297
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   298
90ce3da70b43 Initial load
duke
parents:
diff changeset
   299
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   300
     * PKCS#1 v1.5 padding (blocktype 1 and 2).
90ce3da70b43 Initial load
duke
parents:
diff changeset
   301
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   302
    private byte[] padV15(byte[] data) throws BadPaddingException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   303
        byte[] padded = new byte[paddedSize];
23911
f93d74f7d6fe 8027766: Enhance RSA processing
wetmore
parents: 22309
diff changeset
   304
        System.arraycopy(data, 0, padded, paddedSize - data.length,
f93d74f7d6fe 8027766: Enhance RSA processing
wetmore
parents: 22309
diff changeset
   305
            data.length);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   306
        int psSize = paddedSize - 3 - data.length;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   307
        int k = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   308
        padded[k++] = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   309
        padded[k++] = (byte)type;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   310
        if (type == PAD_BLOCKTYPE_1) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   311
            // blocktype 1: all padding bytes are 0xff
90ce3da70b43 Initial load
duke
parents:
diff changeset
   312
            while (psSize-- > 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   313
                padded[k++] = (byte)0xff;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   314
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   315
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   316
            // blocktype 2: padding bytes are random non-zero bytes
90ce3da70b43 Initial load
duke
parents:
diff changeset
   317
            if (random == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   318
                random = JCAUtil.getSecureRandom();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   319
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   320
            // generate non-zero padding bytes
90ce3da70b43 Initial load
duke
parents:
diff changeset
   321
            // use a buffer to reduce calls to SecureRandom
90ce3da70b43 Initial load
duke
parents:
diff changeset
   322
            byte[] r = new byte[64];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   323
            int i = -1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   324
            while (psSize-- > 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   325
                int b;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   326
                do {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   327
                    if (i < 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   328
                        random.nextBytes(r);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   329
                        i = r.length - 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   330
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   331
                    b = r[i--] & 0xff;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   332
                } while (b == 0);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   333
                padded[k++] = (byte)b;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   334
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   335
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   336
        return padded;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   337
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   338
90ce3da70b43 Initial load
duke
parents:
diff changeset
   339
    /**
23911
f93d74f7d6fe 8027766: Enhance RSA processing
wetmore
parents: 22309
diff changeset
   340
     * PKCS#1 v1.5 unpadding (blocktype 1 (signature) and 2 (encryption)).
22309
1990211a42e5 8023069: Enhance TLS connections
xuelei
parents: 19436
diff changeset
   341
     *
1990211a42e5 8023069: Enhance TLS connections
xuelei
parents: 19436
diff changeset
   342
     * Note that we want to make it a constant-time operation
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   343
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   344
    private byte[] unpadV15(byte[] padded) throws BadPaddingException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   345
        int k = 0;
23911
f93d74f7d6fe 8027766: Enhance RSA processing
wetmore
parents: 22309
diff changeset
   346
        boolean bp = false;
22309
1990211a42e5 8023069: Enhance TLS connections
xuelei
parents: 19436
diff changeset
   347
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   348
        if (padded[k++] != 0) {
23911
f93d74f7d6fe 8027766: Enhance RSA processing
wetmore
parents: 22309
diff changeset
   349
            bp = true;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   350
        }
23911
f93d74f7d6fe 8027766: Enhance RSA processing
wetmore
parents: 22309
diff changeset
   351
        if (padded[k++] != type) {
f93d74f7d6fe 8027766: Enhance RSA processing
wetmore
parents: 22309
diff changeset
   352
            bp = true;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   353
        }
22309
1990211a42e5 8023069: Enhance TLS connections
xuelei
parents: 19436
diff changeset
   354
        int p = 0;
1990211a42e5 8023069: Enhance TLS connections
xuelei
parents: 19436
diff changeset
   355
        while (k < padded.length) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   356
            int b = padded[k++] & 0xff;
23911
f93d74f7d6fe 8027766: Enhance RSA processing
wetmore
parents: 22309
diff changeset
   357
            if ((b == 0) && (p == 0)) {
22309
1990211a42e5 8023069: Enhance TLS connections
xuelei
parents: 19436
diff changeset
   358
                p = k;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   359
            }
23911
f93d74f7d6fe 8027766: Enhance RSA processing
wetmore
parents: 22309
diff changeset
   360
            if ((k == padded.length) && (p == 0)) {
f93d74f7d6fe 8027766: Enhance RSA processing
wetmore
parents: 22309
diff changeset
   361
                bp = true;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   362
            }
22309
1990211a42e5 8023069: Enhance TLS connections
xuelei
parents: 19436
diff changeset
   363
            if ((type == PAD_BLOCKTYPE_1) && (b != 0xff) &&
23911
f93d74f7d6fe 8027766: Enhance RSA processing
wetmore
parents: 22309
diff changeset
   364
                    (p == 0)) {
f93d74f7d6fe 8027766: Enhance RSA processing
wetmore
parents: 22309
diff changeset
   365
                bp = true;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   366
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   367
        }
22309
1990211a42e5 8023069: Enhance TLS connections
xuelei
parents: 19436
diff changeset
   368
        int n = padded.length - p;
23911
f93d74f7d6fe 8027766: Enhance RSA processing
wetmore
parents: 22309
diff changeset
   369
        if (n > maxDataSize) {
f93d74f7d6fe 8027766: Enhance RSA processing
wetmore
parents: 22309
diff changeset
   370
            bp = true;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   371
        }
22309
1990211a42e5 8023069: Enhance TLS connections
xuelei
parents: 19436
diff changeset
   372
1990211a42e5 8023069: Enhance TLS connections
xuelei
parents: 19436
diff changeset
   373
        // copy useless padding array for a constant-time method
1990211a42e5 8023069: Enhance TLS connections
xuelei
parents: 19436
diff changeset
   374
        byte[] padding = new byte[p];
1990211a42e5 8023069: Enhance TLS connections
xuelei
parents: 19436
diff changeset
   375
        System.arraycopy(padded, 0, padding, 0, p);
1990211a42e5 8023069: Enhance TLS connections
xuelei
parents: 19436
diff changeset
   376
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   377
        byte[] data = new byte[n];
22309
1990211a42e5 8023069: Enhance TLS connections
xuelei
parents: 19436
diff changeset
   378
        System.arraycopy(padded, p, data, 0, n);
1990211a42e5 8023069: Enhance TLS connections
xuelei
parents: 19436
diff changeset
   379
23911
f93d74f7d6fe 8027766: Enhance RSA processing
wetmore
parents: 22309
diff changeset
   380
        BadPaddingException bpe = new BadPaddingException("Decryption error");
f93d74f7d6fe 8027766: Enhance RSA processing
wetmore
parents: 22309
diff changeset
   381
f93d74f7d6fe 8027766: Enhance RSA processing
wetmore
parents: 22309
diff changeset
   382
        if (bp) {
22309
1990211a42e5 8023069: Enhance TLS connections
xuelei
parents: 19436
diff changeset
   383
            throw bpe;
23911
f93d74f7d6fe 8027766: Enhance RSA processing
wetmore
parents: 22309
diff changeset
   384
        } else {
f93d74f7d6fe 8027766: Enhance RSA processing
wetmore
parents: 22309
diff changeset
   385
            return data;
22309
1990211a42e5 8023069: Enhance TLS connections
xuelei
parents: 19436
diff changeset
   386
        }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   387
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   388
90ce3da70b43 Initial load
duke
parents:
diff changeset
   389
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   390
     * PKCS#1 v2.0 OAEP padding (MGF1).
90ce3da70b43 Initial load
duke
parents:
diff changeset
   391
     * Paragraph references refer to PKCS#1 v2.1 (June 14, 2002)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   392
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   393
    private byte[] padOAEP(byte[] M) throws BadPaddingException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   394
        if (random == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   395
            random = JCAUtil.getSecureRandom();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   396
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   397
        int hLen = lHash.length;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   398
90ce3da70b43 Initial load
duke
parents:
diff changeset
   399
        // 2.d: generate a random octet string seed of length hLen
90ce3da70b43 Initial load
duke
parents:
diff changeset
   400
        // if necessary
90ce3da70b43 Initial load
duke
parents:
diff changeset
   401
        byte[] seed = new byte[hLen];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   402
        random.nextBytes(seed);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   403
90ce3da70b43 Initial load
duke
parents:
diff changeset
   404
        // buffer for encoded message EM
90ce3da70b43 Initial load
duke
parents:
diff changeset
   405
        byte[] EM = new byte[paddedSize];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   406
90ce3da70b43 Initial load
duke
parents:
diff changeset
   407
        // start and length of seed (as index into EM)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   408
        int seedStart = 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   409
        int seedLen = hLen;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   410
90ce3da70b43 Initial load
duke
parents:
diff changeset
   411
        // copy seed into EM
90ce3da70b43 Initial load
duke
parents:
diff changeset
   412
        System.arraycopy(seed, 0, EM, seedStart, seedLen);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   413
90ce3da70b43 Initial load
duke
parents:
diff changeset
   414
        // start and length of data block DB in EM
90ce3da70b43 Initial load
duke
parents:
diff changeset
   415
        // we place it inside of EM to reduce copying
90ce3da70b43 Initial load
duke
parents:
diff changeset
   416
        int dbStart = hLen + 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   417
        int dbLen = EM.length - dbStart;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   418
90ce3da70b43 Initial load
duke
parents:
diff changeset
   419
        // start of message M in EM
90ce3da70b43 Initial load
duke
parents:
diff changeset
   420
        int mStart = paddedSize - M.length;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   421
90ce3da70b43 Initial load
duke
parents:
diff changeset
   422
        // build DB
90ce3da70b43 Initial load
duke
parents:
diff changeset
   423
        // 2.b: Concatenate lHash, PS, a single octet with hexadecimal value
90ce3da70b43 Initial load
duke
parents:
diff changeset
   424
        // 0x01, and the message M to form a data block DB of length
90ce3da70b43 Initial load
duke
parents:
diff changeset
   425
        // k - hLen -1 octets as DB = lHash || PS || 0x01 || M
90ce3da70b43 Initial load
duke
parents:
diff changeset
   426
        // (note that PS is all zeros)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   427
        System.arraycopy(lHash, 0, EM, dbStart, hLen);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   428
        EM[mStart - 1] = 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   429
        System.arraycopy(M, 0, EM, mStart, M.length);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   430
90ce3da70b43 Initial load
duke
parents:
diff changeset
   431
        // produce maskedDB
90ce3da70b43 Initial load
duke
parents:
diff changeset
   432
        mgf1(EM, seedStart, seedLen, EM, dbStart, dbLen);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   433
90ce3da70b43 Initial load
duke
parents:
diff changeset
   434
        // produce maskSeed
90ce3da70b43 Initial load
duke
parents:
diff changeset
   435
        mgf1(EM, dbStart, dbLen, EM, seedStart, seedLen);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   436
90ce3da70b43 Initial load
duke
parents:
diff changeset
   437
        return EM;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   438
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   439
90ce3da70b43 Initial load
duke
parents:
diff changeset
   440
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   441
     * PKCS#1 v2.1 OAEP unpadding (MGF1).
90ce3da70b43 Initial load
duke
parents:
diff changeset
   442
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   443
    private byte[] unpadOAEP(byte[] padded) throws BadPaddingException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   444
        byte[] EM = padded;
23911
f93d74f7d6fe 8027766: Enhance RSA processing
wetmore
parents: 22309
diff changeset
   445
        boolean bp = false;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   446
        int hLen = lHash.length;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   447
90ce3da70b43 Initial load
duke
parents:
diff changeset
   448
        if (EM[0] != 0) {
23911
f93d74f7d6fe 8027766: Enhance RSA processing
wetmore
parents: 22309
diff changeset
   449
            bp = true;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   450
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   451
90ce3da70b43 Initial load
duke
parents:
diff changeset
   452
        int seedStart = 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   453
        int seedLen = hLen;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   454
90ce3da70b43 Initial load
duke
parents:
diff changeset
   455
        int dbStart = hLen + 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   456
        int dbLen = EM.length - dbStart;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   457
90ce3da70b43 Initial load
duke
parents:
diff changeset
   458
        mgf1(EM, dbStart, dbLen, EM, seedStart, seedLen);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   459
        mgf1(EM, seedStart, seedLen, EM, dbStart, dbLen);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   460
90ce3da70b43 Initial load
duke
parents:
diff changeset
   461
        // verify lHash == lHash'
90ce3da70b43 Initial load
duke
parents:
diff changeset
   462
        for (int i = 0; i < hLen; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   463
            if (lHash[i] != EM[dbStart + i]) {
23911
f93d74f7d6fe 8027766: Enhance RSA processing
wetmore
parents: 22309
diff changeset
   464
                bp = true;
f93d74f7d6fe 8027766: Enhance RSA processing
wetmore
parents: 22309
diff changeset
   465
            }
f93d74f7d6fe 8027766: Enhance RSA processing
wetmore
parents: 22309
diff changeset
   466
        }
f93d74f7d6fe 8027766: Enhance RSA processing
wetmore
parents: 22309
diff changeset
   467
f93d74f7d6fe 8027766: Enhance RSA processing
wetmore
parents: 22309
diff changeset
   468
        int padStart = dbStart + hLen;
f93d74f7d6fe 8027766: Enhance RSA processing
wetmore
parents: 22309
diff changeset
   469
        int onePos = -1;
f93d74f7d6fe 8027766: Enhance RSA processing
wetmore
parents: 22309
diff changeset
   470
f93d74f7d6fe 8027766: Enhance RSA processing
wetmore
parents: 22309
diff changeset
   471
        for (int i = padStart; i < EM.length; i++) {
f93d74f7d6fe 8027766: Enhance RSA processing
wetmore
parents: 22309
diff changeset
   472
            int value = EM[i];
f93d74f7d6fe 8027766: Enhance RSA processing
wetmore
parents: 22309
diff changeset
   473
            if (onePos == -1) {
f93d74f7d6fe 8027766: Enhance RSA processing
wetmore
parents: 22309
diff changeset
   474
                if (value == 0x00) {
f93d74f7d6fe 8027766: Enhance RSA processing
wetmore
parents: 22309
diff changeset
   475
                    // continue;
f93d74f7d6fe 8027766: Enhance RSA processing
wetmore
parents: 22309
diff changeset
   476
                } else if (value == 0x01) {
f93d74f7d6fe 8027766: Enhance RSA processing
wetmore
parents: 22309
diff changeset
   477
                    onePos = i;
f93d74f7d6fe 8027766: Enhance RSA processing
wetmore
parents: 22309
diff changeset
   478
                } else {  // Anything other than {0,1} is bad.
f93d74f7d6fe 8027766: Enhance RSA processing
wetmore
parents: 22309
diff changeset
   479
                    bp = true;
f93d74f7d6fe 8027766: Enhance RSA processing
wetmore
parents: 22309
diff changeset
   480
                }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   481
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   482
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   483
23911
f93d74f7d6fe 8027766: Enhance RSA processing
wetmore
parents: 22309
diff changeset
   484
        // We either ran off the rails or found something other than 0/1.
f93d74f7d6fe 8027766: Enhance RSA processing
wetmore
parents: 22309
diff changeset
   485
        if (onePos == -1) {
f93d74f7d6fe 8027766: Enhance RSA processing
wetmore
parents: 22309
diff changeset
   486
            bp = true;
f93d74f7d6fe 8027766: Enhance RSA processing
wetmore
parents: 22309
diff changeset
   487
            onePos = EM.length - 1;  // Don't inadvertently return any data.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   488
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   489
23911
f93d74f7d6fe 8027766: Enhance RSA processing
wetmore
parents: 22309
diff changeset
   490
        int mStart = onePos + 1;
f93d74f7d6fe 8027766: Enhance RSA processing
wetmore
parents: 22309
diff changeset
   491
f93d74f7d6fe 8027766: Enhance RSA processing
wetmore
parents: 22309
diff changeset
   492
        // copy useless padding array for a constant-time method
f93d74f7d6fe 8027766: Enhance RSA processing
wetmore
parents: 22309
diff changeset
   493
        byte [] tmp = new byte[mStart - padStart];
f93d74f7d6fe 8027766: Enhance RSA processing
wetmore
parents: 22309
diff changeset
   494
        System.arraycopy(EM, padStart, tmp, 0, tmp.length);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   495
23911
f93d74f7d6fe 8027766: Enhance RSA processing
wetmore
parents: 22309
diff changeset
   496
        byte [] m = new byte[EM.length - mStart];
f93d74f7d6fe 8027766: Enhance RSA processing
wetmore
parents: 22309
diff changeset
   497
        System.arraycopy(EM, mStart, m, 0, m.length);
f93d74f7d6fe 8027766: Enhance RSA processing
wetmore
parents: 22309
diff changeset
   498
f93d74f7d6fe 8027766: Enhance RSA processing
wetmore
parents: 22309
diff changeset
   499
        BadPaddingException bpe = new BadPaddingException("Decryption error");
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   500
23911
f93d74f7d6fe 8027766: Enhance RSA processing
wetmore
parents: 22309
diff changeset
   501
        if (bp) {
f93d74f7d6fe 8027766: Enhance RSA processing
wetmore
parents: 22309
diff changeset
   502
            throw bpe;
f93d74f7d6fe 8027766: Enhance RSA processing
wetmore
parents: 22309
diff changeset
   503
        } else {
f93d74f7d6fe 8027766: Enhance RSA processing
wetmore
parents: 22309
diff changeset
   504
            return m;
f93d74f7d6fe 8027766: Enhance RSA processing
wetmore
parents: 22309
diff changeset
   505
        }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   506
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   507
90ce3da70b43 Initial load
duke
parents:
diff changeset
   508
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   509
     * Compute MGF1 using mgfMD as the message digest.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   510
     * Note that we combine MGF1 with the XOR operation to reduce data
90ce3da70b43 Initial load
duke
parents:
diff changeset
   511
     * copying.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   512
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   513
     * We generate maskLen bytes of MGF1 from the seed and XOR it into
90ce3da70b43 Initial load
duke
parents:
diff changeset
   514
     * out[] starting at outOfs;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   515
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   516
    private void mgf1(byte[] seed, int seedOfs, int seedLen,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   517
            byte[] out, int outOfs, int maskLen)  throws BadPaddingException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   518
        byte[] C = new byte[4]; // 32 bit counter
19436
cfc7d402795c 8022669: OAEPParameterSpec does not work if MGF1ParameterSpec is set to SHA2 algorithms
ascarpino
parents: 5506
diff changeset
   519
        byte[] digest = new byte[mgfMd.getDigestLength()];
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   520
        while (maskLen > 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   521
            mgfMd.update(seed, seedOfs, seedLen);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   522
            mgfMd.update(C);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   523
            try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   524
                mgfMd.digest(digest, 0, digest.length);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   525
            } catch (DigestException e) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   526
                // should never happen
90ce3da70b43 Initial load
duke
parents:
diff changeset
   527
                throw new BadPaddingException(e.toString());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   528
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   529
            for (int i = 0; (i < digest.length) && (maskLen > 0); maskLen--) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   530
                out[outOfs++] ^= digest[i++];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   531
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   532
            if (maskLen > 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   533
                // increment counter
90ce3da70b43 Initial load
duke
parents:
diff changeset
   534
                for (int i = C.length - 1; (++C[i] == 0) && (i > 0); i--) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   535
                    // empty
90ce3da70b43 Initial load
duke
parents:
diff changeset
   536
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   537
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   538
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   539
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   540
}