OpenSslCommonMode.java

  1. /*
  2. * Licensed to the Apache Software Foundation (ASF) under one
  3. * or more contributor license agreements.  See the NOTICE file
  4. * distributed with this work for additional information
  5. * regarding copyright ownership.  The ASF licenses this file
  6. * to you under the Apache License, Version 2.0 (the
  7. * "License"); you may not use this file except in compliance
  8. * with the License.  You may obtain a copy of the License at
  9. *
  10. *     http://www.apache.org/licenses/LICENSE-2.0
  11. *
  12. * Unless required by applicable law or agreed to in writing, software
  13. * distributed under the License is distributed on an "AS IS" BASIS,
  14. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15. * See the License for the specific language governing permissions and
  16. * limitations under the License.
  17. */
  18. package org.apache.commons.crypto.cipher;

  19. import java.nio.ByteBuffer;
  20. import java.security.InvalidAlgorithmParameterException;
  21. import java.security.spec.AlgorithmParameterSpec;

  22. import javax.crypto.BadPaddingException;
  23. import javax.crypto.IllegalBlockSizeException;
  24. import javax.crypto.ShortBufferException;
  25. import javax.crypto.spec.IvParameterSpec;

  26. /**
  27.  * This class do the real work(Encryption/Decryption) for non-authenticated modes, such as CTR, CBC.
  28.  * <p>
  29.  * It will call the OpenSSL API to implement encryption/decryption
  30.  * </p>
  31.  */
  32. final class OpenSslCommonMode extends AbstractOpenSslFeedbackCipher {

  33.     OpenSslCommonMode(final long context, final int algorithmMode, final int padding) {
  34.         super(context, algorithmMode, padding);
  35.     }

  36.     @Override
  37.     public int doFinal(final byte[] input, final int inputOffset, final int inputLen, final byte[] output, final int outputOffset)
  38.             throws ShortBufferException, IllegalBlockSizeException, BadPaddingException {
  39.         checkState();
  40.         final int outputLength = output.length;

  41.         int len = OpenSslNative.updateByteArray(context, input, inputOffset, inputLen, output, outputOffset, outputLength - outputOffset);

  42.         len += OpenSslNative.doFinalByteArray(context, output, outputOffset + len, outputLength - outputOffset - len);

  43.         return len;
  44.     }

  45.     @Override
  46.     public int doFinal(final ByteBuffer input, final ByteBuffer output) throws ShortBufferException, IllegalBlockSizeException, BadPaddingException {
  47.         checkState();

  48.         int totalLen = 0;
  49.         int len = OpenSslNative.update(context, input, input.position(), input.remaining(), output, output.position(), output.remaining());
  50.         totalLen += len;

  51.         input.position(input.limit());
  52.         output.position(output.position() + len);

  53.         len = OpenSslNative.doFinal(context, output, output.position(), output.remaining());
  54.         totalLen += len;

  55.         output.position(output.position() + len);

  56.         return totalLen;
  57.     }

  58.     @Override
  59.     public void init(final int mode, final byte[] key, final AlgorithmParameterSpec params) throws InvalidAlgorithmParameterException {
  60.         this.cipherMode = mode;
  61.         final byte[] iv;
  62.         if (!(params instanceof IvParameterSpec)) {
  63.             // other AlgorithmParameterSpec is not supported now.
  64.             throw new InvalidAlgorithmParameterException("Illegal parameters");
  65.         }
  66.         iv = ((IvParameterSpec) params).getIV();
  67.         context = OpenSslNative.init(context, mode, algorithmMode, padding, key, iv);
  68.     }

  69.     @Override
  70.     public int update(final byte[] input, final int inputOffset, final int inputLen, final byte[] output, final int outputOffset) throws ShortBufferException {
  71.         checkState();

  72.         return OpenSslNative.updateByteArray(context, input, inputOffset, inputLen, output, outputOffset, output.length - outputOffset);
  73.     }

  74.     @Override
  75.     public int update(final ByteBuffer input, final ByteBuffer output) throws ShortBufferException {
  76.         checkState();

  77.         final int len = OpenSslNative.update(context, input, input.position(), input.remaining(), output, output.position(), output.remaining());
  78.         input.position(input.limit());
  79.         output.position(output.position() + len);

  80.         return len;
  81.     }

  82.     @Override
  83.     public void updateAAD(final byte[] aad) {
  84.         throw new UnsupportedOperationException("The underlying Cipher implementation does not support this method");
  85.     }
  86. }