1adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/*
2adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  Licensed to the Apache Software Foundation (ASF) under one or more
3adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  contributor license agreements.  See the NOTICE file distributed with
4adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  this work for additional information regarding copyright ownership.
5adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  The ASF licenses this file to You under the Apache License, Version 2.0
6adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  (the "License"); you may not use this file except in compliance with
7adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  the License.  You may obtain a copy of the License at
8adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
9adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *     http://www.apache.org/licenses/LICENSE-2.0
10adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
11adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  Unless required by applicable law or agreed to in writing, software
12adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  distributed under the License is distributed on an "AS IS" BASIS,
13adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  See the License for the specific language governing permissions and
15adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  limitations under the License.
16adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */
17adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
18adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpackage javax.crypto;
19adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
20adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.nio.ByteBuffer;
21adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.security.InvalidAlgorithmParameterException;
22adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.security.InvalidKeyException;
23adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.security.Key;
24adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.security.NoSuchAlgorithmException;
25adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.security.NoSuchProviderException;
26adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.security.Provider;
27adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.security.Security;
28adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.security.spec.AlgorithmParameterSpec;
29adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport org.apache.harmony.security.fortress.Engine;
30adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
31adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
32adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/**
33adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * This class provides the public API for <i>Message Authentication Code</i>
34adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * (MAC) algorithms.
35adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */
36adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpublic class Mac implements Cloneable {
37adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
38adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    //Used to access common engine functionality
390a480846a9798c763b088a122ab0dcd3dc3a17b6Brian Carlstrom    private static final Engine ENGINE = new Engine("Mac");
40adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
41adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    // Store used provider
42adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private final Provider provider;
43adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
44adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    // Store used spi implementation
45adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private final MacSpi spiImpl;
46adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
47adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    // Store used algorithm name
48adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private final String algorithm;
49adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
50adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    // Store Mac state (initialized or not initialized)
51adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private boolean isInitMac;
52adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
53adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
54adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Creates a new {@code Mac} instance.
55ce9ec01c0b6da3f3ba01e9c81cc3e5a461aabfb6Jesse Wilson     *
56adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param macSpi
57adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the implementation delegate.
58adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param provider
59adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the implementation provider.
60adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param algorithm
61adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the name of the MAC algorithm.
62adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
63adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    protected Mac(MacSpi macSpi, Provider provider, String algorithm) {
64adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this.provider = provider;
65adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this.algorithm = algorithm;
66adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this.spiImpl = macSpi;
67adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this.isInitMac = false;
68adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
69adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
70adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
71adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns the name of the MAC algorithm.
72f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
73adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the name of the MAC algorithm.
74adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
75adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public final String getAlgorithm() {
76adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return algorithm;
77adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
78adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
79adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
80adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns the provider of this {@code Mac} instance.
81ce9ec01c0b6da3f3ba01e9c81cc3e5a461aabfb6Jesse Wilson     *
82adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the provider of this {@code Mac} instance.
83adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
84adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public final Provider getProvider() {
85adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return provider;
86adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
87adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
88adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
89adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Creates a new {@code Mac} instance that provides the specified MAC
90adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * algorithm.
91f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
92adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param algorithm
93adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the name of the requested MAC algorithm.
94adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the new {@code Mac} instance.
95adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws NoSuchAlgorithmException
96adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if the specified algorithm is not available by any provider.
97adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws NullPointerException
98ce9ec01c0b6da3f3ba01e9c81cc3e5a461aabfb6Jesse Wilson     *             if {@code algorithm} is {@code null} (instead of
99ce9ec01c0b6da3f3ba01e9c81cc3e5a461aabfb6Jesse Wilson     *             NoSuchAlgorithmException as in 1.4 release).
100adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
101adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public static final Mac getInstance(String algorithm)
102adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throws NoSuchAlgorithmException {
103adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (algorithm == null) {
10486acc043d3334651ee26c65467d78d6cefedd397Kenny Root            throw new NullPointerException("algorithm == null");
105adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1066cdb6b7e6939270ccd21790ec95e42197cefc0c3Brian Carlstrom        Engine.SpiAndProvider sap = ENGINE.getInstance(algorithm, null);
1076cdb6b7e6939270ccd21790ec95e42197cefc0c3Brian Carlstrom        return new Mac((MacSpi) sap.spi, sap.provider, algorithm);
108adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
109adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
110adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
111adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Creates a new {@code Mac} instance that provides the specified MAC
112adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * algorithm from the specified provider.
113f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
114adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param algorithm
115adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the name of the requested MAC algorithm.
116adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param provider
117adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the name of the provider that is providing the algorithm.
118adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the new {@code Mac} instance.
119adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws NoSuchAlgorithmException
120adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if the specified algorithm is not provided by the specified
121adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             provider.
122adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws NoSuchProviderException
123adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if the specified provider is not available.
124adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IllegalArgumentException
125adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if the specified provider name is {@code null} or empty.
126adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws NullPointerException
127ce9ec01c0b6da3f3ba01e9c81cc3e5a461aabfb6Jesse Wilson     *             if {@code algorithm} is {@code null} (instead of
128ce9ec01c0b6da3f3ba01e9c81cc3e5a461aabfb6Jesse Wilson     *             NoSuchAlgorithmException as in 1.4 release).
129adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
130adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public static final Mac getInstance(String algorithm, String provider)
131adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throws NoSuchAlgorithmException, NoSuchProviderException {
13280a7fbab52b96c9fd47c72f8987d1babe2cd001dElliott Hughes        if (provider == null || provider.isEmpty()) {
13380a7fbab52b96c9fd47c72f8987d1babe2cd001dElliott Hughes            throw new IllegalArgumentException("Provider is null or empty");
134adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
135adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        Provider impProvider = Security.getProvider(provider);
136adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (impProvider == null) {
137adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throw new NoSuchProviderException(provider);
138adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
139adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return getInstance(algorithm, impProvider);
140adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
141adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
142adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
143adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Creates a new {@code Mac} instance that provides the specified MAC
144adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * algorithm from the specified provider.
145f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
146adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param algorithm
147adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the name of the requested MAC algorithm.
148adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param provider
149adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the provider that is providing the algorithm.
150adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the new {@code Mac} instance.
151adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws NoSuchAlgorithmException
152adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if the specified algorithm is not provided by the specified
153adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             provider.
154adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IllegalArgumentException
155adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if {@code provider} is {@code null}.
156adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws NullPointerException
157ce9ec01c0b6da3f3ba01e9c81cc3e5a461aabfb6Jesse Wilson     *             if {@code algorithm} is {@code null} (instead of
158ce9ec01c0b6da3f3ba01e9c81cc3e5a461aabfb6Jesse Wilson     *             NoSuchAlgorithmException as in 1.4 release).
159adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
160adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public static final Mac getInstance(String algorithm, Provider provider)
161adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throws NoSuchAlgorithmException {
162adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (provider == null) {
16380a7fbab52b96c9fd47c72f8987d1babe2cd001dElliott Hughes            throw new IllegalArgumentException("provider == null");
164adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
165adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (algorithm == null) {
16686acc043d3334651ee26c65467d78d6cefedd397Kenny Root            throw new NullPointerException("algorithm == null");
167adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
1686cdb6b7e6939270ccd21790ec95e42197cefc0c3Brian Carlstrom        Object spi = ENGINE.getInstance(algorithm, provider, null);
1696cdb6b7e6939270ccd21790ec95e42197cefc0c3Brian Carlstrom        return new Mac((MacSpi) spi, provider, algorithm);
170adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
171adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
172adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
173adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns the length of this MAC (in bytes).
174ce9ec01c0b6da3f3ba01e9c81cc3e5a461aabfb6Jesse Wilson     *
175adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the length of this MAC (in bytes).
176adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
177adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public final int getMacLength() {
178adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return spiImpl.engineGetMacLength();
179adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
180adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
181adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
182adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Initializes this {@code Mac} instance with the specified key and
183adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * algorithm parameters.
184ce9ec01c0b6da3f3ba01e9c81cc3e5a461aabfb6Jesse Wilson     *
185adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param key
186adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the key to initialize this algorithm.
187adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param params
188adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the parameters for this algorithm.
189adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws InvalidKeyException
190adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if the specified key cannot be used to initialize this
191adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             algorithm, or it is null.
192adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws InvalidAlgorithmParameterException
193adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if the specified parameters cannot be used to initialize this
194adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             algorithm.
195adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
196adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public final void init(Key key, AlgorithmParameterSpec params)
197adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throws InvalidKeyException, InvalidAlgorithmParameterException {
198adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (key == null) {
19980a7fbab52b96c9fd47c72f8987d1babe2cd001dElliott Hughes            throw new InvalidKeyException("key == null");
200adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
201adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        spiImpl.engineInit(key, params);
202adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        isInitMac = true;
203adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
204adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
205adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
206adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Initializes this {@code Mac} instance with the specified key.
207ce9ec01c0b6da3f3ba01e9c81cc3e5a461aabfb6Jesse Wilson     *
208adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param key
209adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the key to initialize this algorithm.
210adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws InvalidKeyException
211adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if initialization fails because the provided key is {@code
212adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             null}.
213adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws RuntimeException
214adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if the specified key cannot be used to initialize this
215adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             algorithm.
216adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
217adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public final void init(Key key) throws InvalidKeyException {
218adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (key == null) {
21980a7fbab52b96c9fd47c72f8987d1babe2cd001dElliott Hughes            throw new InvalidKeyException("key == null");
220adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
221adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        try {
222adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            spiImpl.engineInit(key, null);
223adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            isInitMac = true;
224adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } catch (InvalidAlgorithmParameterException e) {
225adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throw new RuntimeException(e);
226adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
227adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
228adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
229adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
230adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Updates this {@code Mac} instance with the specified byte.
231ce9ec01c0b6da3f3ba01e9c81cc3e5a461aabfb6Jesse Wilson     *
232adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param input
233adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the byte
234adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IllegalStateException
235adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if this MAC is not initialized.
236adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
237adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public final void update(byte input) throws IllegalStateException {
238adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (!isInitMac) {
23980a7fbab52b96c9fd47c72f8987d1babe2cd001dElliott Hughes            throw new IllegalStateException();
240adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
241adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        spiImpl.engineUpdate(input);
242adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
243adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
244adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
245adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Updates this {@code Mac} instance with the data from the specified buffer
246adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * {@code input} from the specified {@code offset} and length {@code len}.
247ce9ec01c0b6da3f3ba01e9c81cc3e5a461aabfb6Jesse Wilson     *
248adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param input
249adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the buffer.
250adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param offset
251adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the offset in the buffer.
252adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param len
253adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the length of the data in the buffer.
254adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IllegalStateException
255adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if this MAC is not initialized.
256adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IllegalArgumentException
257adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if {@code offset} and {@code len} do not specified a valid
258adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             chunk in {@code input} buffer.
259adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
26080a7fbab52b96c9fd47c72f8987d1babe2cd001dElliott Hughes    public final void update(byte[] input, int offset, int len) throws IllegalStateException {
261adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (!isInitMac) {
26280a7fbab52b96c9fd47c72f8987d1babe2cd001dElliott Hughes            throw new IllegalStateException();
263adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
264adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (input == null) {
265adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return;
266adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
267adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if ((offset < 0) || (len < 0) || ((offset + len) > input.length)) {
2685043cc0baaccf647d97a20a9e88f174215e4c9ccBrian Carlstrom            throw new IllegalArgumentException("Incorrect arguments."
2695043cc0baaccf647d97a20a9e88f174215e4c9ccBrian Carlstrom                                               + " input.length=" + input.length
2705043cc0baaccf647d97a20a9e88f174215e4c9ccBrian Carlstrom                                               + " offset=" + offset + ", len=" + len);
271adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
272adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        spiImpl.engineUpdate(input, offset, len);
273adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
274adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
275adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
276adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Copies the buffer provided as input for further processing.
277ce9ec01c0b6da3f3ba01e9c81cc3e5a461aabfb6Jesse Wilson     *
278adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param input
279adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the buffer.
280adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IllegalStateException
281adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if this MAC is not initialized.
282adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
283adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public final void update(byte[] input) throws IllegalStateException {
284adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (!isInitMac) {
28580a7fbab52b96c9fd47c72f8987d1babe2cd001dElliott Hughes            throw new IllegalStateException();
286adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
287adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (input != null) {
288adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            spiImpl.engineUpdate(input, 0, input.length);
289adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
290adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
291adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
292adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
293adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Updates this {@code Mac} instance with the data from the specified
294adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * buffer, starting at {@link ByteBuffer#position()}, including the next
295adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * {@link ByteBuffer#remaining()} bytes.
296ce9ec01c0b6da3f3ba01e9c81cc3e5a461aabfb6Jesse Wilson     *
297adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param input
298adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the buffer.
299adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IllegalStateException
300adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if this MAC is not initialized.
301adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
302adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public final void update(ByteBuffer input) {
303adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (!isInitMac) {
30480a7fbab52b96c9fd47c72f8987d1babe2cd001dElliott Hughes            throw new IllegalStateException();
305adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
306adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (input != null) {
307adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            spiImpl.engineUpdate(input);
308adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } else {
30980a7fbab52b96c9fd47c72f8987d1babe2cd001dElliott Hughes            throw new IllegalArgumentException("input == null");
310adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
311adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
312adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
313adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
314adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Computes the digest of this MAC based on the data previously specified in
315adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * {@link #update} calls.
316adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <p>
317adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * This {@code Mac} instance is reverted to its initial state and can be
318adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * used to start the next MAC computation with the same parameters or
319adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * initialized with different parameters.
320ce9ec01c0b6da3f3ba01e9c81cc3e5a461aabfb6Jesse Wilson     *
321adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the generated digest.
322adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IllegalStateException
323adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if this MAC is not initialized.
324adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
325adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public final byte[] doFinal() throws IllegalStateException {
326adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (!isInitMac) {
32780a7fbab52b96c9fd47c72f8987d1babe2cd001dElliott Hughes            throw new IllegalStateException();
328adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
329adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return spiImpl.engineDoFinal();
330adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
331adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
332adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
333adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Computes the digest of this MAC based on the data previously specified in
334adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * {@link #update} calls and stores the digest in the specified {@code
335adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * output} buffer at offset {@code outOffset}.
336adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <p>
337adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * This {@code Mac} instance is reverted to its initial state and can be
338adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * used to start the next MAC computation with the same parameters or
339adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * initialized with different parameters.
340ce9ec01c0b6da3f3ba01e9c81cc3e5a461aabfb6Jesse Wilson     *
341adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param output
342adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the output buffer
343adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param outOffset
344adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the offset in the output buffer
345adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws ShortBufferException
346adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if the specified output buffer is either too small for the
347adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             digest to be stored, the specified output buffer is {@code
348adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             null}, or the specified offset is negative or past the length
349adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             of the output buffer.
350adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IllegalStateException
351adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if this MAC is not initialized.
352adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
353adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public final void doFinal(byte[] output, int outOffset)
354adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throws ShortBufferException, IllegalStateException {
355adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (!isInitMac) {
35680a7fbab52b96c9fd47c72f8987d1babe2cd001dElliott Hughes            throw new IllegalStateException();
357adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
358adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (output == null) {
35980a7fbab52b96c9fd47c72f8987d1babe2cd001dElliott Hughes            throw new ShortBufferException("output == null");
360adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
361adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if ((outOffset < 0) || (outOffset >= output.length)) {
36280a7fbab52b96c9fd47c72f8987d1babe2cd001dElliott Hughes            throw new ShortBufferException("Incorrect outOffset: " + outOffset);
363adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
364adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        int t = spiImpl.engineGetMacLength();
365adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (t > (output.length - outOffset)) {
36680a7fbab52b96c9fd47c72f8987d1babe2cd001dElliott Hughes            throw new ShortBufferException("Output buffer is short. Needed " + t + " bytes.");
367adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
368adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        byte[] result = spiImpl.engineDoFinal();
369adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        System.arraycopy(result, 0, output, outOffset, result.length);
370adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
371adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
372adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
373adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
374adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Computes the digest of this MAC based on the data previously specified on
375adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * {@link #update} calls and on the final bytes specified by {@code input}
376adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * (or based on those bytes only).
377adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <p>
378adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * This {@code Mac} instance is reverted to its initial state and can be
379adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * used to start the next MAC computation with the same parameters or
380adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * initialized with different parameters.
381ce9ec01c0b6da3f3ba01e9c81cc3e5a461aabfb6Jesse Wilson     *
382adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param input
383adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the final bytes.
384adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the generated digest.
385adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IllegalStateException
386adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if this MAC is not initialized.
387adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
388adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public final byte[] doFinal(byte[] input) throws IllegalStateException {
389adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (!isInitMac) {
39080a7fbab52b96c9fd47c72f8987d1babe2cd001dElliott Hughes            throw new IllegalStateException();
391adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
392adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (input != null) {
393adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            spiImpl.engineUpdate(input, 0, input.length);
394adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
395adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return spiImpl.engineDoFinal();
396adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
397adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
398adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
399adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Resets this {@code Mac} instance to its initial state.
400adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <p>
401adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * This {@code Mac} instance is reverted to its initial state and can be
402adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * used to start the next MAC computation with the same parameters or
403adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * initialized with different parameters.
404adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
405adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public final void reset() {
406adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        spiImpl.engineReset();
407adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
408adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
409adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
410adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Clones this {@code Mac} instance and the underlying implementation.
411ce9ec01c0b6da3f3ba01e9c81cc3e5a461aabfb6Jesse Wilson     *
412adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the cloned instance.
413adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws CloneNotSupportedException
414adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if the underlying implementation does not support cloning.
415adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
416adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    @Override
417adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public final Object clone() throws CloneNotSupportedException {
418f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes        MacSpi newSpiImpl = (MacSpi)spiImpl.clone();
419adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        Mac mac = new Mac(newSpiImpl, this.provider, this.algorithm);
420f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes        mac.isInitMac = this.isInitMac;
421adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return mac;
422adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
42380a7fbab52b96c9fd47c72f8987d1babe2cd001dElliott Hughes}
424