Source for javax.crypto.CipherSpi

   1: /* CipherSpi.java -- The cipher service provider interface.
   2:    Copyright (C) 2004  Free Software Foundation, Inc.
   3: 
   4: This file is part of GNU Classpath.
   5: 
   6: GNU Classpath is free software; you can redistribute it and/or modify
   7: it under the terms of the GNU General Public License as published by
   8: the Free Software Foundation; either version 2, or (at your option)
   9: any later version.
  10: 
  11: GNU Classpath is distributed in the hope that it will be useful, but
  12: WITHOUT ANY WARRANTY; without even the implied warranty of
  13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  14: General Public License for more details.
  15: 
  16: You should have received a copy of the GNU General Public License
  17: along with GNU Classpath; see the file COPYING.  If not, write to the
  18: Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  19: 02110-1301 USA.
  20: 
  21: Linking this library statically or dynamically with other modules is
  22: making a combined work based on this library.  Thus, the terms and
  23: conditions of the GNU General Public License cover the whole
  24: combination.
  25: 
  26: As a special exception, the copyright holders of this library give you
  27: permission to link this library with independent modules to produce an
  28: executable, regardless of the license terms of these independent
  29: modules, and to copy and distribute the resulting executable under
  30: terms of your choice, provided that you also meet, for each linked
  31: independent module, the terms and conditions of the license of that
  32: module.  An independent module is a module which is not derived from
  33: or based on this library.  If you modify this library, you may extend
  34: this exception to your version of the library, but you are not
  35: obligated to do so.  If you do not wish to do so, delete this
  36: exception statement from your version. */
  37: 
  38: 
  39: package javax.crypto;
  40: 
  41: import java.security.AlgorithmParameters;
  42: import java.security.InvalidAlgorithmParameterException;
  43: import java.security.InvalidKeyException;
  44: import java.security.Key;
  45: import java.security.NoSuchAlgorithmException;
  46: import java.security.SecureRandom;
  47: import java.security.spec.AlgorithmParameterSpec;
  48: 
  49: /**
  50:  * <p>This class represents the <i>Service Provider Interface</i>
  51:  * (<b>SPI</b>) for cryptographic ciphers.</p>
  52:  *
  53:  * <p>Providers of cryptographic ciphers must subclass this for every
  54:  * cipher they implement, implementing the abstract methods as
  55:  * appropriate, then provide an entry that points to the subclass in
  56:  * their implementation of {@link java.security.Provider}.</p>
  57:  *
  58:  * <p>CipherSpi objects are instantiated along with {@link Cipher}s when
  59:  * the {@link Cipher#getInstance(java.lang.String)} methods are invoked.
  60:  * Particular ciphers are referenced by a <i>transformation</i>, which
  61:  * is a String consisting of the cipher's name or the ciper's name
  62:  * followed by a mode and a padding. Transformations all follow the
  63:  * general form:</p>
  64:  *
  65:  * <ul>
  66:  * <li><i>algorithm</i>, or</li>
  67:  * <li><i>algorithm</i>/<i>mode</i>/<i>padding</i>
  68:  * </ul>
  69:  *
  70:  * <p>Cipher names in the master {@link java.security.Provider} class
  71:  * may be:</p>
  72:  *
  73:  * <ol>
  74:  * <li>The algorithm's name, which uses a pluggable mode and padding:
  75:  * <code>Cipher.<i>algorithm</i></code></li>
  76:  * <li>The algorithm's name and the mode, which uses pluggable padding:
  77:  * <code>Cipher.<i>algorithm</i>/<i>mode</i></code></li>
  78:  * <li>The algorithm's name and the padding, which uses a pluggable
  79:  * mode: <code>Cipher.<i>algorithm</i>//<i>padding</i></code></li>
  80:  * <li>The algorihtm's name, the mode, and the padding:
  81:  * <code>Cipher.<i>algorithm</i>/<i>mode</i>/<i>padding</i></code></li>
  82:  * </ol>
  83:  *
  84:  * <p>When any {@link Cipher#getInstance(java.lang.String)} method is
  85:  * invoked, the following happens if the transformation is simply
  86:  * <i>algorithm</i>:</p>
  87:  *
  88:  * <ol>
  89:  * <li>If the provider defines a <code>CipherSpi</code> implementation
  90:  * for "<i>algorithm</i>", return it. Otherwise throw a {@link
  91:  * java.security.NoSuchAlgorithmException}.</li>
  92:  * </ol>
  93:  *
  94:  * <p>If the transformation is of the form
  95:  * <i>algorithm</i>/<i>mode</i>/<i>padding</i>:</p>
  96:  *
  97:  * <ol>
  98:  * <li>If the provider defines a <code>CipherSpi</code> subclass for
  99:  * "<i>algorithm</i>/<i>mode</i>/<i>padding</i>", return it. Otherwise
 100:  * go to step 2.</li>
 101:  *
 102:  * <li>If the provider defines a <code>CipherSpi</code> subclass for
 103:  * "<i>algorithm</i>/<i>mode</i>", instatiate it, call {@link
 104:  * #engineSetPadding(java.lang.String)} for the padding name, and return
 105:  * it. Otherwise go to step 3.</li>
 106:  *
 107:  * <li>If the provider defines a <code>CipherSpi</code> subclass for
 108:  * "<i>algorithm</i>//<i>padding</i>", instatiate it, call {@link
 109:  * #engineSetMode(java.lang.String)} for the mode name, and return
 110:  * it. Otherwise go to step 4.</li>
 111:  *
 112:  * <li>If the provider defines a <code>CipherSpi</code> subclass for
 113:  * "<i>algorithm</i>", instatiate it, call {@link
 114:  * #engineSetMode(java.lang.String)} for the mode name, call {@link
 115:  * #engineSetPadding(java.lang.String)} for the padding name, and return
 116:  * it. Otherwise throw a {@link java.security.NoSuchAlgorithmException}.</li>
 117:  * </ol>
 118:  *
 119:  * @author Casey Marshall (csm@gnu.org)
 120:  * @since 1.4
 121:  */
 122: public abstract class CipherSpi
 123: {
 124: 
 125:   // Constructors.
 126:   // ------------------------------------------------------------------------
 127: 
 128:   /**
 129:    * Create a new CipherSpi.
 130:    */
 131:   public CipherSpi()
 132:   {
 133:   }
 134: 
 135:   // Abstract methods to be implemented by providers.
 136:   // ------------------------------------------------------------------------
 137: 
 138:   /**
 139:    * Finishes a multi-part transformation or transforms a portion of a
 140:    * byte array, and returns the transformed bytes.
 141:    *
 142:    * @param input       The input bytes.
 143:    * @param inputOffset The index in the input at which to start.
 144:    * @param inputLength The number of bytes to transform.
 145:    * @return The transformed bytes in a new array.
 146:    * @throws javax.crypto.IllegalBlockSizeException If this instance has
 147:    *         no padding and the input size is not a multiple of the
 148:    *         block size.
 149:    * @throws javax.crypto.BadPaddingException If this instance is being
 150:    *         used for decryption and the padding is not appropriate for
 151:    *         this instance's padding scheme.
 152:    */
 153:   protected abstract byte[]
 154:   engineDoFinal(byte[] input, int inputOffset, int inputLength)
 155:   throws IllegalBlockSizeException, BadPaddingException;
 156: 
 157:   /**
 158:    * Finishes a multi-part transformation or transforms a portion of a
 159:    * byte array, and stores the transformed bytes in the supplied array.
 160:    *
 161:    * @param input        The input bytes.
 162:    * @param inputOffset  The index in the input at which to start.
 163:    * @param inputLength  The number of bytes to transform.
 164:    * @param output       The output byte array.
 165:    * @param outputOffset The index in the output array at which to start.
 166:    * @return The number of transformed bytes stored in the output array.
 167:    * @throws javax.crypto.IllegalBlockSizeException If this instance has
 168:    *         no padding and the input size is not a multiple of the
 169:    *         block size.
 170:    * @throws javax.crypto.BadPaddingException If this instance is being
 171:    *         used for decryption and the padding is not appropriate for
 172:    *         this instance's padding scheme.
 173:    * @throws javax.crypto.ShortBufferException If there is not enough
 174:    *         space in the output array for the transformed bytes.
 175:    */
 176:   protected abstract int
 177:   engineDoFinal(byte[] input, int inputOffset, int inputLength,
 178:                 byte[] output, int outputOffset)
 179:   throws IllegalBlockSizeException, BadPaddingException, ShortBufferException;
 180: 
 181:   /**
 182:    * Returns the block size of the underlying cipher.
 183:    *
 184:    * @return The block size.
 185:    */
 186:   protected abstract int engineGetBlockSize();
 187: 
 188:   /**
 189:    * Returns the initializaiton vector this cipher was initialized with,
 190:    * if any.
 191:    *
 192:    * @return The IV, or null if this cipher uses no IV or if this
 193:    *         instance has not been initialized yet.
 194:    */
 195:   protected abstract byte[] engineGetIV();
 196: 
 197:   /**
 198:    * <p>Return the length of the given key in bits.</p>
 199:    *
 200:    * <p>For compatibility this method is not declared
 201:    * <code>abstract</code>, and the default implementation will throw an
 202:    * {@link java.lang.UnsupportedOperationException}. Concrete
 203:    * subclasses should override this method to return the correct
 204:    * value.</p>
 205:    *
 206:    * @param key The key to get the size for.
 207:    * @return The size of the key, in bits.
 208:    * @throws java.security.InvalidKeyException If the key's length
 209:    *         cannot be determined by this implementation.
 210:    */
 211:   protected int engineGetKeySize(Key key) throws InvalidKeyException
 212:   {
 213:     throw new UnsupportedOperationException();
 214:   }
 215: 
 216:   /**
 217:    * <p>Returns the size, in bytes, an output buffer must be for a call
 218:    * to {@link #engineUpdate(byte[],int,int,byte[],int)} or {@link
 219:    * #engineDoFinal(byte[],int,int,byte[],int)} to succeed.</p>
 220:    *
 221:    * <p>The actual output length may be smaller than the value returned
 222:    * by this method, as it considers the padding length as well. The
 223:    * length considered is the argument plus the length of any buffered,
 224:    * unprocessed bytes.</p>
 225:    *
 226:    * @param inputLength The input length, in bytes.
 227:    * @return The size an output buffer must be.
 228:    */
 229:   protected abstract int engineGetOutputSize(int inputLength);
 230: 
 231:   /**
 232:    * Returns the parameters that this cipher is using. This may be the
 233:    * parameters used to initialize this cipher, or it may be parameters
 234:    * that have been initialized with random values.
 235:    *
 236:    * @return This cipher's parameters, or <code>null</code> if this
 237:    *         cipher does not use parameters.
 238:    */
 239:   protected abstract AlgorithmParameters engineGetParameters();
 240: 
 241:   /**
 242:    * Initializes this cipher with an operation mode, key, and source of
 243:    * randomness. If this cipher requires any other initializing data,
 244:    * for example an initialization vector, then it should generate it
 245:    * from the provided source of randomness.
 246:    *
 247:    * @param opmode The operation mode, one of {@link
 248:    *        Cipher#DECRYPT_MODE}, {@link Cipher#ENCRYPT_MODE}, {@link
 249:    *        Cipher#UNWRAP_MODE}, or {@link Cipher#WRAP_MODE}.
 250:    * @param key    The key to initialize this cipher with.
 251:    * @param random The source of random bytes to use.
 252:    * @throws java.security.InvalidKeyException If the given key is not
 253:    *         acceptable for this implementation.
 254:    */
 255:   protected abstract void engineInit(int opmode, Key key, SecureRandom random)
 256:   throws InvalidKeyException;
 257: 
 258:   /**
 259:    * Initializes this cipher with an operation mode, key, parameters,
 260:    * and source of randomness. If this cipher requires any other
 261:    * initializing data, for example an initialization vector, then it should
 262:    * generate it from the provided source of randomness.
 263:    *
 264:    * @param opmode The operation mode, one of {@link
 265:    *        Cipher#DECRYPT_MODE}, {@link Cipher#ENCRYPT_MODE}, {@link
 266:    *        Cipher#UNWRAP_MODE}, or {@link Cipher#WRAP_MODE}.
 267:    * @param key    The key to initialize this cipher with.
 268:    * @param params The algorithm parameters to initialize with.
 269:    * @param random The source of random bytes to use.
 270:    * @throws java.security.InvalidAlgorithmParameterException If the
 271:    *         given parameters are not appropriate for this
 272:    *         implementation.
 273:    * @throws java.security.InvalidKeyException If the given key is not
 274:    *         acceptable for this implementation.
 275:    */
 276:   protected abstract void
 277:   engineInit(int opmode, Key key, AlgorithmParameters params,
 278:              SecureRandom random)
 279:   throws InvalidAlgorithmParameterException, InvalidKeyException;
 280: 
 281:   /**
 282:    * Initializes this cipher with an operation mode, key, parameters,
 283:    * and source of randomness. If this cipher requires any other
 284:    * initializing data, for example an initialization vector, then it should
 285:    * generate it from the provided source of randomness.
 286:    *
 287:    * @param opmode The operation mode, one of {@link
 288:    *        Cipher#DECRYPT_MODE}, {@link Cipher#ENCRYPT_MODE}, {@link
 289:    *        Cipher#UNWRAP_MODE}, or {@link Cipher#WRAP_MODE}.
 290:    * @param key    The key to initialize this cipher with.
 291:    * @param params The algorithm parameters to initialize with.
 292:    * @param random The source of random bytes to use.
 293:    * @throws java.security.InvalidAlgorithmParameterException If the
 294:    *         given parameters are not appropriate for this
 295:    *         implementation.
 296:    * @throws java.security.InvalidKeyException If the given key is not
 297:    *         acceptable for this implementation.
 298:    */
 299:   protected abstract void
 300:   engineInit(int opmode, Key key, AlgorithmParameterSpec params,
 301:              SecureRandom random)
 302:   throws InvalidAlgorithmParameterException, InvalidKeyException;
 303: 
 304:   /**
 305:    * Set the mode in which this cipher is to run.
 306:    *
 307:    * @param mode The name of the mode to use.
 308:    * @throws java.security.NoSuchAlgorithmException If the mode is
 309:    *         not supported by this cipher's provider.
 310:    */
 311:   protected abstract void engineSetMode(String mode)
 312:   throws NoSuchAlgorithmException;
 313: 
 314:   /**
 315:    * Set the method with which the input is to be padded.
 316:    *
 317:    * @param padding The name of the padding to use.
 318:    * @throws javax.crypto.NoSuchPaddingException If the padding is not
 319:    *         supported by this cipher's provider.
 320:    */
 321:   protected abstract void engineSetPadding(String padding)
 322:   throws NoSuchPaddingException;
 323: 
 324:   /**
 325:    * <p>Unwraps a previously-wrapped key.</p>
 326:    *
 327:    * <p>For compatibility this method is not declared
 328:    * <code>abstract</code>, and the default implementation will throw an
 329:    * {@link java.lang.UnsupportedOperationException}.</p>
 330:    *
 331:    * @param wrappedKey          The wrapped key.
 332:    * @param wrappedKeyAlgorithm The name of the algorithm used to wrap
 333:    *                            this key.
 334:    * @param wrappedKeyType      The type of wrapped key; one of
 335:    *                            {@link Cipher#PRIVATE_KEY},
 336:    *                            {@link Cipher#PUBLIC_KEY}, or
 337:    *                            {@link Cipher#SECRET_KEY}.
 338:    * @return The unwrapped key.
 339:    * @throws java.security.InvalidKeyException If the key cannot be
 340:    *         unwrapped, or if <code>wrappedKeyType</code> is an
 341:    *         inappropriate type for the unwrapped key.
 342:    * @throws java.security.NoSuchAlgorithmException If the
 343:    *         <code>wrappedKeyAlgorithm</code> is unknown.
 344:    */
 345:   protected Key engineUnwrap(byte[] wrappedKey, String wrappedKeyAlgorithm,
 346:                              int wrappedKeyType)
 347:   throws InvalidKeyException, NoSuchAlgorithmException
 348:   {
 349:     throw new UnsupportedOperationException();
 350:   }
 351: 
 352:   /**
 353:    * Continue with a multi-part transformation, returning a new array of
 354:    * the transformed bytes.
 355:    *
 356:    * @param input       The next input bytes.
 357:    * @param inputOffset The index in the input array from which to start.
 358:    * @param inputLength The number of bytes to input.
 359:    * @return The transformed bytes.
 360:    */
 361:   protected abstract byte[]
 362:   engineUpdate(byte[] input, int inputOffset, int inputLength);
 363: 
 364:   /**
 365:    * Continue with a multi-part transformation, storing the transformed
 366:    * bytes into the specified array.
 367:    *
 368:    * @param input        The next input bytes.
 369:    * @param inputOffset  The index in the input from which to start.
 370:    * @param inputLength  The number of bytes to input.
 371:    * @param output       The output buffer.
 372:    * @param outputOffset The index in the output array from which to start.
 373:    * @return The transformed bytes.
 374:    * @throws javax.crypto.ShortBufferException If there is not enough
 375:    *         space in the output array to store the transformed bytes.
 376:    */
 377:   protected abstract int
 378:   engineUpdate(byte[] input, int inputOffset, int inputLength,
 379:                byte[] output, int outputOffset)
 380:   throws ShortBufferException;
 381: 
 382:   /**
 383:    * <p>Wrap a key.</p>
 384:    *
 385:    * <p>For compatibility this method is not declared
 386:    * <code>abstract</code>, and the default implementation will throw an
 387:    * {@link java.lang.UnsupportedOperationException}.</p>
 388:    *
 389:    * @param key The key to wrap.
 390:    * @return The wrapped key.
 391:    * @throws java.security.InvalidKeyException If the key cannot be
 392:    *         wrapped.
 393:    */
 394:   protected byte[] engineWrap(Key key) throws InvalidKeyException, IllegalBlockSizeException
 395:   {
 396:     throw new UnsupportedOperationException();
 397:   }
 398: }