1ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin/*
2ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin * Copyright (C) 2015 The Android Open Source Project
3ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin *
4ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin * Licensed under the Apache License, Version 2.0 (the "License");
5ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin * you may not use this file except in compliance with the License.
6ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin * You may obtain a copy of the License at
7ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin *
8ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin *      http://www.apache.org/licenses/LICENSE-2.0
9ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin *
10ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin * Unless required by applicable law or agreed to in writing, software
11ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin * distributed under the License is distributed on an "AS IS" BASIS,
12ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin * See the License for the specific language governing permissions and
14ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin * limitations under the License.
15ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin */
16ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin
17ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubinpackage android.security.keystore;
18ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin
19ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubinimport android.annotation.CallSuper;
20ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubinimport android.annotation.NonNull;
21ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubinimport android.os.IBinder;
22ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubinimport android.security.KeyStore;
23ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubinimport android.security.KeyStoreException;
24ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubinimport android.security.keymaster.KeymasterArguments;
25ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubinimport android.security.keymaster.KeymasterDefs;
26ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubinimport android.security.keymaster.OperationResult;
27ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin
284a0ff7ca984d29bd34b02e54441957cad65e8b53Alex Klyubinimport libcore.util.EmptyArray;
29ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin
30ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubinimport java.nio.ByteBuffer;
31ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubinimport java.security.InvalidKeyException;
32ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubinimport java.security.InvalidParameterException;
33ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubinimport java.security.PrivateKey;
34ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubinimport java.security.ProviderException;
35ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubinimport java.security.PublicKey;
36ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubinimport java.security.SecureRandom;
37ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubinimport java.security.SignatureException;
38ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubinimport java.security.SignatureSpi;
39ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin
40ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin/**
41ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin * Base class for {@link SignatureSpi} implementations of Android KeyStore backed ciphers.
42ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin *
43ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin * @hide
44ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin */
45ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubinabstract class AndroidKeyStoreSignatureSpiBase extends SignatureSpi
46ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin        implements KeyStoreCryptoOperation {
47ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin    private final KeyStore mKeyStore;
48ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin
49ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin    // Fields below are populated by SignatureSpi.engineInitSign/engineInitVerify and KeyStore.begin
50ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin    // and should be preserved after SignatureSpi.engineSign/engineVerify finishes.
51ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin    private boolean mSigning;
52ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin    private AndroidKeyStoreKey mKey;
53ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin
54ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin    /**
55ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin     * Token referencing this operation inside keystore service. It is initialized by
56ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin     * {@code engineInitSign}/{@code engineInitVerify} and is invalidated when
57ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin     * {@code engineSign}/{@code engineVerify} succeeds and on some error conditions in between.
58ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin     */
59ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin    private IBinder mOperationToken;
60ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin    private long mOperationHandle;
61d23dc502b0a1952887d4453cba98aa2e3d2f5009Alex Klyubin    private KeyStoreCryptoOperationStreamer mMessageStreamer;
62ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin
63ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin    /**
64ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin     * Encountered exception which could not be immediately thrown because it was encountered inside
65ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin     * a method that does not throw checked exception. This exception will be thrown from
66ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin     * {@code engineSign} or {@code engineVerify}. Once such an exception is encountered,
67ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin     * {@code engineUpdate} starts ignoring input data.
68ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin     */
69ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin    private Exception mCachedException;
70ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin
71ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin    AndroidKeyStoreSignatureSpiBase() {
72ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin        mKeyStore = KeyStore.getInstance();
73ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin    }
74ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin
75ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin    @Override
76ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin    protected final void engineInitSign(PrivateKey key) throws InvalidKeyException {
77ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin        engineInitSign(key, null);
78ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin    }
79ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin
80ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin    @Override
81ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin    protected final void engineInitSign(PrivateKey privateKey, SecureRandom random)
82ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin            throws InvalidKeyException {
83ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin        resetAll();
84ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin
85ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin        boolean success = false;
86ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin        try {
87ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin            if (privateKey == null) {
88ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin                throw new InvalidKeyException("Unsupported key: null");
89ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin            }
90ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin            AndroidKeyStoreKey keystoreKey;
91ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin            if (privateKey instanceof AndroidKeyStorePrivateKey) {
92ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin                keystoreKey = (AndroidKeyStoreKey) privateKey;
93ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin            } else {
94ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin                throw new InvalidKeyException("Unsupported private key type: " + privateKey);
95ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin            }
96ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin            mSigning = true;
97ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin            initKey(keystoreKey);
98ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin            appRandom = random;
99ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin            ensureKeystoreOperationInitialized();
100ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin            success = true;
101ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin        } finally {
102ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin            if (!success) {
103ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin                resetAll();
104ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin            }
105ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin        }
106ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin    }
107ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin
108ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin    @Override
109ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin    protected final void engineInitVerify(PublicKey publicKey) throws InvalidKeyException {
110ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin        resetAll();
111ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin
112ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin        boolean success = false;
113ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin        try {
114ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin            if (publicKey == null) {
115ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin                throw new InvalidKeyException("Unsupported key: null");
116ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin            }
117ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin            AndroidKeyStoreKey keystoreKey;
118ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin            if (publicKey instanceof AndroidKeyStorePublicKey) {
119ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin                keystoreKey = (AndroidKeyStorePublicKey) publicKey;
120ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin            } else {
121ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin                throw new InvalidKeyException("Unsupported public key type: " + publicKey);
122ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin            }
123ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin            mSigning = false;
124ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin            initKey(keystoreKey);
125ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin            appRandom = null;
126ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin            ensureKeystoreOperationInitialized();
127ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin            success = true;
128ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin        } finally {
129ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin            if (!success) {
130ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin                resetAll();
131ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin            }
132ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin        }
133ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin    }
134ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin
135ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin    /**
136ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin     * Configures this signature instance to use the provided key.
137ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin     *
138ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin     * @throws InvalidKeyException if the {@code key} is not suitable.
139ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin     */
140ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin    @CallSuper
141ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin    protected void initKey(AndroidKeyStoreKey key) throws InvalidKeyException {
142ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin        mKey = key;
143ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin    }
144ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin
145ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin    /**
146ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin     * Resets this cipher to its pristine pre-init state. This must be equivalent to obtaining a new
147ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin     * cipher instance.
148ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin     *
149ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin     * <p>Subclasses storing additional state should override this method, reset the additional
150ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin     * state, and then chain to superclass.
151ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin     */
152ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin    @CallSuper
153ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin    protected void resetAll() {
154ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin        IBinder operationToken = mOperationToken;
155ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin        if (operationToken != null) {
156ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin            mOperationToken = null;
157ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin            mKeyStore.abort(operationToken);
158ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin        }
159ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin        mSigning = false;
160ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin        mKey = null;
161ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin        appRandom = null;
162ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin        mOperationToken = null;
163ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin        mOperationHandle = 0;
164ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin        mMessageStreamer = null;
165ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin        mCachedException = null;
166ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin    }
167ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin
168ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin    /**
169ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin     * Resets this cipher while preserving the initialized state. This must be equivalent to
170ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin     * rolling back the cipher's state to just after the most recent {@code engineInit} completed
171ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin     * successfully.
172ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin     *
173ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin     * <p>Subclasses storing additional post-init state should override this method, reset the
174ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin     * additional state, and then chain to superclass.
175ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin     */
176ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin    @CallSuper
177ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin    protected void resetWhilePreservingInitState() {
178ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin        IBinder operationToken = mOperationToken;
179ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin        if (operationToken != null) {
180ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin            mOperationToken = null;
181ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin            mKeyStore.abort(operationToken);
182ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin        }
183ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin        mOperationHandle = 0;
184ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin        mMessageStreamer = null;
185ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin        mCachedException = null;
186ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin    }
187ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin
188ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin    private void ensureKeystoreOperationInitialized() throws InvalidKeyException {
189ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin        if (mMessageStreamer != null) {
190ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin            return;
191ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin        }
192ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin        if (mCachedException != null) {
193ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin            return;
194ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin        }
195ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin        if (mKey == null) {
196ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin            throw new IllegalStateException("Not initialized");
197ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin        }
198ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin
199ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin        KeymasterArguments keymasterInputArgs = new KeymasterArguments();
200ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin        addAlgorithmSpecificParametersToBegin(keymasterInputArgs);
201ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin
202ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin        OperationResult opResult = mKeyStore.begin(
203ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin                mKey.getAlias(),
204ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin                mSigning ? KeymasterDefs.KM_PURPOSE_SIGN : KeymasterDefs.KM_PURPOSE_VERIFY,
205ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin                true, // permit aborting this operation if keystore runs out of resources
206ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin                keymasterInputArgs,
2073876b1be27e3aefde9a72eb2e4f856e94fc5f946Alex Klyubin                null, // no additional entropy for begin -- only finish might need some
2083876b1be27e3aefde9a72eb2e4f856e94fc5f946Alex Klyubin                mKey.getUid());
209ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin        if (opResult == null) {
210ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin            throw new KeyStoreConnectException();
211ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin        }
212ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin
213ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin        // Store operation token and handle regardless of the error code returned by KeyStore to
214ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin        // ensure that the operation gets aborted immediately if the code below throws an exception.
215ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin        mOperationToken = opResult.token;
216ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin        mOperationHandle = opResult.operationHandle;
217ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin
218ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin        // If necessary, throw an exception due to KeyStore operation having failed.
219ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin        InvalidKeyException e = KeyStoreCryptoOperationUtils.getInvalidKeyExceptionForInit(
220ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin                mKeyStore, mKey, opResult.resultCode);
221ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin        if (e != null) {
222ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin            throw e;
223ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin        }
224ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin
225ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin        if (mOperationToken == null) {
226ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin            throw new ProviderException("Keystore returned null operation token");
227ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin        }
228ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin        if (mOperationHandle == 0) {
229ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin            throw new ProviderException("Keystore returned invalid operation handle");
230ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin        }
231ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin
232d23dc502b0a1952887d4453cba98aa2e3d2f5009Alex Klyubin        mMessageStreamer = createMainDataStreamer(mKeyStore, opResult.token);
233d23dc502b0a1952887d4453cba98aa2e3d2f5009Alex Klyubin    }
234d23dc502b0a1952887d4453cba98aa2e3d2f5009Alex Klyubin
235d23dc502b0a1952887d4453cba98aa2e3d2f5009Alex Klyubin    /**
236d23dc502b0a1952887d4453cba98aa2e3d2f5009Alex Klyubin     * Creates a streamer which sends the message to be signed/verified into the provided KeyStore
237d23dc502b0a1952887d4453cba98aa2e3d2f5009Alex Klyubin     *
238d23dc502b0a1952887d4453cba98aa2e3d2f5009Alex Klyubin     * <p>This implementation returns a working streamer.
239d23dc502b0a1952887d4453cba98aa2e3d2f5009Alex Klyubin     */
240d23dc502b0a1952887d4453cba98aa2e3d2f5009Alex Klyubin    @NonNull
241d23dc502b0a1952887d4453cba98aa2e3d2f5009Alex Klyubin    protected KeyStoreCryptoOperationStreamer createMainDataStreamer(
242d23dc502b0a1952887d4453cba98aa2e3d2f5009Alex Klyubin            KeyStore keyStore, IBinder operationToken) {
243d23dc502b0a1952887d4453cba98aa2e3d2f5009Alex Klyubin        return new KeyStoreCryptoOperationChunkedStreamer(
244ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin                new KeyStoreCryptoOperationChunkedStreamer.MainDataStream(
245d23dc502b0a1952887d4453cba98aa2e3d2f5009Alex Klyubin                        keyStore, operationToken));
246ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin    }
247ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin
248ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin    @Override
249ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin    public final long getOperationHandle() {
250ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin        return mOperationHandle;
251ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin    }
252ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin
253ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin    @Override
254ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin    protected final void engineUpdate(byte[] b, int off, int len) throws SignatureException {
255ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin        if (mCachedException != null) {
256ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin            throw new SignatureException(mCachedException);
257ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin        }
258ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin
259ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin        try {
260ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin            ensureKeystoreOperationInitialized();
261ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin        } catch (InvalidKeyException e) {
262ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin            throw new SignatureException(e);
263ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin        }
264ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin
265ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin        if (len == 0) {
266ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin            return;
267ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin        }
268ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin
269ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin        byte[] output;
270ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin        try {
271ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin            output = mMessageStreamer.update(b, off, len);
272ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin        } catch (KeyStoreException e) {
273ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin            throw new SignatureException(e);
274ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin        }
275ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin
276ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin        if (output.length != 0) {
277ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin            throw new ProviderException(
278ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin                    "Update operation unexpectedly produced output: " + output.length + " bytes");
279ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin        }
280ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin    }
281ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin
282ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin    @Override
283ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin    protected final void engineUpdate(byte b) throws SignatureException {
284ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin        engineUpdate(new byte[] {b}, 0, 1);
285ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin    }
286ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin
287ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin    @Override
288ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin    protected final void engineUpdate(ByteBuffer input) {
289ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin        byte[] b;
290ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin        int off;
291ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin        int len = input.remaining();
292ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin        if (input.hasArray()) {
293ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin            b = input.array();
294ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin            off = input.arrayOffset() + input.position();
295ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin            input.position(input.limit());
296ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin        } else {
297ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin            b = new byte[len];
298ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin            off = 0;
299ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin            input.get(b);
300ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin        }
301ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin
302ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin        try {
303ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin            engineUpdate(b, off, len);
304ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin        } catch (SignatureException e) {
305ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin            mCachedException = e;
306ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin        }
307ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin    }
308ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin
309ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin    @Override
310ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin    protected final int engineSign(byte[] out, int outOffset, int outLen)
311ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin            throws SignatureException {
312ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin        return super.engineSign(out, outOffset, outLen);
313ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin    }
314ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin
315ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin    @Override
316ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin    protected final byte[] engineSign() throws SignatureException {
317ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin        if (mCachedException != null) {
318ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin            throw new SignatureException(mCachedException);
319ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin        }
320ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin
321ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin        byte[] signature;
322ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin        try {
323ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin            ensureKeystoreOperationInitialized();
324a72b55195c23fc06d1600efe8f6aac85290c7f8fAlex Klyubin
325a72b55195c23fc06d1600efe8f6aac85290c7f8fAlex Klyubin            byte[] additionalEntropy =
326a72b55195c23fc06d1600efe8f6aac85290c7f8fAlex Klyubin                    KeyStoreCryptoOperationUtils.getRandomBytesToMixIntoKeystoreRng(
327a72b55195c23fc06d1600efe8f6aac85290c7f8fAlex Klyubin                            appRandom, getAdditionalEntropyAmountForSign());
328d23dc502b0a1952887d4453cba98aa2e3d2f5009Alex Klyubin            signature = mMessageStreamer.doFinal(
329d23dc502b0a1952887d4453cba98aa2e3d2f5009Alex Klyubin                    EmptyArray.BYTE, 0, 0,
330d23dc502b0a1952887d4453cba98aa2e3d2f5009Alex Klyubin                    null, // no signature provided -- it'll be generated by this invocation
331d23dc502b0a1952887d4453cba98aa2e3d2f5009Alex Klyubin                    additionalEntropy);
332ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin        } catch (InvalidKeyException | KeyStoreException e) {
333ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin            throw new SignatureException(e);
334ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin        }
335ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin
336ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin        resetWhilePreservingInitState();
337ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin        return signature;
338ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin    }
339ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin
340ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin    @Override
341ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin    protected final boolean engineVerify(byte[] signature) throws SignatureException {
342ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin        if (mCachedException != null) {
343ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin            throw new SignatureException(mCachedException);
344ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin        }
345ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin
346ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin        try {
347ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin            ensureKeystoreOperationInitialized();
348d23dc502b0a1952887d4453cba98aa2e3d2f5009Alex Klyubin        } catch (InvalidKeyException e) {
349d23dc502b0a1952887d4453cba98aa2e3d2f5009Alex Klyubin            throw new SignatureException(e);
350d23dc502b0a1952887d4453cba98aa2e3d2f5009Alex Klyubin        }
351d23dc502b0a1952887d4453cba98aa2e3d2f5009Alex Klyubin
352d23dc502b0a1952887d4453cba98aa2e3d2f5009Alex Klyubin        boolean verified;
353d23dc502b0a1952887d4453cba98aa2e3d2f5009Alex Klyubin        try {
354d23dc502b0a1952887d4453cba98aa2e3d2f5009Alex Klyubin            byte[] output = mMessageStreamer.doFinal(
355d23dc502b0a1952887d4453cba98aa2e3d2f5009Alex Klyubin                    EmptyArray.BYTE, 0, 0,
356d23dc502b0a1952887d4453cba98aa2e3d2f5009Alex Klyubin                    signature,
357d23dc502b0a1952887d4453cba98aa2e3d2f5009Alex Klyubin                    null // no additional entropy needed -- verification is deterministic
358d23dc502b0a1952887d4453cba98aa2e3d2f5009Alex Klyubin                    );
359d23dc502b0a1952887d4453cba98aa2e3d2f5009Alex Klyubin            if (output.length != 0) {
360d23dc502b0a1952887d4453cba98aa2e3d2f5009Alex Klyubin                throw new ProviderException(
361d23dc502b0a1952887d4453cba98aa2e3d2f5009Alex Klyubin                        "Signature verification unexpected produced output: " + output.length
362d23dc502b0a1952887d4453cba98aa2e3d2f5009Alex Klyubin                        + " bytes");
363ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin            }
364d23dc502b0a1952887d4453cba98aa2e3d2f5009Alex Klyubin            verified = true;
365d23dc502b0a1952887d4453cba98aa2e3d2f5009Alex Klyubin        } catch (KeyStoreException e) {
366d23dc502b0a1952887d4453cba98aa2e3d2f5009Alex Klyubin            switch (e.getErrorCode()) {
367ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin                case KeymasterDefs.KM_ERROR_VERIFICATION_FAILED:
368d23dc502b0a1952887d4453cba98aa2e3d2f5009Alex Klyubin                    verified = false;
369ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin                    break;
370ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin                default:
371d23dc502b0a1952887d4453cba98aa2e3d2f5009Alex Klyubin                    throw new SignatureException(e);
372ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin            }
373ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin        }
374ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin
375ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin        resetWhilePreservingInitState();
376d23dc502b0a1952887d4453cba98aa2e3d2f5009Alex Klyubin        return verified;
377ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin    }
378ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin
379ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin    @Override
380ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin    protected final boolean engineVerify(byte[] sigBytes, int offset, int len)
381ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin            throws SignatureException {
382ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin        return engineVerify(ArrayUtils.subarray(sigBytes, offset, len));
383ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin    }
384ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin
385ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin    @Deprecated
386ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin    @Override
387ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin    protected final Object engineGetParameter(String param) throws InvalidParameterException {
388ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin        throw new InvalidParameterException();
389ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin    }
390ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin
391ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin    @Deprecated
392ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin    @Override
393ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin    protected final void engineSetParameter(String param, Object value)
394ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin            throws InvalidParameterException {
395ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin        throw new InvalidParameterException();
396ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin    }
397ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin
398ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin    protected final KeyStore getKeyStore() {
399ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin        return mKeyStore;
400ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin    }
401ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin
402ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin    /**
403ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin     * Returns {@code true} if this signature is initialized for signing, {@code false} if this
404ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin     * signature is initialized for verification.
405ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin     */
406ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin    protected final boolean isSigning() {
407ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin        return mSigning;
408ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin    }
409ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin
410ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin    // The methods below need to be implemented by subclasses.
411ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin
412ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin    /**
413ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin     * Returns the amount of additional entropy (in bytes) to be provided to the KeyStore's
414a72b55195c23fc06d1600efe8f6aac85290c7f8fAlex Klyubin     * {@code finish} operation when generating a signature.
415ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin     *
416a72b55195c23fc06d1600efe8f6aac85290c7f8fAlex Klyubin     * <p>This value should match (or exceed) the amount of Shannon entropy of the produced
417a72b55195c23fc06d1600efe8f6aac85290c7f8fAlex Klyubin     * signature assuming the key and the message are known. For example, for ECDSA signature this
418a72b55195c23fc06d1600efe8f6aac85290c7f8fAlex Klyubin     * should be the size of {@code R}, whereas for the RSA signature with PKCS#1 padding this
419a72b55195c23fc06d1600efe8f6aac85290c7f8fAlex Klyubin     * should be {@code 0}.
420ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin     */
421a72b55195c23fc06d1600efe8f6aac85290c7f8fAlex Klyubin    protected abstract int getAdditionalEntropyAmountForSign();
422ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin
423ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin    /**
424ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin     * Invoked to add algorithm-specific parameters for the KeyStore's {@code begin} operation.
425ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin     *
426ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin     * @param keymasterArgs keystore/keymaster arguments to be populated with algorithm-specific
427ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin     *        parameters.
428ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin     */
429ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin    protected abstract void addAlgorithmSpecificParametersToBegin(
430ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin            @NonNull KeymasterArguments keymasterArgs);
431ccbe88a505848896e59ef8eb4e8405037ba94e88Alex Klyubin}
432