src/java.base/share/classes/sun/security/rsa/RSAPadding.java
author wetmore
Fri, 11 May 2018 15:53:12 -0700
branchJDK-8145252-TLS13-branch
changeset 56542 56aaa6cb3693
parent 47216 71c04702a3d5
permissions -rw-r--r--
Initial TLSv1.3 Implementation
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     1
/*
56542
56aaa6cb3693 Initial TLSv1.3 Implementation
wetmore
parents: 47216
diff changeset
     2
 * Copyright (c) 2003, 2018, 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
 *
56542
56aaa6cb3693 Initial TLSv1.3 Implementation
wetmore
parents: 47216
diff changeset
    42
 * The various PKCS#1 versions can be found in the IETF RFCs
56aaa6cb3693 Initial TLSv1.3 Implementation
wetmore
parents: 47216
diff changeset
    43
 * tracking the corresponding PKCS#1 standards.
23911
f93d74f7d6fe 8027766: Enhance RSA processing
wetmore
parents: 22309
diff changeset
    44
 *
56542
56aaa6cb3693 Initial TLSv1.3 Implementation
wetmore
parents: 47216
diff changeset
    45
 *     RFC 2313: PKCS#1 v1.5
56aaa6cb3693 Initial TLSv1.3 Implementation
wetmore
parents: 47216
diff changeset
    46
 *     RFC 2437: PKCS#1 v2.0
56aaa6cb3693 Initial TLSv1.3 Implementation
wetmore
parents: 47216
diff changeset
    47
 *     RFC 3447: PKCS#1 v2.1
56aaa6cb3693 Initial TLSv1.3 Implementation
wetmore
parents: 47216
diff changeset
    48
 *     RFC 8017: PKCS#1 v2.2
23911
f93d74f7d6fe 8027766: Enhance RSA processing
wetmore
parents: 22309
diff changeset
    49
 *
f93d74f7d6fe 8027766: Enhance RSA processing
wetmore
parents: 22309
diff changeset
    50
 * The format of PKCS#1 v1.5 padding is:
f93d74f7d6fe 8027766: Enhance RSA processing
wetmore
parents: 22309
diff changeset
    51
 *
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    52
 *   0x00 | BT | PS...PS | 0x00 | data...data
23911
f93d74f7d6fe 8027766: Enhance RSA processing
wetmore
parents: 22309
diff changeset
    53
 *
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    54
 * where BT is the blocktype (1 or 2). The length of the entire string
90ce3da70b43 Initial load
duke
parents:
diff changeset
    55
 * 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
    56
 * key). Per spec, the padding string must be at least 8 bytes long. That
90ce3da70b43 Initial load
duke
parents:
diff changeset
    57
 * leaves up to (length of key in bytes) - 11 bytes for the data.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    58
 *
23911
f93d74f7d6fe 8027766: Enhance RSA processing
wetmore
parents: 22309
diff changeset
    59
 * 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
    60
 * and has a number of options. We support:
f93d74f7d6fe 8027766: Enhance RSA processing
wetmore
parents: 22309
diff changeset
    61
 *
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    62
 *   . arbitrary hash functions ('Hash' in the specification), MessageDigest
90ce3da70b43 Initial load
duke
parents:
diff changeset
    63
 *     implementation must be available
90ce3da70b43 Initial load
duke
parents:
diff changeset
    64
 *   . MGF1 as the mask generation function
90ce3da70b43 Initial load
duke
parents:
diff changeset
    65
 *   . the empty string as the default value for label L and whatever
90ce3da70b43 Initial load
duke
parents:
diff changeset
    66
 *     specified in javax.crypto.spec.OAEPParameterSpec
90ce3da70b43 Initial load
duke
parents:
diff changeset
    67
 *
23911
f93d74f7d6fe 8027766: Enhance RSA processing
wetmore
parents: 22309
diff changeset
    68
 * The algorithms (representations) are forwards-compatible: that is,
f93d74f7d6fe 8027766: Enhance RSA processing
wetmore
parents: 22309
diff changeset
    69
 * the algorithm described in previous releases are in later releases.
f93d74f7d6fe 8027766: Enhance RSA processing
wetmore
parents: 22309
diff changeset
    70
 * However, additional comments/checks/clarifications were added to the
f93d74f7d6fe 8027766: Enhance RSA processing
wetmore
parents: 22309
diff changeset
    71
 * later versions based on real-world experience (e.g. stricter v1.5
f93d74f7d6fe 8027766: Enhance RSA processing
wetmore
parents: 22309
diff changeset
    72
 * format checking.)
f93d74f7d6fe 8027766: Enhance RSA processing
wetmore
parents: 22309
diff changeset
    73
 *
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    74
 * Note: RSA keys should be at least 512 bits long
90ce3da70b43 Initial load
duke
parents:
diff changeset
    75
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    76
 * @since   1.5
90ce3da70b43 Initial load
duke
parents:
diff changeset
    77
 * @author  Andreas Sterbenz
90ce3da70b43 Initial load
duke
parents:
diff changeset
    78
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    79
public final class RSAPadding {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    80
90ce3da70b43 Initial load
duke
parents:
diff changeset
    81
    // NOTE: the constants below are embedded in the JCE RSACipher class
90ce3da70b43 Initial load
duke
parents:
diff changeset
    82
    // file. Do not change without coordinating the update
90ce3da70b43 Initial load
duke
parents:
diff changeset
    83
90ce3da70b43 Initial load
duke
parents:
diff changeset
    84
    // PKCS#1 v1.5 padding, blocktype 1 (signing)
32649
2ee9017c7597 8136583: Core libraries should use blessed modifier order
martin
parents: 32212
diff changeset
    85
    public static final int PAD_BLOCKTYPE_1    = 1;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    86
    // PKCS#1 v1.5 padding, blocktype 2 (encryption)
32649
2ee9017c7597 8136583: Core libraries should use blessed modifier order
martin
parents: 32212
diff changeset
    87
    public static final int PAD_BLOCKTYPE_2    = 2;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    88
    // nopadding. Does not do anything, but allows simpler RSACipher code
32649
2ee9017c7597 8136583: Core libraries should use blessed modifier order
martin
parents: 32212
diff changeset
    89
    public static final int PAD_NONE           = 3;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    90
    // PKCS#1 v2.1 OAEP padding
32649
2ee9017c7597 8136583: Core libraries should use blessed modifier order
martin
parents: 32212
diff changeset
    91
    public static final int PAD_OAEP_MGF1 = 4;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    92
90ce3da70b43 Initial load
duke
parents:
diff changeset
    93
    // type, one of PAD_*
90ce3da70b43 Initial load
duke
parents:
diff changeset
    94
    private final int type;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    95
90ce3da70b43 Initial load
duke
parents:
diff changeset
    96
    // size of the padded block (i.e. size of the modulus)
90ce3da70b43 Initial load
duke
parents:
diff changeset
    97
    private final int paddedSize;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    98
90ce3da70b43 Initial load
duke
parents:
diff changeset
    99
    // PRNG used to generate padding bytes (PAD_BLOCKTYPE_2, PAD_OAEP_MGF1)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   100
    private SecureRandom random;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   101
90ce3da70b43 Initial load
duke
parents:
diff changeset
   102
    // maximum size of the data
90ce3da70b43 Initial load
duke
parents:
diff changeset
   103
    private final int maxDataSize;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   104
56542
56aaa6cb3693 Initial TLSv1.3 Implementation
wetmore
parents: 47216
diff changeset
   105
    // OAEP: main message digest
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   106
    private MessageDigest md;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   107
56542
56aaa6cb3693 Initial TLSv1.3 Implementation
wetmore
parents: 47216
diff changeset
   108
    // OAEP: MGF1
56aaa6cb3693 Initial TLSv1.3 Implementation
wetmore
parents: 47216
diff changeset
   109
    private MGF1 mgf;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   110
90ce3da70b43 Initial load
duke
parents:
diff changeset
   111
    // OAEP: value of digest of data (user-supplied or zero-length) using md
90ce3da70b43 Initial load
duke
parents:
diff changeset
   112
    private byte[] lHash;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   113
90ce3da70b43 Initial load
duke
parents:
diff changeset
   114
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   115
     * Get a RSAPadding instance of the specified type.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   116
     * Keys used with this padding must be paddedSize bytes long.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   117
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   118
    public static RSAPadding getInstance(int type, int paddedSize)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   119
            throws InvalidKeyException, InvalidAlgorithmParameterException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   120
        return new RSAPadding(type, paddedSize, null, null);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   121
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   122
90ce3da70b43 Initial load
duke
parents:
diff changeset
   123
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   124
     * Get a RSAPadding instance of the specified type.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   125
     * Keys used with this padding must be paddedSize bytes long.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   126
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   127
    public static RSAPadding getInstance(int type, int paddedSize,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   128
            SecureRandom random) throws InvalidKeyException,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   129
            InvalidAlgorithmParameterException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   130
        return new RSAPadding(type, paddedSize, random, null);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   131
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   132
90ce3da70b43 Initial load
duke
parents:
diff changeset
   133
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   134
     * Get a RSAPadding instance of the specified type, which must be
90ce3da70b43 Initial load
duke
parents:
diff changeset
   135
     * OAEP. Keys used with this padding must be paddedSize bytes long.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   136
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   137
    public static RSAPadding getInstance(int type, int paddedSize,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   138
            SecureRandom random, OAEPParameterSpec spec)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   139
        throws InvalidKeyException, InvalidAlgorithmParameterException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   140
        return new RSAPadding(type, paddedSize, random, spec);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   141
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   142
90ce3da70b43 Initial load
duke
parents:
diff changeset
   143
    // internal constructor
90ce3da70b43 Initial load
duke
parents:
diff changeset
   144
    private RSAPadding(int type, int paddedSize, SecureRandom random,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   145
            OAEPParameterSpec spec) throws InvalidKeyException,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   146
            InvalidAlgorithmParameterException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   147
        this.type = type;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   148
        this.paddedSize = paddedSize;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   149
        this.random = random;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   150
        if (paddedSize < 64) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   151
            // sanity check, already verified in RSASignature/RSACipher
90ce3da70b43 Initial load
duke
parents:
diff changeset
   152
            throw new InvalidKeyException("Padded size must be at least 64");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   153
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   154
        switch (type) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   155
        case PAD_BLOCKTYPE_1:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   156
        case PAD_BLOCKTYPE_2:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   157
            maxDataSize = paddedSize - 11;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   158
            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   159
        case PAD_NONE:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   160
            maxDataSize = paddedSize;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   161
            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   162
        case PAD_OAEP_MGF1:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   163
            String mdName = "SHA-1";
56542
56aaa6cb3693 Initial TLSv1.3 Implementation
wetmore
parents: 47216
diff changeset
   164
            String mgfMdName = mdName;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   165
            byte[] digestInput = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   166
            try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   167
                if (spec != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   168
                    mdName = spec.getDigestAlgorithm();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   169
                    String mgfName = spec.getMGFAlgorithm();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   170
                    if (!mgfName.equalsIgnoreCase("MGF1")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   171
                        throw new InvalidAlgorithmParameterException
90ce3da70b43 Initial load
duke
parents:
diff changeset
   172
                            ("Unsupported MGF algo: " + mgfName);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   173
                    }
23911
f93d74f7d6fe 8027766: Enhance RSA processing
wetmore
parents: 22309
diff changeset
   174
                    mgfMdName = ((MGF1ParameterSpec)spec.getMGFParameters())
f93d74f7d6fe 8027766: Enhance RSA processing
wetmore
parents: 22309
diff changeset
   175
                            .getDigestAlgorithm();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   176
                    PSource pSrc = spec.getPSource();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   177
                    String pSrcAlgo = pSrc.getAlgorithm();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   178
                    if (!pSrcAlgo.equalsIgnoreCase("PSpecified")) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   179
                        throw new InvalidAlgorithmParameterException
90ce3da70b43 Initial load
duke
parents:
diff changeset
   180
                            ("Unsupported pSource algo: " + pSrcAlgo);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   181
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   182
                    digestInput = ((PSource.PSpecified) pSrc).getValue();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   183
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   184
                md = MessageDigest.getInstance(mdName);
56542
56aaa6cb3693 Initial TLSv1.3 Implementation
wetmore
parents: 47216
diff changeset
   185
                mgf = new MGF1(mgfMdName);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   186
            } catch (NoSuchAlgorithmException e) {
56542
56aaa6cb3693 Initial TLSv1.3 Implementation
wetmore
parents: 47216
diff changeset
   187
                throw new InvalidKeyException("Digest not available", e);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   188
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   189
            lHash = getInitialHash(md, digestInput);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   190
            int digestLen = lHash.length;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   191
            maxDataSize = paddedSize - 2 - 2 * digestLen;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   192
            if (maxDataSize <= 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   193
                throw new InvalidKeyException
90ce3da70b43 Initial load
duke
parents:
diff changeset
   194
                        ("Key is too short for encryption using OAEPPadding" +
56542
56aaa6cb3693 Initial TLSv1.3 Implementation
wetmore
parents: 47216
diff changeset
   195
                         " with " + mdName + " and " + mgf.getName());
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   196
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   197
            break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   198
        default:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   199
            throw new InvalidKeyException("Invalid padding: " + type);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   200
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   201
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   202
90ce3da70b43 Initial load
duke
parents:
diff changeset
   203
    // cache of hashes of zero length data
90ce3da70b43 Initial load
duke
parents:
diff changeset
   204
    private static final Map<String,byte[]> emptyHashes =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   205
        Collections.synchronizedMap(new HashMap<String,byte[]>());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   206
90ce3da70b43 Initial load
duke
parents:
diff changeset
   207
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   208
     * Return the value of the digest using the specified message digest
90ce3da70b43 Initial load
duke
parents:
diff changeset
   209
     * <code>md</code> and the digest input <code>digestInput</code>.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   210
     * if <code>digestInput</code> is null or 0-length, zero length
90ce3da70b43 Initial load
duke
parents:
diff changeset
   211
     * is used to generate the initial digest.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   212
     * Note: the md object must be in reset state
90ce3da70b43 Initial load
duke
parents:
diff changeset
   213
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   214
    private static byte[] getInitialHash(MessageDigest md,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   215
        byte[] digestInput) {
23911
f93d74f7d6fe 8027766: Enhance RSA processing
wetmore
parents: 22309
diff changeset
   216
        byte[] result;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   217
        if ((digestInput == null) || (digestInput.length == 0)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   218
            String digestName = md.getAlgorithm();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   219
            result = emptyHashes.get(digestName);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   220
            if (result == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   221
                result = md.digest();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   222
                emptyHashes.put(digestName, result);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   223
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   224
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   225
            result = md.digest(digestInput);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   226
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   227
        return result;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   228
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   229
90ce3da70b43 Initial load
duke
parents:
diff changeset
   230
    /**
23911
f93d74f7d6fe 8027766: Enhance RSA processing
wetmore
parents: 22309
diff changeset
   231
     * Return the maximum size of the plaintext data that can be processed
f93d74f7d6fe 8027766: Enhance RSA processing
wetmore
parents: 22309
diff changeset
   232
     * using this object.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   233
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   234
    public int getMaxDataSize() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   235
        return maxDataSize;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   236
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   237
90ce3da70b43 Initial load
duke
parents:
diff changeset
   238
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   239
     * Pad the data and return the padded block.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   240
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   241
    public byte[] pad(byte[] data, int ofs, int len)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   242
            throws BadPaddingException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   243
        return pad(RSACore.convert(data, ofs, len));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   244
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   245
90ce3da70b43 Initial load
duke
parents:
diff changeset
   246
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   247
     * Pad the data and return the padded block.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   248
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   249
    public byte[] pad(byte[] data) throws BadPaddingException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   250
        if (data.length > maxDataSize) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   251
            throw new BadPaddingException("Data must be shorter than "
40544
807dd9a425db 8150530: Improve javax.crypto.BadPaddingException messages
coffeys
parents: 32649
diff changeset
   252
                + (maxDataSize + 1) + " bytes but received "
807dd9a425db 8150530: Improve javax.crypto.BadPaddingException messages
coffeys
parents: 32649
diff changeset
   253
                + data.length + " bytes.");
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   254
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   255
        switch (type) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   256
        case PAD_NONE:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   257
            return data;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   258
        case PAD_BLOCKTYPE_1:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   259
        case PAD_BLOCKTYPE_2:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   260
            return padV15(data);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   261
        case PAD_OAEP_MGF1:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   262
            return padOAEP(data);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   263
        default:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   264
            throw new AssertionError();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   265
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   266
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   267
90ce3da70b43 Initial load
duke
parents:
diff changeset
   268
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   269
     * Unpad the padded block and return the data.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   270
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   271
    public byte[] unpad(byte[] padded, int ofs, int len)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   272
            throws BadPaddingException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   273
        return unpad(RSACore.convert(padded, ofs, len));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   274
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   275
90ce3da70b43 Initial load
duke
parents:
diff changeset
   276
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   277
     * Unpad the padded block and return the data.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   278
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   279
    public byte[] unpad(byte[] padded) throws BadPaddingException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   280
        if (padded.length != paddedSize) {
40544
807dd9a425db 8150530: Improve javax.crypto.BadPaddingException messages
coffeys
parents: 32649
diff changeset
   281
            throw new BadPaddingException("Decryption error." +
807dd9a425db 8150530: Improve javax.crypto.BadPaddingException messages
coffeys
parents: 32649
diff changeset
   282
                "The padded array length (" + padded.length +
807dd9a425db 8150530: Improve javax.crypto.BadPaddingException messages
coffeys
parents: 32649
diff changeset
   283
                ") is not the specified padded size (" + paddedSize + ")");
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   284
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   285
        switch (type) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   286
        case PAD_NONE:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   287
            return padded;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   288
        case PAD_BLOCKTYPE_1:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   289
        case PAD_BLOCKTYPE_2:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   290
            return unpadV15(padded);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   291
        case PAD_OAEP_MGF1:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   292
            return unpadOAEP(padded);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   293
        default:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   294
            throw new AssertionError();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   295
        }
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
     * PKCS#1 v1.5 padding (blocktype 1 and 2).
90ce3da70b43 Initial load
duke
parents:
diff changeset
   300
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   301
    private byte[] padV15(byte[] data) throws BadPaddingException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   302
        byte[] padded = new byte[paddedSize];
23911
f93d74f7d6fe 8027766: Enhance RSA processing
wetmore
parents: 22309
diff changeset
   303
        System.arraycopy(data, 0, padded, paddedSize - data.length,
f93d74f7d6fe 8027766: Enhance RSA processing
wetmore
parents: 22309
diff changeset
   304
            data.length);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   305
        int psSize = paddedSize - 3 - data.length;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   306
        int k = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   307
        padded[k++] = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   308
        padded[k++] = (byte)type;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   309
        if (type == PAD_BLOCKTYPE_1) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   310
            // blocktype 1: all padding bytes are 0xff
90ce3da70b43 Initial load
duke
parents:
diff changeset
   311
            while (psSize-- > 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   312
                padded[k++] = (byte)0xff;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   313
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   314
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   315
            // blocktype 2: padding bytes are random non-zero bytes
90ce3da70b43 Initial load
duke
parents:
diff changeset
   316
            if (random == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   317
                random = JCAUtil.getSecureRandom();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   318
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   319
            // generate non-zero padding bytes
90ce3da70b43 Initial load
duke
parents:
diff changeset
   320
            // use a buffer to reduce calls to SecureRandom
32212
9ced42a5a609 8132330: Ineffective SecureRandom usage in RSA encoding with PKCS1Padding
weijun
parents: 25859
diff changeset
   321
            while (psSize > 0) {
9ced42a5a609 8132330: Ineffective SecureRandom usage in RSA encoding with PKCS1Padding
weijun
parents: 25859
diff changeset
   322
                // extra bytes to avoid zero bytes,
9ced42a5a609 8132330: Ineffective SecureRandom usage in RSA encoding with PKCS1Padding
weijun
parents: 25859
diff changeset
   323
                // number of zero bytes <= 4 in 98% cases
9ced42a5a609 8132330: Ineffective SecureRandom usage in RSA encoding with PKCS1Padding
weijun
parents: 25859
diff changeset
   324
                byte[] r = new byte[psSize + 4];
9ced42a5a609 8132330: Ineffective SecureRandom usage in RSA encoding with PKCS1Padding
weijun
parents: 25859
diff changeset
   325
                random.nextBytes(r);
9ced42a5a609 8132330: Ineffective SecureRandom usage in RSA encoding with PKCS1Padding
weijun
parents: 25859
diff changeset
   326
                for (int i = 0; i < r.length && psSize > 0; i++) {
9ced42a5a609 8132330: Ineffective SecureRandom usage in RSA encoding with PKCS1Padding
weijun
parents: 25859
diff changeset
   327
                    if (r[i] != 0) {
9ced42a5a609 8132330: Ineffective SecureRandom usage in RSA encoding with PKCS1Padding
weijun
parents: 25859
diff changeset
   328
                        padded[k++] = r[i];
9ced42a5a609 8132330: Ineffective SecureRandom usage in RSA encoding with PKCS1Padding
weijun
parents: 25859
diff changeset
   329
                        psSize--;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   330
                    }
32212
9ced42a5a609 8132330: Ineffective SecureRandom usage in RSA encoding with PKCS1Padding
weijun
parents: 25859
diff changeset
   331
                }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   332
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   333
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   334
        return padded;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   335
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   336
90ce3da70b43 Initial load
duke
parents:
diff changeset
   337
    /**
23911
f93d74f7d6fe 8027766: Enhance RSA processing
wetmore
parents: 22309
diff changeset
   338
     * PKCS#1 v1.5 unpadding (blocktype 1 (signature) and 2 (encryption)).
22309
1990211a42e5 8023069: Enhance TLS connections
xuelei
parents: 19436
diff changeset
   339
     *
1990211a42e5 8023069: Enhance TLS connections
xuelei
parents: 19436
diff changeset
   340
     * Note that we want to make it a constant-time operation
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   341
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   342
    private byte[] unpadV15(byte[] padded) throws BadPaddingException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   343
        int k = 0;
23911
f93d74f7d6fe 8027766: Enhance RSA processing
wetmore
parents: 22309
diff changeset
   344
        boolean bp = false;
22309
1990211a42e5 8023069: Enhance TLS connections
xuelei
parents: 19436
diff changeset
   345
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   346
        if (padded[k++] != 0) {
23911
f93d74f7d6fe 8027766: Enhance RSA processing
wetmore
parents: 22309
diff changeset
   347
            bp = true;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   348
        }
23911
f93d74f7d6fe 8027766: Enhance RSA processing
wetmore
parents: 22309
diff changeset
   349
        if (padded[k++] != type) {
f93d74f7d6fe 8027766: Enhance RSA processing
wetmore
parents: 22309
diff changeset
   350
            bp = true;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   351
        }
22309
1990211a42e5 8023069: Enhance TLS connections
xuelei
parents: 19436
diff changeset
   352
        int p = 0;
1990211a42e5 8023069: Enhance TLS connections
xuelei
parents: 19436
diff changeset
   353
        while (k < padded.length) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   354
            int b = padded[k++] & 0xff;
23911
f93d74f7d6fe 8027766: Enhance RSA processing
wetmore
parents: 22309
diff changeset
   355
            if ((b == 0) && (p == 0)) {
22309
1990211a42e5 8023069: Enhance TLS connections
xuelei
parents: 19436
diff changeset
   356
                p = k;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   357
            }
23911
f93d74f7d6fe 8027766: Enhance RSA processing
wetmore
parents: 22309
diff changeset
   358
            if ((k == padded.length) && (p == 0)) {
f93d74f7d6fe 8027766: Enhance RSA processing
wetmore
parents: 22309
diff changeset
   359
                bp = true;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   360
            }
22309
1990211a42e5 8023069: Enhance TLS connections
xuelei
parents: 19436
diff changeset
   361
            if ((type == PAD_BLOCKTYPE_1) && (b != 0xff) &&
23911
f93d74f7d6fe 8027766: Enhance RSA processing
wetmore
parents: 22309
diff changeset
   362
                    (p == 0)) {
f93d74f7d6fe 8027766: Enhance RSA processing
wetmore
parents: 22309
diff changeset
   363
                bp = true;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   364
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   365
        }
22309
1990211a42e5 8023069: Enhance TLS connections
xuelei
parents: 19436
diff changeset
   366
        int n = padded.length - p;
23911
f93d74f7d6fe 8027766: Enhance RSA processing
wetmore
parents: 22309
diff changeset
   367
        if (n > maxDataSize) {
f93d74f7d6fe 8027766: Enhance RSA processing
wetmore
parents: 22309
diff changeset
   368
            bp = true;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   369
        }
22309
1990211a42e5 8023069: Enhance TLS connections
xuelei
parents: 19436
diff changeset
   370
1990211a42e5 8023069: Enhance TLS connections
xuelei
parents: 19436
diff changeset
   371
        // copy useless padding array for a constant-time method
1990211a42e5 8023069: Enhance TLS connections
xuelei
parents: 19436
diff changeset
   372
        byte[] padding = new byte[p];
1990211a42e5 8023069: Enhance TLS connections
xuelei
parents: 19436
diff changeset
   373
        System.arraycopy(padded, 0, padding, 0, p);
1990211a42e5 8023069: Enhance TLS connections
xuelei
parents: 19436
diff changeset
   374
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   375
        byte[] data = new byte[n];
22309
1990211a42e5 8023069: Enhance TLS connections
xuelei
parents: 19436
diff changeset
   376
        System.arraycopy(padded, p, data, 0, n);
1990211a42e5 8023069: Enhance TLS connections
xuelei
parents: 19436
diff changeset
   377
23911
f93d74f7d6fe 8027766: Enhance RSA processing
wetmore
parents: 22309
diff changeset
   378
        BadPaddingException bpe = new BadPaddingException("Decryption error");
f93d74f7d6fe 8027766: Enhance RSA processing
wetmore
parents: 22309
diff changeset
   379
f93d74f7d6fe 8027766: Enhance RSA processing
wetmore
parents: 22309
diff changeset
   380
        if (bp) {
22309
1990211a42e5 8023069: Enhance TLS connections
xuelei
parents: 19436
diff changeset
   381
            throw bpe;
23911
f93d74f7d6fe 8027766: Enhance RSA processing
wetmore
parents: 22309
diff changeset
   382
        } else {
f93d74f7d6fe 8027766: Enhance RSA processing
wetmore
parents: 22309
diff changeset
   383
            return data;
22309
1990211a42e5 8023069: Enhance TLS connections
xuelei
parents: 19436
diff changeset
   384
        }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   385
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   386
90ce3da70b43 Initial load
duke
parents:
diff changeset
   387
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   388
     * PKCS#1 v2.0 OAEP padding (MGF1).
90ce3da70b43 Initial load
duke
parents:
diff changeset
   389
     * Paragraph references refer to PKCS#1 v2.1 (June 14, 2002)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   390
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   391
    private byte[] padOAEP(byte[] M) throws BadPaddingException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   392
        if (random == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   393
            random = JCAUtil.getSecureRandom();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   394
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   395
        int hLen = lHash.length;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   396
90ce3da70b43 Initial load
duke
parents:
diff changeset
   397
        // 2.d: generate a random octet string seed of length hLen
90ce3da70b43 Initial load
duke
parents:
diff changeset
   398
        // if necessary
90ce3da70b43 Initial load
duke
parents:
diff changeset
   399
        byte[] seed = new byte[hLen];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   400
        random.nextBytes(seed);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   401
90ce3da70b43 Initial load
duke
parents:
diff changeset
   402
        // buffer for encoded message EM
90ce3da70b43 Initial load
duke
parents:
diff changeset
   403
        byte[] EM = new byte[paddedSize];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   404
90ce3da70b43 Initial load
duke
parents:
diff changeset
   405
        // start and length of seed (as index into EM)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   406
        int seedStart = 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   407
        int seedLen = hLen;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   408
90ce3da70b43 Initial load
duke
parents:
diff changeset
   409
        // copy seed into EM
90ce3da70b43 Initial load
duke
parents:
diff changeset
   410
        System.arraycopy(seed, 0, EM, seedStart, seedLen);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   411
90ce3da70b43 Initial load
duke
parents:
diff changeset
   412
        // start and length of data block DB in EM
90ce3da70b43 Initial load
duke
parents:
diff changeset
   413
        // we place it inside of EM to reduce copying
90ce3da70b43 Initial load
duke
parents:
diff changeset
   414
        int dbStart = hLen + 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   415
        int dbLen = EM.length - dbStart;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   416
90ce3da70b43 Initial load
duke
parents:
diff changeset
   417
        // start of message M in EM
90ce3da70b43 Initial load
duke
parents:
diff changeset
   418
        int mStart = paddedSize - M.length;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   419
90ce3da70b43 Initial load
duke
parents:
diff changeset
   420
        // build DB
90ce3da70b43 Initial load
duke
parents:
diff changeset
   421
        // 2.b: Concatenate lHash, PS, a single octet with hexadecimal value
90ce3da70b43 Initial load
duke
parents:
diff changeset
   422
        // 0x01, and the message M to form a data block DB of length
90ce3da70b43 Initial load
duke
parents:
diff changeset
   423
        // k - hLen -1 octets as DB = lHash || PS || 0x01 || M
90ce3da70b43 Initial load
duke
parents:
diff changeset
   424
        // (note that PS is all zeros)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   425
        System.arraycopy(lHash, 0, EM, dbStart, hLen);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   426
        EM[mStart - 1] = 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   427
        System.arraycopy(M, 0, EM, mStart, M.length);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   428
90ce3da70b43 Initial load
duke
parents:
diff changeset
   429
        // produce maskedDB
56542
56aaa6cb3693 Initial TLSv1.3 Implementation
wetmore
parents: 47216
diff changeset
   430
        mgf.generateAndXor(EM, seedStart, seedLen, dbLen, EM, dbStart);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   431
90ce3da70b43 Initial load
duke
parents:
diff changeset
   432
        // produce maskSeed
56542
56aaa6cb3693 Initial TLSv1.3 Implementation
wetmore
parents: 47216
diff changeset
   433
        mgf.generateAndXor(EM, dbStart, dbLen, seedLen, EM, seedStart);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   434
90ce3da70b43 Initial load
duke
parents:
diff changeset
   435
        return EM;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   436
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   437
90ce3da70b43 Initial load
duke
parents:
diff changeset
   438
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   439
     * PKCS#1 v2.1 OAEP unpadding (MGF1).
90ce3da70b43 Initial load
duke
parents:
diff changeset
   440
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   441
    private byte[] unpadOAEP(byte[] padded) throws BadPaddingException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   442
        byte[] EM = padded;
23911
f93d74f7d6fe 8027766: Enhance RSA processing
wetmore
parents: 22309
diff changeset
   443
        boolean bp = false;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   444
        int hLen = lHash.length;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   445
90ce3da70b43 Initial load
duke
parents:
diff changeset
   446
        if (EM[0] != 0) {
23911
f93d74f7d6fe 8027766: Enhance RSA processing
wetmore
parents: 22309
diff changeset
   447
            bp = true;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   448
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   449
90ce3da70b43 Initial load
duke
parents:
diff changeset
   450
        int seedStart = 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   451
        int seedLen = hLen;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   452
90ce3da70b43 Initial load
duke
parents:
diff changeset
   453
        int dbStart = hLen + 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   454
        int dbLen = EM.length - dbStart;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   455
56542
56aaa6cb3693 Initial TLSv1.3 Implementation
wetmore
parents: 47216
diff changeset
   456
        mgf.generateAndXor(EM, dbStart, dbLen, seedLen, EM, seedStart);
56aaa6cb3693 Initial TLSv1.3 Implementation
wetmore
parents: 47216
diff changeset
   457
        mgf.generateAndXor(EM, seedStart, seedLen, dbLen, EM, dbStart);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   458
90ce3da70b43 Initial load
duke
parents:
diff changeset
   459
        // verify lHash == lHash'
90ce3da70b43 Initial load
duke
parents:
diff changeset
   460
        for (int i = 0; i < hLen; i++) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   461
            if (lHash[i] != EM[dbStart + i]) {
23911
f93d74f7d6fe 8027766: Enhance RSA processing
wetmore
parents: 22309
diff changeset
   462
                bp = true;
f93d74f7d6fe 8027766: Enhance RSA processing
wetmore
parents: 22309
diff changeset
   463
            }
f93d74f7d6fe 8027766: Enhance RSA processing
wetmore
parents: 22309
diff changeset
   464
        }
f93d74f7d6fe 8027766: Enhance RSA processing
wetmore
parents: 22309
diff changeset
   465
f93d74f7d6fe 8027766: Enhance RSA processing
wetmore
parents: 22309
diff changeset
   466
        int padStart = dbStart + hLen;
f93d74f7d6fe 8027766: Enhance RSA processing
wetmore
parents: 22309
diff changeset
   467
        int onePos = -1;
f93d74f7d6fe 8027766: Enhance RSA processing
wetmore
parents: 22309
diff changeset
   468
f93d74f7d6fe 8027766: Enhance RSA processing
wetmore
parents: 22309
diff changeset
   469
        for (int i = padStart; i < EM.length; i++) {
f93d74f7d6fe 8027766: Enhance RSA processing
wetmore
parents: 22309
diff changeset
   470
            int value = EM[i];
f93d74f7d6fe 8027766: Enhance RSA processing
wetmore
parents: 22309
diff changeset
   471
            if (onePos == -1) {
f93d74f7d6fe 8027766: Enhance RSA processing
wetmore
parents: 22309
diff changeset
   472
                if (value == 0x00) {
f93d74f7d6fe 8027766: Enhance RSA processing
wetmore
parents: 22309
diff changeset
   473
                    // continue;
f93d74f7d6fe 8027766: Enhance RSA processing
wetmore
parents: 22309
diff changeset
   474
                } else if (value == 0x01) {
f93d74f7d6fe 8027766: Enhance RSA processing
wetmore
parents: 22309
diff changeset
   475
                    onePos = i;
f93d74f7d6fe 8027766: Enhance RSA processing
wetmore
parents: 22309
diff changeset
   476
                } else {  // Anything other than {0,1} is bad.
f93d74f7d6fe 8027766: Enhance RSA processing
wetmore
parents: 22309
diff changeset
   477
                    bp = true;
f93d74f7d6fe 8027766: Enhance RSA processing
wetmore
parents: 22309
diff changeset
   478
                }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   479
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   480
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   481
23911
f93d74f7d6fe 8027766: Enhance RSA processing
wetmore
parents: 22309
diff changeset
   482
        // We either ran off the rails or found something other than 0/1.
f93d74f7d6fe 8027766: Enhance RSA processing
wetmore
parents: 22309
diff changeset
   483
        if (onePos == -1) {
f93d74f7d6fe 8027766: Enhance RSA processing
wetmore
parents: 22309
diff changeset
   484
            bp = true;
f93d74f7d6fe 8027766: Enhance RSA processing
wetmore
parents: 22309
diff changeset
   485
            onePos = EM.length - 1;  // Don't inadvertently return any data.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   486
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   487
23911
f93d74f7d6fe 8027766: Enhance RSA processing
wetmore
parents: 22309
diff changeset
   488
        int mStart = onePos + 1;
f93d74f7d6fe 8027766: Enhance RSA processing
wetmore
parents: 22309
diff changeset
   489
f93d74f7d6fe 8027766: Enhance RSA processing
wetmore
parents: 22309
diff changeset
   490
        // copy useless padding array for a constant-time method
f93d74f7d6fe 8027766: Enhance RSA processing
wetmore
parents: 22309
diff changeset
   491
        byte [] tmp = new byte[mStart - padStart];
f93d74f7d6fe 8027766: Enhance RSA processing
wetmore
parents: 22309
diff changeset
   492
        System.arraycopy(EM, padStart, tmp, 0, tmp.length);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   493
23911
f93d74f7d6fe 8027766: Enhance RSA processing
wetmore
parents: 22309
diff changeset
   494
        byte [] m = new byte[EM.length - mStart];
f93d74f7d6fe 8027766: Enhance RSA processing
wetmore
parents: 22309
diff changeset
   495
        System.arraycopy(EM, mStart, m, 0, m.length);
f93d74f7d6fe 8027766: Enhance RSA processing
wetmore
parents: 22309
diff changeset
   496
f93d74f7d6fe 8027766: Enhance RSA processing
wetmore
parents: 22309
diff changeset
   497
        BadPaddingException bpe = new BadPaddingException("Decryption error");
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   498
23911
f93d74f7d6fe 8027766: Enhance RSA processing
wetmore
parents: 22309
diff changeset
   499
        if (bp) {
f93d74f7d6fe 8027766: Enhance RSA processing
wetmore
parents: 22309
diff changeset
   500
            throw bpe;
f93d74f7d6fe 8027766: Enhance RSA processing
wetmore
parents: 22309
diff changeset
   501
        } else {
f93d74f7d6fe 8027766: Enhance RSA processing
wetmore
parents: 22309
diff changeset
   502
            return m;
f93d74f7d6fe 8027766: Enhance RSA processing
wetmore
parents: 22309
diff changeset
   503
        }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   504
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   505
}