src/java.base/share/classes/sun/security/ssl/CipherBox.java

Print this page

        

*** 152,164 **** /** * NULL cipherbox. Identity operation, no encryption. */ private CipherBox() { ! this.protocolVersion = ProtocolVersion.DEFAULT; this.cipher = null; ! this.cipherType = STREAM_CIPHER; this.fixedIv = new byte[0]; this.key = null; this.mode = Cipher.ENCRYPT_MODE; // choose at random this.random = null; this.tagSize = 0; --- 152,164 ---- /** * NULL cipherbox. Identity operation, no encryption. */ private CipherBox() { ! this.protocolVersion = ProtocolVersion.DEFAULT_TLS; this.cipher = null; ! this.cipherType = NULL_CIPHER; this.fixedIv = new byte[0]; this.key = null; this.mode = Cipher.ENCRYPT_MODE; // choose at random this.random = null; this.tagSize = 0;
*** 195,205 **** * value generated by Cipher.init() for encryption, and a fixed * mask for decryption. */ if (iv == null && bulkCipher.ivSize != 0 && mode == Cipher.DECRYPT_MODE && ! protocolVersion.v >= ProtocolVersion.TLS11.v) { iv = getFixedMask(bulkCipher.ivSize); } if (cipherType == AEAD_CIPHER) { // AEAD must completely initialize the cipher for each packet, --- 195,205 ---- * value generated by Cipher.init() for encryption, and a fixed * mask for decryption. */ if (iv == null && bulkCipher.ivSize != 0 && mode == Cipher.DECRYPT_MODE && ! protocolVersion.useTLS11PlusSpec()) { iv = getFixedMask(bulkCipher.ivSize); } if (cipherType == AEAD_CIPHER) { // AEAD must completely initialize the cipher for each packet,
*** 489,499 **** if (cipherType == BLOCK_CIPHER) { int blockSize = cipher.getBlockSize(); newLen = removePadding( buf, offset, newLen, tagLen, blockSize, protocolVersion); ! if (protocolVersion.v >= ProtocolVersion.TLS11.v) { if (newLen < blockSize) { throw new BadPaddingException("invalid explicit IV"); } } } --- 489,499 ---- if (cipherType == BLOCK_CIPHER) { int blockSize = cipher.getBlockSize(); newLen = removePadding( buf, offset, newLen, tagLen, blockSize, protocolVersion); ! if (protocolVersion.useTLS11PlusSpec()) { if (newLen < blockSize) { throw new BadPaddingException("invalid explicit IV"); } } }
*** 571,581 **** int blockSize = cipher.getBlockSize(); bb.position(pos); newLen = removePadding(bb, tagLen, blockSize, protocolVersion); // check the explicit IV of TLS v1.1 or later ! if (protocolVersion.v >= ProtocolVersion.TLS11.v) { if (newLen < blockSize) { throw new BadPaddingException("invalid explicit IV"); } // reset the position to the end of the decrypted data --- 571,581 ---- int blockSize = cipher.getBlockSize(); bb.position(pos); newLen = removePadding(bb, tagLen, blockSize, protocolVersion); // check the explicit IV of TLS v1.1 or later ! if (protocolVersion.useTLS11PlusSpec()) { if (newLen < blockSize) { throw new BadPaddingException("invalid explicit IV"); } // reset the position to the end of the decrypted data
*** 744,754 **** } // The padding data should be filled with the padding length value. int[] results = checkPadding(buf, offset + newLen, padLen + 1, (byte)(padLen & 0xFF)); ! if (protocolVersion.v >= ProtocolVersion.TLS10.v) { if (results[0] != 0) { // padding data has invalid bytes throw new BadPaddingException("Invalid TLS padding data"); } } else { // SSLv3 // SSLv3 requires 0 <= length byte < block size --- 744,754 ---- } // The padding data should be filled with the padding length value. int[] results = checkPadding(buf, offset + newLen, padLen + 1, (byte)(padLen & 0xFF)); ! if (protocolVersion.useTLS10PlusSpec()) { if (results[0] != 0) { // padding data has invalid bytes throw new BadPaddingException("Invalid TLS padding data"); } } else { // SSLv3 // SSLv3 requires 0 <= length byte < block size
*** 790,800 **** // The padding data should be filled with the padding length value. int[] results = checkPadding( bb.duplicate().position(offset + newLen), (byte)(padLen & 0xFF)); ! if (protocolVersion.v >= ProtocolVersion.TLS10.v) { if (results[0] != 0) { // padding data has invalid bytes throw new BadPaddingException("Invalid TLS padding data"); } } else { // SSLv3 // SSLv3 requires 0 <= length byte < block size --- 790,800 ---- // The padding data should be filled with the padding length value. int[] results = checkPadding( bb.duplicate().position(offset + newLen), (byte)(padLen & 0xFF)); ! if (protocolVersion.useTLS10PlusSpec()) { if (results[0] != 0) { // padding data has invalid bytes throw new BadPaddingException("Invalid TLS padding data"); } } else { // SSLv3 // SSLv3 requires 0 <= length byte < block size
*** 871,881 **** switch (cipherType) { case BLOCK_CIPHER: // For block ciphers, the explicit IV length is of length // SecurityParameters.record_iv_length, which is equal to // the SecurityParameters.block_size. ! if (protocolVersion.v >= ProtocolVersion.TLS11.v) { return cipher.getBlockSize(); } break; case AEAD_CIPHER: return recordIvSize; --- 871,881 ---- switch (cipherType) { case BLOCK_CIPHER: // For block ciphers, the explicit IV length is of length // SecurityParameters.record_iv_length, which is equal to // the SecurityParameters.block_size. ! if (protocolVersion.useTLS11PlusSpec()) { return cipher.getBlockSize(); } break; case AEAD_CIPHER: return recordIvSize;
*** 900,910 **** * @param bb the byte buffer to get the explicit nonce from * * @return the explicit nonce size of the cipher. */ int applyExplicitNonce(Authenticator authenticator, byte contentType, ! ByteBuffer bb) throws BadPaddingException { switch (cipherType) { case BLOCK_CIPHER: // sanity check length of the ciphertext int tagLen = (authenticator instanceof MAC) ? ((MAC)authenticator).MAClen() : 0; --- 900,910 ---- * @param bb the byte buffer to get the explicit nonce from * * @return the explicit nonce size of the cipher. */ int applyExplicitNonce(Authenticator authenticator, byte contentType, ! ByteBuffer bb, byte[] sequence) throws BadPaddingException { switch (cipherType) { case BLOCK_CIPHER: // sanity check length of the ciphertext int tagLen = (authenticator instanceof MAC) ? ((MAC)authenticator).MAClen() : 0;
*** 916,926 **** } // For block ciphers, the explicit IV length is of length // SecurityParameters.record_iv_length, which is equal to // the SecurityParameters.block_size. ! if (protocolVersion.v >= ProtocolVersion.TLS11.v) { return cipher.getBlockSize(); } break; case AEAD_CIPHER: if (bb.remaining() < (recordIvSize + tagSize)) { --- 916,926 ---- } // For block ciphers, the explicit IV length is of length // SecurityParameters.record_iv_length, which is equal to // the SecurityParameters.block_size. ! if (protocolVersion.useTLS11PlusSpec()) { return cipher.getBlockSize(); } break; case AEAD_CIPHER: if (bb.remaining() < (recordIvSize + tagSize)) {
*** 943,953 **** "invalid key or spec in GCM mode", ikae); } // update the additional authentication data byte[] aad = authenticator.acquireAuthenticationBytes( ! contentType, bb.remaining() - recordIvSize - tagSize); cipher.updateAAD(aad); return recordIvSize; // It is also the length of sequence number, which is // used as the nonce_explicit for AEAD cipher suites. --- 943,954 ---- "invalid key or spec in GCM mode", ikae); } // update the additional authentication data byte[] aad = authenticator.acquireAuthenticationBytes( ! contentType, bb.remaining() - recordIvSize - tagSize, ! sequence); cipher.updateAAD(aad); return recordIvSize; // It is also the length of sequence number, which is // used as the nonce_explicit for AEAD cipher suites.
*** 955,991 **** return 0; } /* - * Applies the explicit nonce/IV to this cipher. This method is used to - * decrypt an SSL/TLS input record. - * - * The returned value is the SecurityParameters.record_iv_length in - * RFC 4346/5246. It is the size of explicit IV for CBC mode, and the - * size of explicit nonce for AEAD mode. - * - * @param authenticator the authenticator to get the additional - * authentication data - * @param contentType the content type of the input record - * @param buf the byte array to get the explicit nonce from - * @param offset the offset of the byte buffer - * @param cipheredLength the ciphered fragment length of the output - * record, it is the TLSCiphertext.length in RFC 4346/5246. - * - * @return the explicit nonce size of the cipher. - */ - int applyExplicitNonce(Authenticator authenticator, - byte contentType, byte[] buf, int offset, - int cipheredLength) throws BadPaddingException { - - ByteBuffer bb = ByteBuffer.wrap(buf, offset, cipheredLength); - - return applyExplicitNonce(authenticator, contentType, bb); - } - - /* * Creates the explicit nonce/IV to this cipher. This method is used to * encrypt an SSL/TLS output record. * * The size of the returned array is the SecurityParameters.record_iv_length * in RFC 4346/5246. It is the size of explicit IV for CBC mode, and the --- 956,965 ----
*** 1003,1013 **** byte contentType, int fragmentLength) { byte[] nonce = new byte[0]; switch (cipherType) { case BLOCK_CIPHER: ! if (protocolVersion.v >= ProtocolVersion.TLS11.v) { // For block ciphers, the explicit IV length is of length // SecurityParameters.record_iv_length, which is equal to // the SecurityParameters.block_size. // // Generate a random number as the explicit IV parameter. --- 977,987 ---- byte contentType, int fragmentLength) { byte[] nonce = new byte[0]; switch (cipherType) { case BLOCK_CIPHER: ! if (protocolVersion.useTLS11PlusSpec()) { // For block ciphers, the explicit IV length is of length // SecurityParameters.record_iv_length, which is equal to // the SecurityParameters.block_size. // // Generate a random number as the explicit IV parameter.
*** 1032,1051 **** // unlikely to happen throw new RuntimeException( "invalid key or spec in GCM mode", ikae); } ! // update the additional authentication data byte[] aad = authenticator.acquireAuthenticationBytes( ! contentType, fragmentLength); cipher.updateAAD(aad); break; } return nonce; } /* * Is this cipher available? * * This method can only be called by CipherSuite.BulkCipher.isAvailable() * to test the availability of a cipher suites. Please DON'T use it in --- 1006,1113 ---- // unlikely to happen throw new RuntimeException( "invalid key or spec in GCM mode", ikae); } ! // Update the additional authentication data, using the ! // implicit sequence number of the authenticator. byte[] aad = authenticator.acquireAuthenticationBytes( ! contentType, fragmentLength, null); cipher.updateAAD(aad); break; } return nonce; } + // See also CipherSuite.calculatePacketSize(). + int calculatePacketSize(int fragmentSize, int macLen, int headerSize) { + int packetSize = fragmentSize; + if (cipher != null) { + int blockSize = cipher.getBlockSize(); + switch (cipherType) { + case BLOCK_CIPHER: + packetSize += macLen; + packetSize += 1; // 1 byte padding length field + packetSize += // use the minimal padding + (blockSize - (packetSize % blockSize)) % blockSize; + if (protocolVersion.useTLS11PlusSpec()) { + packetSize += blockSize; // explicit IV + } + + break; + case AEAD_CIPHER: + packetSize += recordIvSize; + packetSize += tagSize; + + break; + default: // NULL_CIPHER or STREAM_CIPHER + packetSize += macLen; + } + } + + return packetSize + headerSize; + } + + // See also CipherSuite.calculateFragSize(). + int calculateFragmentSize(int packetLimit, int macLen, int headerSize) { + int fragLen = packetLimit - headerSize; + if (cipher != null) { + int blockSize = cipher.getBlockSize(); + switch (cipherType) { + case BLOCK_CIPHER: + if (protocolVersion.useTLS11PlusSpec()) { + fragLen -= blockSize; // explicit IV + } + fragLen -= (fragLen % blockSize); // cannot hold a block + // No padding for a maximum fragment. + fragLen -= 1; // 1 byte padding length field: 0x00 + fragLen -= macLen; + + break; + case AEAD_CIPHER: + fragLen -= recordIvSize; + fragLen -= tagSize; + + break; + default: // NULL_CIPHER or STREAM_CIPHER + fragLen -= macLen; + } + } + + return fragLen; + } + + // Estimate the maximum fragment size of a received packet. + int estimateFragmentSize(int packetSize, int macLen, int headerSize) { + int fragLen = packetSize - headerSize; + if (cipher != null) { + int blockSize = cipher.getBlockSize(); + switch (cipherType) { + case BLOCK_CIPHER: + if (protocolVersion.useTLS11PlusSpec()) { + fragLen -= blockSize; // explicit IV + } + // No padding for a maximum fragment. + fragLen -= 1; // 1 byte padding length field: 0x00 + fragLen -= macLen; + + break; + case AEAD_CIPHER: + fragLen -= recordIvSize; + fragLen -= tagSize; + + break; + default: // NULL_CIPHER or STREAM_CIPHER + fragLen -= macLen; + } + } + + return fragLen; + } + + /* * Is this cipher available? * * This method can only be called by CipherSuite.BulkCipher.isAvailable() * to test the availability of a cipher suites. Please DON'T use it in
*** 1098,1108 **** int blockSize = cipher.getBlockSize(); if ((fragmentLen % blockSize) == 0) { int minimal = tagLen + 1; minimal = (minimal >= blockSize) ? minimal : blockSize; ! if (protocolVersion.v >= ProtocolVersion.TLS11.v) { minimal += blockSize; // plus the size of the explicit IV } return (fragmentLen >= minimal); } --- 1160,1170 ---- int blockSize = cipher.getBlockSize(); if ((fragmentLen % blockSize) == 0) { int minimal = tagLen + 1; minimal = (minimal >= blockSize) ? minimal : blockSize; ! if (protocolVersion.useTLS11PlusSpec()) { minimal += blockSize; // plus the size of the explicit IV } return (fragmentLen >= minimal); }