1 /* 2 * Copyright (c) 1996, 2015, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 27 package sun.security.ssl; 28 29 import java.io.ByteArrayInputStream; 30 import java.io.IOException; 31 import java.util.Hashtable; 32 import java.util.Arrays; 33 34 import java.security.*; 35 import javax.crypto.*; 36 import javax.crypto.spec.IvParameterSpec; 37 import javax.crypto.spec.GCMParameterSpec; 38 39 import java.nio.*; 40 41 import sun.security.ssl.CipherSuite.*; 42 import static sun.security.ssl.CipherSuite.*; 43 import static sun.security.ssl.CipherSuite.CipherType.*; 44 45 import sun.security.util.HexDumpEncoder; 46 47 48 /** 49 * This class handles bulk data enciphering/deciphering for each SSLv3 50 * message. This provides data confidentiality. Stream ciphers (such 51 * as RC4) don't need to do padding; block ciphers (e.g. DES) need it. 52 * 53 * Individual instances are obtained by calling the static method 54 * newCipherBox(), which should only be invoked by BulkCipher.newCipher(). 55 * 56 * In RFC 2246, with bock ciphers in CBC mode, the Initialization 57 * Vector (IV) for the first record is generated with the other keys 58 * and secrets when the security parameters are set. The IV for 59 * subsequent records is the last ciphertext block from the previous 60 * record. 61 * 62 * In RFC 4346, the implicit Initialization Vector (IV) is replaced 63 * with an explicit IV to protect against CBC attacks. RFC 4346 64 * recommends two algorithms used to generated the per-record IV. 65 * The implementation uses the algorithm (2)(b), as described at 66 * section 6.2.3.2 of RFC 4346. 67 * 68 * The usage of IV in CBC block cipher can be illustrated in 69 * the following diagrams. 70 * 71 * (random) 72 * R P1 IV C1 73 * | | | | 74 * SIV---+ |-----+ |-... |----- |------ 75 * | | | | | | | | 76 * +----+ | +----+ | +----+ | +----+ | 77 * | Ek | | + Ek + | | Dk | | | Dk | | 78 * +----+ | +----+ | +----+ | +----+ | 79 * | | | | | | | | 80 * |----| |----| SIV--+ |----| |-... 81 * | | | | 82 * IV C1 R P1 83 * (discard) 84 * 85 * CBC Encryption CBC Decryption 86 * 87 * NOTE that any ciphering involved in key exchange (e.g. with RSA) is 88 * handled separately. 89 * 90 * @author David Brownell 91 * @author Andreas Sterbenz 92 */ 93 final class CipherBox { 94 95 // A CipherBox that implements the identity operation 96 static final CipherBox NULL = new CipherBox(); 97 98 /* Class and subclass dynamic debugging support */ 99 private static final Debug debug = Debug.getInstance("ssl"); 100 101 // the protocol version this cipher conforms to 102 private final ProtocolVersion protocolVersion; 103 104 // cipher object 105 private final Cipher cipher; 106 107 /** 108 * secure random 109 */ 110 private SecureRandom random; 111 112 /** 113 * fixed IV, the implicit nonce of AEAD cipher suite, only apply to 114 * AEAD cipher suites 115 */ 116 private final byte[] fixedIv; 117 118 /** 119 * the key, reserved only for AEAD cipher initialization 120 */ 121 private final Key key; 122 123 /** 124 * the operation mode, reserved for AEAD cipher initialization 125 */ 126 private final int mode; 127 128 /** 129 * the authentication tag size, only apply to AEAD cipher suites 130 */ 131 private final int tagSize; 132 133 /** 134 * the record IV length, only apply to AEAD cipher suites 135 */ 136 private final int recordIvSize; 137 138 /** 139 * cipher type 140 */ 141 private final CipherType cipherType; 142 143 /** 144 * Fixed masks of various block size, as the initial decryption IVs 145 * for TLS 1.1 or later. 146 * 147 * For performance, we do not use random IVs. As the initial decryption 148 * IVs will be discarded by TLS decryption processes, so the fixed masks 149 * do not hurt cryptographic strength. 150 */ 151 private static Hashtable<Integer, IvParameterSpec> masks; 152 153 /** 154 * NULL cipherbox. Identity operation, no encryption. 155 */ 156 private CipherBox() { 157 this.protocolVersion = ProtocolVersion.DEFAULT_TLS; 158 this.cipher = null; 159 this.cipherType = NULL_CIPHER; 160 this.fixedIv = new byte[0]; 161 this.key = null; 162 this.mode = Cipher.ENCRYPT_MODE; // choose at random 163 this.random = null; 164 this.tagSize = 0; 165 this.recordIvSize = 0; 166 } 167 168 /** 169 * Construct a new CipherBox using the cipher transformation. 170 * 171 * @exception NoSuchAlgorithmException if no appropriate JCE Cipher 172 * implementation could be found. 173 */ 174 private CipherBox(ProtocolVersion protocolVersion, BulkCipher bulkCipher, 175 SecretKey key, IvParameterSpec iv, SecureRandom random, 176 boolean encrypt) throws NoSuchAlgorithmException { 177 try { 178 this.protocolVersion = protocolVersion; 179 this.cipher = JsseJce.getCipher(bulkCipher.transformation); 180 this.mode = encrypt ? Cipher.ENCRYPT_MODE : Cipher.DECRYPT_MODE; 181 182 if (random == null) { 183 random = JsseJce.getSecureRandom(); 184 } 185 this.random = random; 186 this.cipherType = bulkCipher.cipherType; 187 188 /* 189 * RFC 4346 recommends two algorithms used to generated the 190 * per-record IV. The implementation uses the algorithm (2)(b), 191 * as described at section 6.2.3.2 of RFC 4346. 192 * 193 * As we don't care about the initial IV value for TLS 1.1 or 194 * later, so if the "iv" parameter is null, we use the default 195 * value generated by Cipher.init() for encryption, and a fixed 196 * mask for decryption. 197 */ 198 if (iv == null && bulkCipher.ivSize != 0 && 199 mode == Cipher.DECRYPT_MODE && 200 protocolVersion.useTLS11PlusSpec()) { 201 iv = getFixedMask(bulkCipher.ivSize); 202 } 203 204 if (cipherType == AEAD_CIPHER) { 205 // AEAD must completely initialize the cipher for each packet, 206 // and so we save initialization parameters for packet 207 // processing time. 208 209 // Set the tag size for AEAD cipher 210 tagSize = bulkCipher.tagSize; 211 212 // Reserve the key for AEAD cipher initialization 213 this.key = key; 214 215 fixedIv = iv.getIV(); 216 if (fixedIv == null || 217 fixedIv.length != bulkCipher.fixedIvSize) { 218 throw new RuntimeException("Improper fixed IV for AEAD"); 219 } 220 221 // Set the record IV length for AEAD cipher 222 recordIvSize = bulkCipher.ivSize - bulkCipher.fixedIvSize; 223 224 // DON'T initialize the cipher for AEAD! 225 } else { 226 // CBC only requires one initialization during its lifetime 227 // (future packets/IVs set the proper CBC state), so we can 228 // initialize now. 229 230 // Zeroize the variables that only apply to AEAD cipher 231 this.tagSize = 0; 232 this.fixedIv = new byte[0]; 233 this.recordIvSize = 0; 234 this.key = null; 235 236 // Initialize the cipher 237 cipher.init(mode, key, iv, random); 238 } 239 } catch (NoSuchAlgorithmException e) { 240 throw e; 241 } catch (Exception e) { 242 throw new NoSuchAlgorithmException 243 ("Could not create cipher " + bulkCipher, e); 244 } catch (ExceptionInInitializerError e) { 245 throw new NoSuchAlgorithmException 246 ("Could not create cipher " + bulkCipher, e); 247 } 248 } 249 250 /* 251 * Factory method to obtain a new CipherBox object. 252 */ 253 static CipherBox newCipherBox(ProtocolVersion version, BulkCipher cipher, 254 SecretKey key, IvParameterSpec iv, SecureRandom random, 255 boolean encrypt) throws NoSuchAlgorithmException { 256 if (cipher.allowed == false) { 257 throw new NoSuchAlgorithmException("Unsupported cipher " + cipher); 258 } 259 260 if (cipher == BulkCipher.B_NULL) { 261 return NULL; 262 } else { 263 return new CipherBox(version, cipher, key, iv, random, encrypt); 264 } 265 } 266 267 /* 268 * Get a fixed mask, as the initial decryption IVs for TLS 1.1 or later. 269 */ 270 private static IvParameterSpec getFixedMask(int ivSize) { 271 if (masks == null) { 272 masks = new Hashtable<Integer, IvParameterSpec>(5); 273 } 274 275 IvParameterSpec iv = masks.get(ivSize); 276 if (iv == null) { 277 iv = new IvParameterSpec(new byte[ivSize]); 278 masks.put(ivSize, iv); 279 } 280 281 return iv; 282 } 283 284 /* 285 * Encrypts a block of data, returning the size of the 286 * resulting block. 287 */ 288 int encrypt(byte[] buf, int offset, int len) { 289 if (cipher == null) { 290 return len; 291 } 292 293 try { 294 int blockSize = cipher.getBlockSize(); 295 if (cipherType == BLOCK_CIPHER) { 296 len = addPadding(buf, offset, len, blockSize); 297 } 298 299 if (debug != null && Debug.isOn("plaintext")) { 300 try { 301 HexDumpEncoder hd = new HexDumpEncoder(); 302 303 System.out.println( 304 "Padded plaintext before ENCRYPTION: len = " 305 + len); 306 hd.encodeBuffer( 307 new ByteArrayInputStream(buf, offset, len), 308 System.out); 309 } catch (IOException e) { } 310 } 311 312 313 if (cipherType == AEAD_CIPHER) { 314 try { 315 return cipher.doFinal(buf, offset, len, buf, offset); 316 } catch (IllegalBlockSizeException | BadPaddingException ibe) { 317 // unlikely to happen 318 throw new RuntimeException( 319 "Cipher error in AEAD mode in JCE provider " + 320 cipher.getProvider().getName(), ibe); 321 } 322 } else { 323 int newLen = cipher.update(buf, offset, len, buf, offset); 324 if (newLen != len) { 325 // catch BouncyCastle buffering error 326 throw new RuntimeException("Cipher buffering error " + 327 "in JCE provider " + cipher.getProvider().getName()); 328 } 329 return newLen; 330 } 331 } catch (ShortBufferException e) { 332 // unlikely to happen, we should have enough buffer space here 333 throw new ArrayIndexOutOfBoundsException(e.toString()); 334 } 335 } 336 337 /* 338 * Encrypts a ByteBuffer block of data, returning the size of the 339 * resulting block. 340 * 341 * The byte buffers position and limit initially define the amount 342 * to encrypt. On return, the position and limit are 343 * set to last position padded/encrypted. The limit may have changed 344 * because of the added padding bytes. 345 */ 346 int encrypt(ByteBuffer bb, int outLimit) { 347 348 int len = bb.remaining(); 349 350 if (cipher == null) { 351 bb.position(bb.limit()); 352 return len; 353 } 354 355 int pos = bb.position(); 356 357 int blockSize = cipher.getBlockSize(); 358 if (cipherType == BLOCK_CIPHER) { 359 // addPadding adjusts pos/limit 360 len = addPadding(bb, blockSize); 361 bb.position(pos); 362 } 363 364 if (debug != null && Debug.isOn("plaintext")) { 365 try { 366 HexDumpEncoder hd = new HexDumpEncoder(); 367 368 System.out.println( 369 "Padded plaintext before ENCRYPTION: len = " 370 + len); 371 hd.encodeBuffer(bb.duplicate(), System.out); 372 373 } catch (IOException e) { } 374 } 375 376 /* 377 * Encrypt "in-place". This does not add its own padding. 378 */ 379 ByteBuffer dup = bb.duplicate(); 380 if (cipherType == AEAD_CIPHER) { 381 try { 382 int outputSize = cipher.getOutputSize(dup.remaining()); 383 if (outputSize > bb.remaining()) { 384 // need to expand the limit of the output buffer for 385 // the authentication tag. 386 // 387 // DON'T worry about the buffer's capacity, we have 388 // reserved space for the authentication tag. 389 if (outLimit < pos + outputSize) { 390 // unlikely to happen 391 throw new ShortBufferException( 392 "need more space in output buffer"); 393 } 394 bb.limit(pos + outputSize); 395 } 396 int newLen = cipher.doFinal(dup, bb); 397 if (newLen != outputSize) { 398 throw new RuntimeException( 399 "Cipher buffering error in JCE provider " + 400 cipher.getProvider().getName()); 401 } 402 return newLen; 403 } catch (IllegalBlockSizeException | 404 BadPaddingException | ShortBufferException ibse) { 405 // unlikely to happen 406 throw new RuntimeException( 407 "Cipher error in AEAD mode in JCE provider " + 408 cipher.getProvider().getName(), ibse); 409 } 410 } else { 411 int newLen; 412 try { 413 newLen = cipher.update(dup, bb); 414 } catch (ShortBufferException sbe) { 415 // unlikely to happen 416 throw new RuntimeException("Cipher buffering error " + 417 "in JCE provider " + cipher.getProvider().getName()); 418 } 419 420 if (bb.position() != dup.position()) { 421 throw new RuntimeException("bytebuffer padding error"); 422 } 423 424 if (newLen != len) { 425 // catch BouncyCastle buffering error 426 throw new RuntimeException("Cipher buffering error " + 427 "in JCE provider " + cipher.getProvider().getName()); 428 } 429 return newLen; 430 } 431 } 432 433 434 /* 435 * Decrypts a block of data, returning the size of the 436 * resulting block if padding was required. 437 * 438 * For SSLv3 and TLSv1.0, with block ciphers in CBC mode the 439 * Initialization Vector (IV) for the first record is generated by 440 * the handshake protocol, the IV for subsequent records is the 441 * last ciphertext block from the previous record. 442 * 443 * From TLSv1.1, the implicit IV is replaced with an explicit IV to 444 * protect against CBC attacks. 445 * 446 * Differentiating between bad_record_mac and decryption_failed alerts 447 * may permit certain attacks against CBC mode. It is preferable to 448 * uniformly use the bad_record_mac alert to hide the specific type of 449 * the error. 450 */ 451 int decrypt(byte[] buf, int offset, int len, 452 int tagLen) throws BadPaddingException { 453 if (cipher == null) { 454 return len; 455 } 456 457 try { 458 int newLen; 459 if (cipherType == AEAD_CIPHER) { 460 try { 461 newLen = cipher.doFinal(buf, offset, len, buf, offset); 462 } catch (IllegalBlockSizeException ibse) { 463 // unlikely to happen 464 throw new RuntimeException( 465 "Cipher error in AEAD mode in JCE provider " + 466 cipher.getProvider().getName(), ibse); 467 } 468 } else { 469 newLen = cipher.update(buf, offset, len, buf, offset); 470 if (newLen != len) { 471 // catch BouncyCastle buffering error 472 throw new RuntimeException("Cipher buffering error " + 473 "in JCE provider " + cipher.getProvider().getName()); 474 } 475 } 476 if (debug != null && Debug.isOn("plaintext")) { 477 try { 478 HexDumpEncoder hd = new HexDumpEncoder(); 479 480 System.out.println( 481 "Padded plaintext after DECRYPTION: len = " 482 + newLen); 483 hd.encodeBuffer( 484 new ByteArrayInputStream(buf, offset, newLen), 485 System.out); 486 } catch (IOException e) { } 487 } 488 489 if (cipherType == BLOCK_CIPHER) { 490 int blockSize = cipher.getBlockSize(); 491 newLen = removePadding( 492 buf, offset, newLen, tagLen, blockSize, protocolVersion); 493 494 if (protocolVersion.useTLS11PlusSpec()) { 495 if (newLen < blockSize) { 496 throw new BadPaddingException("The length after " + 497 "padding removal (" + newLen + ") should be larger " + 498 "than <" + blockSize + "> since explicit IV used"); 499 } 500 } 501 } 502 return newLen; 503 } catch (ShortBufferException e) { 504 // unlikely to happen, we should have enough buffer space here 505 throw new ArrayIndexOutOfBoundsException(e.toString()); 506 } 507 } 508 509 /* 510 * Decrypts a block of data, returning the size of the 511 * resulting block if padding was required. position and limit 512 * point to the end of the decrypted/depadded data. The initial 513 * limit and new limit may be different, given we may 514 * have stripped off some padding bytes. 515 * 516 * @see decrypt(byte[], int, int) 517 */ 518 int decrypt(ByteBuffer bb, int tagLen) throws BadPaddingException { 519 520 int len = bb.remaining(); 521 522 if (cipher == null) { 523 bb.position(bb.limit()); 524 return len; 525 } 526 527 try { 528 /* 529 * Decrypt "in-place". 530 */ 531 int pos = bb.position(); 532 ByteBuffer dup = bb.duplicate(); 533 int newLen; 534 if (cipherType == AEAD_CIPHER) { 535 try { 536 newLen = cipher.doFinal(dup, bb); 537 } catch (IllegalBlockSizeException ibse) { 538 // unlikely to happen 539 throw new RuntimeException( 540 "Cipher error in AEAD mode \"" + ibse.getMessage() + 541 " \"in JCE provider " + cipher.getProvider().getName()); 542 } 543 } else { 544 newLen = cipher.update(dup, bb); 545 if (newLen != len) { 546 // catch BouncyCastle buffering error 547 throw new RuntimeException("Cipher buffering error " + 548 "in JCE provider " + cipher.getProvider().getName()); 549 } 550 } 551 552 // reset the limit to the end of the decryted data 553 bb.limit(pos + newLen); 554 555 if (debug != null && Debug.isOn("plaintext")) { 556 try { 557 HexDumpEncoder hd = new HexDumpEncoder(); 558 559 System.out.println( 560 "Padded plaintext after DECRYPTION: len = " 561 + newLen); 562 563 hd.encodeBuffer( 564 bb.duplicate().position(pos), System.out); 565 } catch (IOException e) { } 566 } 567 568 /* 569 * Remove the block padding. 570 */ 571 if (cipherType == BLOCK_CIPHER) { 572 int blockSize = cipher.getBlockSize(); 573 bb.position(pos); 574 newLen = removePadding(bb, tagLen, blockSize, protocolVersion); 575 576 // check the explicit IV of TLS v1.1 or later 577 if (protocolVersion.useTLS11PlusSpec()) { 578 if (newLen < blockSize) { 579 throw new BadPaddingException("The length after " + 580 "padding removal (" + newLen + ") should be larger " + 581 "than <" + blockSize + "> since explicit IV used"); 582 } 583 584 // reset the position to the end of the decrypted data 585 bb.position(bb.limit()); 586 } 587 } 588 return newLen; 589 } catch (ShortBufferException e) { 590 // unlikely to happen, we should have enough buffer space here 591 throw new ArrayIndexOutOfBoundsException(e.toString()); 592 } 593 } 594 595 private static int addPadding(byte[] buf, int offset, int len, 596 int blockSize) { 597 int newlen = len + 1; 598 byte pad; 599 int i; 600 601 if ((newlen % blockSize) != 0) { 602 newlen += blockSize - 1; 603 newlen -= newlen % blockSize; 604 } 605 pad = (byte) (newlen - len); 606 607 if (buf.length < (newlen + offset)) { 608 throw new IllegalArgumentException("no space to pad buffer"); 609 } 610 611 /* 612 * TLS version of the padding works for both SSLv3 and TLSv1 613 */ 614 for (i = 0, offset += len; i < pad; i++) { 615 buf [offset++] = (byte) (pad - 1); 616 } 617 return newlen; 618 } 619 620 /* 621 * Apply the padding to the buffer. 622 * 623 * Limit is advanced to the new buffer length. 624 * Position is equal to limit. 625 */ 626 private static int addPadding(ByteBuffer bb, int blockSize) { 627 628 int len = bb.remaining(); 629 int offset = bb.position(); 630 631 int newlen = len + 1; 632 byte pad; 633 int i; 634 635 if ((newlen % blockSize) != 0) { 636 newlen += blockSize - 1; 637 newlen -= newlen % blockSize; 638 } 639 pad = (byte) (newlen - len); 640 641 /* 642 * Update the limit to what will be padded. 643 */ 644 bb.limit(newlen + offset); 645 646 /* 647 * TLS version of the padding works for both SSLv3 and TLSv1 648 */ 649 for (i = 0, offset += len; i < pad; i++) { 650 bb.put(offset++, (byte) (pad - 1)); 651 } 652 653 bb.position(offset); 654 bb.limit(offset); 655 656 return newlen; 657 } 658 659 /* 660 * A constant-time check of the padding. 661 * 662 * NOTE that we are checking both the padding and the padLen bytes here. 663 * 664 * The caller MUST ensure that the len parameter is a positive number. 665 */ 666 private static int[] checkPadding( 667 byte[] buf, int offset, int len, byte pad) { 668 669 if (len <= 0) { 670 throw new RuntimeException("padding len must be positive"); 671 } 672 673 // An array of hits is used to prevent Hotspot optimization for 674 // the purpose of a constant-time check. 675 int[] results = {0, 0}; // {missed #, matched #} 676 for (int i = 0; i <= 256;) { 677 for (int j = 0; j < len && i <= 256; j++, i++) { // j <= i 678 if (buf[offset + j] != pad) { 679 results[0]++; // mismatched padding data 680 } else { 681 results[1]++; // matched padding data 682 } 683 } 684 } 685 686 return results; 687 } 688 689 /* 690 * A constant-time check of the padding. 691 * 692 * NOTE that we are checking both the padding and the padLen bytes here. 693 * 694 * The caller MUST ensure that the bb parameter has remaining. 695 */ 696 private static int[] checkPadding(ByteBuffer bb, byte pad) { 697 698 if (!bb.hasRemaining()) { 699 throw new RuntimeException("hasRemaining() must be positive"); 700 } 701 702 // An array of hits is used to prevent Hotspot optimization for 703 // the purpose of a constant-time check. 704 int[] results = {0, 0}; // {missed #, matched #} 705 bb.mark(); 706 for (int i = 0; i <= 256; bb.reset()) { 707 for (; bb.hasRemaining() && i <= 256; i++) { 708 if (bb.get() != pad) { 709 results[0]++; // mismatched padding data 710 } else { 711 results[1]++; // matched padding data 712 } 713 } 714 } 715 716 return results; 717 } 718 719 /* 720 * Typical TLS padding format for a 64 bit block cipher is as follows: 721 * xx xx xx xx xx xx xx 00 722 * xx xx xx xx xx xx 01 01 723 * ... 724 * xx 06 06 06 06 06 06 06 725 * 07 07 07 07 07 07 07 07 726 * TLS also allows any amount of padding from 1 and 256 bytes as long 727 * as it makes the data a multiple of the block size 728 */ 729 private static int removePadding(byte[] buf, int offset, int len, 730 int tagLen, int blockSize, 731 ProtocolVersion protocolVersion) throws BadPaddingException { 732 733 // last byte is length byte (i.e. actual padding length - 1) 734 int padOffset = offset + len - 1; 735 int padLen = buf[padOffset] & 0xFF; 736 737 int newLen = len - (padLen + 1); 738 if ((newLen - tagLen) < 0) { 739 // If the buffer is not long enough to contain the padding plus 740 // a MAC tag, do a dummy constant-time padding check. 741 // 742 // Note that it is a dummy check, so we won't care about what is 743 // the actual padding data. 744 checkPadding(buf, offset, len, (byte)(padLen & 0xFF)); 745 746 throw new BadPaddingException("Invalid Padding length: " + padLen); 747 } 748 749 // The padding data should be filled with the padding length value. 750 int[] results = checkPadding(buf, offset + newLen, 751 padLen + 1, (byte)(padLen & 0xFF)); 752 if (protocolVersion.useTLS10PlusSpec()) { 753 if (results[0] != 0) { // padding data has invalid bytes 754 throw new BadPaddingException("Invalid TLS padding data"); 755 } 756 } else { // SSLv3 757 // SSLv3 requires 0 <= length byte < block size 758 // some implementations do 1 <= length byte <= block size, 759 // so accept that as well 760 // v3 does not require any particular value for the other bytes 761 if (padLen > blockSize) { 762 throw new BadPaddingException("Padding length (" + 763 padLen + ") of SSLv3 message should not be bigger " + 764 "than the block size (" + blockSize + ")"); 765 } 766 } 767 return newLen; 768 } 769 770 /* 771 * Position/limit is equal the removed padding. 772 */ 773 private static int removePadding(ByteBuffer bb, 774 int tagLen, int blockSize, 775 ProtocolVersion protocolVersion) throws BadPaddingException { 776 777 int len = bb.remaining(); 778 int offset = bb.position(); 779 780 // last byte is length byte (i.e. actual padding length - 1) 781 int padOffset = offset + len - 1; 782 int padLen = bb.get(padOffset) & 0xFF; 783 784 int newLen = len - (padLen + 1); 785 if ((newLen - tagLen) < 0) { 786 // If the buffer is not long enough to contain the padding plus 787 // a MAC tag, do a dummy constant-time padding check. 788 // 789 // Note that it is a dummy check, so we won't care about what is 790 // the actual padding data. 791 checkPadding(bb.duplicate(), (byte)(padLen & 0xFF)); 792 793 throw new BadPaddingException("Invalid Padding length: " + padLen); 794 } 795 796 // The padding data should be filled with the padding length value. 797 int[] results = checkPadding( 798 bb.duplicate().position(offset + newLen), 799 (byte)(padLen & 0xFF)); 800 if (protocolVersion.useTLS10PlusSpec()) { 801 if (results[0] != 0) { // padding data has invalid bytes 802 throw new BadPaddingException("Invalid TLS padding data"); 803 } 804 } else { // SSLv3 805 // SSLv3 requires 0 <= length byte < block size 806 // some implementations do 1 <= length byte <= block size, 807 // so accept that as well 808 // v3 does not require any particular value for the other bytes 809 if (padLen > blockSize) { 810 throw new BadPaddingException("Padding length (" + 811 padLen + ") of SSLv3 message should not be bigger " + 812 "than the block size (" + blockSize + ")"); 813 } 814 } 815 816 /* 817 * Reset buffer limit to remove padding. 818 */ 819 bb.position(offset + newLen); 820 bb.limit(offset + newLen); 821 822 return newLen; 823 } 824 825 /* 826 * Dispose of any intermediate state in the underlying cipher. 827 * For PKCS11 ciphers, this will release any attached sessions, and 828 * thus make finalization faster. 829 */ 830 void dispose() { 831 try { 832 if (cipher != null) { 833 // ignore return value. 834 cipher.doFinal(); 835 } 836 } catch (Exception e) { 837 // swallow all types of exceptions. 838 } 839 } 840 841 /* 842 * Does the cipher use CBC mode? 843 * 844 * @return true if the cipher use CBC mode, false otherwise. 845 */ 846 boolean isCBCMode() { 847 return cipherType == BLOCK_CIPHER; 848 } 849 850 /* 851 * Does the cipher use AEAD mode? 852 * 853 * @return true if the cipher use AEAD mode, false otherwise. 854 */ 855 boolean isAEADMode() { 856 return cipherType == AEAD_CIPHER; 857 } 858 859 /* 860 * Is the cipher null? 861 * 862 * @return true if the cipher is null, false otherwise. 863 */ 864 boolean isNullCipher() { 865 return cipher == null; 866 } 867 868 /* 869 * Gets the explicit nonce/IV size of the cipher. 870 * 871 * The returned value is the SecurityParameters.record_iv_length in 872 * RFC 4346/5246. It is the size of explicit IV for CBC mode, and the 873 * size of explicit nonce for AEAD mode. 874 * 875 * @return the explicit nonce size of the cipher. 876 */ 877 int getExplicitNonceSize() { 878 switch (cipherType) { 879 case BLOCK_CIPHER: 880 // For block ciphers, the explicit IV length is of length 881 // SecurityParameters.record_iv_length, which is equal to 882 // the SecurityParameters.block_size. 883 if (protocolVersion.useTLS11PlusSpec()) { 884 return cipher.getBlockSize(); 885 } 886 break; 887 case AEAD_CIPHER: 888 return recordIvSize; 889 // It is also the length of sequence number, which is 890 // used as the nonce_explicit for AEAD cipher suites. 891 } 892 893 return 0; 894 } 895 896 /* 897 * Applies the explicit nonce/IV to this cipher. This method is used to 898 * decrypt an SSL/TLS input record. 899 * 900 * The returned value is the SecurityParameters.record_iv_length in 901 * RFC 4346/5246. It is the size of explicit IV for CBC mode, and the 902 * size of explicit nonce for AEAD mode. 903 * 904 * @param authenticator the authenticator to get the additional 905 * authentication data 906 * @param contentType the content type of the input record 907 * @param bb the byte buffer to get the explicit nonce from 908 * 909 * @return the explicit nonce size of the cipher. 910 */ 911 int applyExplicitNonce(Authenticator authenticator, byte contentType, 912 ByteBuffer bb, byte[] sequence) throws BadPaddingException { 913 switch (cipherType) { 914 case BLOCK_CIPHER: 915 // sanity check length of the ciphertext 916 int tagLen = (authenticator instanceof MAC) ? 917 ((MAC)authenticator).MAClen() : 0; 918 if (tagLen != 0) { 919 if (!sanityCheck(tagLen, bb.remaining())) { 920 throw new BadPaddingException( 921 "ciphertext sanity check failed"); 922 } 923 } 924 925 // For block ciphers, the explicit IV length is of length 926 // SecurityParameters.record_iv_length, which is equal to 927 // the SecurityParameters.block_size. 928 if (protocolVersion.useTLS11PlusSpec()) { 929 return cipher.getBlockSize(); 930 } 931 break; 932 case AEAD_CIPHER: 933 if (bb.remaining() < (recordIvSize + tagSize)) { 934 throw new BadPaddingException( 935 "Insufficient buffer remaining for AEAD cipher " + 936 "fragment (" + bb.remaining() + "). Needs to be " + 937 "more than or equal to IV size (" + recordIvSize + 938 ") + tag size (" + tagSize + ")"); 939 } 940 941 // initialize the AEAD cipher for the unique IV 942 byte[] iv = Arrays.copyOf(fixedIv, 943 fixedIv.length + recordIvSize); 944 bb.get(iv, fixedIv.length, recordIvSize); 945 bb.position(bb.position() - recordIvSize); 946 GCMParameterSpec spec = new GCMParameterSpec(tagSize * 8, iv); 947 try { 948 cipher.init(mode, key, spec, random); 949 } catch (InvalidKeyException | 950 InvalidAlgorithmParameterException ikae) { 951 // unlikely to happen 952 throw new RuntimeException( 953 "invalid key or spec in GCM mode", ikae); 954 } 955 956 // update the additional authentication data 957 byte[] aad = authenticator.acquireAuthenticationBytes( 958 contentType, bb.remaining() - recordIvSize - tagSize, 959 sequence); 960 cipher.updateAAD(aad); 961 962 return recordIvSize; 963 // It is also the length of sequence number, which is 964 // used as the nonce_explicit for AEAD cipher suites. 965 } 966 967 return 0; 968 } 969 970 /* 971 * Creates the explicit nonce/IV to this cipher. This method is used to 972 * encrypt an SSL/TLS output record. 973 * 974 * The size of the returned array is the SecurityParameters.record_iv_length 975 * in RFC 4346/5246. It is the size of explicit IV for CBC mode, and the 976 * size of explicit nonce for AEAD mode. 977 * 978 * @param authenticator the authenticator to get the additional 979 * authentication data 980 * @param contentType the content type of the input record 981 * @param fragmentLength the fragment length of the output record, it is 982 * the TLSCompressed.length in RFC 4346/5246. 983 * 984 * @return the explicit nonce of the cipher. 985 */ 986 byte[] createExplicitNonce(Authenticator authenticator, 987 byte contentType, int fragmentLength) { 988 989 byte[] nonce = new byte[0]; 990 switch (cipherType) { 991 case BLOCK_CIPHER: 992 if (protocolVersion.useTLS11PlusSpec()) { 993 // For block ciphers, the explicit IV length is of length 994 // SecurityParameters.record_iv_length, which is equal to 995 // the SecurityParameters.block_size. 996 // 997 // Generate a random number as the explicit IV parameter. 998 nonce = new byte[cipher.getBlockSize()]; 999 random.nextBytes(nonce); 1000 } 1001 break; 1002 case AEAD_CIPHER: 1003 // To be unique and aware of overflow-wrap, sequence number 1004 // is used as the nonce_explicit of AEAD cipher suites. 1005 nonce = authenticator.sequenceNumber(); 1006 1007 // initialize the AEAD cipher for the unique IV 1008 byte[] iv = Arrays.copyOf(fixedIv, 1009 fixedIv.length + nonce.length); 1010 System.arraycopy(nonce, 0, iv, fixedIv.length, nonce.length); 1011 GCMParameterSpec spec = new GCMParameterSpec(tagSize * 8, iv); 1012 try { 1013 cipher.init(mode, key, spec, random); 1014 } catch (InvalidKeyException | 1015 InvalidAlgorithmParameterException ikae) { 1016 // unlikely to happen 1017 throw new RuntimeException( 1018 "invalid key or spec in GCM mode", ikae); 1019 } 1020 1021 // Update the additional authentication data, using the 1022 // implicit sequence number of the authenticator. 1023 byte[] aad = authenticator.acquireAuthenticationBytes( 1024 contentType, fragmentLength, null); 1025 cipher.updateAAD(aad); 1026 break; 1027 } 1028 1029 return nonce; 1030 } 1031 1032 // See also CipherSuite.calculatePacketSize(). 1033 int calculatePacketSize(int fragmentSize, int macLen, int headerSize) { 1034 int packetSize = fragmentSize; 1035 if (cipher != null) { 1036 int blockSize = cipher.getBlockSize(); 1037 switch (cipherType) { 1038 case BLOCK_CIPHER: 1039 packetSize += macLen; 1040 packetSize += 1; // 1 byte padding length field 1041 packetSize += // use the minimal padding 1042 (blockSize - (packetSize % blockSize)) % blockSize; 1043 if (protocolVersion.useTLS11PlusSpec()) { 1044 packetSize += blockSize; // explicit IV 1045 } 1046 1047 break; 1048 case AEAD_CIPHER: 1049 packetSize += recordIvSize; 1050 packetSize += tagSize; 1051 1052 break; 1053 default: // NULL_CIPHER or STREAM_CIPHER 1054 packetSize += macLen; 1055 } 1056 } 1057 1058 return packetSize + headerSize; 1059 } 1060 1061 // See also CipherSuite.calculateFragSize(). 1062 int calculateFragmentSize(int packetLimit, int macLen, int headerSize) { 1063 int fragLen = packetLimit - headerSize; 1064 if (cipher != null) { 1065 int blockSize = cipher.getBlockSize(); 1066 switch (cipherType) { 1067 case BLOCK_CIPHER: 1068 if (protocolVersion.useTLS11PlusSpec()) { 1069 fragLen -= blockSize; // explicit IV 1070 } 1071 fragLen -= (fragLen % blockSize); // cannot hold a block 1072 // No padding for a maximum fragment. 1073 fragLen -= 1; // 1 byte padding length field: 0x00 1074 fragLen -= macLen; 1075 1076 break; 1077 case AEAD_CIPHER: 1078 fragLen -= recordIvSize; 1079 fragLen -= tagSize; 1080 1081 break; 1082 default: // NULL_CIPHER or STREAM_CIPHER 1083 fragLen -= macLen; 1084 } 1085 } 1086 1087 return fragLen; 1088 } 1089 1090 // Estimate the maximum fragment size of a received packet. 1091 int estimateFragmentSize(int packetSize, int macLen, int headerSize) { 1092 int fragLen = packetSize - headerSize; 1093 if (cipher != null) { 1094 int blockSize = cipher.getBlockSize(); 1095 switch (cipherType) { 1096 case BLOCK_CIPHER: 1097 if (protocolVersion.useTLS11PlusSpec()) { 1098 fragLen -= blockSize; // explicit IV 1099 } 1100 // No padding for a maximum fragment. 1101 fragLen -= 1; // 1 byte padding length field: 0x00 1102 fragLen -= macLen; 1103 1104 break; 1105 case AEAD_CIPHER: 1106 fragLen -= recordIvSize; 1107 fragLen -= tagSize; 1108 1109 break; 1110 default: // NULL_CIPHER or STREAM_CIPHER 1111 fragLen -= macLen; 1112 } 1113 } 1114 1115 return fragLen; 1116 } 1117 1118 /** 1119 * Sanity check the length of a fragment before decryption. 1120 * 1121 * In CBC mode, check that the fragment length is one or multiple times 1122 * of the block size of the cipher suite, and is at least one (one is the 1123 * smallest size of padding in CBC mode) bigger than the tag size of the 1124 * MAC algorithm except the explicit IV size for TLS 1.1 or later. 1125 * 1126 * In non-CBC mode, check that the fragment length is not less than the 1127 * tag size of the MAC algorithm. 1128 * 1129 * @return true if the length of a fragment matches above requirements 1130 */ 1131 private boolean sanityCheck(int tagLen, int fragmentLen) { 1132 if (!isCBCMode()) { 1133 return fragmentLen >= tagLen; 1134 } 1135 1136 int blockSize = cipher.getBlockSize(); 1137 if ((fragmentLen % blockSize) == 0) { 1138 int minimal = tagLen + 1; 1139 minimal = (minimal >= blockSize) ? minimal : blockSize; 1140 if (protocolVersion.useTLS11PlusSpec()) { 1141 minimal += blockSize; // plus the size of the explicit IV 1142 } 1143 1144 return (fragmentLen >= minimal); 1145 } 1146 1147 return false; 1148 } 1149 1150 } | 1 /* 2 * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package sun.security.ssl; 27 28 import java.nio.ByteBuffer; 29 import java.security.AccessController; 30 import java.security.GeneralSecurityException; 31 import java.security.InvalidAlgorithmParameterException; 32 import java.security.InvalidKeyException; 33 import java.security.Key; 34 import java.security.PrivilegedAction; 35 import java.security.SecureRandom; 36 import java.security.Security; 37 import java.security.spec.AlgorithmParameterSpec; 38 import java.util.AbstractMap.SimpleImmutableEntry; 39 import java.util.Arrays; 40 import java.util.HashMap; 41 import java.util.Map; 42 import javax.crypto.BadPaddingException; 43 import javax.crypto.Cipher; 44 import javax.crypto.IllegalBlockSizeException; 45 import javax.crypto.SecretKey; 46 import javax.crypto.ShortBufferException; 47 import javax.crypto.spec.GCMParameterSpec; 48 import javax.crypto.spec.IvParameterSpec; 49 import sun.security.ssl.Authenticator.MAC; 50 import static sun.security.ssl.CipherType.*; 51 import static sun.security.ssl.JsseJce.*; 52 53 enum SSLCipher { 54 // exportable ciphers 55 @SuppressWarnings({"unchecked", "rawtypes"}) 56 B_NULL("NULL", NULL_CIPHER, 0, 0, 0, 0, true, true, 57 (Map.Entry<ReadCipherGenerator, 58 ProtocolVersion[]>[])(new Map.Entry[] { 59 new SimpleImmutableEntry<ReadCipherGenerator, ProtocolVersion[]>( 60 new NullReadCipherGenerator(), 61 ProtocolVersion.PROTOCOLS_OF_NONE 62 ), 63 new SimpleImmutableEntry<ReadCipherGenerator, ProtocolVersion[]>( 64 new NullReadCipherGenerator(), 65 ProtocolVersion.PROTOCOLS_TO_13 66 ) 67 }), 68 (Map.Entry<WriteCipherGenerator, 69 ProtocolVersion[]>[])(new Map.Entry[] { 70 new SimpleImmutableEntry<WriteCipherGenerator, ProtocolVersion[]>( 71 new NullWriteCipherGenerator(), 72 ProtocolVersion.PROTOCOLS_OF_NONE 73 ), 74 new SimpleImmutableEntry<WriteCipherGenerator, ProtocolVersion[]>( 75 new NullWriteCipherGenerator(), 76 ProtocolVersion.PROTOCOLS_TO_13 77 ) 78 })), 79 80 @SuppressWarnings({"unchecked", "rawtypes"}) 81 B_RC4_40(CIPHER_RC4, STREAM_CIPHER, 5, 16, 0, 0, true, true, 82 (Map.Entry<ReadCipherGenerator, 83 ProtocolVersion[]>[])(new Map.Entry[] { 84 new SimpleImmutableEntry<ReadCipherGenerator, ProtocolVersion[]>( 85 new StreamReadCipherGenerator(), 86 ProtocolVersion.PROTOCOLS_TO_10 87 ) 88 }), 89 (Map.Entry<WriteCipherGenerator, 90 ProtocolVersion[]>[])(new Map.Entry[] { 91 new SimpleImmutableEntry<WriteCipherGenerator, ProtocolVersion[]>( 92 new StreamWriteCipherGenerator(), 93 ProtocolVersion.PROTOCOLS_TO_10 94 ) 95 })), 96 97 @SuppressWarnings({"unchecked", "rawtypes"}) 98 B_RC2_40("RC2", BLOCK_CIPHER, 5, 16, 8, 0, false, true, 99 (Map.Entry<ReadCipherGenerator, 100 ProtocolVersion[]>[])(new Map.Entry[] { 101 new SimpleImmutableEntry<ReadCipherGenerator, ProtocolVersion[]>( 102 new StreamReadCipherGenerator(), 103 ProtocolVersion.PROTOCOLS_TO_10 104 ) 105 }), 106 (Map.Entry<WriteCipherGenerator, 107 ProtocolVersion[]>[])(new Map.Entry[] { 108 new SimpleImmutableEntry<WriteCipherGenerator, ProtocolVersion[]>( 109 new StreamWriteCipherGenerator(), 110 ProtocolVersion.PROTOCOLS_TO_10 111 ) 112 })), 113 114 @SuppressWarnings({"unchecked", "rawtypes"}) 115 B_DES_40(CIPHER_DES, BLOCK_CIPHER, 5, 8, 8, 0, true, true, 116 (Map.Entry<ReadCipherGenerator, 117 ProtocolVersion[]>[])(new Map.Entry[] { 118 new SimpleImmutableEntry<ReadCipherGenerator, ProtocolVersion[]>( 119 new T10BlockReadCipherGenerator(), 120 ProtocolVersion.PROTOCOLS_TO_10 121 ) 122 }), 123 (Map.Entry<WriteCipherGenerator, 124 ProtocolVersion[]>[])(new Map.Entry[] { 125 new SimpleImmutableEntry<WriteCipherGenerator, ProtocolVersion[]>( 126 new T10BlockWriteCipherGenerator(), 127 ProtocolVersion.PROTOCOLS_TO_10 128 ) 129 })), 130 131 // domestic strength ciphers 132 @SuppressWarnings({"unchecked", "rawtypes"}) 133 B_RC4_128(CIPHER_RC4, STREAM_CIPHER, 16, 16, 0, 0, true, false, 134 (Map.Entry<ReadCipherGenerator, 135 ProtocolVersion[]>[])(new Map.Entry[] { 136 new SimpleImmutableEntry<ReadCipherGenerator, ProtocolVersion[]>( 137 new StreamReadCipherGenerator(), 138 ProtocolVersion.PROTOCOLS_TO_12 139 ) 140 }), 141 (Map.Entry<WriteCipherGenerator, 142 ProtocolVersion[]>[])(new Map.Entry[] { 143 new SimpleImmutableEntry<WriteCipherGenerator, ProtocolVersion[]>( 144 new StreamWriteCipherGenerator(), 145 ProtocolVersion.PROTOCOLS_TO_12 146 ) 147 })), 148 149 @SuppressWarnings({"unchecked", "rawtypes"}) 150 B_DES(CIPHER_DES, BLOCK_CIPHER, 8, 8, 8, 0, true, false, 151 (Map.Entry<ReadCipherGenerator, 152 ProtocolVersion[]>[])(new Map.Entry[] { 153 new SimpleImmutableEntry<ReadCipherGenerator, ProtocolVersion[]>( 154 new T10BlockReadCipherGenerator(), 155 ProtocolVersion.PROTOCOLS_TO_10 156 ), 157 new SimpleImmutableEntry<ReadCipherGenerator, ProtocolVersion[]>( 158 new T11BlockReadCipherGenerator(), 159 ProtocolVersion.PROTOCOLS_OF_11 160 ) 161 }), 162 (Map.Entry<WriteCipherGenerator, 163 ProtocolVersion[]>[])(new Map.Entry[] { 164 new SimpleImmutableEntry<WriteCipherGenerator, ProtocolVersion[]>( 165 new T10BlockWriteCipherGenerator(), 166 ProtocolVersion.PROTOCOLS_TO_10 167 ), 168 new SimpleImmutableEntry<WriteCipherGenerator, ProtocolVersion[]>( 169 new T11BlockWriteCipherGenerator(), 170 ProtocolVersion.PROTOCOLS_OF_11 171 ) 172 })), 173 174 @SuppressWarnings({"unchecked", "rawtypes"}) 175 B_3DES(CIPHER_3DES, BLOCK_CIPHER, 24, 24, 8, 0, true, false, 176 (Map.Entry<ReadCipherGenerator, 177 ProtocolVersion[]>[])(new Map.Entry[] { 178 new SimpleImmutableEntry<ReadCipherGenerator, ProtocolVersion[]>( 179 new T10BlockReadCipherGenerator(), 180 ProtocolVersion.PROTOCOLS_TO_10 181 ), 182 new SimpleImmutableEntry<ReadCipherGenerator, ProtocolVersion[]>( 183 new T11BlockReadCipherGenerator(), 184 ProtocolVersion.PROTOCOLS_11_12 185 ) 186 }), 187 (Map.Entry<WriteCipherGenerator, 188 ProtocolVersion[]>[])(new Map.Entry[] { 189 new SimpleImmutableEntry<WriteCipherGenerator, ProtocolVersion[]>( 190 new T10BlockWriteCipherGenerator(), 191 ProtocolVersion.PROTOCOLS_TO_10 192 ), 193 new SimpleImmutableEntry<WriteCipherGenerator, ProtocolVersion[]>( 194 new T11BlockWriteCipherGenerator(), 195 ProtocolVersion.PROTOCOLS_11_12 196 ) 197 })), 198 199 @SuppressWarnings({"unchecked", "rawtypes"}) 200 B_IDEA("IDEA", BLOCK_CIPHER, 16, 16, 8, 0, false, false, 201 (Map.Entry<ReadCipherGenerator, 202 ProtocolVersion[]>[])(new Map.Entry[] { 203 new SimpleImmutableEntry<ReadCipherGenerator, ProtocolVersion[]>( 204 null, 205 ProtocolVersion.PROTOCOLS_TO_12 206 ) 207 }), 208 (Map.Entry<WriteCipherGenerator, 209 ProtocolVersion[]>[])(new Map.Entry[] { 210 new SimpleImmutableEntry<WriteCipherGenerator, ProtocolVersion[]>( 211 null, 212 ProtocolVersion.PROTOCOLS_TO_12 213 ) 214 })), 215 216 @SuppressWarnings({"unchecked", "rawtypes"}) 217 B_AES_128(CIPHER_AES, BLOCK_CIPHER, 16, 16, 16, 0, true, false, 218 (Map.Entry<ReadCipherGenerator, 219 ProtocolVersion[]>[])(new Map.Entry[] { 220 new SimpleImmutableEntry<ReadCipherGenerator, ProtocolVersion[]>( 221 new T10BlockReadCipherGenerator(), 222 ProtocolVersion.PROTOCOLS_TO_10 223 ), 224 new SimpleImmutableEntry<ReadCipherGenerator, ProtocolVersion[]>( 225 new T11BlockReadCipherGenerator(), 226 ProtocolVersion.PROTOCOLS_11_12 227 ) 228 }), 229 (Map.Entry<WriteCipherGenerator, 230 ProtocolVersion[]>[])(new Map.Entry[] { 231 new SimpleImmutableEntry<WriteCipherGenerator, ProtocolVersion[]>( 232 new T10BlockWriteCipherGenerator(), 233 ProtocolVersion.PROTOCOLS_TO_10 234 ), 235 new SimpleImmutableEntry<WriteCipherGenerator, ProtocolVersion[]>( 236 new T11BlockWriteCipherGenerator(), 237 ProtocolVersion.PROTOCOLS_11_12 238 ) 239 })), 240 241 @SuppressWarnings({"unchecked", "rawtypes"}) 242 B_AES_256(CIPHER_AES, BLOCK_CIPHER, 32, 32, 16, 0, true, false, 243 (Map.Entry<ReadCipherGenerator, 244 ProtocolVersion[]>[])(new Map.Entry[] { 245 new SimpleImmutableEntry<ReadCipherGenerator, ProtocolVersion[]>( 246 new T10BlockReadCipherGenerator(), 247 ProtocolVersion.PROTOCOLS_TO_10 248 ), 249 new SimpleImmutableEntry<ReadCipherGenerator, ProtocolVersion[]>( 250 new T11BlockReadCipherGenerator(), 251 ProtocolVersion.PROTOCOLS_11_12 252 ) 253 }), 254 (Map.Entry<WriteCipherGenerator, 255 ProtocolVersion[]>[])(new Map.Entry[] { 256 new SimpleImmutableEntry<WriteCipherGenerator, ProtocolVersion[]>( 257 new T10BlockWriteCipherGenerator(), 258 ProtocolVersion.PROTOCOLS_TO_10 259 ), 260 new SimpleImmutableEntry<WriteCipherGenerator, ProtocolVersion[]>( 261 new T11BlockWriteCipherGenerator(), 262 ProtocolVersion.PROTOCOLS_11_12 263 ) 264 })), 265 266 @SuppressWarnings({"unchecked", "rawtypes"}) 267 B_AES_128_GCM(CIPHER_AES_GCM, AEAD_CIPHER, 16, 16, 12, 4, true, false, 268 (Map.Entry<ReadCipherGenerator, 269 ProtocolVersion[]>[])(new Map.Entry[] { 270 new SimpleImmutableEntry<ReadCipherGenerator, ProtocolVersion[]>( 271 new T12GcmReadCipherGenerator(), 272 ProtocolVersion.PROTOCOLS_OF_12 273 ) 274 }), 275 (Map.Entry<WriteCipherGenerator, 276 ProtocolVersion[]>[])(new Map.Entry[] { 277 new SimpleImmutableEntry<WriteCipherGenerator, ProtocolVersion[]>( 278 new T12GcmWriteCipherGenerator(), 279 ProtocolVersion.PROTOCOLS_OF_12 280 ) 281 })), 282 283 @SuppressWarnings({"unchecked", "rawtypes"}) 284 B_AES_256_GCM(CIPHER_AES_GCM, AEAD_CIPHER, 32, 32, 12, 4, true, false, 285 (Map.Entry<ReadCipherGenerator, 286 ProtocolVersion[]>[])(new Map.Entry[] { 287 new SimpleImmutableEntry<ReadCipherGenerator, ProtocolVersion[]>( 288 new T12GcmReadCipherGenerator(), 289 ProtocolVersion.PROTOCOLS_OF_12 290 ) 291 }), 292 (Map.Entry<WriteCipherGenerator, 293 ProtocolVersion[]>[])(new Map.Entry[] { 294 new SimpleImmutableEntry<WriteCipherGenerator, ProtocolVersion[]>( 295 new T12GcmWriteCipherGenerator(), 296 ProtocolVersion.PROTOCOLS_OF_12 297 ) 298 })), 299 300 @SuppressWarnings({"unchecked", "rawtypes"}) 301 B_AES_128_GCM_IV(CIPHER_AES_GCM, AEAD_CIPHER, 16, 16, 12, 0, true, false, 302 (Map.Entry<ReadCipherGenerator, 303 ProtocolVersion[]>[])(new Map.Entry[] { 304 new SimpleImmutableEntry<ReadCipherGenerator, ProtocolVersion[]>( 305 new T13GcmReadCipherGenerator(), 306 ProtocolVersion.PROTOCOLS_OF_13 307 ) 308 }), 309 (Map.Entry<WriteCipherGenerator, 310 ProtocolVersion[]>[])(new Map.Entry[] { 311 new SimpleImmutableEntry<WriteCipherGenerator, ProtocolVersion[]>( 312 new T13GcmWriteCipherGenerator(), 313 ProtocolVersion.PROTOCOLS_OF_13 314 ) 315 })), 316 317 @SuppressWarnings({"unchecked", "rawtypes"}) 318 B_AES_256_GCM_IV(CIPHER_AES_GCM, AEAD_CIPHER, 32, 32, 12, 0, true, false, 319 (Map.Entry<ReadCipherGenerator, 320 ProtocolVersion[]>[])(new Map.Entry[] { 321 new SimpleImmutableEntry<ReadCipherGenerator, ProtocolVersion[]>( 322 new T13GcmReadCipherGenerator(), 323 ProtocolVersion.PROTOCOLS_OF_13 324 ) 325 }), 326 (Map.Entry<WriteCipherGenerator, 327 ProtocolVersion[]>[])(new Map.Entry[] { 328 new SimpleImmutableEntry<WriteCipherGenerator, ProtocolVersion[]>( 329 new T13GcmWriteCipherGenerator(), 330 ProtocolVersion.PROTOCOLS_OF_13 331 ) 332 })); 333 334 // descriptive name including key size, e.g. AES/128 335 final String description; 336 337 // JCE cipher transformation string, e.g. AES/CBC/NoPadding 338 final String transformation; 339 340 // algorithm name, e.g. AES 341 final String algorithm; 342 343 // supported and compile time enabled. Also see isAvailable() 344 final boolean allowed; 345 346 // number of bytes of entropy in the key 347 final int keySize; 348 349 // length of the actual cipher key in bytes. 350 // for non-exportable ciphers, this is the same as keySize 351 final int expandedKeySize; 352 353 // size of the IV 354 final int ivSize; 355 356 // size of fixed IV 357 // 358 // record_iv_length = ivSize - fixedIvSize 359 final int fixedIvSize; 360 361 // exportable under 512/40 bit rules 362 final boolean exportable; 363 364 // Is the cipher algorithm of Cipher Block Chaining (CBC) mode? 365 final CipherType cipherType; 366 367 // size of the authentication tag, only applicable to cipher suites in 368 // Galois Counter Mode (GCM) 369 // 370 // As far as we know, all supported GCM cipher suites use 128-bits 371 // authentication tags. 372 final int tagSize = 16; 373 374 // runtime availability 375 private final boolean isAvailable; 376 377 private final Map.Entry<ReadCipherGenerator, 378 ProtocolVersion[]>[] readCipherGenerators; 379 private final Map.Entry<WriteCipherGenerator, 380 ProtocolVersion[]>[] writeCipherGenerators; 381 382 // Map of Ciphers listed in jdk.tls.KeyLimit 383 private static final HashMap<String, Long> cipherLimits = new HashMap<>(); 384 385 // Keywords found on the jdk.tls.KeyLimit security property. 386 final static String tag[] = {"KEYUPDATE"}; 387 388 static { 389 final long max = 4611686018427387904L; // 2^62 390 String prop = AccessController.doPrivileged( 391 new PrivilegedAction<String>() { 392 @Override 393 public String run() { 394 return Security.getProperty("jdk.tls.keyLimits"); 395 } 396 }); 397 398 if (prop != null) { 399 String propvalue[] = prop.split(","); 400 401 for (String entry : propvalue) { 402 int index; 403 // If this is not a UsageLimit, goto to next entry. 404 String values[] = entry.trim().toUpperCase().split(" "); 405 406 if (values[1].contains(tag[0])) { 407 index = 0; 408 } else { 409 if (SSLLogger.isOn && SSLLogger.isOn("ssl")) { 410 SSLLogger.fine("jdk.net.keyLimits: Unknown action: " + 411 entry); 412 } 413 continue; 414 } 415 416 long size; 417 int i = values[2].indexOf("^"); 418 try { 419 if (i >= 0) { 420 size = (long) Math.pow(2, 421 Integer.parseInt(values[2].substring(i + 1))); 422 } else { 423 size = Long.parseLong(values[2]); 424 } 425 if (size < 1 || size > max) { 426 throw new NumberFormatException("Length exceeded limits"); 427 } 428 } catch (NumberFormatException e) { 429 if (SSLLogger.isOn && SSLLogger.isOn("ssl")) { 430 SSLLogger.fine("jdk.net.keyLimits: " + e.getMessage() + 431 ": " + entry); 432 } 433 continue; 434 } 435 if (SSLLogger.isOn && SSLLogger.isOn("ssl")) { 436 SSLLogger.fine("jdk.net.keyLimits: entry = " + entry + 437 ". " + values[0] + ":" + tag[index] + " = " + size); 438 } 439 cipherLimits.put(values[0] + ":" + tag[index], size); 440 } 441 } 442 } 443 444 private SSLCipher(String transformation, 445 CipherType cipherType, int keySize, 446 int expandedKeySize, int ivSize, 447 int fixedIvSize, boolean allowed, boolean exportable, 448 Map.Entry<ReadCipherGenerator, 449 ProtocolVersion[]>[] readCipherGenerators, 450 Map.Entry<WriteCipherGenerator, 451 ProtocolVersion[]>[] writeCipherGenerators) { 452 this.transformation = transformation; 453 String[] splits = transformation.split("/"); 454 this.algorithm = splits[0]; 455 this.cipherType = cipherType; 456 this.description = this.algorithm + "/" + (keySize << 3); 457 this.keySize = keySize; 458 this.ivSize = ivSize; 459 this.fixedIvSize = fixedIvSize; 460 this.allowed = allowed; 461 462 this.expandedKeySize = expandedKeySize; 463 this.exportable = exportable; 464 465 // availability of this bulk cipher 466 // 467 // We assume all supported ciphers are always available since they are 468 // shipped with the SunJCE provider. However, AES/256 is unavailable 469 // when the default JCE policy jurisdiction files are installed because 470 // of key length restrictions. 471 this.isAvailable = 472 allowed ? isUnlimited(keySize, transformation) : false; 473 474 this.readCipherGenerators = readCipherGenerators; 475 this.writeCipherGenerators = writeCipherGenerators; 476 } 477 478 SSLReadCipher createReadCipher(Authenticator authenticator, 479 ProtocolVersion protocolVersion, 480 SecretKey key, IvParameterSpec iv, 481 SecureRandom random) throws GeneralSecurityException { 482 if (readCipherGenerators.length == 0) { 483 return null; 484 } 485 486 ReadCipherGenerator rcg = null; 487 for (Map.Entry<ReadCipherGenerator, 488 ProtocolVersion[]> me : readCipherGenerators) { 489 for (ProtocolVersion pv : me.getValue()) { 490 if (protocolVersion == pv) { 491 rcg = me.getKey(); 492 } 493 } 494 } 495 496 if (rcg != null) { 497 return rcg.createCipher(this, authenticator, 498 protocolVersion, transformation, key, iv, random); 499 } 500 return null; 501 } 502 503 SSLWriteCipher createWriteCipher(Authenticator authenticator, 504 ProtocolVersion protocolVersion, 505 SecretKey key, IvParameterSpec iv, 506 SecureRandom random) throws GeneralSecurityException { 507 if (readCipherGenerators.length == 0) { 508 return null; 509 } 510 511 WriteCipherGenerator rcg = null; 512 for (Map.Entry<WriteCipherGenerator, 513 ProtocolVersion[]> me : writeCipherGenerators) { 514 for (ProtocolVersion pv : me.getValue()) { 515 if (protocolVersion == pv) { 516 rcg = me.getKey(); 517 } 518 } 519 } 520 521 if (rcg != null) { 522 return rcg.createCipher(this, authenticator, 523 protocolVersion, transformation, key, iv, random); 524 } 525 return null; 526 } 527 528 public static final String getDefaultType() { 529 String prop = AccessController.doPrivileged( 530 new PrivilegedAction<String>() { 531 @Override 532 public String run() { 533 return Security.getProperty("jdk.tls.KeyLimits"); 534 } 535 }); 536 return prop; 537 } 538 539 /** 540 * Test if this bulk cipher is available. For use by CipherSuite. 541 */ 542 boolean isAvailable() { 543 return this.isAvailable; 544 } 545 546 private static boolean isUnlimited(int keySize, String transformation) { 547 int keySizeInBits = keySize * 8; 548 if (keySizeInBits > 128) { // need the JCE unlimited 549 // strength jurisdiction policy 550 try { 551 if (Cipher.getMaxAllowedKeyLength( 552 transformation) < keySizeInBits) { 553 return false; 554 } 555 } catch (Exception e) { 556 return false; 557 } 558 } 559 560 return true; 561 } 562 563 @Override 564 public String toString() { 565 return description; 566 } 567 568 interface ReadCipherGenerator { 569 SSLReadCipher createCipher(SSLCipher sslCipher, 570 Authenticator authenticator, 571 ProtocolVersion protocolVersion, String algorithm, 572 Key key, AlgorithmParameterSpec params, 573 SecureRandom random) throws GeneralSecurityException; 574 } 575 576 abstract static class SSLReadCipher { 577 final Authenticator authenticator; 578 final ProtocolVersion protocolVersion; 579 SecretKey baseSecret; 580 581 SSLReadCipher(Authenticator authenticator, 582 ProtocolVersion protocolVersion) { 583 this.authenticator = authenticator; 584 this.protocolVersion = protocolVersion; 585 } 586 587 static final SSLReadCipher nullTlsReadCipher() { 588 try { 589 return B_NULL.createReadCipher( 590 Authenticator.nullTlsMac(), 591 ProtocolVersion.NONE, null, null, null); 592 } catch (GeneralSecurityException gse) { 593 // unlikely 594 throw new RuntimeException("Cannot create NULL SSLCipher", gse); 595 } 596 } 597 598 static final SSLReadCipher nullDTlsReadCipher() { 599 try { 600 return B_NULL.createReadCipher( 601 Authenticator.nullDtlsMac(), 602 ProtocolVersion.NONE, null, null, null); 603 } catch (GeneralSecurityException gse) { 604 // unlikely 605 throw new RuntimeException("Cannot create NULL SSLCipher", gse); 606 } 607 } 608 609 abstract Plaintext decrypt(byte contentType, ByteBuffer bb, 610 byte[] sequence) throws GeneralSecurityException; 611 612 void dispose() { 613 // blank 614 } 615 616 abstract int estimateFragmentSize(int packetSize, int headerSize); 617 618 boolean isNullCipher() { 619 return false; 620 } 621 } 622 623 interface WriteCipherGenerator { 624 SSLWriteCipher createCipher(SSLCipher sslCipher, 625 Authenticator authenticator, 626 ProtocolVersion protocolVersion, String algorithm, 627 Key key, AlgorithmParameterSpec params, 628 SecureRandom random) throws GeneralSecurityException; 629 } 630 631 abstract static class SSLWriteCipher { 632 final Authenticator authenticator; 633 final ProtocolVersion protocolVersion; 634 boolean keyLimitEnabled = false; 635 long keyLimitCountdown = 0; 636 SecretKey baseSecret; 637 638 SSLWriteCipher(Authenticator authenticator, 639 ProtocolVersion protocolVersion) { 640 this.authenticator = authenticator; 641 this.protocolVersion = protocolVersion; 642 } 643 644 abstract int encrypt(byte contentType, ByteBuffer bb); 645 646 static final SSLWriteCipher nullTlsWriteCipher() { 647 try { 648 return B_NULL.createWriteCipher( 649 Authenticator.nullTlsMac(), 650 ProtocolVersion.NONE, null, null, null); 651 } catch (GeneralSecurityException gse) { 652 // unlikely 653 throw new RuntimeException( 654 "Cannot create NULL SSL write Cipher", gse); 655 } 656 } 657 658 static final SSLWriteCipher nullDTlsWriteCipher() { 659 try { 660 return B_NULL.createWriteCipher( 661 Authenticator.nullDtlsMac(), 662 ProtocolVersion.NONE, null, null, null); 663 } catch (GeneralSecurityException gse) { 664 // unlikely 665 throw new RuntimeException( 666 "Cannot create NULL SSL write Cipher", gse); 667 } 668 } 669 670 void dispose() { 671 // blank 672 } 673 674 abstract int getExplicitNonceSize(); 675 abstract int calculateFragmentSize(int packetLimit, int headerSize); 676 abstract int calculatePacketSize(int fragmentSize, int headerSize); 677 678 boolean isCBCMode() { 679 return false; 680 } 681 682 boolean isNullCipher() { 683 return false; 684 } 685 686 /** 687 * Check if processed bytes have reached the key usage limit. 688 * If key usage limit is not be monitored, return false. 689 */ 690 public boolean atKeyLimit() { 691 if (keyLimitCountdown >= 0) { 692 return false; 693 } 694 695 // Turn off limit checking as KeyUpdate will be occurring 696 keyLimitEnabled = false; 697 return true; 698 } 699 } 700 701 private static final 702 class NullReadCipherGenerator implements ReadCipherGenerator { 703 @Override 704 public SSLReadCipher createCipher(SSLCipher sslCipher, 705 Authenticator authenticator, 706 ProtocolVersion protocolVersion, String algorithm, 707 Key key, AlgorithmParameterSpec params, 708 SecureRandom random) throws GeneralSecurityException { 709 return new NullReadCipher(authenticator, protocolVersion); 710 } 711 712 static final class NullReadCipher extends SSLReadCipher { 713 NullReadCipher(Authenticator authenticator, 714 ProtocolVersion protocolVersion) { 715 super(authenticator, protocolVersion); 716 } 717 718 @Override 719 public Plaintext decrypt(byte contentType, ByteBuffer bb, 720 byte[] sequence) throws GeneralSecurityException { 721 MAC signer = (MAC)authenticator; 722 if (signer.macAlg().size != 0) { 723 checkStreamMac(signer, bb, contentType, sequence); 724 } else { 725 authenticator.increaseSequenceNumber(); 726 } 727 728 return new Plaintext(contentType, 729 ProtocolVersion.NONE.major, ProtocolVersion.NONE.minor, 730 -1, -1L, bb.slice()); 731 } 732 733 @Override 734 int estimateFragmentSize(int packetSize, int headerSize) { 735 int macLen = ((MAC)authenticator).macAlg().size; 736 return packetSize - headerSize - macLen; 737 } 738 739 @Override 740 boolean isNullCipher() { 741 return true; 742 } 743 } 744 } 745 746 private static final 747 class NullWriteCipherGenerator implements WriteCipherGenerator { 748 @Override 749 public SSLWriteCipher createCipher(SSLCipher sslCipher, 750 Authenticator authenticator, 751 ProtocolVersion protocolVersion, String algorithm, 752 Key key, AlgorithmParameterSpec params, 753 SecureRandom random) throws GeneralSecurityException { 754 return new NullWriteCipher(authenticator, protocolVersion); 755 } 756 757 static final class NullWriteCipher extends SSLWriteCipher { 758 NullWriteCipher(Authenticator authenticator, 759 ProtocolVersion protocolVersion) { 760 super(authenticator, protocolVersion); 761 } 762 763 @Override 764 public int encrypt(byte contentType, ByteBuffer bb) { 765 // add message authentication code 766 MAC signer = (MAC)authenticator; 767 if (signer.macAlg().size != 0) { 768 addMac(signer, bb, contentType); 769 } else { 770 authenticator.increaseSequenceNumber(); 771 } 772 773 int len = bb.remaining(); 774 bb.position(bb.limit()); 775 return len; 776 } 777 778 779 @Override 780 int getExplicitNonceSize() { 781 return 0; 782 } 783 784 @Override 785 int calculateFragmentSize(int packetLimit, int headerSize) { 786 int macLen = ((MAC)authenticator).macAlg().size; 787 return packetLimit - headerSize - macLen; 788 } 789 790 @Override 791 int calculatePacketSize(int fragmentSize, int headerSize) { 792 int macLen = ((MAC)authenticator).macAlg().size; 793 return fragmentSize + headerSize + macLen; 794 } 795 796 @Override 797 boolean isNullCipher() { 798 return true; 799 } 800 } 801 } 802 803 private static final 804 class StreamReadCipherGenerator implements ReadCipherGenerator { 805 @Override 806 public SSLReadCipher createCipher(SSLCipher sslCipher, 807 Authenticator authenticator, 808 ProtocolVersion protocolVersion, String algorithm, 809 Key key, AlgorithmParameterSpec params, 810 SecureRandom random) throws GeneralSecurityException { 811 return new StreamReadCipher(authenticator, protocolVersion, 812 algorithm, key, params, random); 813 } 814 815 static final class StreamReadCipher extends SSLReadCipher { 816 private final Cipher cipher; 817 818 StreamReadCipher(Authenticator authenticator, 819 ProtocolVersion protocolVersion, String algorithm, 820 Key key, AlgorithmParameterSpec params, 821 SecureRandom random) throws GeneralSecurityException { 822 super(authenticator, protocolVersion); 823 this.cipher = JsseJce.getCipher(algorithm); 824 cipher.init(Cipher.DECRYPT_MODE, key, params, random); 825 } 826 827 @Override 828 public Plaintext decrypt(byte contentType, ByteBuffer bb, 829 byte[] sequence) throws GeneralSecurityException { 830 int len = bb.remaining(); 831 int pos = bb.position(); 832 ByteBuffer dup = bb.duplicate(); 833 try { 834 if (len != cipher.update(dup, bb)) { 835 // catch BouncyCastle buffering error 836 throw new RuntimeException( 837 "Unexpected number of plaintext bytes"); 838 } 839 if (bb.position() != dup.position()) { 840 throw new RuntimeException( 841 "Unexpected Bytebuffer position"); 842 } 843 } catch (ShortBufferException sbe) { 844 // catch BouncyCastle buffering error 845 throw new RuntimeException("Cipher buffering error in " + 846 "JCE provider " + cipher.getProvider().getName(), sbe); 847 } 848 bb.position(pos); 849 if (SSLLogger.isOn && SSLLogger.isOn("plaintext")) { 850 SSLLogger.fine( 851 "Plaintext after DECRYPTION", bb.duplicate()); 852 } 853 854 MAC signer = (MAC)authenticator; 855 if (signer.macAlg().size != 0) { 856 checkStreamMac(signer, bb, contentType, sequence); 857 } else { 858 authenticator.increaseSequenceNumber(); 859 } 860 861 return new Plaintext(contentType, 862 ProtocolVersion.NONE.major, ProtocolVersion.NONE.minor, 863 -1, -1L, bb.slice()); 864 } 865 866 @Override 867 void dispose() { 868 if (cipher != null) { 869 try { 870 cipher.doFinal(); 871 } catch (Exception e) { 872 // swallow all types of exceptions. 873 } 874 } 875 } 876 877 @Override 878 int estimateFragmentSize(int packetSize, int headerSize) { 879 int macLen = ((MAC)authenticator).macAlg().size; 880 return packetSize - headerSize - macLen; 881 } 882 } 883 } 884 885 private static final 886 class StreamWriteCipherGenerator implements WriteCipherGenerator { 887 @Override 888 public SSLWriteCipher createCipher(SSLCipher sslCipher, 889 Authenticator authenticator, 890 ProtocolVersion protocolVersion, String algorithm, 891 Key key, AlgorithmParameterSpec params, 892 SecureRandom random) throws GeneralSecurityException { 893 return new StreamWriteCipher(authenticator, 894 protocolVersion, algorithm, key, params, random); 895 } 896 897 static final class StreamWriteCipher extends SSLWriteCipher { 898 private final Cipher cipher; 899 900 StreamWriteCipher(Authenticator authenticator, 901 ProtocolVersion protocolVersion, String algorithm, 902 Key key, AlgorithmParameterSpec params, 903 SecureRandom random) throws GeneralSecurityException { 904 super(authenticator, protocolVersion); 905 this.cipher = JsseJce.getCipher(algorithm); 906 cipher.init(Cipher.ENCRYPT_MODE, key, params, random); 907 } 908 909 @Override 910 public int encrypt(byte contentType, ByteBuffer bb) { 911 // add message authentication code 912 MAC signer = (MAC)authenticator; 913 if (signer.macAlg().size != 0) { 914 addMac(signer, bb, contentType); 915 } else { 916 authenticator.increaseSequenceNumber(); 917 } 918 919 if (SSLLogger.isOn && SSLLogger.isOn("plaintext")) { 920 SSLLogger.finest( 921 "Padded plaintext before ENCRYPTION", bb.duplicate()); 922 } 923 924 int len = bb.remaining(); 925 ByteBuffer dup = bb.duplicate(); 926 try { 927 if (len != cipher.update(dup, bb)) { 928 // catch BouncyCastle buffering error 929 throw new RuntimeException( 930 "Unexpected number of plaintext bytes"); 931 } 932 if (bb.position() != dup.position()) { 933 throw new RuntimeException( 934 "Unexpected Bytebuffer position"); 935 } 936 } catch (ShortBufferException sbe) { 937 // catch BouncyCastle buffering error 938 throw new RuntimeException("Cipher buffering error in " + 939 "JCE provider " + cipher.getProvider().getName(), sbe); 940 } 941 942 return len; 943 } 944 945 @Override 946 void dispose() { 947 if (cipher != null) { 948 try { 949 cipher.doFinal(); 950 } catch (Exception e) { 951 // swallow all types of exceptions. 952 } 953 } 954 } 955 956 @Override 957 int getExplicitNonceSize() { 958 return 0; 959 } 960 961 @Override 962 int calculateFragmentSize(int packetLimit, int headerSize) { 963 int macLen = ((MAC)authenticator).macAlg().size; 964 return packetLimit - headerSize - macLen; 965 } 966 967 @Override 968 int calculatePacketSize(int fragmentSize, int headerSize) { 969 int macLen = ((MAC)authenticator).macAlg().size; 970 return fragmentSize + headerSize + macLen; 971 } 972 } 973 } 974 975 private static final 976 class T10BlockReadCipherGenerator implements ReadCipherGenerator { 977 @Override 978 public SSLReadCipher createCipher(SSLCipher sslCipher, 979 Authenticator authenticator, 980 ProtocolVersion protocolVersion, String algorithm, 981 Key key, AlgorithmParameterSpec params, 982 SecureRandom random) throws GeneralSecurityException { 983 return new BlockReadCipher(authenticator, 984 protocolVersion, algorithm, key, params, random); 985 } 986 987 static final class BlockReadCipher extends SSLReadCipher { 988 private final Cipher cipher; 989 990 BlockReadCipher(Authenticator authenticator, 991 ProtocolVersion protocolVersion, String algorithm, 992 Key key, AlgorithmParameterSpec params, 993 SecureRandom random) throws GeneralSecurityException { 994 super(authenticator, protocolVersion); 995 this.cipher = JsseJce.getCipher(algorithm); 996 cipher.init(Cipher.DECRYPT_MODE, key, params, random); 997 } 998 999 @Override 1000 public Plaintext decrypt(byte contentType, ByteBuffer bb, 1001 byte[] sequence) throws GeneralSecurityException { 1002 BadPaddingException reservedBPE = null; 1003 1004 // sanity check length of the ciphertext 1005 MAC signer = (MAC)authenticator; 1006 int cipheredLength = bb.remaining(); 1007 int tagLen = signer.macAlg().size; 1008 if (tagLen != 0) { 1009 if (!sanityCheck(tagLen, bb.remaining())) { 1010 reservedBPE = new BadPaddingException( 1011 "ciphertext sanity check failed"); 1012 } 1013 } 1014 // decryption 1015 int len = bb.remaining(); 1016 int pos = bb.position(); 1017 ByteBuffer dup = bb.duplicate(); 1018 try { 1019 if (len != cipher.update(dup, bb)) { 1020 // catch BouncyCastle buffering error 1021 throw new RuntimeException( 1022 "Unexpected number of plaintext bytes"); 1023 } 1024 1025 if (bb.position() != dup.position()) { 1026 throw new RuntimeException( 1027 "Unexpected Bytebuffer position"); 1028 } 1029 } catch (ShortBufferException sbe) { 1030 // catch BouncyCastle buffering error 1031 throw new RuntimeException("Cipher buffering error in " + 1032 "JCE provider " + cipher.getProvider().getName(), sbe); 1033 } 1034 1035 if (SSLLogger.isOn && SSLLogger.isOn("plaintext")) { 1036 SSLLogger.fine( 1037 "Padded plaintext after DECRYPTION", 1038 bb.duplicate().position(pos)); 1039 } 1040 1041 // remove the block padding 1042 int blockSize = cipher.getBlockSize(); 1043 bb.position(pos); 1044 try { 1045 removePadding(bb, tagLen, blockSize, protocolVersion); 1046 } catch (BadPaddingException bpe) { 1047 if (reservedBPE == null) { 1048 reservedBPE = bpe; 1049 } 1050 } 1051 1052 // Requires message authentication code for null, stream and 1053 // block cipher suites. 1054 try { 1055 if (tagLen != 0) { 1056 checkCBCMac(signer, bb, 1057 contentType, cipheredLength, sequence); 1058 } else { 1059 authenticator.increaseSequenceNumber(); 1060 } 1061 } catch (BadPaddingException bpe) { 1062 if (reservedBPE == null) { 1063 reservedBPE = bpe; 1064 } 1065 } 1066 1067 // Is it a failover? 1068 if (reservedBPE != null) { 1069 throw reservedBPE; 1070 } 1071 1072 return new Plaintext(contentType, 1073 ProtocolVersion.NONE.major, ProtocolVersion.NONE.minor, 1074 -1, -1L, bb.slice()); 1075 } 1076 1077 @Override 1078 void dispose() { 1079 if (cipher != null) { 1080 try { 1081 cipher.doFinal(); 1082 } catch (Exception e) { 1083 // swallow all types of exceptions. 1084 } 1085 } 1086 } 1087 1088 @Override 1089 int estimateFragmentSize(int packetSize, int headerSize) { 1090 int macLen = ((MAC)authenticator).macAlg().size; 1091 1092 // No padding for a maximum fragment. 1093 // 1094 // 1 byte padding length field: 0x00 1095 return packetSize - headerSize - macLen - 1; 1096 } 1097 1098 /** 1099 * Sanity check the length of a fragment before decryption. 1100 * 1101 * In CBC mode, check that the fragment length is one or multiple 1102 * times of the block size of the cipher suite, and is at least 1103 * one (one is the smallest size of padding in CBC mode) bigger 1104 * than the tag size of the MAC algorithm except the explicit IV 1105 * size for TLS 1.1 or later. 1106 * 1107 * In non-CBC mode, check that the fragment length is not less than 1108 * the tag size of the MAC algorithm. 1109 * 1110 * @return true if the length of a fragment matches above 1111 * requirements 1112 */ 1113 private boolean sanityCheck(int tagLen, int fragmentLen) { 1114 int blockSize = cipher.getBlockSize(); 1115 if ((fragmentLen % blockSize) == 0) { 1116 int minimal = tagLen + 1; 1117 minimal = (minimal >= blockSize) ? minimal : blockSize; 1118 1119 return (fragmentLen >= minimal); 1120 } 1121 1122 return false; 1123 } 1124 } 1125 } 1126 1127 private static final 1128 class T10BlockWriteCipherGenerator implements WriteCipherGenerator { 1129 @Override 1130 public SSLWriteCipher createCipher(SSLCipher sslCipher, 1131 Authenticator authenticator, 1132 ProtocolVersion protocolVersion, String algorithm, 1133 Key key, AlgorithmParameterSpec params, 1134 SecureRandom random) throws GeneralSecurityException { 1135 return new BlockWriteCipher(authenticator, 1136 protocolVersion, algorithm, key, params, random); 1137 } 1138 1139 static final class BlockWriteCipher extends SSLWriteCipher { 1140 private final Cipher cipher; 1141 1142 BlockWriteCipher(Authenticator authenticator, 1143 ProtocolVersion protocolVersion, String algorithm, 1144 Key key, AlgorithmParameterSpec params, 1145 SecureRandom random) throws GeneralSecurityException { 1146 super(authenticator, protocolVersion); 1147 this.cipher = JsseJce.getCipher(algorithm); 1148 cipher.init(Cipher.ENCRYPT_MODE, key, params, random); 1149 } 1150 1151 @Override 1152 public int encrypt(byte contentType, ByteBuffer bb) { 1153 int pos = bb.position(); 1154 1155 // add message authentication code 1156 MAC signer = (MAC)authenticator; 1157 if (signer.macAlg().size != 0) { 1158 addMac(signer, bb, contentType); 1159 } else { 1160 authenticator.increaseSequenceNumber(); 1161 } 1162 1163 int blockSize = cipher.getBlockSize(); 1164 int len = addPadding(bb, blockSize); 1165 bb.position(pos); 1166 1167 if (SSLLogger.isOn && SSLLogger.isOn("plaintext")) { 1168 SSLLogger.fine( 1169 "Padded plaintext before ENCRYPTION", 1170 bb.duplicate()); 1171 } 1172 1173 ByteBuffer dup = bb.duplicate(); 1174 try { 1175 if (len != cipher.update(dup, bb)) { 1176 // catch BouncyCastle buffering error 1177 throw new RuntimeException( 1178 "Unexpected number of plaintext bytes"); 1179 } 1180 1181 if (bb.position() != dup.position()) { 1182 throw new RuntimeException( 1183 "Unexpected Bytebuffer position"); 1184 } 1185 } catch (ShortBufferException sbe) { 1186 // catch BouncyCastle buffering error 1187 throw new RuntimeException("Cipher buffering error in " + 1188 "JCE provider " + cipher.getProvider().getName(), sbe); 1189 } 1190 1191 return len; 1192 } 1193 1194 @Override 1195 void dispose() { 1196 if (cipher != null) { 1197 try { 1198 cipher.doFinal(); 1199 } catch (Exception e) { 1200 // swallow all types of exceptions. 1201 } 1202 } 1203 } 1204 1205 @Override 1206 int getExplicitNonceSize() { 1207 return 0; 1208 } 1209 1210 @Override 1211 int calculateFragmentSize(int packetLimit, int headerSize) { 1212 int macLen = ((MAC)authenticator).macAlg().size; 1213 int blockSize = cipher.getBlockSize(); 1214 int fragLen = packetLimit - headerSize; 1215 fragLen -= (fragLen % blockSize); // cannot hold a block 1216 // No padding for a maximum fragment. 1217 fragLen -= 1; // 1 byte padding length field: 0x00 1218 fragLen -= macLen; 1219 return fragLen; 1220 } 1221 1222 @Override 1223 int calculatePacketSize(int fragmentSize, int headerSize) { 1224 int macLen = ((MAC)authenticator).macAlg().size; 1225 int blockSize = cipher.getBlockSize(); 1226 int paddedLen = fragmentSize + macLen + 1; 1227 if ((paddedLen % blockSize) != 0) { 1228 paddedLen += blockSize - 1; 1229 paddedLen -= paddedLen % blockSize; 1230 } 1231 1232 return headerSize + paddedLen; 1233 } 1234 1235 @Override 1236 boolean isCBCMode() { 1237 return true; 1238 } 1239 } 1240 } 1241 1242 // For TLS 1.1 and 1.2 1243 private static final 1244 class T11BlockReadCipherGenerator implements ReadCipherGenerator { 1245 @Override 1246 public SSLReadCipher createCipher(SSLCipher sslCipher, 1247 Authenticator authenticator, ProtocolVersion protocolVersion, 1248 String algorithm, Key key, AlgorithmParameterSpec params, 1249 SecureRandom random) throws GeneralSecurityException { 1250 return new BlockReadCipher(authenticator, protocolVersion, 1251 sslCipher, algorithm, key, params, random); 1252 } 1253 1254 static final class BlockReadCipher extends SSLReadCipher { 1255 private final Cipher cipher; 1256 1257 BlockReadCipher(Authenticator authenticator, 1258 ProtocolVersion protocolVersion, 1259 SSLCipher sslCipher, String algorithm, 1260 Key key, AlgorithmParameterSpec params, 1261 SecureRandom random) throws GeneralSecurityException { 1262 super(authenticator, protocolVersion); 1263 this.cipher = JsseJce.getCipher(algorithm); 1264 if (params == null) { 1265 params = new IvParameterSpec(new byte[sslCipher.ivSize]); 1266 } 1267 cipher.init(Cipher.DECRYPT_MODE, key, params, random); 1268 } 1269 1270 @Override 1271 public Plaintext decrypt(byte contentType, ByteBuffer bb, 1272 byte[] sequence) throws GeneralSecurityException { 1273 BadPaddingException reservedBPE = null; 1274 1275 // sanity check length of the ciphertext 1276 MAC signer = (MAC)authenticator; 1277 int cipheredLength = bb.remaining(); 1278 int tagLen = signer.macAlg().size; 1279 if (tagLen != 0) { 1280 if (!sanityCheck(tagLen, bb.remaining())) { 1281 reservedBPE = new BadPaddingException( 1282 "ciphertext sanity check failed"); 1283 } 1284 } 1285 1286 // decryption 1287 int len = bb.remaining(); 1288 int pos = bb.position(); 1289 ByteBuffer dup = bb.duplicate(); 1290 try { 1291 if (len != cipher.update(dup, bb)) { 1292 // catch BouncyCastle buffering error 1293 throw new RuntimeException( 1294 "Unexpected number of plaintext bytes"); 1295 } 1296 1297 if (bb.position() != dup.position()) { 1298 throw new RuntimeException( 1299 "Unexpected Bytebuffer position"); 1300 } 1301 } catch (ShortBufferException sbe) { 1302 // catch BouncyCastle buffering error 1303 throw new RuntimeException("Cipher buffering error in " + 1304 "JCE provider " + cipher.getProvider().getName(), sbe); 1305 } 1306 1307 if (SSLLogger.isOn && SSLLogger.isOn("plaintext")) { 1308 SSLLogger.fine( 1309 "Padded plaintext after DECRYPTION", 1310 bb.duplicate().position(pos)); 1311 } 1312 1313 // Ignore the explicit nonce. 1314 bb.position(pos + cipher.getBlockSize()); 1315 pos = bb.position(); 1316 1317 // remove the block padding 1318 int blockSize = cipher.getBlockSize(); 1319 bb.position(pos); 1320 try { 1321 removePadding(bb, tagLen, blockSize, protocolVersion); 1322 } catch (BadPaddingException bpe) { 1323 if (reservedBPE == null) { 1324 reservedBPE = bpe; 1325 } 1326 } 1327 1328 // Requires message authentication code for null, stream and 1329 // block cipher suites. 1330 try { 1331 if (tagLen != 0) { 1332 checkCBCMac(signer, bb, 1333 contentType, cipheredLength, sequence); 1334 } else { 1335 authenticator.increaseSequenceNumber(); 1336 } 1337 } catch (BadPaddingException bpe) { 1338 if (reservedBPE == null) { 1339 reservedBPE = bpe; 1340 } 1341 } 1342 1343 // Is it a failover? 1344 if (reservedBPE != null) { 1345 throw reservedBPE; 1346 } 1347 1348 return new Plaintext(contentType, 1349 ProtocolVersion.NONE.major, ProtocolVersion.NONE.minor, 1350 -1, -1L, bb.slice()); 1351 } 1352 1353 @Override 1354 void dispose() { 1355 if (cipher != null) { 1356 try { 1357 cipher.doFinal(); 1358 } catch (Exception e) { 1359 // swallow all types of exceptions. 1360 } 1361 } 1362 } 1363 1364 @Override 1365 int estimateFragmentSize(int packetSize, int headerSize) { 1366 int macLen = ((MAC)authenticator).macAlg().size; 1367 1368 // No padding for a maximum fragment. 1369 // 1370 // 1 byte padding length field: 0x00 1371 int nonceSize = cipher.getBlockSize(); 1372 return packetSize - headerSize - nonceSize - macLen - 1; 1373 } 1374 1375 /** 1376 * Sanity check the length of a fragment before decryption. 1377 * 1378 * In CBC mode, check that the fragment length is one or multiple 1379 * times of the block size of the cipher suite, and is at least 1380 * one (one is the smallest size of padding in CBC mode) bigger 1381 * than the tag size of the MAC algorithm except the explicit IV 1382 * size for TLS 1.1 or later. 1383 * 1384 * In non-CBC mode, check that the fragment length is not less than 1385 * the tag size of the MAC algorithm. 1386 * 1387 * @return true if the length of a fragment matches above 1388 * requirements 1389 */ 1390 private boolean sanityCheck(int tagLen, int fragmentLen) { 1391 int blockSize = cipher.getBlockSize(); 1392 if ((fragmentLen % blockSize) == 0) { 1393 int minimal = tagLen + 1; 1394 minimal = (minimal >= blockSize) ? minimal : blockSize; 1395 minimal += blockSize; 1396 1397 return (fragmentLen >= minimal); 1398 } 1399 1400 return false; 1401 } 1402 } 1403 } 1404 1405 // For TLS 1.1 and 1.2 1406 private static final 1407 class T11BlockWriteCipherGenerator implements WriteCipherGenerator { 1408 @Override 1409 public SSLWriteCipher createCipher(SSLCipher sslCipher, 1410 Authenticator authenticator, ProtocolVersion protocolVersion, 1411 String algorithm, Key key, AlgorithmParameterSpec params, 1412 SecureRandom random) throws GeneralSecurityException { 1413 return new BlockWriteCipher(authenticator, protocolVersion, 1414 sslCipher, algorithm, key, params, random); 1415 } 1416 1417 static final class BlockWriteCipher extends SSLWriteCipher { 1418 private final Cipher cipher; 1419 private final SecureRandom random; 1420 1421 BlockWriteCipher(Authenticator authenticator, 1422 ProtocolVersion protocolVersion, 1423 SSLCipher sslCipher, String algorithm, 1424 Key key, AlgorithmParameterSpec params, 1425 SecureRandom random) throws GeneralSecurityException { 1426 super(authenticator, protocolVersion); 1427 this.cipher = JsseJce.getCipher(algorithm); 1428 this.random = random; 1429 if (params == null) { 1430 params = new IvParameterSpec(new byte[sslCipher.ivSize]); 1431 } 1432 cipher.init(Cipher.ENCRYPT_MODE, key, params, random); 1433 } 1434 1435 @Override 1436 public int encrypt(byte contentType, ByteBuffer bb) { 1437 // To be unique and aware of overflow-wrap, sequence number 1438 // is used as the nonce_explicit of block cipher suites. 1439 int pos = bb.position(); 1440 1441 // add message authentication code 1442 MAC signer = (MAC)authenticator; 1443 if (signer.macAlg().size != 0) { 1444 addMac(signer, bb, contentType); 1445 } else { 1446 authenticator.increaseSequenceNumber(); 1447 } 1448 1449 // DON'T WORRY, the nonce spaces are considered already. 1450 byte[] nonce = new byte[cipher.getBlockSize()]; 1451 random.nextBytes(nonce); 1452 pos = pos - nonce.length; 1453 bb.position(pos); 1454 bb.put(nonce); 1455 bb.position(pos); 1456 1457 int blockSize = cipher.getBlockSize(); 1458 int len = addPadding(bb, blockSize); 1459 bb.position(pos); 1460 1461 if (SSLLogger.isOn && SSLLogger.isOn("plaintext")) { 1462 SSLLogger.fine( 1463 "Padded plaintext before ENCRYPTION", 1464 bb.duplicate()); 1465 } 1466 1467 ByteBuffer dup = bb.duplicate(); 1468 try { 1469 if (len != cipher.update(dup, bb)) { 1470 // catch BouncyCastle buffering error 1471 throw new RuntimeException( 1472 "Unexpected number of plaintext bytes"); 1473 } 1474 1475 if (bb.position() != dup.position()) { 1476 throw new RuntimeException( 1477 "Unexpected Bytebuffer position"); 1478 } 1479 } catch (ShortBufferException sbe) { 1480 // catch BouncyCastle buffering error 1481 throw new RuntimeException("Cipher buffering error in " + 1482 "JCE provider " + cipher.getProvider().getName(), sbe); 1483 } 1484 1485 return len; 1486 } 1487 1488 @Override 1489 void dispose() { 1490 if (cipher != null) { 1491 try { 1492 cipher.doFinal(); 1493 } catch (Exception e) { 1494 // swallow all types of exceptions. 1495 } 1496 } 1497 } 1498 1499 @Override 1500 int getExplicitNonceSize() { 1501 return cipher.getBlockSize(); 1502 } 1503 1504 @Override 1505 int calculateFragmentSize(int packetLimit, int headerSize) { 1506 int macLen = ((MAC)authenticator).macAlg().size; 1507 int blockSize = cipher.getBlockSize(); 1508 int fragLen = packetLimit - headerSize - blockSize; 1509 fragLen -= (fragLen % blockSize); // cannot hold a block 1510 // No padding for a maximum fragment. 1511 fragLen -= 1; // 1 byte padding length field: 0x00 1512 fragLen -= macLen; 1513 return fragLen; 1514 } 1515 1516 @Override 1517 int calculatePacketSize(int fragmentSize, int headerSize) { 1518 int macLen = ((MAC)authenticator).macAlg().size; 1519 int blockSize = cipher.getBlockSize(); 1520 int paddedLen = fragmentSize + macLen + 1; 1521 if ((paddedLen % blockSize) != 0) { 1522 paddedLen += blockSize - 1; 1523 paddedLen -= paddedLen % blockSize; 1524 } 1525 1526 return headerSize + blockSize + paddedLen; 1527 } 1528 1529 @Override 1530 boolean isCBCMode() { 1531 return true; 1532 } 1533 } 1534 } 1535 1536 private static final 1537 class T12GcmReadCipherGenerator implements ReadCipherGenerator { 1538 @Override 1539 public SSLReadCipher createCipher(SSLCipher sslCipher, 1540 Authenticator authenticator, 1541 ProtocolVersion protocolVersion, String algorithm, 1542 Key key, AlgorithmParameterSpec params, 1543 SecureRandom random) throws GeneralSecurityException { 1544 return new GcmReadCipher(authenticator, protocolVersion, sslCipher, 1545 algorithm, key, params, random); 1546 } 1547 1548 static final class GcmReadCipher extends SSLReadCipher { 1549 private final Cipher cipher; 1550 private final int tagSize; 1551 private final Key key; 1552 private final byte[] fixedIv; 1553 private final int recordIvSize; 1554 private final SecureRandom random; 1555 1556 GcmReadCipher(Authenticator authenticator, 1557 ProtocolVersion protocolVersion, 1558 SSLCipher sslCipher, String algorithm, 1559 Key key, AlgorithmParameterSpec params, 1560 SecureRandom random) throws GeneralSecurityException { 1561 super(authenticator, protocolVersion); 1562 this.cipher = JsseJce.getCipher(algorithm); 1563 this.tagSize = sslCipher.tagSize; 1564 this.key = key; 1565 this.fixedIv = ((IvParameterSpec)params).getIV(); 1566 this.recordIvSize = sslCipher.ivSize - sslCipher.fixedIvSize; 1567 this.random = random; 1568 1569 // DON'T initialize the cipher for AEAD! 1570 } 1571 1572 @Override 1573 public Plaintext decrypt(byte contentType, ByteBuffer bb, 1574 byte[] sequence) throws GeneralSecurityException { 1575 if (bb.remaining() < (recordIvSize + tagSize)) { 1576 throw new BadPaddingException( 1577 "Insufficient buffer remaining for AEAD cipher " + 1578 "fragment (" + bb.remaining() + "). Needs to be " + 1579 "more than or equal to IV size (" + recordIvSize + 1580 ") + tag size (" + tagSize + ")"); 1581 } 1582 1583 // initialize the AEAD cipher for the unique IV 1584 byte[] iv = Arrays.copyOf(fixedIv, 1585 fixedIv.length + recordIvSize); 1586 bb.get(iv, fixedIv.length, recordIvSize); 1587 GCMParameterSpec spec = new GCMParameterSpec(tagSize * 8, iv); 1588 try { 1589 cipher.init(Cipher.DECRYPT_MODE, key, spec, random); 1590 } catch (InvalidKeyException | 1591 InvalidAlgorithmParameterException ikae) { 1592 // unlikely to happen 1593 throw new RuntimeException( 1594 "invalid key or spec in GCM mode", ikae); 1595 } 1596 1597 // update the additional authentication data 1598 byte[] aad = authenticator.acquireAuthenticationBytes( 1599 contentType, bb.remaining() - tagSize, 1600 sequence); 1601 cipher.updateAAD(aad); 1602 1603 // DON'T decrypt the nonce_explicit for AEAD mode. The buffer 1604 // position has moved out of the nonce_explicit range. 1605 int len = bb.remaining(); 1606 int pos = bb.position(); 1607 ByteBuffer dup = bb.duplicate(); 1608 try { 1609 len = cipher.doFinal(dup, bb); 1610 } catch (IllegalBlockSizeException ibse) { 1611 // unlikely to happen 1612 throw new RuntimeException( 1613 "Cipher error in AEAD mode \"" + ibse.getMessage() + 1614 " \"in JCE provider " + cipher.getProvider().getName()); 1615 } catch (ShortBufferException sbe) { 1616 // catch BouncyCastle buffering error 1617 throw new RuntimeException("Cipher buffering error in " + 1618 "JCE provider " + cipher.getProvider().getName(), sbe); 1619 } 1620 // reset the limit to the end of the decryted data 1621 bb.position(pos); 1622 bb.limit(pos + len); 1623 1624 if (SSLLogger.isOn && SSLLogger.isOn("plaintext")) { 1625 SSLLogger.fine( 1626 "Plaintext after DECRYPTION", bb.duplicate()); 1627 } 1628 1629 return new Plaintext(contentType, 1630 ProtocolVersion.NONE.major, ProtocolVersion.NONE.minor, 1631 -1, -1L, bb.slice()); 1632 } 1633 1634 @Override 1635 void dispose() { 1636 if (cipher != null) { 1637 try { 1638 cipher.doFinal(); 1639 } catch (Exception e) { 1640 // swallow all types of exceptions. 1641 } 1642 } 1643 } 1644 1645 @Override 1646 int estimateFragmentSize(int packetSize, int headerSize) { 1647 return packetSize - headerSize - recordIvSize - tagSize; 1648 } 1649 } 1650 } 1651 1652 private static final 1653 class T12GcmWriteCipherGenerator implements WriteCipherGenerator { 1654 @Override 1655 public SSLWriteCipher createCipher(SSLCipher sslCipher, 1656 Authenticator authenticator, 1657 ProtocolVersion protocolVersion, String algorithm, 1658 Key key, AlgorithmParameterSpec params, 1659 SecureRandom random) throws GeneralSecurityException { 1660 return new GcmWriteCipher(authenticator, protocolVersion, sslCipher, 1661 algorithm, key, params, random); 1662 } 1663 1664 private static final class GcmWriteCipher extends SSLWriteCipher { 1665 private final Cipher cipher; 1666 private final int tagSize; 1667 private final Key key; 1668 private final byte[] fixedIv; 1669 private final int recordIvSize; 1670 private final SecureRandom random; 1671 1672 GcmWriteCipher(Authenticator authenticator, 1673 ProtocolVersion protocolVersion, 1674 SSLCipher sslCipher, String algorithm, 1675 Key key, AlgorithmParameterSpec params, 1676 SecureRandom random) throws GeneralSecurityException { 1677 super(authenticator, protocolVersion); 1678 this.cipher = JsseJce.getCipher(algorithm); 1679 this.tagSize = sslCipher.tagSize; 1680 this.key = key; 1681 this.fixedIv = ((IvParameterSpec)params).getIV(); 1682 this.recordIvSize = sslCipher.ivSize - sslCipher.fixedIvSize; 1683 this.random = random; 1684 1685 // DON'T initialize the cipher for AEAD! 1686 } 1687 1688 @Override 1689 public int encrypt(byte contentType, 1690 ByteBuffer bb) { 1691 // To be unique and aware of overflow-wrap, sequence number 1692 // is used as the nonce_explicit of AEAD cipher suites. 1693 byte[] nonce = authenticator.sequenceNumber(); 1694 1695 // initialize the AEAD cipher for the unique IV 1696 byte[] iv = Arrays.copyOf(fixedIv, 1697 fixedIv.length + nonce.length); 1698 System.arraycopy(nonce, 0, iv, fixedIv.length, nonce.length); 1699 1700 GCMParameterSpec spec = new GCMParameterSpec(tagSize * 8, iv); 1701 try { 1702 cipher.init(Cipher.ENCRYPT_MODE, key, spec, random); 1703 } catch (InvalidKeyException | 1704 InvalidAlgorithmParameterException ikae) { 1705 // unlikely to happen 1706 throw new RuntimeException( 1707 "invalid key or spec in GCM mode", ikae); 1708 } 1709 1710 // Update the additional authentication data, using the 1711 // implicit sequence number of the authenticator. 1712 byte[] aad = authenticator.acquireAuthenticationBytes( 1713 contentType, bb.remaining(), null); 1714 cipher.updateAAD(aad); 1715 1716 // DON'T WORRY, the nonce spaces are considered already. 1717 bb.position(bb.position() - nonce.length); 1718 bb.put(nonce); 1719 1720 // DON'T encrypt the nonce for AEAD mode. 1721 int len = bb.remaining(); 1722 int pos = bb.position(); 1723 if (SSLLogger.isOn && SSLLogger.isOn("plaintext")) { 1724 SSLLogger.fine( 1725 "Plaintext before ENCRYPTION", 1726 bb.duplicate()); 1727 } 1728 1729 ByteBuffer dup = bb.duplicate(); 1730 int outputSize = cipher.getOutputSize(dup.remaining()); 1731 if (outputSize > bb.remaining()) { 1732 // Need to expand the limit of the output buffer for 1733 // the authentication tag. 1734 // 1735 // DON'T worry about the buffer's capacity, we have 1736 // reserved space for the authentication tag. 1737 bb.limit(pos + outputSize); 1738 } 1739 1740 try { 1741 len = cipher.doFinal(dup, bb); 1742 } catch (IllegalBlockSizeException | 1743 BadPaddingException | ShortBufferException ibse) { 1744 // unlikely to happen 1745 throw new RuntimeException( 1746 "Cipher error in AEAD mode in JCE provider " + 1747 cipher.getProvider().getName(), ibse); 1748 } 1749 1750 if (len != outputSize) { 1751 throw new RuntimeException( 1752 "Cipher buffering error in JCE provider " + 1753 cipher.getProvider().getName()); 1754 } 1755 1756 return len + nonce.length; 1757 } 1758 1759 @Override 1760 void dispose() { 1761 if (cipher != null) { 1762 try { 1763 cipher.doFinal(); 1764 } catch (Exception e) { 1765 // swallow all types of exceptions. 1766 } 1767 } 1768 } 1769 1770 @Override 1771 int getExplicitNonceSize() { 1772 return recordIvSize; 1773 } 1774 1775 @Override 1776 int calculateFragmentSize(int packetLimit, int headerSize) { 1777 return packetLimit - headerSize - recordIvSize - tagSize; 1778 } 1779 1780 @Override 1781 int calculatePacketSize(int fragmentSize, int headerSize) { 1782 return fragmentSize + headerSize + recordIvSize + tagSize; 1783 } 1784 } 1785 } 1786 1787 private static final 1788 class T13GcmReadCipherGenerator implements ReadCipherGenerator { 1789 1790 @Override 1791 public SSLReadCipher createCipher(SSLCipher sslCipher, 1792 Authenticator authenticator, ProtocolVersion protocolVersion, 1793 String algorithm, Key key, AlgorithmParameterSpec params, 1794 SecureRandom random) throws GeneralSecurityException { 1795 return new GcmReadCipher(authenticator, protocolVersion, sslCipher, 1796 algorithm, key, params, random); 1797 } 1798 1799 static final class GcmReadCipher extends SSLReadCipher { 1800 private final Cipher cipher; 1801 private final int tagSize; 1802 private final Key key; 1803 private final byte[] iv; 1804 private final SecureRandom random; 1805 1806 GcmReadCipher(Authenticator authenticator, 1807 ProtocolVersion protocolVersion, 1808 SSLCipher sslCipher, String algorithm, 1809 Key key, AlgorithmParameterSpec params, 1810 SecureRandom random) throws GeneralSecurityException { 1811 super(authenticator, protocolVersion); 1812 this.cipher = JsseJce.getCipher(algorithm); 1813 this.tagSize = sslCipher.tagSize; 1814 this.key = key; 1815 this.iv = ((IvParameterSpec)params).getIV(); 1816 this.random = random; 1817 1818 // DON'T initialize the cipher for AEAD! 1819 } 1820 1821 @Override 1822 public Plaintext decrypt(byte contentType, ByteBuffer bb, 1823 byte[] sequence) throws GeneralSecurityException { 1824 // An implementation may receive an unencrypted record of type 1825 // change_cipher_spec consisting of the single byte value 0x01 1826 // at any time after the first ClientHello message has been 1827 // sent or received and before the peer's Finished message has 1828 // been received and MUST simply drop it without further 1829 // processing. 1830 if (contentType == ContentType.CHANGE_CIPHER_SPEC.id) { 1831 return new Plaintext(contentType, 1832 ProtocolVersion.NONE.major, ProtocolVersion.NONE.minor, 1833 -1, -1L, bb.slice()); 1834 } 1835 1836 if (bb.remaining() <= tagSize) { 1837 throw new BadPaddingException( 1838 "Insufficient buffer remaining for AEAD cipher " + 1839 "fragment (" + bb.remaining() + "). Needs to be " + 1840 "more than tag size (" + tagSize + ")"); 1841 } 1842 1843 byte[] sn = sequence; 1844 if (sn == null) { 1845 sn = authenticator.sequenceNumber(); 1846 } 1847 byte[] nonce = iv.clone(); 1848 int offset = nonce.length - sn.length; 1849 for (int i = 0; i < sn.length; i++) { 1850 nonce[offset + i] ^= sn[i]; 1851 } 1852 1853 // initialize the AEAD cipher for the unique IV 1854 GCMParameterSpec spec = 1855 new GCMParameterSpec(tagSize * 8, nonce); 1856 try { 1857 cipher.init(Cipher.DECRYPT_MODE, key, spec, random); 1858 } catch (InvalidKeyException | 1859 InvalidAlgorithmParameterException ikae) { 1860 // unlikely to happen 1861 throw new RuntimeException( 1862 "invalid key or spec in GCM mode", ikae); 1863 } 1864 1865 // Update the additional authentication data, using the 1866 // implicit sequence number of the authenticator. 1867 byte[] aad = authenticator.acquireAuthenticationBytes( 1868 contentType, bb.remaining(), sn); 1869 cipher.updateAAD(aad); 1870 1871 int len = bb.remaining(); 1872 int pos = bb.position(); 1873 ByteBuffer dup = bb.duplicate(); 1874 try { 1875 len = cipher.doFinal(dup, bb); 1876 } catch (IllegalBlockSizeException ibse) { 1877 // unlikely to happen 1878 throw new RuntimeException( 1879 "Cipher error in AEAD mode \"" + ibse.getMessage() + 1880 " \"in JCE provider " + cipher.getProvider().getName()); 1881 } catch (ShortBufferException sbe) { 1882 // catch BouncyCastle buffering error 1883 throw new RuntimeException("Cipher buffering error in " + 1884 "JCE provider " + cipher.getProvider().getName(), sbe); 1885 } 1886 // reset the limit to the end of the decryted data 1887 bb.position(pos); 1888 bb.limit(pos + len); 1889 1890 // remove inner plaintext padding 1891 int i = bb.limit() - 1; 1892 for (; i > 0 && bb.get(i) == 0; i--) { 1893 // blank 1894 } 1895 if (i < (pos + 1)) { 1896 throw new BadPaddingException( 1897 "Incorrect inner plaintext: no content type"); 1898 } 1899 contentType = bb.get(i); 1900 bb.limit(i); 1901 1902 if (SSLLogger.isOn && SSLLogger.isOn("plaintext")) { 1903 SSLLogger.fine( 1904 "Plaintext after DECRYPTION", bb.duplicate()); 1905 } 1906 1907 return new Plaintext(contentType, 1908 ProtocolVersion.NONE.major, ProtocolVersion.NONE.minor, 1909 -1, -1L, bb.slice()); 1910 } 1911 1912 @Override 1913 void dispose() { 1914 if (cipher != null) { 1915 try { 1916 cipher.doFinal(); 1917 } catch (Exception e) { 1918 // swallow all types of exceptions. 1919 } 1920 } 1921 } 1922 1923 @Override 1924 int estimateFragmentSize(int packetSize, int headerSize) { 1925 return packetSize - headerSize - tagSize; 1926 } 1927 } 1928 } 1929 1930 private static final 1931 class T13GcmWriteCipherGenerator implements WriteCipherGenerator { 1932 @Override 1933 public SSLWriteCipher createCipher(SSLCipher sslCipher, 1934 Authenticator authenticator, ProtocolVersion protocolVersion, 1935 String algorithm, Key key, AlgorithmParameterSpec params, 1936 SecureRandom random) throws GeneralSecurityException { 1937 return new GcmWriteCipher(authenticator, protocolVersion, sslCipher, 1938 algorithm, key, params, random); 1939 } 1940 1941 private static final class GcmWriteCipher extends SSLWriteCipher { 1942 private final Cipher cipher; 1943 private final int tagSize; 1944 private final Key key; 1945 private final byte[] iv; 1946 private final SecureRandom random; 1947 1948 GcmWriteCipher(Authenticator authenticator, 1949 ProtocolVersion protocolVersion, 1950 SSLCipher sslCipher, String algorithm, 1951 Key key, AlgorithmParameterSpec params, 1952 SecureRandom random) throws GeneralSecurityException { 1953 super(authenticator, protocolVersion); 1954 this.cipher = JsseJce.getCipher(algorithm); 1955 this.tagSize = sslCipher.tagSize; 1956 this.key = key; 1957 this.iv = ((IvParameterSpec)params).getIV(); 1958 this.random = random; 1959 1960 keyLimitCountdown = cipherLimits.getOrDefault( 1961 algorithm.toUpperCase() + ":" + tag[0], 0L); 1962 if (SSLLogger.isOn && SSLLogger.isOn("ssl")) { 1963 SSLLogger.fine("algorithm = " + algorithm.toUpperCase() + 1964 ":" + tag[0] + "\ncountdown value = " + 1965 keyLimitCountdown); 1966 } 1967 if (keyLimitCountdown > 0) { 1968 keyLimitEnabled = true; 1969 } 1970 1971 // DON'T initialize the cipher for AEAD! 1972 } 1973 1974 @Override 1975 public int encrypt(byte contentType, 1976 ByteBuffer bb) { 1977 byte[] sn = authenticator.sequenceNumber(); 1978 byte[] nonce = iv.clone(); 1979 int offset = nonce.length - sn.length; 1980 for (int i = 0; i < sn.length; i++) { 1981 nonce[offset + i] ^= sn[i]; 1982 } 1983 1984 // initialize the AEAD cipher for the unique IV 1985 GCMParameterSpec spec = 1986 new GCMParameterSpec(tagSize * 8, nonce); 1987 try { 1988 cipher.init(Cipher.ENCRYPT_MODE, key, spec, random); 1989 } catch (InvalidKeyException | 1990 InvalidAlgorithmParameterException ikae) { 1991 // unlikely to happen 1992 throw new RuntimeException( 1993 "invalid key or spec in GCM mode", ikae); 1994 } 1995 1996 // Update the additional authentication data, using the 1997 // implicit sequence number of the authenticator. 1998 int outputSize = cipher.getOutputSize(bb.remaining()); 1999 byte[] aad = authenticator.acquireAuthenticationBytes( 2000 contentType, outputSize, sn); 2001 cipher.updateAAD(aad); 2002 2003 int len = bb.remaining(); 2004 int pos = bb.position(); 2005 if (SSLLogger.isOn && SSLLogger.isOn("plaintext")) { 2006 SSLLogger.fine( 2007 "Plaintext before ENCRYPTION", 2008 bb.duplicate()); 2009 } 2010 2011 ByteBuffer dup = bb.duplicate(); 2012 if (outputSize > bb.remaining()) { 2013 // Need to expand the limit of the output buffer for 2014 // the authentication tag. 2015 // 2016 // DON'T worry about the buffer's capacity, we have 2017 // reserved space for the authentication tag. 2018 bb.limit(pos + outputSize); 2019 } 2020 2021 try { 2022 len = cipher.doFinal(dup, bb); 2023 } catch (IllegalBlockSizeException | 2024 BadPaddingException | ShortBufferException ibse) { 2025 // unlikely to happen 2026 throw new RuntimeException( 2027 "Cipher error in AEAD mode in JCE provider " + 2028 cipher.getProvider().getName(), ibse); 2029 } 2030 2031 if (len != outputSize) { 2032 throw new RuntimeException( 2033 "Cipher buffering error in JCE provider " + 2034 cipher.getProvider().getName()); 2035 } 2036 2037 if (keyLimitEnabled) { 2038 keyLimitCountdown -= len; 2039 } 2040 return len; 2041 } 2042 2043 @Override 2044 void dispose() { 2045 if (cipher != null) { 2046 try { 2047 cipher.doFinal(); 2048 } catch (Exception e) { 2049 // swallow all types of exceptions. 2050 } 2051 } 2052 } 2053 2054 @Override 2055 int getExplicitNonceSize() { 2056 return 0; 2057 } 2058 2059 @Override 2060 int calculateFragmentSize(int packetLimit, int headerSize) { 2061 return packetLimit - headerSize - tagSize; 2062 } 2063 2064 @Override 2065 int calculatePacketSize(int fragmentSize, int headerSize) { 2066 return fragmentSize + headerSize + tagSize; 2067 } 2068 } 2069 } 2070 2071 private static void addMac(MAC signer, 2072 ByteBuffer destination, byte contentType) { 2073 if (signer.macAlg().size != 0) { 2074 int dstContent = destination.position(); 2075 byte[] hash = signer.compute(contentType, destination, false); 2076 2077 /* 2078 * position was advanced to limit in MAC compute above. 2079 * 2080 * Mark next area as writable (above layers should have 2081 * established that we have plenty of room), then write 2082 * out the hash. 2083 */ 2084 destination.limit(destination.limit() + hash.length); 2085 destination.put(hash); 2086 2087 // reset the position and limit 2088 destination.position(dstContent); 2089 } 2090 } 2091 2092 // for null and stream cipher 2093 private static void checkStreamMac(MAC signer, ByteBuffer bb, 2094 byte contentType, byte[] sequence) throws BadPaddingException { 2095 int tagLen = signer.macAlg().size; 2096 2097 // Requires message authentication code for null, stream and 2098 // block cipher suites. 2099 if (tagLen != 0) { 2100 int contentLen = bb.remaining() - tagLen; 2101 if (contentLen < 0) { 2102 throw new BadPaddingException("bad record"); 2103 } 2104 2105 // Run MAC computation and comparison on the payload. 2106 // 2107 // MAC data would be stripped off during the check. 2108 if (checkMacTags(contentType, bb, signer, sequence, false)) { 2109 throw new BadPaddingException("bad record MAC"); 2110 } 2111 } 2112 } 2113 2114 // for CBC cipher 2115 private static void checkCBCMac(MAC signer, ByteBuffer bb, 2116 byte contentType, int cipheredLength, 2117 byte[] sequence) throws BadPaddingException { 2118 BadPaddingException reservedBPE = null; 2119 int tagLen = signer.macAlg().size; 2120 int pos = bb.position(); 2121 2122 if (tagLen != 0) { 2123 int contentLen = bb.remaining() - tagLen; 2124 if (contentLen < 0) { 2125 reservedBPE = new BadPaddingException("bad record"); 2126 2127 // set offset of the dummy MAC 2128 contentLen = cipheredLength - tagLen; 2129 bb.limit(pos + cipheredLength); 2130 } 2131 2132 // Run MAC computation and comparison on the payload. 2133 // 2134 // MAC data would be stripped off during the check. 2135 if (checkMacTags(contentType, bb, signer, sequence, false)) { 2136 if (reservedBPE == null) { 2137 reservedBPE = 2138 new BadPaddingException("bad record MAC"); 2139 } 2140 } 2141 2142 // Run MAC computation and comparison on the remainder. 2143 int remainingLen = calculateRemainingLen( 2144 signer, cipheredLength, contentLen); 2145 2146 // NOTE: remainingLen may be bigger (less than 1 block of the 2147 // hash algorithm of the MAC) than the cipheredLength. 2148 // 2149 // Is it possible to use a static buffer, rather than allocate 2150 // it dynamically? 2151 remainingLen += signer.macAlg().size; 2152 ByteBuffer temporary = ByteBuffer.allocate(remainingLen); 2153 2154 // Won't need to worry about the result on the remainder. And 2155 // then we won't need to worry about what's actual data to 2156 // check MAC tag on. We start the check from the header of the 2157 // buffer so that we don't need to construct a new byte buffer. 2158 checkMacTags(contentType, temporary, signer, sequence, true); 2159 } 2160 2161 // Is it a failover? 2162 if (reservedBPE != null) { 2163 throw reservedBPE; 2164 } 2165 } 2166 2167 /* 2168 * Run MAC computation and comparison 2169 */ 2170 private static boolean checkMacTags(byte contentType, ByteBuffer bb, 2171 MAC signer, byte[] sequence, boolean isSimulated) { 2172 int tagLen = signer.macAlg().size; 2173 int position = bb.position(); 2174 int lim = bb.limit(); 2175 int macOffset = lim - tagLen; 2176 2177 bb.limit(macOffset); 2178 byte[] hash = signer.compute(contentType, bb, sequence, isSimulated); 2179 if (hash == null || tagLen != hash.length) { 2180 // Something is wrong with MAC implementation. 2181 throw new RuntimeException("Internal MAC error"); 2182 } 2183 2184 bb.position(macOffset); 2185 bb.limit(lim); 2186 try { 2187 int[] results = compareMacTags(bb, hash); 2188 return (results[0] != 0); 2189 } finally { 2190 // reset to the data 2191 bb.position(position); 2192 bb.limit(macOffset); 2193 } 2194 } 2195 2196 /* 2197 * A constant-time comparison of the MAC tags. 2198 * 2199 * Please DON'T change the content of the ByteBuffer parameter! 2200 */ 2201 private static int[] compareMacTags(ByteBuffer bb, byte[] tag) { 2202 // An array of hits is used to prevent Hotspot optimization for 2203 // the purpose of a constant-time check. 2204 int[] results = {0, 0}; // {missed #, matched #} 2205 2206 // The caller ensures there are enough bytes available in the buffer. 2207 // So we won't need to check the remaining of the buffer. 2208 for (int i = 0; i < tag.length; i++) { 2209 if (bb.get() != tag[i]) { 2210 results[0]++; // mismatched bytes 2211 } else { 2212 results[1]++; // matched bytes 2213 } 2214 } 2215 2216 return results; 2217 } 2218 2219 /* 2220 * Calculate the length of a dummy buffer to run MAC computation 2221 * and comparison on the remainder. 2222 * 2223 * The caller MUST ensure that the fullLen is not less than usedLen. 2224 */ 2225 private static int calculateRemainingLen( 2226 MAC signer, int fullLen, int usedLen) { 2227 2228 int blockLen = signer.macAlg().hashBlockSize; 2229 int minimalPaddingLen = signer.macAlg().minimalPaddingSize; 2230 2231 // (blockLen - minimalPaddingLen) is the maximum message size of 2232 // the last block of hash function operation. See FIPS 180-4, or 2233 // MD5 specification. 2234 fullLen += 13 - (blockLen - minimalPaddingLen); 2235 usedLen += 13 - (blockLen - minimalPaddingLen); 2236 2237 // Note: fullLen is always not less than usedLen, and blockLen 2238 // is always bigger than minimalPaddingLen, so we don't worry 2239 // about negative values. 0x01 is added to the result to ensure 2240 // that the return value is positive. The extra one byte does 2241 // not impact the overall MAC compression function evaluations. 2242 return 0x01 + (int)(Math.ceil(fullLen/(1.0d * blockLen)) - 2243 Math.ceil(usedLen/(1.0d * blockLen))) * blockLen; 2244 } 2245 2246 private static int addPadding(ByteBuffer bb, int blockSize) { 2247 2248 int len = bb.remaining(); 2249 int offset = bb.position(); 2250 2251 int newlen = len + 1; 2252 byte pad; 2253 int i; 2254 2255 if ((newlen % blockSize) != 0) { 2256 newlen += blockSize - 1; 2257 newlen -= newlen % blockSize; 2258 } 2259 pad = (byte) (newlen - len); 2260 2261 /* 2262 * Update the limit to what will be padded. 2263 */ 2264 bb.limit(newlen + offset); 2265 2266 /* 2267 * TLS version of the padding works for both SSLv3 and TLSv1 2268 */ 2269 for (i = 0, offset += len; i < pad; i++) { 2270 bb.put(offset++, (byte) (pad - 1)); 2271 } 2272 2273 bb.position(offset); 2274 bb.limit(offset); 2275 2276 return newlen; 2277 } 2278 2279 private static int removePadding(ByteBuffer bb, 2280 int tagLen, int blockSize, 2281 ProtocolVersion protocolVersion) throws BadPaddingException { 2282 int len = bb.remaining(); 2283 int offset = bb.position(); 2284 2285 // last byte is length byte (i.e. actual padding length - 1) 2286 int padOffset = offset + len - 1; 2287 int padLen = bb.get(padOffset) & 0xFF; 2288 2289 int newLen = len - (padLen + 1); 2290 if ((newLen - tagLen) < 0) { 2291 // If the buffer is not long enough to contain the padding plus 2292 // a MAC tag, do a dummy constant-time padding check. 2293 // 2294 // Note that it is a dummy check, so we won't care about what is 2295 // the actual padding data. 2296 checkPadding(bb.duplicate(), (byte)(padLen & 0xFF)); 2297 2298 throw new BadPaddingException("Invalid Padding length: " + padLen); 2299 } 2300 2301 // The padding data should be filled with the padding length value. 2302 int[] results = checkPadding( 2303 bb.duplicate().position(offset + newLen), 2304 (byte)(padLen & 0xFF)); 2305 if (protocolVersion.useTLS10PlusSpec()) { 2306 if (results[0] != 0) { // padding data has invalid bytes 2307 throw new BadPaddingException("Invalid TLS padding data"); 2308 } 2309 } else { // SSLv3 2310 // SSLv3 requires 0 <= length byte < block size 2311 // some implementations do 1 <= length byte <= block size, 2312 // so accept that as well 2313 // v3 does not require any particular value for the other bytes 2314 if (padLen > blockSize) { 2315 throw new BadPaddingException("Padding length (" + 2316 padLen + ") of SSLv3 message should not be bigger " + 2317 "than the block size (" + blockSize + ")"); 2318 } 2319 } 2320 2321 // Reset buffer limit to remove padding. 2322 bb.limit(offset + newLen); 2323 2324 return newLen; 2325 } 2326 2327 /* 2328 * A constant-time check of the padding. 2329 * 2330 * NOTE that we are checking both the padding and the padLen bytes here. 2331 * 2332 * The caller MUST ensure that the bb parameter has remaining. 2333 */ 2334 private static int[] checkPadding(ByteBuffer bb, byte pad) { 2335 if (!bb.hasRemaining()) { 2336 throw new RuntimeException("hasRemaining() must be positive"); 2337 } 2338 2339 // An array of hits is used to prevent Hotspot optimization for 2340 // the purpose of a constant-time check. 2341 int[] results = {0, 0}; // {missed #, matched #} 2342 bb.mark(); 2343 for (int i = 0; i <= 256; bb.reset()) { 2344 for (; bb.hasRemaining() && i <= 256; i++) { 2345 if (bb.get() != pad) { 2346 results[0]++; // mismatched padding data 2347 } else { 2348 results[1]++; // matched padding data 2349 } 2350 } 2351 } 2352 2353 return results; 2354 } 2355 } 2356 |