151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski/*
22b41a213a1acd92193c724398919fcfdf89e1f55Shubham Ajmera * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *
551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This code is free software; you can redistribute it and/or modify it
651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * under the terms of the GNU General Public License version 2 only, as
751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * published by the Free Software Foundation.  Oracle designates this
851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * particular file as subject to the "Classpath" exception as provided
951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * by Oracle in the LICENSE file that accompanied this code.
1051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *
1151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This code is distributed in the hope that it will be useful, but WITHOUT
1251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
1351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
1451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * version 2 for more details (a copy is included in the LICENSE file that
1551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * accompanied this code).
1651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *
1751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * You should have received a copy of the GNU General Public License version
1851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 2 along with this work; if not, write to the Free Software Foundation,
1951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
2051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *
2151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
2251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * or visit www.oracle.com if you need additional information or have any
2351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * questions.
2451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */
2551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
2651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskipackage javax.crypto;
2751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
282b41a213a1acd92193c724398919fcfdf89e1f55Shubham Ajmeraimport java.io.InputStream;
292b41a213a1acd92193c724398919fcfdf89e1f55Shubham Ajmeraimport java.io.FilterInputStream;
302b41a213a1acd92193c724398919fcfdf89e1f55Shubham Ajmeraimport java.io.IOException;
312b41a213a1acd92193c724398919fcfdf89e1f55Shubham Ajmeraimport javax.crypto.BadPaddingException;
322b41a213a1acd92193c724398919fcfdf89e1f55Shubham Ajmeraimport javax.crypto.IllegalBlockSizeException;
3351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
3451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski/**
3551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * A CipherInputStream is composed of an InputStream and a Cipher so
3651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * that read() methods return data that are read in from the
3751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * underlying InputStream but have been additionally processed by the
3851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Cipher.  The Cipher must be fully initialized before being used by
3951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * a CipherInputStream.
4051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *
4151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p> For example, if the Cipher is initialized for decryption, the
4251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * CipherInputStream will attempt to read in data and decrypt them,
4351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * before returning the decrypted data.
4451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *
4551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p> This class adheres strictly to the semantics, especially the
4651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * failure semantics, of its ancestor classes
4751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * java.io.FilterInputStream and java.io.InputStream.  This class has
4851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * exactly those methods specified in its ancestor classes, and
4951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * overrides them all.  Moreover, this class catches all exceptions
5051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * that are not thrown by its ancestor classes.  In particular, the
5151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <code>skip</code> method skips, and the <code>available</code>
5251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * method counts only data that have been processed by the encapsulated Cipher.
5351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *
5451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p> It is crucial for a programmer using this class not to use
5551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * methods that are not defined or overriden in this class (such as a
5651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * new method or constructor that is later added to one of the super
5751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * classes), because the design and implementation of those methods
5851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * are unlikely to have considered security impact with regard to
5951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * CipherInputStream.
6051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *
6151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @author  Li Gong
6251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @see     java.io.InputStream
6351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @see     java.io.FilterInputStream
6451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @see     javax.crypto.Cipher
6551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @see     javax.crypto.CipherOutputStream
6651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski *
6751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @since 1.4
6851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */
6951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
7051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskipublic class CipherInputStream extends FilterInputStream {
7151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
7251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    // the cipher engine to use to process stream data
7351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private Cipher cipher;
7451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
7551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    // the underlying input stream
7651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private InputStream input;
7751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
7851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /* the buffer holding data that have been read in from the
7951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski       underlying stream, but have not been processed by the cipher
8051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski       engine. the size 512 bytes is somewhat randomly chosen */
8151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private byte[] ibuffer = new byte[512];
8251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
8351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    // having reached the end of the underlying input stream
8451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private boolean done = false;
8551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
8651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /* the buffer holding data that have been processed by the cipher
8751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski       engine, but have not been read out */
8851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private byte[] obuffer;
8951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    // the offset pointing to the next "new" byte
9051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private int ostart = 0;
9151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    // the offset pointing to the last "new" byte
9251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private int ofinish = 0;
932b41a213a1acd92193c724398919fcfdf89e1f55Shubham Ajmera    // stream status
942b41a213a1acd92193c724398919fcfdf89e1f55Shubham Ajmera    private boolean closed = false;
9551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
9651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
9751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * private convenience function.
9851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
9951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Entry condition: ostart = ofinish
10051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
10151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Exit condition: ostart <= ofinish
10251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
10351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * return (ofinish-ostart) (we have this many bytes for you)
10451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * return 0 (no data now, but could have more later)
10551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * return -1 (absolutely no more data)
1062b41a213a1acd92193c724398919fcfdf89e1f55Shubham Ajmera     *
1072b41a213a1acd92193c724398919fcfdf89e1f55Shubham Ajmera     * Note:  Exceptions are only thrown after the stream is completely read.
1082b41a213a1acd92193c724398919fcfdf89e1f55Shubham Ajmera     * For AEAD ciphers a read() of any length will internally cause the
1092b41a213a1acd92193c724398919fcfdf89e1f55Shubham Ajmera     * whole stream to be read fully and verify the authentication tag before
1102b41a213a1acd92193c724398919fcfdf89e1f55Shubham Ajmera     * returning decrypted data or exceptions.
11151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
11251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    private int getMoreData() throws IOException {
113e115d420adb1319cc157c57695ee0d643adc6f96Shubham Ajmera        // Android-changed: The method was creating a new object every time update(byte[], int, int)
114e115d420adb1319cc157c57695ee0d643adc6f96Shubham Ajmera        // or doFinal() was called resulting in the old object being GCed. With do(byte[], int) and
115e115d420adb1319cc157c57695ee0d643adc6f96Shubham Ajmera        // update(byte[], int, int, byte[], int), we use already initialized obuffer.
11651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (done) return -1;
117e115d420adb1319cc157c57695ee0d643adc6f96Shubham Ajmera        ofinish = 0;
118e115d420adb1319cc157c57695ee0d643adc6f96Shubham Ajmera        ostart = 0;
119e115d420adb1319cc157c57695ee0d643adc6f96Shubham Ajmera        int expectedOutputSize = cipher.getOutputSize(ibuffer.length);
120e115d420adb1319cc157c57695ee0d643adc6f96Shubham Ajmera        if (obuffer == null || expectedOutputSize > obuffer.length) {
121e115d420adb1319cc157c57695ee0d643adc6f96Shubham Ajmera            obuffer = new byte[expectedOutputSize];
122e115d420adb1319cc157c57695ee0d643adc6f96Shubham Ajmera        }
12351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        int readin = input.read(ibuffer);
12451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (readin == -1) {
12551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            done = true;
12651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            try {
127e115d420adb1319cc157c57695ee0d643adc6f96Shubham Ajmera                // doFinal resets the cipher and it is the final call that is made. If there isn't
128e115d420adb1319cc157c57695ee0d643adc6f96Shubham Ajmera                // any more byte available, it returns 0. In case of any exception is raised,
129e115d420adb1319cc157c57695ee0d643adc6f96Shubham Ajmera                // obuffer will get reset and therefore, it is equivalent to no bytes returned.
130e115d420adb1319cc157c57695ee0d643adc6f96Shubham Ajmera                ofinish = cipher.doFinal(obuffer, 0);
1312b41a213a1acd92193c724398919fcfdf89e1f55Shubham Ajmera            } catch (IllegalBlockSizeException | BadPaddingException e) {
1322b41a213a1acd92193c724398919fcfdf89e1f55Shubham Ajmera                obuffer = null;
1332b41a213a1acd92193c724398919fcfdf89e1f55Shubham Ajmera                throw new IOException(e);
134e115d420adb1319cc157c57695ee0d643adc6f96Shubham Ajmera            } catch (ShortBufferException e) {
135e115d420adb1319cc157c57695ee0d643adc6f96Shubham Ajmera                obuffer = null;
136e115d420adb1319cc157c57695ee0d643adc6f96Shubham Ajmera                throw new IllegalStateException("ShortBufferException is not expected", e);
13751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
138e115d420adb1319cc157c57695ee0d643adc6f96Shubham Ajmera        } else {
139e115d420adb1319cc157c57695ee0d643adc6f96Shubham Ajmera            // update returns number of bytes stored in obuffer.
140e115d420adb1319cc157c57695ee0d643adc6f96Shubham Ajmera            try {
141e115d420adb1319cc157c57695ee0d643adc6f96Shubham Ajmera                ofinish = cipher.update(ibuffer, 0, readin, obuffer, 0);
142e115d420adb1319cc157c57695ee0d643adc6f96Shubham Ajmera            } catch (IllegalStateException e) {
143e115d420adb1319cc157c57695ee0d643adc6f96Shubham Ajmera                obuffer = null;
144e115d420adb1319cc157c57695ee0d643adc6f96Shubham Ajmera                throw e;
145e115d420adb1319cc157c57695ee0d643adc6f96Shubham Ajmera            } catch (ShortBufferException e) {
146e115d420adb1319cc157c57695ee0d643adc6f96Shubham Ajmera                // Should not reset the value of ofinish as the cipher is still not invalidated.
147e115d420adb1319cc157c57695ee0d643adc6f96Shubham Ajmera                obuffer = null;
148e115d420adb1319cc157c57695ee0d643adc6f96Shubham Ajmera                throw new IllegalStateException("ShortBufferException is not expected", e);
14951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            }
15051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
15151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return ofinish;
15251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
15351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
15451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
15551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Constructs a CipherInputStream from an InputStream and a
15651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Cipher.
15751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <br>Note: if the specified input stream or cipher is
15851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * null, a NullPointerException may be thrown later when
15951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * they are used.
16051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param is the to-be-processed input stream
16151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param c an initialized Cipher object
16251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
16351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public CipherInputStream(InputStream is, Cipher c) {
16451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        super(is);
16551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        input = is;
16651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        cipher = c;
16751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
16851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
16951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
17051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Constructs a CipherInputStream from an InputStream without
17151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * specifying a Cipher. This has the effect of constructing a
17251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * CipherInputStream using a NullCipher.
17351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <br>Note: if the specified input stream is null, a
17451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * NullPointerException may be thrown later when it is used.
17551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param is the to-be-processed input stream
17651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
17751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    protected CipherInputStream(InputStream is) {
17851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        super(is);
17951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        input = is;
18051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        cipher = new NullCipher();
18151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
18251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
18351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
18451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Reads the next byte of data from this input stream. The value
18551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * byte is returned as an <code>int</code> in the range
18651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <code>0</code> to <code>255</code>. If no byte is available
18751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * because the end of the stream has been reached, the value
18851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <code>-1</code> is returned. This method blocks until input data
18951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * is available, the end of the stream is detected, or an exception
19051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * is thrown.
19151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>
19251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
19351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @return  the next byte of data, or <code>-1</code> if the end of the
19451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *          stream is reached.
19551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @exception  IOException  if an I/O error occurs.
19651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @since JCE1.2
19751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
19851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public int read() throws IOException {
19951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (ostart >= ofinish) {
20051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // we loop for new data as the spec says we are blocking
20151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            int i = 0;
20251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            while (i == 0) i = getMoreData();
20351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if (i == -1) return -1;
20451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
20551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return ((int) obuffer[ostart++] & 0xff);
20651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    };
20751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
20851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
20951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Reads up to <code>b.length</code> bytes of data from this input
21051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * stream into an array of bytes.
21151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>
21251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * The <code>read</code> method of <code>InputStream</code> calls
21351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * the <code>read</code> method of three arguments with the arguments
21451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <code>b</code>, <code>0</code>, and <code>b.length</code>.
21551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
21651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param      b   the buffer into which the data is read.
21751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @return     the total number of bytes read into the buffer, or
21851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *             <code>-1</code> is there is no more data because the end of
21951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *             the stream has been reached.
22051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @exception  IOException  if an I/O error occurs.
22151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @see        java.io.InputStream#read(byte[], int, int)
22251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @since      JCE1.2
22351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
22451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public int read(byte b[]) throws IOException {
22551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return read(b, 0, b.length);
22651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
22751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
22851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
22951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Reads up to <code>len</code> bytes of data from this input stream
23051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * into an array of bytes. This method blocks until some input is
23151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * available. If the first argument is <code>null,</code> up to
23251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <code>len</code> bytes are read and discarded.
23351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
23451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param      b     the buffer into which the data is read.
23551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param      off   the start offset in the destination array
23651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *                   <code>buf</code>
23751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param      len   the maximum number of bytes read.
23851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @return     the total number of bytes read into the buffer, or
23951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *             <code>-1</code> if there is no more data because the end of
24051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *             the stream has been reached.
24151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @exception  IOException  if an I/O error occurs.
24251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @see        java.io.InputStream#read()
24351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @since      JCE1.2
24451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
24551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public int read(byte b[], int off, int len) throws IOException {
24651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (ostart >= ofinish) {
24751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            // we loop for new data as the spec says we are blocking
24851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            int i = 0;
24951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            while (i == 0) i = getMoreData();
25051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            if (i == -1) return -1;
25151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
25251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (len <= 0) {
25351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            return 0;
25451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
25551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        int available = ofinish - ostart;
25651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (len < available) available = len;
25751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (b != null) {
25851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            System.arraycopy(obuffer, ostart, b, off, available);
25951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
26051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        ostart = ostart + available;
26151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return available;
26251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
26351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
26451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
26551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Skips <code>n</code> bytes of input from the bytes that can be read
26651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * from this input stream without blocking.
26751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
26851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>Fewer bytes than requested might be skipped.
26951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * The actual number of bytes skipped is equal to <code>n</code> or
27051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * the result of a call to
2712b41a213a1acd92193c724398919fcfdf89e1f55Shubham Ajmera     * {@link #available() available},
27251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * whichever is smaller.
27351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * If <code>n</code> is less than zero, no bytes are skipped.
27451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
27551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>The actual number of bytes skipped is returned.
27651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
27751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @param      n the number of bytes to be skipped.
27851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @return     the actual number of bytes skipped.
27951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @exception  IOException  if an I/O error occurs.
28051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @since JCE1.2
28151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
28251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public long skip(long n) throws IOException {
28351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        int available = ofinish - ostart;
28451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (n > available) {
28551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            n = available;
28651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
28751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        if (n < 0) {
28851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski            return 0;
28951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
29051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        ostart += n;
29151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return n;
29251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
29351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
29451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
29551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Returns the number of bytes that can be read from this input
29651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * stream without blocking. The <code>available</code> method of
29751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <code>InputStream</code> returns <code>0</code>. This method
29851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <B>should</B> be overridden by subclasses.
29951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
30051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @return     the number of bytes that can be read from this input stream
30151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *             without blocking.
30251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @exception  IOException  if an I/O error occurs.
30351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @since      JCE1.2
30451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
30551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public int available() throws IOException {
30651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return (ofinish - ostart);
30751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
30851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
30951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
31051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Closes this input stream and releases any system resources
31151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * associated with the stream.
31251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * <p>
31351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * The <code>close</code> method of <code>CipherInputStream</code>
31451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * calls the <code>close</code> method of its underlying input
31551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * stream.
31651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
31751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @exception  IOException  if an I/O error occurs.
31851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @since JCE1.2
31951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
32051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public void close() throws IOException {
3212b41a213a1acd92193c724398919fcfdf89e1f55Shubham Ajmera        if (closed) {
3222b41a213a1acd92193c724398919fcfdf89e1f55Shubham Ajmera            return;
32351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
3242b41a213a1acd92193c724398919fcfdf89e1f55Shubham Ajmera
3252b41a213a1acd92193c724398919fcfdf89e1f55Shubham Ajmera        closed = true;
3262b41a213a1acd92193c724398919fcfdf89e1f55Shubham Ajmera        input.close();
3272b41a213a1acd92193c724398919fcfdf89e1f55Shubham Ajmera
328b1fb0c291caf4025e060b81cba92a3299a8b8033Adam Vartanian        // Android-removed: Removed a now-inaccurate comment
3292b41a213a1acd92193c724398919fcfdf89e1f55Shubham Ajmera        if (!done) {
3302b41a213a1acd92193c724398919fcfdf89e1f55Shubham Ajmera            try {
3312b41a213a1acd92193c724398919fcfdf89e1f55Shubham Ajmera                cipher.doFinal();
3322b41a213a1acd92193c724398919fcfdf89e1f55Shubham Ajmera            }
3332b41a213a1acd92193c724398919fcfdf89e1f55Shubham Ajmera            catch (BadPaddingException | IllegalBlockSizeException ex) {
334b1fb0c291caf4025e060b81cba92a3299a8b8033Adam Vartanian                // Android-changed: Added throw if bad tag is seen.  See b/31590622.
335b1fb0c291caf4025e060b81cba92a3299a8b8033Adam Vartanian                if (ex instanceof AEADBadTagException) {
336b1fb0c291caf4025e060b81cba92a3299a8b8033Adam Vartanian                    throw new IOException(ex);
337b1fb0c291caf4025e060b81cba92a3299a8b8033Adam Vartanian                }
3382b41a213a1acd92193c724398919fcfdf89e1f55Shubham Ajmera            }
33951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        }
34051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        ostart = 0;
34151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        ofinish = 0;
34251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
34351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski
34451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    /**
34551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * Tests if this input stream supports the <code>mark</code>
34651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * and <code>reset</code> methods, which it does not.
34751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *
34851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @return  <code>false</code>, since this class does not support the
34951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     *          <code>mark</code> and <code>reset</code> methods.
35051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @see     java.io.InputStream#mark(int)
35151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @see     java.io.InputStream#reset()
35251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     * @since   JCE1.2
35351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski     */
35451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    public boolean markSupported() {
35551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski        return false;
35651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski    }
35751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski}
358