1 /* 2 * Copyright (c) 2002, 2016, 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 com.sun.crypto.provider; 27 28 import java.security.*; 29 import java.security.spec.*; 30 import javax.crypto.*; 31 import javax.crypto.spec.*; 32 import javax.crypto.BadPaddingException; 33 import java.nio.ByteBuffer; 34 35 /** 36 * This class implements the AES algorithm in its various modes 37 * (<code>ECB</code>, <code>CFB</code>, <code>OFB</code>, <code>CBC</code>, 38 * <code>PCBC</code>) and padding schemes (<code>PKCS5Padding</code>, 39 * <code>NoPadding</code>, <code>ISO10126Padding</code>). 40 * 41 * @author Valerie Peng 42 * 43 * 44 * @see AESCrypt 45 * @see CipherBlockChaining 46 * @see ElectronicCodeBook 47 * @see CipherFeedback 48 * @see OutputFeedback 49 */ 50 51 abstract class AESCipher extends CipherSpi { 52 public static final class General extends AESCipher { 53 public General() { 54 super(-1); 55 } 56 } 57 abstract static class OidImpl extends AESCipher { 58 protected OidImpl(int keySize, String mode, String padding) { 59 super(keySize); 60 try { 61 engineSetMode(mode); 62 engineSetPadding(padding); 63 } catch (GeneralSecurityException gse) { 64 // internal error; re-throw as provider exception 65 ProviderException pe =new ProviderException("Internal Error"); 66 pe.initCause(gse); 67 throw pe; 68 } 69 } 70 } 71 public static final class AES128_ECB_NoPadding extends OidImpl { 72 public AES128_ECB_NoPadding() { 73 super(16, "ECB", "NOPADDING"); 74 } 75 } 76 public static final class AES192_ECB_NoPadding extends OidImpl { 77 public AES192_ECB_NoPadding() { 78 super(24, "ECB", "NOPADDING"); 79 } 80 } 81 public static final class AES256_ECB_NoPadding extends OidImpl { 82 public AES256_ECB_NoPadding() { 83 super(32, "ECB", "NOPADDING"); 84 } 85 } 86 public static final class AES128_CBC_NoPadding extends OidImpl { 87 public AES128_CBC_NoPadding() { 88 super(16, "CBC", "NOPADDING"); 89 } 90 } 91 public static final class AES192_CBC_NoPadding extends OidImpl { 92 public AES192_CBC_NoPadding() { 93 super(24, "CBC", "NOPADDING"); 94 } 95 } 96 public static final class AES256_CBC_NoPadding extends OidImpl { 97 public AES256_CBC_NoPadding() { 98 super(32, "CBC", "NOPADDING"); 99 } 100 } 101 public static final class AES128_OFB_NoPadding extends OidImpl { 102 public AES128_OFB_NoPadding() { 103 super(16, "OFB", "NOPADDING"); 104 } 105 } 106 public static final class AES192_OFB_NoPadding extends OidImpl { 107 public AES192_OFB_NoPadding() { 108 super(24, "OFB", "NOPADDING"); 109 } 110 } 111 public static final class AES256_OFB_NoPadding extends OidImpl { 112 public AES256_OFB_NoPadding() { 113 super(32, "OFB", "NOPADDING"); 114 } 115 } 116 public static final class AES128_CFB_NoPadding extends OidImpl { 117 public AES128_CFB_NoPadding() { 118 super(16, "CFB", "NOPADDING"); 119 } 120 } 121 public static final class AES192_CFB_NoPadding extends OidImpl { 122 public AES192_CFB_NoPadding() { 123 super(24, "CFB", "NOPADDING"); 124 } 125 } 126 public static final class AES256_CFB_NoPadding extends OidImpl { 127 public AES256_CFB_NoPadding() { 128 super(32, "CFB", "NOPADDING"); 129 } 130 } 131 public static final class AES128_GCM_NoPadding extends OidImpl { 132 public AES128_GCM_NoPadding() { 133 super(16, "GCM", "NOPADDING"); 134 } 135 } 136 public static final class AES192_GCM_NoPadding extends OidImpl { 137 public AES192_GCM_NoPadding() { 138 super(24, "GCM", "NOPADDING"); 139 } 140 } 141 public static final class AES256_GCM_NoPadding extends OidImpl { 142 public AES256_GCM_NoPadding() { 143 super(32, "GCM", "NOPADDING"); 144 } 145 } 146 147 // utility method used by AESCipher and AESWrapCipher 148 static final void checkKeySize(Key key, int fixedKeySize) 149 throws InvalidKeyException { 150 if (fixedKeySize != -1) { 151 if (key == null) { 152 throw new InvalidKeyException("The key must not be null"); 153 } 154 byte[] value = key.getEncoded(); 155 if (value == null) { 156 throw new InvalidKeyException("Key encoding must not be null"); 157 } else if (value.length != fixedKeySize) { 158 throw new InvalidKeyException("The key must be " + 159 fixedKeySize*8 + " bits"); 160 } 161 } 162 } 163 164 /* 165 * internal CipherCore object which does the real work. 166 */ 167 private CipherCore core = null; 168 169 /* 170 * needed to support AES oids which associates a fixed key size 171 * to the cipher object. 172 */ 173 private final int fixedKeySize; // in bytes, -1 if no restriction 174 175 /* 176 * needed to enforce ISE thrown when updateAAD is called after update for GCM mode. 177 */ 178 private boolean updateCalled; 179 180 /** 181 * Creates an instance of AES cipher with default ECB mode and 182 * PKCS5Padding. 183 */ 184 protected AESCipher(int keySize) { 185 core = new CipherCore(new AESCrypt(), AESConstants.AES_BLOCK_SIZE); 186 fixedKeySize = keySize; 187 } 188 189 /** 190 * Sets the mode of this cipher. 191 * 192 * @param mode the cipher mode 193 * 194 * @exception NoSuchAlgorithmException if the requested cipher mode does 195 * not exist 196 */ 197 protected void engineSetMode(String mode) 198 throws NoSuchAlgorithmException { 199 core.setMode(mode); 200 } 201 202 /** 203 * Sets the padding mechanism of this cipher. 204 * 205 * @param padding the padding mechanism 206 * 207 * @exception NoSuchPaddingException if the requested padding mechanism 208 * does not exist 209 */ 210 protected void engineSetPadding(String paddingScheme) 211 throws NoSuchPaddingException { 212 core.setPadding(paddingScheme); 213 } 214 215 /** 216 * Returns the block size (in bytes). 217 * 218 * @return the block size (in bytes), or 0 if the underlying algorithm is 219 * not a block cipher 220 */ 221 protected int engineGetBlockSize() { 222 return AESConstants.AES_BLOCK_SIZE; 223 } 224 225 /** 226 * Returns the length in bytes that an output buffer would need to be in 227 * order to hold the result of the next <code>update</code> or 228 * <code>doFinal</code> operation, given the input length 229 * <code>inputLen</code> (in bytes). 230 * 231 * <p>This call takes into account any unprocessed (buffered) data from a 232 * previous <code>update</code> call, and padding. 233 * 234 * <p>The actual output length of the next <code>update</code> or 235 * <code>doFinal</code> call may be smaller than the length returned by 236 * this method. 237 * 238 * @param inputLen the input length (in bytes) 239 * 240 * @return the required output buffer size (in bytes) 241 */ 242 protected int engineGetOutputSize(int inputLen) { 243 return core.getOutputSize(inputLen); 244 } 245 246 /** 247 * Returns the initialization vector (IV) in a new buffer. 248 * 249 * <p>This is useful in the case where a random IV has been created 250 * (see <a href = "#init">init</a>), 251 * or in the context of password-based encryption or 252 * decryption, where the IV is derived from a user-provided password. 253 * 254 * @return the initialization vector in a new buffer, or null if the 255 * underlying algorithm does not use an IV, or if the IV has not yet 256 * been set. 257 */ 258 protected byte[] engineGetIV() { 259 return core.getIV(); 260 } 261 262 /** 263 * Returns the parameters used with this cipher. 264 * 265 * <p>The returned parameters may be the same that were used to initialize 266 * this cipher, or may contain the default set of parameters or a set of 267 * randomly generated parameters used by the underlying cipher 268 * implementation (provided that the underlying cipher implementation 269 * uses a default set of parameters or creates new parameters if it needs 270 * parameters but was not initialized with any). 271 * 272 * @return the parameters used with this cipher, or null if this cipher 273 * does not use any parameters. 274 */ 275 protected AlgorithmParameters engineGetParameters() { 276 return core.getParameters("AES"); 277 } 278 279 /** 280 * Initializes this cipher with a key and a source of randomness. 281 * 282 * <p>The cipher is initialized for one of the following four operations: 283 * encryption, decryption, key wrapping or key unwrapping, depending on 284 * the value of <code>opmode</code>. 285 * 286 * <p>If this cipher requires an initialization vector (IV), it will get 287 * it from <code>random</code>. 288 * This behaviour should only be used in encryption or key wrapping 289 * mode, however. 290 * When initializing a cipher that requires an IV for decryption or 291 * key unwrapping, the IV 292 * (same IV that was used for encryption or key wrapping) must be provided 293 * explicitly as a 294 * parameter, in order to get the correct result. 295 * 296 * <p>This method also cleans existing buffer and other related state 297 * information. 298 * 299 * @param opmode the operation mode of this cipher (this is one of 300 * the following: 301 * <code>ENCRYPT_MODE</code>, <code>DECRYPT_MODE</code>, 302 * <code>WRAP_MODE</code> or <code>UNWRAP_MODE</code>) 303 * @param key the secret key 304 * @param random the source of randomness 305 * 306 * @exception InvalidKeyException if the given key is inappropriate for 307 * initializing this cipher 308 */ 309 protected void engineInit(int opmode, Key key, SecureRandom random) 310 throws InvalidKeyException { 311 checkKeySize(key, fixedKeySize); 312 updateCalled = false; 313 core.init(opmode, key, random); 314 } 315 316 /** 317 * Initializes this cipher with a key, a set of 318 * algorithm parameters, and a source of randomness. 319 * 320 * <p>The cipher is initialized for one of the following four operations: 321 * encryption, decryption, key wrapping or key unwrapping, depending on 322 * the value of <code>opmode</code>. 323 * 324 * <p>If this cipher (including its underlying feedback or padding scheme) 325 * requires any random bytes, it will get them from <code>random</code>. 326 * 327 * @param opmode the operation mode of this cipher (this is one of 328 * the following: 329 * <code>ENCRYPT_MODE</code>, <code>DECRYPT_MODE</code>, 330 * <code>WRAP_MODE</code> or <code>UNWRAP_MODE</code>) 331 * @param key the encryption key 332 * @param params the algorithm parameters 333 * @param random the source of randomness 334 * 335 * @exception InvalidKeyException if the given key is inappropriate for 336 * initializing this cipher 337 * @exception InvalidAlgorithmParameterException if the given algorithm 338 * parameters are inappropriate for this cipher 339 */ 340 protected void engineInit(int opmode, Key key, 341 AlgorithmParameterSpec params, 342 SecureRandom random) 343 throws InvalidKeyException, InvalidAlgorithmParameterException { 344 checkKeySize(key, fixedKeySize); 345 updateCalled = false; 346 core.init(opmode, key, params, random); 347 } 348 349 protected void engineInit(int opmode, Key key, 350 AlgorithmParameters params, 351 SecureRandom random) 352 throws InvalidKeyException, InvalidAlgorithmParameterException { 353 checkKeySize(key, fixedKeySize); 354 updateCalled = false; 355 core.init(opmode, key, params, random); 356 } 357 358 /** 359 * Continues a multiple-part encryption or decryption operation 360 * (depending on how this cipher was initialized), processing another data 361 * part. 362 * 363 * <p>The first <code>inputLen</code> bytes in the <code>input</code> 364 * buffer, starting at <code>inputOffset</code>, are processed, and the 365 * result is stored in a new buffer. 366 * 367 * @param input the input buffer 368 * @param inputOffset the offset in <code>input</code> where the input 369 * starts 370 * @param inputLen the input length 371 * 372 * @return the new buffer with the result 373 * 374 * @exception IllegalStateException if this cipher is in a wrong state 375 * (e.g., has not been initialized) 376 */ 377 protected byte[] engineUpdate(byte[] input, int inputOffset, 378 int inputLen) { 379 updateCalled = true; 380 return core.update(input, inputOffset, inputLen); 381 } 382 383 /** 384 * Continues a multiple-part encryption or decryption operation 385 * (depending on how this cipher was initialized), processing another data 386 * part. 387 * 388 * <p>The first <code>inputLen</code> bytes in the <code>input</code> 389 * buffer, starting at <code>inputOffset</code>, are processed, and the 390 * result is stored in the <code>output</code> buffer, starting at 391 * <code>outputOffset</code>. 392 * 393 * @param input the input buffer 394 * @param inputOffset the offset in <code>input</code> where the input 395 * starts 396 * @param inputLen the input length 397 * @param output the buffer for the result 398 * @param outputOffset the offset in <code>output</code> where the result 399 * is stored 400 * 401 * @return the number of bytes stored in <code>output</code> 402 * 403 * @exception ShortBufferException if the given output buffer is too small 404 * to hold the result 405 */ 406 protected int engineUpdate(byte[] input, int inputOffset, int inputLen, 407 byte[] output, int outputOffset) 408 throws ShortBufferException { 409 updateCalled = true; 410 return core.update(input, inputOffset, inputLen, output, 411 outputOffset); 412 } 413 414 /** 415 * Encrypts or decrypts data in a single-part operation, 416 * or finishes a multiple-part operation. 417 * The data is encrypted or decrypted, depending on how this cipher was 418 * initialized. 419 * 420 * <p>The first <code>inputLen</code> bytes in the <code>input</code> 421 * buffer, starting at <code>inputOffset</code>, and any input bytes that 422 * may have been buffered during a previous <code>update</code> operation, 423 * are processed, with padding (if requested) being applied. 424 * The result is stored in a new buffer. 425 * 426 * <p>The cipher is reset to its initial state (uninitialized) after this 427 * call. 428 * 429 * @param input the input buffer 430 * @param inputOffset the offset in <code>input</code> where the input 431 * starts 432 * @param inputLen the input length 433 * 434 * @return the new buffer with the result 435 * 436 * @exception IllegalBlockSizeException if this cipher is a block cipher, 437 * no padding has been requested (only in encryption mode), and the total 438 * input length of the data processed by this cipher is not a multiple of 439 * block size 440 * @exception BadPaddingException if this cipher is in decryption mode, 441 * and (un)padding has been requested, but the decrypted data is not 442 * bounded by the appropriate padding bytes 443 */ 444 protected byte[] engineDoFinal(byte[] input, int inputOffset, int inputLen) 445 throws IllegalBlockSizeException, BadPaddingException { 446 byte[] out = core.doFinal(input, inputOffset, inputLen); 447 updateCalled = false; 448 return out; 449 } 450 451 /** 452 * Encrypts or decrypts data in a single-part operation, 453 * or finishes a multiple-part operation. 454 * The data is encrypted or decrypted, depending on how this cipher was 455 * initialized. 456 * 457 * <p>The first <code>inputLen</code> bytes in the <code>input</code> 458 * buffer, starting at <code>inputOffset</code>, and any input bytes that 459 * may have been buffered during a previous <code>update</code> operation, 460 * are processed, with padding (if requested) being applied. 461 * The result is stored in the <code>output</code> buffer, starting at 462 * <code>outputOffset</code>. 463 * 464 * <p>The cipher is reset to its initial state (uninitialized) after this 465 * call. 466 * 467 * @param input the input buffer 468 * @param inputOffset the offset in <code>input</code> where the input 469 * starts 470 * @param inputLen the input length 471 * @param output the buffer for the result 472 * @param outputOffset the offset in <code>output</code> where the result 473 * is stored 474 * 475 * @return the number of bytes stored in <code>output</code> 476 * 477 * @exception IllegalBlockSizeException if this cipher is a block cipher, 478 * no padding has been requested (only in encryption mode), and the total 479 * input length of the data processed by this cipher is not a multiple of 480 * block size 481 * @exception ShortBufferException if the given output buffer is too small 482 * to hold the result 483 * @exception BadPaddingException if this cipher is in decryption mode, 484 * and (un)padding has been requested, but the decrypted data is not 485 * bounded by the appropriate padding bytes 486 */ 487 protected int engineDoFinal(byte[] input, int inputOffset, int inputLen, 488 byte[] output, int outputOffset) 489 throws IllegalBlockSizeException, ShortBufferException, 490 BadPaddingException { 491 int outLen = core.doFinal(input, inputOffset, inputLen, output, 492 outputOffset); 493 updateCalled = false; 494 return outLen; 495 } 496 497 /** 498 * Returns the key size of the given key object. 499 * 500 * @param key the key object. 501 * 502 * @return the key size of the given key object. 503 * 504 * @exception InvalidKeyException if <code>key</code> is invalid. 505 */ 506 protected int engineGetKeySize(Key key) throws InvalidKeyException { 507 byte[] encoded = key.getEncoded(); 508 if (!AESCrypt.isKeySizeValid(encoded.length)) { 509 throw new InvalidKeyException("Invalid AES key length: " + 510 encoded.length + " bytes"); 511 } 512 return encoded.length * 8; 513 } 514 515 /** 516 * Wrap a key. 517 * 518 * @param key the key to be wrapped. 519 * 520 * @return the wrapped key. 521 * 522 * @exception IllegalBlockSizeException if this cipher is a block 523 * cipher, no padding has been requested, and the length of the 524 * encoding of the key to be wrapped is not a 525 * multiple of the block size. 526 * 527 * @exception InvalidKeyException if it is impossible or unsafe to 528 * wrap the key with this cipher (e.g., a hardware protected key is 529 * being passed to a software only cipher). 530 */ 531 protected byte[] engineWrap(Key key) 532 throws IllegalBlockSizeException, InvalidKeyException { 533 return core.wrap(key); 534 } 535 536 /** 537 * Unwrap a previously wrapped key. 538 * 539 * @param wrappedKey the key to be unwrapped. 540 * 541 * @param wrappedKeyAlgorithm the algorithm the wrapped key is for. 542 * 543 * @param wrappedKeyType the type of the wrapped key. 544 * This is one of <code>Cipher.SECRET_KEY</code>, 545 * <code>Cipher.PRIVATE_KEY</code>, or <code>Cipher.PUBLIC_KEY</code>. 546 * 547 * @return the unwrapped key. 548 * 549 * @exception NoSuchAlgorithmException if no installed providers 550 * can create keys of type <code>wrappedKeyType</code> for the 551 * <code>wrappedKeyAlgorithm</code>. 552 * 553 * @exception InvalidKeyException if <code>wrappedKey</code> does not 554 * represent a wrapped key of type <code>wrappedKeyType</code> for 555 * the <code>wrappedKeyAlgorithm</code>. 556 */ 557 protected Key engineUnwrap(byte[] wrappedKey, 558 String wrappedKeyAlgorithm, 559 int wrappedKeyType) 560 throws InvalidKeyException, NoSuchAlgorithmException { 561 return core.unwrap(wrappedKey, wrappedKeyAlgorithm, 562 wrappedKeyType); 563 } 564 565 /** 566 * Continues a multi-part update of the Additional Authentication 567 * Data (AAD), using a subset of the provided buffer. 568 * <p> 569 * Calls to this method provide AAD to the cipher when operating in 570 * modes such as AEAD (GCM/CCM). If this cipher is operating in 571 * either GCM or CCM mode, all AAD must be supplied before beginning 572 * operations on the ciphertext (via the {@code update} and {@code 573 * doFinal} methods). 574 * 575 * @param src the buffer containing the AAD 576 * @param offset the offset in {@code src} where the AAD input starts 577 * @param len the number of AAD bytes 578 * 579 * @throws IllegalStateException if this cipher is in a wrong state 580 * (e.g., has not been initialized), does not accept AAD, or if 581 * operating in either GCM or CCM mode and one of the {@code update} 582 * methods has already been called for the active 583 * encryption/decryption operation 584 * @throws UnsupportedOperationException if this method 585 * has not been overridden by an implementation 586 * 587 * @since 1.8 588 */ 589 @Override 590 protected void engineUpdateAAD(byte[] src, int offset, int len) { 591 if (core.getMode() == CipherCore.GCM_MODE && updateCalled) { 592 throw new IllegalStateException("AAD must be supplied before encryption/decryption starts"); 593 } 594 core.updateAAD(src, offset, len); 595 } 596 597 /** 598 * Continues a multi-part update of the Additional Authentication 599 * Data (AAD). 600 * <p> 601 * Calls to this method provide AAD to the cipher when operating in 602 * modes such as AEAD (GCM/CCM). If this cipher is operating in 603 * either GCM or CCM mode, all AAD must be supplied before beginning 604 * operations on the ciphertext (via the {@code update} and {@code 605 * doFinal} methods). 606 * <p> 607 * All {@code src.remaining()} bytes starting at 608 * {@code src.position()} are processed. 609 * Upon return, the input buffer's position will be equal 610 * to its limit; its limit will not have changed. 611 * 612 * @param src the buffer containing the AAD 613 * 614 * @throws IllegalStateException if this cipher is in a wrong state 615 * (e.g., has not been initialized), does not accept AAD, or if 616 * operating in either GCM or CCM mode and one of the {@code update} 617 * methods has already been called for the active 618 * encryption/decryption operation 619 * @throws UnsupportedOperationException if this method 620 * has not been overridden by an implementation 621 * 622 * @since 1.8 623 */ 624 @Override 625 protected void engineUpdateAAD(ByteBuffer src) { 626 if (core.getMode() == CipherCore.GCM_MODE && updateCalled) { 627 throw new IllegalStateException("AAD must be supplied before encryption/decryption starts"); 628 } 629 if (src != null) { 630 int aadLen = src.limit() - src.position(); 631 if (aadLen != 0) { 632 if (src.hasArray()) { 633 int aadOfs = src.arrayOffset() + src.position(); 634 core.updateAAD(src.array(), aadOfs, aadLen); 635 src.position(src.limit()); 636 } else { 637 byte[] aad = new byte[aadLen]; 638 src.get(aad); 639 core.updateAAD(aad, 0, aadLen); 640 } 641 } 642 } 643 } 644 } 645