Save This Page
Home » openjdk-7 » com.sun.crypto » provider » [javadoc | source]
    1   /*
    2    * Copyright (c) 1997, 2007, 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.InvalidKeyException;
   29   
   30   /**
   31    * This class represents ciphers in output-feedback (OFB) mode.
   32    *
   33    * <p>This mode is implemented independently of a particular cipher.
   34    * Ciphers to which this mode should apply (e.g., DES) must be
   35    * <i>plugged-in</i> using the constructor.
   36    *
   37    * <p>NOTE: This class does not deal with buffering or padding.
   38    *
   39    * @author Gigi Ankeny
   40    */
   41   final class OutputFeedback extends FeedbackCipher {
   42   
   43       /*
   44        * output buffer
   45        */
   46       private byte[] k = null;
   47   
   48       /*
   49        * register buffer
   50        */
   51       private byte[] register = null;
   52   
   53       /*
   54        * number of bytes for each stream unit, defaults to the blocksize
   55        * of the embedded cipher
   56        */
   57       private int numBytes;
   58   
   59       // variables for save/restore calls
   60       private byte[] registerSave = null;
   61   
   62       OutputFeedback(SymmetricCipher embeddedCipher, int numBytes) {
   63           super(embeddedCipher);
   64           if (numBytes > blockSize) {
   65               numBytes = blockSize;
   66           }
   67           this.numBytes = numBytes;
   68           k = new byte[blockSize];
   69           register = new byte[blockSize];
   70       }
   71   
   72       /**
   73        * Gets the name of this feedback mode.
   74        *
   75        * @return the string <code>OFB</code>
   76        */
   77       String getFeedback() {
   78           return "OFB";
   79       }
   80   
   81       /**
   82        * Initializes the cipher in the specified mode with the given key
   83        * and iv.
   84        *
   85        * @param decrypting flag indicating encryption or decryption
   86        * @param algorithm the algorithm name
   87        * @param key the key
   88        * @param iv the iv
   89        *
   90        * @exception InvalidKeyException if the given key is inappropriate for
   91        * initializing this cipher
   92        */
   93       void init(boolean decrypting, String algorithm, byte[] key, byte[] iv)
   94               throws InvalidKeyException {
   95           if ((key == null) || (iv == null) || (iv.length != blockSize)) {
   96               throw new InvalidKeyException("Internal error");
   97           }
   98           this.iv = iv;
   99           reset();
  100           // always encrypt mode for embedded cipher
  101           embeddedCipher.init(false, algorithm, key);
  102       }
  103   
  104       /**
  105        * Resets the iv to its original value.
  106        * This is used when doFinal is called in the Cipher class, so that the
  107        * cipher can be reused (with its original iv).
  108        */
  109       void reset() {
  110           System.arraycopy(iv, 0, register, 0, blockSize);
  111       }
  112   
  113       /**
  114        * Save the current content of this cipher.
  115        */
  116       void save() {
  117           if (registerSave == null) {
  118               registerSave = new byte[blockSize];
  119           }
  120           System.arraycopy(register, 0, registerSave, 0, blockSize);
  121       }
  122   
  123       /**
  124        * Restores the content of this cipher to the previous saved one.
  125        */
  126       void restore() {
  127           System.arraycopy(registerSave, 0, register, 0, blockSize);
  128       }
  129   
  130       /**
  131        * Performs encryption operation.
  132        *
  133        * <p>The input plain text <code>plain</code>, starting at
  134        * <code>plainOffset</code> and ending at
  135        * <code>(plainOffset + len - 1)</code>, is encrypted.
  136        * The result is stored in <code>cipher</code>, starting at
  137        * <code>cipherOffset</code>.
  138        *
  139        * <p>It is the application's responsibility to make sure that
  140        * <code>plainLen</code> is a multiple of the stream unit size
  141        * <code>numBytes</code>, as any excess bytes are ignored.
  142        *
  143        * <p>It is also the application's responsibility to make sure that
  144        * <code>init</code> has been called before this method is called.
  145        * (This check is omitted here, to avoid double checking.)
  146        *
  147        * @param plain the buffer with the input data to be encrypted
  148        * @param plainOffset the offset in <code>plain</code>
  149        * @param plainLen the length of the input data
  150        * @param cipher the buffer for the result
  151        * @param cipherOffset the offset in <code>cipher</code>
  152        */
  153       void encrypt(byte[] plain, int plainOffset, int plainLen,
  154                           byte[] cipher, int cipherOffset)
  155       {
  156           int i;
  157           int len = blockSize - numBytes;
  158           int loopCount = plainLen / numBytes;
  159           int oddBytes = plainLen % numBytes;
  160   
  161           if (len == 0) {
  162               for (; loopCount > 0;
  163                    plainOffset += numBytes, cipherOffset += numBytes,
  164                    loopCount--) {
  165                   embeddedCipher.encryptBlock(register, 0, k, 0);
  166                   for (i=0; i<numBytes; i++)
  167                       cipher[i+cipherOffset] =
  168                           (byte)(k[i] ^ plain[i+plainOffset]);
  169                   System.arraycopy(k, 0, register, 0, numBytes);
  170               }
  171               if (oddBytes > 0) {
  172                   embeddedCipher.encryptBlock(register, 0, k, 0);
  173                   for (i=0; i<oddBytes; i++)
  174                       cipher[i+cipherOffset] =
  175                           (byte)(k[i] ^ plain[i+plainOffset]);
  176                   System.arraycopy(k, 0, register, 0, numBytes);
  177               }
  178           } else {
  179               for (; loopCount > 0;
  180                    plainOffset += numBytes, cipherOffset += numBytes,
  181                    loopCount--) {
  182                   embeddedCipher.encryptBlock(register, 0, k, 0);
  183                   for (i=0; i<numBytes; i++)
  184                       cipher[i+cipherOffset] =
  185                           (byte)(k[i] ^ plain[i+plainOffset]);
  186                   System.arraycopy(register, numBytes, register, 0, len);
  187                   System.arraycopy(k, 0, register, len, numBytes);
  188               }
  189               if (oddBytes > 0) {
  190                   embeddedCipher.encryptBlock(register, 0, k, 0);
  191                   for (i=0; i<oddBytes; i++)
  192                       cipher[i+cipherOffset] =
  193                           (byte)(k[i] ^ plain[i+plainOffset]);
  194                   System.arraycopy(register, numBytes, register, 0, len);
  195                   System.arraycopy(k, 0, register, len, numBytes);
  196               }
  197           }
  198       }
  199   
  200       /**
  201        * Performs decryption operation.
  202        *
  203        * <p>The input cipher text <code>cipher</code>, starting at
  204        * <code>cipherOffset</code> and ending at
  205        * <code>(cipherOffset + len - 1)</code>, is decrypted.
  206        * The result is stored in <code>plain</code>, starting at
  207        * <code>plainOffset</code>.
  208        *
  209        * <p>It is the application's responsibility to make sure that
  210        * <code>cipherLen</code> is a multiple of the stream unit size
  211        * <code>numBytes</code>, as any excess bytes are ignored.
  212        *
  213        * <p>It is also the application's responsibility to make sure that
  214        * <code>init</code> has been called before this method is called.
  215        * (This check is omitted here, to avoid double checking.)
  216        *
  217        * @param cipher the buffer with the input data to be decrypted
  218        * @param cipherOffset the offset in <code>cipherOffset</code>
  219        * @param cipherLen the length of the input data
  220        * @param plain the buffer for the result
  221        * @param plainOffset the offset in <code>plain</code>
  222        */
  223       void decrypt(byte[] cipher, int cipherOffset, int cipherLen,
  224                           byte[] plain, int plainOffset)
  225       {
  226           // OFB encrypt and decrypt are identical
  227           encrypt(cipher, cipherOffset, cipherLen, plain, plainOffset);
  228       }
  229   }

Save This Page
Home » openjdk-7 » com.sun.crypto » provider » [javadoc | source]