< prev index next >

src/share/classes/com/sun/crypto/provider/AESCrypt.java

Print this page
rev 11746 : 8152172: PPC64: Support AES intrinsics
Reviewed-by: ascarpino, simonis
Contributed-by: Hiroshi H Horii <HORII@jp.ibm.com>


  35  */
  36 
  37 package com.sun.crypto.provider;
  38 
  39 import java.security.InvalidKeyException;
  40 import java.security.MessageDigest;
  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
  61     private byte[] lastKey = null;
  62 
  63     /** ROUNDS * 4 */
  64     private int limit = 0;
  65 
  66     AESCrypt() {
  67         // empty
  68     }
  69 
  70     /**
  71      * Returns this cipher's block size.
  72      *
  73      * @return this cipher's block size
  74      */
  75     int getBlockSize() {


  78 
  79     void init(boolean decrypting, String algorithm, byte[] key)
  80             throws InvalidKeyException {
  81         if (!algorithm.equalsIgnoreCase("AES")
  82                     && !algorithm.equalsIgnoreCase("Rijndael")) {
  83             throw new InvalidKeyException
  84                 ("Wrong algorithm: AES or Rijndael required");
  85         }
  86         if (!isKeySizeValid(key.length)) {
  87             throw new InvalidKeyException("Invalid AES key length: " +
  88                 key.length + " bytes");
  89         }
  90 
  91         if (!MessageDigest.isEqual(key, lastKey)) {
  92             // re-generate session key 'sessionK' when cipher key changes
  93             makeSessionKey(key);
  94             lastKey = key.clone();  // save cipher key
  95         }
  96 
  97         // set sub key to the corresponding session Key
  98         this.K = (int[]) sessionK[(decrypting? 1:0)];
  99     }
 100 
 101     /**
 102      * Expand an int[(ROUNDS+1)][4] into int[(ROUNDS+1)*4].
 103      * For decryption round keys, need to rotate right by 4 ints.
 104      * @param kr The round keys for encryption or decryption.
 105      * @param decrypting True if 'kr' is for decryption and false otherwise.
 106      */
 107     private static final int[] expandToSubKey(int[][] kr, boolean decrypting) {
 108         int total = kr.length;
 109         int[] expK = new int[total*4];
 110         if (decrypting) {
 111             // decrypting, rotate right by 4 ints
 112             // i.e. i==0
 113             for(int j=0; j<4; j++) {
 114                 expK[j] = kr[total-1][j];
 115             }
 116             for(int i=1; i<total; i++) {
 117                 for(int j=0; j<4; j++) {
 118                     expK[i*4 + j] = kr[i-1][j];


 643             // inverse MixColumn where needed
 644             for (j = 0; j < BC; j++) {
 645                 tt = Kd[r][j];
 646                 Kd[r][j] = U1[(tt >>> 24) & 0xFF] ^
 647                            U2[(tt >>> 16) & 0xFF] ^
 648                            U3[(tt >>>  8) & 0xFF] ^
 649                            U4[ tt         & 0xFF];
 650             }
 651         }
 652 
 653         // assemble the encryption (Ke) and decryption (Kd) round keys
 654         // and expand them into arrays of ints.
 655         int[] expandedKe = expandToSubKey(Ke, false); // decrypting==false
 656         int[] expandedKd = expandToSubKey(Kd, true);  // decrypting==true
 657 
 658         ROUNDS_12 = (ROUNDS>=12);
 659         ROUNDS_14 = (ROUNDS==14);
 660         limit = ROUNDS*4;
 661 
 662         // store the expanded sub keys into 'sessionK'
 663         sessionK = new Object[] { expandedKe, expandedKd };
 664     }
 665 
 666 
 667     /**
 668      * Return The number of rounds for a given Rijndael keysize.
 669      *
 670      * @param keySize  The size of the user key material in bytes.
 671      *                 MUST be one of (16, 24, 32).
 672      * @return         The number of rounds.
 673      */
 674     private static int getRounds(int keySize) {
 675         return (keySize >> 2) + 6;
 676     }
 677 }


  35  */
  36 
  37 package com.sun.crypto.provider;
  38 
  39 import java.security.InvalidKeyException;
  40 import java.security.MessageDigest;
  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 int[][] 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
  61     private byte[] lastKey = null;
  62 
  63     /** ROUNDS * 4 */
  64     private int limit = 0;
  65 
  66     AESCrypt() {
  67         // empty
  68     }
  69 
  70     /**
  71      * Returns this cipher's block size.
  72      *
  73      * @return this cipher's block size
  74      */
  75     int getBlockSize() {


  78 
  79     void init(boolean decrypting, String algorithm, byte[] key)
  80             throws InvalidKeyException {
  81         if (!algorithm.equalsIgnoreCase("AES")
  82                     && !algorithm.equalsIgnoreCase("Rijndael")) {
  83             throw new InvalidKeyException
  84                 ("Wrong algorithm: AES or Rijndael required");
  85         }
  86         if (!isKeySizeValid(key.length)) {
  87             throw new InvalidKeyException("Invalid AES key length: " +
  88                 key.length + " bytes");
  89         }
  90 
  91         if (!MessageDigest.isEqual(key, lastKey)) {
  92             // re-generate session key 'sessionK' when cipher key changes
  93             makeSessionKey(key);
  94             lastKey = key.clone();  // save cipher key
  95         }
  96 
  97         // set sub key to the corresponding session Key
  98         this.K = sessionK[(decrypting? 1:0)];
  99     }
 100 
 101     /**
 102      * Expand an int[(ROUNDS+1)][4] into int[(ROUNDS+1)*4].
 103      * For decryption round keys, need to rotate right by 4 ints.
 104      * @param kr The round keys for encryption or decryption.
 105      * @param decrypting True if 'kr' is for decryption and false otherwise.
 106      */
 107     private static final int[] expandToSubKey(int[][] kr, boolean decrypting) {
 108         int total = kr.length;
 109         int[] expK = new int[total*4];
 110         if (decrypting) {
 111             // decrypting, rotate right by 4 ints
 112             // i.e. i==0
 113             for(int j=0; j<4; j++) {
 114                 expK[j] = kr[total-1][j];
 115             }
 116             for(int i=1; i<total; i++) {
 117                 for(int j=0; j<4; j++) {
 118                     expK[i*4 + j] = kr[i-1][j];


 643             // inverse MixColumn where needed
 644             for (j = 0; j < BC; j++) {
 645                 tt = Kd[r][j];
 646                 Kd[r][j] = U1[(tt >>> 24) & 0xFF] ^
 647                            U2[(tt >>> 16) & 0xFF] ^
 648                            U3[(tt >>>  8) & 0xFF] ^
 649                            U4[ tt         & 0xFF];
 650             }
 651         }
 652 
 653         // assemble the encryption (Ke) and decryption (Kd) round keys
 654         // and expand them into arrays of ints.
 655         int[] expandedKe = expandToSubKey(Ke, false); // decrypting==false
 656         int[] expandedKd = expandToSubKey(Kd, true);  // decrypting==true
 657 
 658         ROUNDS_12 = (ROUNDS>=12);
 659         ROUNDS_14 = (ROUNDS==14);
 660         limit = ROUNDS*4;
 661 
 662         // store the expanded sub keys into 'sessionK'
 663         sessionK = new int[][] { expandedKe, expandedKd };
 664     }
 665 
 666 
 667     /**
 668      * Return The number of rounds for a given Rijndael keysize.
 669      *
 670      * @param keySize  The size of the user key material in bytes.
 671      *                 MUST be one of (16, 24, 32).
 672      * @return         The number of rounds.
 673      */
 674     private static int getRounds(int keySize) {
 675         return (keySize >> 2) + 6;
 676     }
 677 }
< prev index next >