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 /* $Id: Rijndael.java,v 1.6 2000/02/10 01:31:41 gelderen Exp $
27 *
28 * Copyright (C) 1995-2000 The Cryptix Foundation Limited.
29 * All rights reserved.
30 *
31 * Use, modification, copying and distribution of this softwareas is subject
32 * the terms and conditions of the Cryptix General Licence. You should have
33 * received a copy of the Cryptix General Licence along with this library;
34 * if not, you can download a copy from http://www.cryptix.org/ .
35 */
36
37 package com.sun.crypto.provider;
38
39 import java.security.InvalidKeyException;
40 import java.util.Arrays;
41
42 /**
43 * Rijndael --pronounced Reindaal-- is a symmetric cipher with a 128-bit
44 * block size and variable key-size (128-, 192- and 256-bit).
45 * <p>
46 * Rijndael was designed by <a href="mailto:rijmen@esat.kuleuven.ac.be">Vincent
47 * Rijmen</a> and <a href="mailto:Joan.Daemen@village.uunet.be">Joan Daemen</a>.
48 */
49 final class AESCrypt extends SymmetricCipher implements AESConstants
50 {
51 private boolean ROUNDS_12 = false;
52 private boolean ROUNDS_14 = false;
53
54 /** Session and Sub keys */
55 private Object[] sessionK = null;
56 private int[] K = null;
57
58 /** Cipher encryption/decryption key */
59 // skip re-generating Session and Sub keys if the cipher key is
60 // the same
329 int a1 = (b[1] != 0) ? alog[(a + log[b[1] & 0xFF]) % 255] & 0xFF : 0;
330 int a2 = (b[2] != 0) ? alog[(a + log[b[2] & 0xFF]) % 255] & 0xFF : 0;
331 int a3 = (b[3] != 0) ? alog[(a + log[b[3] & 0xFF]) % 255] & 0xFF : 0;
332 return a0 << 24 | a1 << 16 | a2 << 8 | a3;
333 }
334
335 // check if the specified length (in bytes) is a valid keysize for AES
336 static final boolean isKeySizeValid(int len) {
337 for (int i = 0; i < AES_KEYSIZES.length; i++) {
338 if (len == AES_KEYSIZES[i]) {
339 return true;
340 }
341 }
342 return false;
343 }
344
345 /**
346 * Encrypt exactly one block of plaintext.
347 */
348 void encryptBlock(byte[] in, int inOffset,
349 byte[] out, int outOffset)
350 {
351 int keyOffset = 0;
352 int t0 = ((in[inOffset++] ) << 24 |
353 (in[inOffset++] & 0xFF) << 16 |
354 (in[inOffset++] & 0xFF) << 8 |
355 (in[inOffset++] & 0xFF) ) ^ K[keyOffset++];
356 int t1 = ((in[inOffset++] ) << 24 |
357 (in[inOffset++] & 0xFF) << 16 |
358 (in[inOffset++] & 0xFF) << 8 |
359 (in[inOffset++] & 0xFF) ) ^ K[keyOffset++];
360 int t2 = ((in[inOffset++] ) << 24 |
361 (in[inOffset++] & 0xFF) << 16 |
362 (in[inOffset++] & 0xFF) << 8 |
363 (in[inOffset++] & 0xFF) ) ^ K[keyOffset++];
364 int t3 = ((in[inOffset++] ) << 24 |
365 (in[inOffset++] & 0xFF) << 16 |
366 (in[inOffset++] & 0xFF) << 8 |
367 (in[inOffset++] & 0xFF) ) ^ K[keyOffset++];
368
395 out[outOffset++] = (byte)(S[(t1 >>> 16) & 0xFF] ^ (tt >>> 16));
396 out[outOffset++] = (byte)(S[(t2 >>> 8) & 0xFF] ^ (tt >>> 8));
397 out[outOffset++] = (byte)(S[(t3 ) & 0xFF] ^ (tt ));
398 tt = K[keyOffset++];
399 out[outOffset++] = (byte)(S[(t1 >>> 24) ] ^ (tt >>> 24));
400 out[outOffset++] = (byte)(S[(t2 >>> 16) & 0xFF] ^ (tt >>> 16));
401 out[outOffset++] = (byte)(S[(t3 >>> 8) & 0xFF] ^ (tt >>> 8));
402 out[outOffset++] = (byte)(S[(t0 ) & 0xFF] ^ (tt ));
403 tt = K[keyOffset++];
404 out[outOffset++] = (byte)(S[(t2 >>> 24) ] ^ (tt >>> 24));
405 out[outOffset++] = (byte)(S[(t3 >>> 16) & 0xFF] ^ (tt >>> 16));
406 out[outOffset++] = (byte)(S[(t0 >>> 8) & 0xFF] ^ (tt >>> 8));
407 out[outOffset++] = (byte)(S[(t1 ) & 0xFF] ^ (tt ));
408 tt = K[keyOffset++];
409 out[outOffset++] = (byte)(S[(t3 >>> 24) ] ^ (tt >>> 24));
410 out[outOffset++] = (byte)(S[(t0 >>> 16) & 0xFF] ^ (tt >>> 16));
411 out[outOffset++] = (byte)(S[(t1 >>> 8) & 0xFF] ^ (tt >>> 8));
412 out[outOffset ] = (byte)(S[(t2 ) & 0xFF] ^ (tt ));
413 }
414
415
416 /**
417 * Decrypt exactly one block of plaintext.
418 */
419 void decryptBlock(byte[] in, int inOffset,
420 byte[] out, int outOffset)
421 {
422 int keyOffset = 4;
423 int t0 = ((in[inOffset++] ) << 24 |
424 (in[inOffset++] & 0xFF) << 16 |
425 (in[inOffset++] & 0xFF) << 8 |
426 (in[inOffset++] & 0xFF) ) ^ K[keyOffset++];
427 int t1 = ((in[inOffset++] ) << 24 |
428 (in[inOffset++] & 0xFF) << 16 |
429 (in[inOffset++] & 0xFF) << 8 |
430 (in[inOffset++] & 0xFF) ) ^ K[keyOffset++];
431 int t2 = ((in[inOffset++] ) << 24 |
432 (in[inOffset++] & 0xFF) << 16 |
433 (in[inOffset++] & 0xFF) << 8 |
434 (in[inOffset++] & 0xFF) ) ^ K[keyOffset++];
435 int t3 = ((in[inOffset++] ) << 24 |
436 (in[inOffset++] & 0xFF) << 16 |
437 (in[inOffset++] & 0xFF) << 8 |
438 (in[inOffset ] & 0xFF) ) ^ K[keyOffset++];
439
555 out[outOffset++] = (byte)(Si[(t3 >>> 16) & 0xFF] ^ (t1 >>> 16));
556 out[outOffset++] = (byte)(Si[(a2 >>> 8) & 0xFF] ^ (t1 >>> 8));
557 out[outOffset++] = (byte)(Si[(a1 ) & 0xFF] ^ (t1 ));
558 t1 = K[1];
559 out[outOffset++] = (byte)(Si[(a1 >>> 24) ] ^ (t1 >>> 24));
560 out[outOffset++] = (byte)(Si[(a0 >>> 16) & 0xFF] ^ (t1 >>> 16));
561 out[outOffset++] = (byte)(Si[(t3 >>> 8) & 0xFF] ^ (t1 >>> 8));
562 out[outOffset++] = (byte)(Si[(a2 ) & 0xFF] ^ (t1 ));
563 t1 = K[2];
564 out[outOffset++] = (byte)(Si[(a2 >>> 24) ] ^ (t1 >>> 24));
565 out[outOffset++] = (byte)(Si[(a1 >>> 16) & 0xFF] ^ (t1 >>> 16));
566 out[outOffset++] = (byte)(Si[(a0 >>> 8) & 0xFF] ^ (t1 >>> 8));
567 out[outOffset++] = (byte)(Si[(t3 ) & 0xFF] ^ (t1 ));
568 t1 = K[3];
569 out[outOffset++] = (byte)(Si[(t3 >>> 24) ] ^ (t1 >>> 24));
570 out[outOffset++] = (byte)(Si[(a2 >>> 16) & 0xFF] ^ (t1 >>> 16));
571 out[outOffset++] = (byte)(Si[(a1 >>> 8) & 0xFF] ^ (t1 >>> 8));
572 out[outOffset ] = (byte)(Si[(a0 ) & 0xFF] ^ (t1 ));
573 }
574
575
576 /**
577 * Expand a user-supplied key material into a session key.
578 *
579 * @param k The 128/192/256-bit cipher key to use.
580 * @exception InvalidKeyException If the key is invalid.
581 */
582 private void makeSessionKey(byte[] k) throws InvalidKeyException {
583 if (k == null) {
584 throw new InvalidKeyException("Empty key");
585 }
586 if (!isKeySizeValid(k.length)) {
587 throw new InvalidKeyException("Invalid AES key length: " +
588 k.length + " bytes");
589 }
590 int ROUNDS = getRounds(k.length);
591 int ROUND_KEY_COUNT = (ROUNDS + 1) * 4;
592
593 int BC = 4;
594 int[][] Ke = new int[ROUNDS + 1][4]; // encryption round keys
|
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 /* $Id: Rijndael.java,v 1.6 2000/02/10 01:31:41 gelderen Exp $
27 *
28 * Copyright (C) 1995-2000 The Cryptix Foundation Limited.
29 * All rights reserved.
30 *
31 * Use, modification, copying and distribution of this softwareas is subject
32 * the terms and conditions of the Cryptix General Licence. You should have
33 * received a copy of the Cryptix General Licence along with this library;
34 * if not, you can download a copy from http://www.cryptix.org/ .
35 */
36
37 package com.sun.crypto.provider;
38
39 import java.security.InvalidKeyException;
40 import java.util.Arrays;
41 import java.util.Objects;
42
43 import jdk.internal.HotSpotIntrinsicCandidate;
44
45 /**
46 * Rijndael --pronounced Reindaal-- is a symmetric cipher with a 128-bit
47 * block size and variable key-size (128-, 192- and 256-bit).
48 * <p>
49 * Rijndael was designed by <a href="mailto:rijmen@esat.kuleuven.ac.be">Vincent
50 * Rijmen</a> and <a href="mailto:Joan.Daemen@village.uunet.be">Joan Daemen</a>.
51 */
52 final class AESCrypt extends SymmetricCipher implements AESConstants
53 {
54 private boolean ROUNDS_12 = false;
55 private boolean ROUNDS_14 = false;
56
57 /** Session and Sub keys */
58 private Object[] sessionK = null;
59 private int[] K = null;
60
61 /** Cipher encryption/decryption key */
62 // skip re-generating Session and Sub keys if the cipher key is
63 // the same
332 int a1 = (b[1] != 0) ? alog[(a + log[b[1] & 0xFF]) % 255] & 0xFF : 0;
333 int a2 = (b[2] != 0) ? alog[(a + log[b[2] & 0xFF]) % 255] & 0xFF : 0;
334 int a3 = (b[3] != 0) ? alog[(a + log[b[3] & 0xFF]) % 255] & 0xFF : 0;
335 return a0 << 24 | a1 << 16 | a2 << 8 | a3;
336 }
337
338 // check if the specified length (in bytes) is a valid keysize for AES
339 static final boolean isKeySizeValid(int len) {
340 for (int i = 0; i < AES_KEYSIZES.length; i++) {
341 if (len == AES_KEYSIZES[i]) {
342 return true;
343 }
344 }
345 return false;
346 }
347
348 /**
349 * Encrypt exactly one block of plaintext.
350 */
351 void encryptBlock(byte[] in, int inOffset,
352 byte[] out, int outOffset) {
353 cryptBlockCheck(in, inOffset);
354 cryptBlockCheck(out, outOffset);
355 implEncryptBlock(in, inOffset, out, outOffset);
356 }
357
358 // Encryption operation. Possibly replaced with a compiler intrinsic.
359 @HotSpotIntrinsicCandidate
360 private void implEncryptBlock(byte[] in, int inOffset,
361 byte[] out, int outOffset)
362 {
363 int keyOffset = 0;
364 int t0 = ((in[inOffset++] ) << 24 |
365 (in[inOffset++] & 0xFF) << 16 |
366 (in[inOffset++] & 0xFF) << 8 |
367 (in[inOffset++] & 0xFF) ) ^ K[keyOffset++];
368 int t1 = ((in[inOffset++] ) << 24 |
369 (in[inOffset++] & 0xFF) << 16 |
370 (in[inOffset++] & 0xFF) << 8 |
371 (in[inOffset++] & 0xFF) ) ^ K[keyOffset++];
372 int t2 = ((in[inOffset++] ) << 24 |
373 (in[inOffset++] & 0xFF) << 16 |
374 (in[inOffset++] & 0xFF) << 8 |
375 (in[inOffset++] & 0xFF) ) ^ K[keyOffset++];
376 int t3 = ((in[inOffset++] ) << 24 |
377 (in[inOffset++] & 0xFF) << 16 |
378 (in[inOffset++] & 0xFF) << 8 |
379 (in[inOffset++] & 0xFF) ) ^ K[keyOffset++];
380
407 out[outOffset++] = (byte)(S[(t1 >>> 16) & 0xFF] ^ (tt >>> 16));
408 out[outOffset++] = (byte)(S[(t2 >>> 8) & 0xFF] ^ (tt >>> 8));
409 out[outOffset++] = (byte)(S[(t3 ) & 0xFF] ^ (tt ));
410 tt = K[keyOffset++];
411 out[outOffset++] = (byte)(S[(t1 >>> 24) ] ^ (tt >>> 24));
412 out[outOffset++] = (byte)(S[(t2 >>> 16) & 0xFF] ^ (tt >>> 16));
413 out[outOffset++] = (byte)(S[(t3 >>> 8) & 0xFF] ^ (tt >>> 8));
414 out[outOffset++] = (byte)(S[(t0 ) & 0xFF] ^ (tt ));
415 tt = K[keyOffset++];
416 out[outOffset++] = (byte)(S[(t2 >>> 24) ] ^ (tt >>> 24));
417 out[outOffset++] = (byte)(S[(t3 >>> 16) & 0xFF] ^ (tt >>> 16));
418 out[outOffset++] = (byte)(S[(t0 >>> 8) & 0xFF] ^ (tt >>> 8));
419 out[outOffset++] = (byte)(S[(t1 ) & 0xFF] ^ (tt ));
420 tt = K[keyOffset++];
421 out[outOffset++] = (byte)(S[(t3 >>> 24) ] ^ (tt >>> 24));
422 out[outOffset++] = (byte)(S[(t0 >>> 16) & 0xFF] ^ (tt >>> 16));
423 out[outOffset++] = (byte)(S[(t1 >>> 8) & 0xFF] ^ (tt >>> 8));
424 out[outOffset ] = (byte)(S[(t2 ) & 0xFF] ^ (tt ));
425 }
426
427 /**
428 * Decrypt exactly one block of plaintext.
429 */
430 void decryptBlock(byte[] in, int inOffset,
431 byte[] out, int outOffset) {
432 cryptBlockCheck(in, inOffset);
433 cryptBlockCheck(out, outOffset);
434 implDecryptBlock(in, inOffset, out, outOffset);
435 }
436
437 // Decrypt operation. Possibly replaced with a compiler intrinsic.
438 @HotSpotIntrinsicCandidate
439 private void implDecryptBlock(byte[] in, int inOffset,
440 byte[] out, int outOffset)
441 {
442 int keyOffset = 4;
443 int t0 = ((in[inOffset++] ) << 24 |
444 (in[inOffset++] & 0xFF) << 16 |
445 (in[inOffset++] & 0xFF) << 8 |
446 (in[inOffset++] & 0xFF) ) ^ K[keyOffset++];
447 int t1 = ((in[inOffset++] ) << 24 |
448 (in[inOffset++] & 0xFF) << 16 |
449 (in[inOffset++] & 0xFF) << 8 |
450 (in[inOffset++] & 0xFF) ) ^ K[keyOffset++];
451 int t2 = ((in[inOffset++] ) << 24 |
452 (in[inOffset++] & 0xFF) << 16 |
453 (in[inOffset++] & 0xFF) << 8 |
454 (in[inOffset++] & 0xFF) ) ^ K[keyOffset++];
455 int t3 = ((in[inOffset++] ) << 24 |
456 (in[inOffset++] & 0xFF) << 16 |
457 (in[inOffset++] & 0xFF) << 8 |
458 (in[inOffset ] & 0xFF) ) ^ K[keyOffset++];
459
575 out[outOffset++] = (byte)(Si[(t3 >>> 16) & 0xFF] ^ (t1 >>> 16));
576 out[outOffset++] = (byte)(Si[(a2 >>> 8) & 0xFF] ^ (t1 >>> 8));
577 out[outOffset++] = (byte)(Si[(a1 ) & 0xFF] ^ (t1 ));
578 t1 = K[1];
579 out[outOffset++] = (byte)(Si[(a1 >>> 24) ] ^ (t1 >>> 24));
580 out[outOffset++] = (byte)(Si[(a0 >>> 16) & 0xFF] ^ (t1 >>> 16));
581 out[outOffset++] = (byte)(Si[(t3 >>> 8) & 0xFF] ^ (t1 >>> 8));
582 out[outOffset++] = (byte)(Si[(a2 ) & 0xFF] ^ (t1 ));
583 t1 = K[2];
584 out[outOffset++] = (byte)(Si[(a2 >>> 24) ] ^ (t1 >>> 24));
585 out[outOffset++] = (byte)(Si[(a1 >>> 16) & 0xFF] ^ (t1 >>> 16));
586 out[outOffset++] = (byte)(Si[(a0 >>> 8) & 0xFF] ^ (t1 >>> 8));
587 out[outOffset++] = (byte)(Si[(t3 ) & 0xFF] ^ (t1 ));
588 t1 = K[3];
589 out[outOffset++] = (byte)(Si[(t3 >>> 24) ] ^ (t1 >>> 24));
590 out[outOffset++] = (byte)(Si[(a2 >>> 16) & 0xFF] ^ (t1 >>> 16));
591 out[outOffset++] = (byte)(Si[(a1 >>> 8) & 0xFF] ^ (t1 >>> 8));
592 out[outOffset ] = (byte)(Si[(a0 ) & 0xFF] ^ (t1 ));
593 }
594
595 // Used to perform all checks required by the Java semantics
596 // (i.e., null checks and bounds checks) on the input parameters
597 // to encryptBlock and to decryptBlock.
598 // Normally, the Java Runtime performs these checks, however, as
599 // encryptBlock and decryptBlock are possibly replaced with
600 // compiler intrinsics, the JDK performs the required checks instead.
601 // Does not check accesses to class-internal (private) arrays.
602 private static void cryptBlockCheck(byte[] array, int offset) {
603 Objects.requireNonNull(array);
604
605 if (offset < 0 || offset >= array.length) {
606 throw new ArrayIndexOutOfBoundsException(offset);
607 }
608
609 int largestIndex = offset + AES_BLOCK_SIZE - 1;
610 if (largestIndex < 0 || largestIndex >= array.length) {
611 throw new ArrayIndexOutOfBoundsException(largestIndex);
612 }
613 }
614
615 /**
616 * Expand a user-supplied key material into a session key.
617 *
618 * @param k The 128/192/256-bit cipher key to use.
619 * @exception InvalidKeyException If the key is invalid.
620 */
621 private void makeSessionKey(byte[] k) throws InvalidKeyException {
622 if (k == null) {
623 throw new InvalidKeyException("Empty key");
624 }
625 if (!isKeySizeValid(k.length)) {
626 throw new InvalidKeyException("Invalid AES key length: " +
627 k.length + " bytes");
628 }
629 int ROUNDS = getRounds(k.length);
630 int ROUND_KEY_COUNT = (ROUNDS + 1) * 4;
631
632 int BC = 4;
633 int[][] Ke = new int[ROUNDS + 1][4]; // encryption round keys
|