17d863c7f2f5f89205756af35989268a81ca5c581Kenny Root/*
27d863c7f2f5f89205756af35989268a81ca5c581Kenny Root * Copyright (C) 2011 The Android Open Source Project
37d863c7f2f5f89205756af35989268a81ca5c581Kenny Root *
47d863c7f2f5f89205756af35989268a81ca5c581Kenny Root * Licensed under the Apache License, Version 2.0 (the "License");
57d863c7f2f5f89205756af35989268a81ca5c581Kenny Root * you may not use this file except in compliance with the License.
67d863c7f2f5f89205756af35989268a81ca5c581Kenny Root * You may obtain a copy of the License at
77d863c7f2f5f89205756af35989268a81ca5c581Kenny Root *
87d863c7f2f5f89205756af35989268a81ca5c581Kenny Root *      http://www.apache.org/licenses/LICENSE-2.0
97d863c7f2f5f89205756af35989268a81ca5c581Kenny Root *
107d863c7f2f5f89205756af35989268a81ca5c581Kenny Root * Unless required by applicable law or agreed to in writing, software
117d863c7f2f5f89205756af35989268a81ca5c581Kenny Root * distributed under the License is distributed on an "AS IS" BASIS,
127d863c7f2f5f89205756af35989268a81ca5c581Kenny Root * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
137d863c7f2f5f89205756af35989268a81ca5c581Kenny Root * See the License for the specific language governing permissions and
147d863c7f2f5f89205756af35989268a81ca5c581Kenny Root * limitations under the License.
157d863c7f2f5f89205756af35989268a81ca5c581Kenny Root */
167d863c7f2f5f89205756af35989268a81ca5c581Kenny Root#include <errno.h>
177d863c7f2f5f89205756af35989268a81ca5c581Kenny Root#include <string.h>
187d863c7f2f5f89205756af35989268a81ca5c581Kenny Root#include <stdint.h>
197d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
207d863c7f2f5f89205756af35989268a81ca5c581Kenny Root// For debugging
217d863c7f2f5f89205756af35989268a81ca5c581Kenny Root#define LOG_NDEBUG 0
227d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
237d863c7f2f5f89205756af35989268a81ca5c581Kenny Root// TEE is the Trusted Execution Environment
247d863c7f2f5f89205756af35989268a81ca5c581Kenny Root#define LOG_TAG "TEEKeyMaster"
257d863c7f2f5f89205756af35989268a81ca5c581Kenny Root#include <cutils/log.h>
267d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
277d863c7f2f5f89205756af35989268a81ca5c581Kenny Root#include <hardware/hardware.h>
287d863c7f2f5f89205756af35989268a81ca5c581Kenny Root#include <hardware/keymaster.h>
297d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
307d863c7f2f5f89205756af35989268a81ca5c581Kenny Root#include <openssl/bn.h>
317d863c7f2f5f89205756af35989268a81ca5c581Kenny Root#include <openssl/err.h>
327d863c7f2f5f89205756af35989268a81ca5c581Kenny Root#include <openssl/evp.h>
337d863c7f2f5f89205756af35989268a81ca5c581Kenny Root#include <openssl/rand.h>
347d863c7f2f5f89205756af35989268a81ca5c581Kenny Root#include <openssl/x509.h>
357d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
367d863c7f2f5f89205756af35989268a81ca5c581Kenny Root#include <cryptoki.h>
377d863c7f2f5f89205756af35989268a81ca5c581Kenny Root#include <pkcs11.h>
387d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
398a1d4ed8f9f88fb44ceaf3bdf270fd372d7b89d3Keun young Park#include <utils/UniquePtr.h>
407d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
417d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
427d863c7f2f5f89205756af35989268a81ca5c581Kenny Root/** The size of a key ID in bytes */
437d863c7f2f5f89205756af35989268a81ca5c581Kenny Root#define ID_LENGTH 32
447d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
457d863c7f2f5f89205756af35989268a81ca5c581Kenny Root/** The current stored key version. */
467d863c7f2f5f89205756af35989268a81ca5c581Kenny Rootconst static uint32_t KEY_VERSION = 1;
477d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
487d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
497d863c7f2f5f89205756af35989268a81ca5c581Kenny Rootstruct EVP_PKEY_Delete {
507d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    void operator()(EVP_PKEY* p) const {
517d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        EVP_PKEY_free(p);
527d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    }
537d863c7f2f5f89205756af35989268a81ca5c581Kenny Root};
547d863c7f2f5f89205756af35989268a81ca5c581Kenny Roottypedef UniquePtr<EVP_PKEY, EVP_PKEY_Delete> Unique_EVP_PKEY;
557d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
567d863c7f2f5f89205756af35989268a81ca5c581Kenny Rootstruct RSA_Delete {
577d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    void operator()(RSA* p) const {
587d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        RSA_free(p);
597d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    }
607d863c7f2f5f89205756af35989268a81ca5c581Kenny Root};
617d863c7f2f5f89205756af35989268a81ca5c581Kenny Roottypedef UniquePtr<RSA, RSA_Delete> Unique_RSA;
627d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
637d863c7f2f5f89205756af35989268a81ca5c581Kenny Rootstruct PKCS8_PRIV_KEY_INFO_Delete {
647d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    void operator()(PKCS8_PRIV_KEY_INFO* p) const {
657d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        PKCS8_PRIV_KEY_INFO_free(p);
667d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    }
677d863c7f2f5f89205756af35989268a81ca5c581Kenny Root};
687d863c7f2f5f89205756af35989268a81ca5c581Kenny Roottypedef UniquePtr<PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO_Delete> Unique_PKCS8_PRIV_KEY_INFO;
697d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
707d863c7f2f5f89205756af35989268a81ca5c581Kenny Roottypedef UniquePtr<keymaster_device_t> Unique_keymaster_device_t;
717d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
727d863c7f2f5f89205756af35989268a81ca5c581Kenny Roottypedef UniquePtr<CK_BYTE[]> Unique_CK_BYTE;
737d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
747d863c7f2f5f89205756af35989268a81ca5c581Kenny Roottypedef UniquePtr<CK_ATTRIBUTE[]> Unique_CK_ATTRIBUTE;
757d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
767d863c7f2f5f89205756af35989268a81ca5c581Kenny Rootclass ByteArray {
777d863c7f2f5f89205756af35989268a81ca5c581Kenny Rootpublic:
787d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    ByteArray(CK_BYTE* array, size_t len) :
797d863c7f2f5f89205756af35989268a81ca5c581Kenny Root            mArray(array), mLength(len) {
807d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    }
817d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
827d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    ByteArray(size_t len) :
837d863c7f2f5f89205756af35989268a81ca5c581Kenny Root            mLength(len) {
847d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        mArray = new CK_BYTE[len];
857d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    }
867d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
877d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    ~ByteArray() {
887d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        if (mArray != NULL) {
897d863c7f2f5f89205756af35989268a81ca5c581Kenny Root            delete[] mArray;
907d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        }
917d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    }
927d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
937d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    CK_BYTE* get() const {
947d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        return mArray;
957d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    }
967d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
977d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    size_t length() const {
987d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        return mLength;
997d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    }
1007d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
1017d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    CK_BYTE* release() {
1027d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        CK_BYTE* array = mArray;
1037d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        mArray = NULL;
1047d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        return array;
1057d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    }
1067d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
1077d863c7f2f5f89205756af35989268a81ca5c581Kenny Rootprivate:
1087d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    CK_BYTE* mArray;
1097d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    size_t mLength;
1107d863c7f2f5f89205756af35989268a81ca5c581Kenny Root};
1117d863c7f2f5f89205756af35989268a81ca5c581Kenny Roottypedef UniquePtr<ByteArray> Unique_ByteArray;
1127d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
1137d863c7f2f5f89205756af35989268a81ca5c581Kenny Rootclass CryptoSession {
1147d863c7f2f5f89205756af35989268a81ca5c581Kenny Rootpublic:
1157d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    CryptoSession(CK_SESSION_HANDLE masterHandle) :
1167d863c7f2f5f89205756af35989268a81ca5c581Kenny Root            mHandle(masterHandle), mSubsession(CK_INVALID_HANDLE) {
1177d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        CK_SESSION_HANDLE subsessionHandle = mHandle;
1187d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        CK_RV openSessionRV = C_OpenSession(CKV_TOKEN_USER,
1197d863c7f2f5f89205756af35989268a81ca5c581Kenny Root                CKF_SERIAL_SESSION | CKF_RW_SESSION | CKVF_OPEN_SUB_SESSION,
1207d863c7f2f5f89205756af35989268a81ca5c581Kenny Root                NULL,
1217d863c7f2f5f89205756af35989268a81ca5c581Kenny Root                NULL,
1227d863c7f2f5f89205756af35989268a81ca5c581Kenny Root                &subsessionHandle);
1237d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
1247d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        if (openSessionRV != CKR_OK || subsessionHandle == CK_INVALID_HANDLE) {
1257d863c7f2f5f89205756af35989268a81ca5c581Kenny Root            (void) C_Finalize(NULL_PTR);
1267d863c7f2f5f89205756af35989268a81ca5c581Kenny Root            ALOGE("Error opening secondary session with TEE: 0x%x", openSessionRV);
1277d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        } else {
1287d863c7f2f5f89205756af35989268a81ca5c581Kenny Root            ALOGV("Opening subsession 0x%x", subsessionHandle);
1297d863c7f2f5f89205756af35989268a81ca5c581Kenny Root            mSubsession = subsessionHandle;
1307d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        }
1317d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    }
1327d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
1337d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    ~CryptoSession() {
1347d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        if (mSubsession != CK_INVALID_HANDLE) {
1357d863c7f2f5f89205756af35989268a81ca5c581Kenny Root            CK_RV rv = C_CloseSession(mSubsession);
1367d863c7f2f5f89205756af35989268a81ca5c581Kenny Root            ALOGV("Closing subsession 0x%x: 0x%x", mSubsession, rv);
1377d863c7f2f5f89205756af35989268a81ca5c581Kenny Root            mSubsession = CK_INVALID_HANDLE;
1387d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        }
1397d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    }
1407d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
1417d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    CK_SESSION_HANDLE get() const {
1427d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        return mSubsession;
1437d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    }
1447d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
1457d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    CK_SESSION_HANDLE getPrimary() const {
1467d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        return mHandle;
1477d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    }
1487d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
1497d863c7f2f5f89205756af35989268a81ca5c581Kenny Rootprivate:
1507d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    CK_SESSION_HANDLE mHandle;
1517d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    CK_SESSION_HANDLE mSubsession;
1527d863c7f2f5f89205756af35989268a81ca5c581Kenny Root};
1537d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
1547d863c7f2f5f89205756af35989268a81ca5c581Kenny Rootclass ObjectHandle {
1557d863c7f2f5f89205756af35989268a81ca5c581Kenny Rootpublic:
1567d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    ObjectHandle(const CryptoSession* session, CK_OBJECT_HANDLE handle = CK_INVALID_HANDLE) :
1577d863c7f2f5f89205756af35989268a81ca5c581Kenny Root            mSession(session), mHandle(handle) {
1587d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    }
1597d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
1607d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    ~ObjectHandle() {
1617d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        if (mHandle != CK_INVALID_HANDLE) {
1627d863c7f2f5f89205756af35989268a81ca5c581Kenny Root            CK_RV rv = C_CloseObjectHandle(mSession->getPrimary(), mHandle);
1637d863c7f2f5f89205756af35989268a81ca5c581Kenny Root            if (rv != CKR_OK) {
1647d863c7f2f5f89205756af35989268a81ca5c581Kenny Root                ALOGW("Couldn't close object handle 0x%x: 0x%x", mHandle, rv);
1657d863c7f2f5f89205756af35989268a81ca5c581Kenny Root            } else {
1667d863c7f2f5f89205756af35989268a81ca5c581Kenny Root                ALOGV("Closing object handle 0x%x", mHandle);
1677d863c7f2f5f89205756af35989268a81ca5c581Kenny Root                mHandle = CK_INVALID_HANDLE;
1687d863c7f2f5f89205756af35989268a81ca5c581Kenny Root            }
1697d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        }
1707d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    }
1717d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
1727d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    CK_OBJECT_HANDLE get() const {
1737d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        return mHandle;
1747d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    }
1757d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
1767d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    void reset(CK_OBJECT_HANDLE handle) {
1777d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        mHandle = handle;
1787d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    }
1797d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
1807d863c7f2f5f89205756af35989268a81ca5c581Kenny Rootprivate:
1817d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    const CryptoSession* mSession;
1827d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    CK_OBJECT_HANDLE mHandle;
1837d863c7f2f5f89205756af35989268a81ca5c581Kenny Root};
1847d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
1857d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
1867d863c7f2f5f89205756af35989268a81ca5c581Kenny Root/**
1877d863c7f2f5f89205756af35989268a81ca5c581Kenny Root * Many OpenSSL APIs take ownership of an argument on success but don't free the argument
1887d863c7f2f5f89205756af35989268a81ca5c581Kenny Root * on failure. This means we need to tell our scoped pointers when we've transferred ownership,
1897d863c7f2f5f89205756af35989268a81ca5c581Kenny Root * without triggering a warning by not using the result of release().
1907d863c7f2f5f89205756af35989268a81ca5c581Kenny Root */
1917d863c7f2f5f89205756af35989268a81ca5c581Kenny Root#define OWNERSHIP_TRANSFERRED(obj) \
1927d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    typeof (obj.release()) _dummy __attribute__((unused)) = obj.release()
1937d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
1947d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
1957d863c7f2f5f89205756af35989268a81ca5c581Kenny Root/*
1967d863c7f2f5f89205756af35989268a81ca5c581Kenny Root * Checks this thread's OpenSSL error queue and logs if
1977d863c7f2f5f89205756af35989268a81ca5c581Kenny Root * necessary.
1987d863c7f2f5f89205756af35989268a81ca5c581Kenny Root */
1997d863c7f2f5f89205756af35989268a81ca5c581Kenny Rootstatic void logOpenSSLError(const char* location) {
2007d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    int error = ERR_get_error();
2017d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
2027d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    if (error != 0) {
2037d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        char message[256];
2047d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        ERR_error_string_n(error, message, sizeof(message));
2057d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        ALOGE("OpenSSL error in %s %d: %s", location, error, message);
2067d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    }
2077d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
2087d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    ERR_clear_error();
2097d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    ERR_remove_state(0);
2107d863c7f2f5f89205756af35989268a81ca5c581Kenny Root}
2117d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
2127d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
2137d863c7f2f5f89205756af35989268a81ca5c581Kenny Root/**
2147d863c7f2f5f89205756af35989268a81ca5c581Kenny Root * Convert from OpenSSL's BIGNUM format to TEE's Big Integer format.
2157d863c7f2f5f89205756af35989268a81ca5c581Kenny Root */
2167d863c7f2f5f89205756af35989268a81ca5c581Kenny Rootstatic ByteArray* bignum_to_array(const BIGNUM* bn) {
2177d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    const int bignumSize = BN_num_bytes(bn);
2187d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
2197d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    Unique_CK_BYTE bytes(new CK_BYTE[bignumSize]);
2207d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
2217d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    unsigned char* tmp = reinterpret_cast<unsigned char*>(bytes.get());
2227d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    if (BN_bn2bin(bn, tmp) != bignumSize) {
2237d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        ALOGE("public exponent size wasn't what was expected");
2247d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        return NULL;
2257d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    }
2267d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
2277d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    return new ByteArray(bytes.release(), bignumSize);
2287d863c7f2f5f89205756af35989268a81ca5c581Kenny Root}
2297d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
2307d863c7f2f5f89205756af35989268a81ca5c581Kenny Rootstatic void set_attribute(CK_ATTRIBUTE* attrib, CK_ATTRIBUTE_TYPE type, void* pValue,
2317d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        CK_ULONG ulValueLen) {
2327d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    attrib->type = type;
2337d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    attrib->pValue = pValue;
2347d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    attrib->ulValueLen = ulValueLen;
2357d863c7f2f5f89205756af35989268a81ca5c581Kenny Root}
2367d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
2377d863c7f2f5f89205756af35989268a81ca5c581Kenny Rootstatic ByteArray* generate_random_id() {
2387d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    Unique_ByteArray id(new ByteArray(ID_LENGTH));
2397d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    if (RAND_pseudo_bytes(reinterpret_cast<unsigned char*>(id->get()), id->length()) < 0) {
2407d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        return NULL;
2417d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    }
2427d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
2437d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    return id.release();
2447d863c7f2f5f89205756af35989268a81ca5c581Kenny Root}
2457d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
2467d863c7f2f5f89205756af35989268a81ca5c581Kenny Rootstatic int keyblob_save(ByteArray* objId, uint8_t** key_blob, size_t* key_blob_length) {
2477d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    Unique_ByteArray handleBlob(new ByteArray(sizeof(uint32_t) + objId->length()));
2487d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    if (handleBlob.get() == NULL) {
2497d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        ALOGE("Could not allocate key blob");
2507d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        return -1;
2517d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    }
2527d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    uint8_t* tmp = handleBlob->get();
2537d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    for (size_t i = 0; i < sizeof(uint32_t); i++) {
2547d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        *tmp++ = KEY_VERSION >> ((sizeof(uint32_t) - i - 1) * 8);
2557d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    }
2567d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    memcpy(tmp, objId->get(), objId->length());
2577d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
2587d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    *key_blob_length = handleBlob->length();
2597d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    *key_blob = handleBlob->get();
2607d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    ByteArray* unused __attribute__((unused)) = handleBlob.release();
2617d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
2627d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    return 0;
2637d863c7f2f5f89205756af35989268a81ca5c581Kenny Root}
2647d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
2657d863c7f2f5f89205756af35989268a81ca5c581Kenny Rootstatic int find_single_object(const uint8_t* obj_id, const size_t obj_id_length,
2667d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        CK_OBJECT_CLASS obj_class, const CryptoSession* session, ObjectHandle* object) {
2677d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
2687d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    // Note that the CKA_ID attribute is never written, so we can cast away const here.
2697d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    void* obj_id_ptr = reinterpret_cast<void*>(const_cast<uint8_t*>(obj_id));
2707d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    CK_ATTRIBUTE attributes[] = {
2717d863c7f2f5f89205756af35989268a81ca5c581Kenny Root            { CKA_ID,    obj_id_ptr, obj_id_length },
2727d863c7f2f5f89205756af35989268a81ca5c581Kenny Root            { CKA_CLASS, &obj_class, sizeof(obj_class) },
2737d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    };
2747d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
2757d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    CK_RV rv = C_FindObjectsInit(session->get(), attributes,
2767d863c7f2f5f89205756af35989268a81ca5c581Kenny Root            sizeof(attributes) / sizeof(CK_ATTRIBUTE));
2777d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    if (rv != CKR_OK) {
2787d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        ALOGE("Error in C_FindObjectsInit: 0x%x", rv);
2797d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        return -1;
2807d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    }
2817d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
2827d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    CK_OBJECT_HANDLE tmpHandle;
2837d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    CK_ULONG tmpCount;
2847d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
2857d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    rv = C_FindObjects(session->get(), &tmpHandle, 1, &tmpCount);
2867d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    ALOGV("Found %d object 0x%x : class 0x%x", tmpCount, tmpHandle, obj_class);
2877d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    if (rv != CKR_OK || tmpCount != 1) {
2887d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        C_FindObjectsFinal(session->get());
2897d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        ALOGE("Couldn't find key!");
2907d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        return -1;
2917d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    }
2927d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    C_FindObjectsFinal(session->get());
2937d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
2947d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    object->reset(tmpHandle);
2957d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    return 0;
2967d863c7f2f5f89205756af35989268a81ca5c581Kenny Root}
2977d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
2987d863c7f2f5f89205756af35989268a81ca5c581Kenny Rootstatic int keyblob_restore(const CryptoSession* session, const uint8_t* keyBlob,
2997d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        const size_t keyBlobLength, ObjectHandle* public_key, ObjectHandle* private_key) {
3007d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    if (keyBlob == NULL) {
3017d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        ALOGE("key blob was null");
3027d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        return -1;
3037d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    }
3047d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
3057d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    if (keyBlobLength < (sizeof(KEY_VERSION) + ID_LENGTH)) {
3067d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        ALOGE("key blob is not correct size");
3077d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        return -1;
3087d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    }
3097d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
3107d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    uint32_t keyVersion = 0;
3117d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
3127d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    const uint8_t* p = keyBlob;
3137d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    for (size_t i = 0; i < sizeof(keyVersion); i++) {
3147d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        keyVersion = (keyVersion << 8) | *p++;
3157d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    }
3167d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
3177d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    if (keyVersion != 1) {
3187d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        ALOGE("Invalid key version %d", keyVersion);
3197d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        return -1;
3207d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    }
3217d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
3227d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    return find_single_object(p, ID_LENGTH, CKO_PUBLIC_KEY, session, public_key)
3237d863c7f2f5f89205756af35989268a81ca5c581Kenny Root            || find_single_object(p, ID_LENGTH, CKO_PRIVATE_KEY, session, private_key);
3247d863c7f2f5f89205756af35989268a81ca5c581Kenny Root}
3257d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
3267d863c7f2f5f89205756af35989268a81ca5c581Kenny Rootstatic int tee_generate_keypair(const keymaster_device_t* dev,
3277d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        const keymaster_keypair_t type, const void* key_params,
3287d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        uint8_t** key_blob, size_t* key_blob_length) {
3297d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    CK_BBOOL bTRUE = CK_TRUE;
3307d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
3317d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    if (type != TYPE_RSA) {
3327d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        ALOGW("Unknown key type %d", type);
3337d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        return -1;
3347d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    }
3357d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
3367d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    if (key_params == NULL) {
3377d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        ALOGW("generate_keypair params were NULL");
3387d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        return -1;
3397d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    }
3407d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
3417d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    keymaster_rsa_keygen_params_t* rsa_params = (keymaster_rsa_keygen_params_t*) key_params;
3427d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
3437d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    CK_MECHANISM mechanism = {
3447d863c7f2f5f89205756af35989268a81ca5c581Kenny Root            CKM_RSA_PKCS_KEY_PAIR_GEN, NULL, 0,
3457d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    };
3467d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    CK_ULONG modulusBits = (CK_ULONG) rsa_params->modulus_size;
3477d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
3487d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    /**
3497d863c7f2f5f89205756af35989268a81ca5c581Kenny Root     * Convert our unsigned 64-bit integer to the TEE Big Integer class. It's
3507d863c7f2f5f89205756af35989268a81ca5c581Kenny Root     * an unsigned array of bytes with MSB first.
3517d863c7f2f5f89205756af35989268a81ca5c581Kenny Root     */
3527d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    CK_BYTE publicExponent[sizeof(uint64_t)];
3537d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    const uint64_t exp = rsa_params->public_exponent;
3547d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    size_t offset = sizeof(publicExponent) - 1;
3557d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    for (size_t i = 0; i < sizeof(publicExponent); i++) {
3567d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        publicExponent[offset--] = (exp >> (i * CHAR_BIT)) & 0xFF;
3577d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    }
3587d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
3597d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    Unique_ByteArray objId(generate_random_id());
3607d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    if (objId.get() == NULL) {
3617d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        ALOGE("Couldn't generate random key ID");
3627d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        return -1;
3637d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    }
3647d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
3657d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    CK_ATTRIBUTE publicKeyTemplate[] = {
3667d863c7f2f5f89205756af35989268a81ca5c581Kenny Root            {CKA_ID,              objId->get(),   objId->length()},
3677d863c7f2f5f89205756af35989268a81ca5c581Kenny Root            {CKA_TOKEN,           &bTRUE,         sizeof(bTRUE)},
3687d863c7f2f5f89205756af35989268a81ca5c581Kenny Root            {CKA_ENCRYPT,         &bTRUE,         sizeof(bTRUE)},
3697d863c7f2f5f89205756af35989268a81ca5c581Kenny Root            {CKA_VERIFY,          &bTRUE,         sizeof(bTRUE)},
3707d863c7f2f5f89205756af35989268a81ca5c581Kenny Root            {CKA_MODULUS_BITS,    &modulusBits,   sizeof(modulusBits)},
3717d863c7f2f5f89205756af35989268a81ca5c581Kenny Root            {CKA_PUBLIC_EXPONENT, publicExponent, sizeof(publicExponent)},
3727d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    };
3737d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
3747d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    CK_ATTRIBUTE privateKeyTemplate[] = {
3757d863c7f2f5f89205756af35989268a81ca5c581Kenny Root            {CKA_ID,              objId->get(),   objId->length()},
3767d863c7f2f5f89205756af35989268a81ca5c581Kenny Root            {CKA_TOKEN,           &bTRUE,         sizeof(bTRUE)},
3777d863c7f2f5f89205756af35989268a81ca5c581Kenny Root            {CKA_DECRYPT,         &bTRUE,         sizeof(bTRUE)},
3787d863c7f2f5f89205756af35989268a81ca5c581Kenny Root            {CKA_SIGN,            &bTRUE,         sizeof(bTRUE)},
3797d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    };
3807d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
3817d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    CryptoSession session(reinterpret_cast<CK_SESSION_HANDLE>(dev->context));
3827d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
3837d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    CK_OBJECT_HANDLE hPublicKey, hPrivateKey;
3847d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    CK_RV rv = C_GenerateKeyPair(session.get(),
3857d863c7f2f5f89205756af35989268a81ca5c581Kenny Root            &mechanism,
3867d863c7f2f5f89205756af35989268a81ca5c581Kenny Root            publicKeyTemplate,
3877d863c7f2f5f89205756af35989268a81ca5c581Kenny Root            sizeof(publicKeyTemplate)/sizeof(CK_ATTRIBUTE),
3887d863c7f2f5f89205756af35989268a81ca5c581Kenny Root            privateKeyTemplate,
3897d863c7f2f5f89205756af35989268a81ca5c581Kenny Root            sizeof(privateKeyTemplate)/sizeof(CK_ATTRIBUTE),
3907d863c7f2f5f89205756af35989268a81ca5c581Kenny Root            &hPublicKey,
3917d863c7f2f5f89205756af35989268a81ca5c581Kenny Root            &hPrivateKey);
3927d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
3937d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    if (rv != CKR_OK) {
3947d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        ALOGE("Generate keypair failed: 0x%x", rv);
3957d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        return -1;
3967d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    }
3977d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
3987d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    ObjectHandle publicKey(&session, hPublicKey);
3997d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    ObjectHandle privateKey(&session, hPrivateKey);
4007d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    ALOGV("public handle = 0x%x, private handle = 0x%x", publicKey.get(), privateKey.get());
4017d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
4027d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    return keyblob_save(objId.get(), key_blob, key_blob_length);
4037d863c7f2f5f89205756af35989268a81ca5c581Kenny Root}
4047d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
4057d863c7f2f5f89205756af35989268a81ca5c581Kenny Rootstatic int tee_import_keypair(const keymaster_device_t* dev,
4067d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        const uint8_t* key, const size_t key_length,
4077d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        uint8_t** key_blob, size_t* key_blob_length) {
4087d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    CK_RV rv;
4097d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    CK_BBOOL bTRUE = CK_TRUE;
4107d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
4117d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    if (key == NULL) {
4127d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        ALOGW("provided key is null");
4137d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        return -1;
4147d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    }
4157d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
4167d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    Unique_PKCS8_PRIV_KEY_INFO pkcs8(d2i_PKCS8_PRIV_KEY_INFO(NULL, &key, key_length));
4177d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    if (pkcs8.get() == NULL) {
4187d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        logOpenSSLError("tee_import_keypair");
4197d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        return -1;
4207d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    }
4217d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
4227d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    /* assign to EVP */
4237d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    Unique_EVP_PKEY pkey(EVP_PKCS82PKEY(pkcs8.get()));
4247d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    if (pkey.get() == NULL) {
4257d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        logOpenSSLError("tee_import_keypair");
4267d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        return -1;
4277d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    }
4287d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
4297d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    if (EVP_PKEY_type(pkey->type) != EVP_PKEY_RSA) {
4307d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        ALOGE("Unsupported key type: %d", EVP_PKEY_type(pkey->type));
4317d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        return -1;
4327d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    }
4337d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
4347d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    Unique_RSA rsa(EVP_PKEY_get1_RSA(pkey.get()));
4357d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    if (rsa.get() == NULL) {
4367d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        logOpenSSLError("tee_import_keypair");
4377d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        return -1;
4387d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    }
4397d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
4407d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    Unique_ByteArray modulus(bignum_to_array(rsa->n));
4417d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    if (modulus.get() == NULL) {
4427d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        ALOGW("Could not convert modulus to array");
4437d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        return -1;
4447d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    }
4457d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
4467d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    Unique_ByteArray publicExponent(bignum_to_array(rsa->e));
4477d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    if (publicExponent.get() == NULL) {
4487d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        ALOGW("Could not convert publicExponent to array");
4497d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        return -1;
4507d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    }
4517d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
4527d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    CK_KEY_TYPE rsaType = CKK_RSA;
4537d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
4547d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    CK_OBJECT_CLASS pubClass = CKO_PUBLIC_KEY;
4557d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
4567d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    Unique_ByteArray objId(generate_random_id());
4577d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    if (objId.get() == NULL) {
4587d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        ALOGE("Couldn't generate random key ID");
4597d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        return -1;
4607d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    }
4617d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
4627d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    CK_ATTRIBUTE publicKeyTemplate[] = {
4637d863c7f2f5f89205756af35989268a81ca5c581Kenny Root            {CKA_ID,              objId->get(),          objId->length()},
4647d863c7f2f5f89205756af35989268a81ca5c581Kenny Root            {CKA_TOKEN,           &bTRUE,                sizeof(bTRUE)},
4657d863c7f2f5f89205756af35989268a81ca5c581Kenny Root            {CKA_CLASS,           &pubClass,             sizeof(pubClass)},
4667d863c7f2f5f89205756af35989268a81ca5c581Kenny Root            {CKA_KEY_TYPE,        &rsaType,              sizeof(rsaType)},
4677d863c7f2f5f89205756af35989268a81ca5c581Kenny Root            {CKA_ENCRYPT,         &bTRUE,                sizeof(bTRUE)},
4687d863c7f2f5f89205756af35989268a81ca5c581Kenny Root            {CKA_VERIFY,          &bTRUE,                sizeof(bTRUE)},
4697d863c7f2f5f89205756af35989268a81ca5c581Kenny Root            {CKA_MODULUS,         modulus->get(),        modulus->length()},
4707d863c7f2f5f89205756af35989268a81ca5c581Kenny Root            {CKA_PUBLIC_EXPONENT, publicExponent->get(), publicExponent->length()},
4717d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    };
4727d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
4737d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    CryptoSession session(reinterpret_cast<CK_SESSION_HANDLE>(dev->context));
4747d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
4757d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    CK_OBJECT_HANDLE hPublicKey;
4767d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    rv = C_CreateObject(session.get(),
4777d863c7f2f5f89205756af35989268a81ca5c581Kenny Root            publicKeyTemplate,
4787d863c7f2f5f89205756af35989268a81ca5c581Kenny Root            sizeof(publicKeyTemplate)/sizeof(CK_ATTRIBUTE),
4797d863c7f2f5f89205756af35989268a81ca5c581Kenny Root            &hPublicKey);
4807d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    if (rv != CKR_OK) {
4817d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        ALOGE("Creation of public key failed: 0x%x", rv);
4827d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        return -1;
4837d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    }
4847d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    ObjectHandle publicKey(&session, hPublicKey);
4857d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
4867d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    Unique_ByteArray privateExponent(bignum_to_array(rsa->d));
4877d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    if (privateExponent.get() == NULL) {
4887d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        ALOGW("Could not convert private exponent");
4897d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        return -1;
4907d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    }
4917d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
4927d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
4937d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    /*
4947d863c7f2f5f89205756af35989268a81ca5c581Kenny Root     * Normally we need:
4957d863c7f2f5f89205756af35989268a81ca5c581Kenny Root     *   CKA_ID
4967d863c7f2f5f89205756af35989268a81ca5c581Kenny Root     *   CKA_TOKEN
4977d863c7f2f5f89205756af35989268a81ca5c581Kenny Root     *   CKA_CLASS
4987d863c7f2f5f89205756af35989268a81ca5c581Kenny Root     *   CKA_KEY_TYPE
4997d863c7f2f5f89205756af35989268a81ca5c581Kenny Root     *
5007d863c7f2f5f89205756af35989268a81ca5c581Kenny Root     *   CKA_DECRYPT
5017d863c7f2f5f89205756af35989268a81ca5c581Kenny Root     *   CKA_SIGN
5027d863c7f2f5f89205756af35989268a81ca5c581Kenny Root     *
5037d863c7f2f5f89205756af35989268a81ca5c581Kenny Root     *   CKA_MODULUS
5047d863c7f2f5f89205756af35989268a81ca5c581Kenny Root     *   CKA_PUBLIC_EXPONENT
5057d863c7f2f5f89205756af35989268a81ca5c581Kenny Root     *   CKA_PRIVATE_EXPONENT
5067d863c7f2f5f89205756af35989268a81ca5c581Kenny Root     */
5077d863c7f2f5f89205756af35989268a81ca5c581Kenny Root#define PRIV_ATTRIB_NORMAL_NUM (4 + 2 + 3)
5087d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
5097d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    /*
5107d863c7f2f5f89205756af35989268a81ca5c581Kenny Root     * For additional private key values:
5117d863c7f2f5f89205756af35989268a81ca5c581Kenny Root     *   CKA_PRIME_1
5127d863c7f2f5f89205756af35989268a81ca5c581Kenny Root     *   CKA_PRIME_2
5137d863c7f2f5f89205756af35989268a81ca5c581Kenny Root     *
5147d863c7f2f5f89205756af35989268a81ca5c581Kenny Root     *   CKA_EXPONENT_1
5157d863c7f2f5f89205756af35989268a81ca5c581Kenny Root     *   CKA_EXPONENT_2
5167d863c7f2f5f89205756af35989268a81ca5c581Kenny Root     *
5177d863c7f2f5f89205756af35989268a81ca5c581Kenny Root     *   CKA_COEFFICIENT
5187d863c7f2f5f89205756af35989268a81ca5c581Kenny Root     */
5197d863c7f2f5f89205756af35989268a81ca5c581Kenny Root#define PRIV_ATTRIB_EXTENDED_NUM (PRIV_ATTRIB_NORMAL_NUM + 5)
5207d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
5217d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    /*
5227d863c7f2f5f89205756af35989268a81ca5c581Kenny Root     * If we have the prime, prime exponents, and coefficient, we can
5237d863c7f2f5f89205756af35989268a81ca5c581Kenny Root     * copy them in.
5247d863c7f2f5f89205756af35989268a81ca5c581Kenny Root     */
5257d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    bool has_extra_data = (rsa->p != NULL) && (rsa->q != NULL) && (rsa->dmp1 != NULL) &&
5267d863c7f2f5f89205756af35989268a81ca5c581Kenny Root            (rsa->dmq1 != NULL) && (rsa->iqmp != NULL);
5277d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
5287d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    Unique_CK_ATTRIBUTE privateKeyTemplate(new CK_ATTRIBUTE[
5297d863c7f2f5f89205756af35989268a81ca5c581Kenny Root            has_extra_data ? PRIV_ATTRIB_EXTENDED_NUM : PRIV_ATTRIB_NORMAL_NUM]);
5307d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
5317d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    CK_OBJECT_CLASS privClass = CKO_PRIVATE_KEY;
5327d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
5337d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    size_t templateOffset = 0;
5347d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
5357d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    set_attribute(&privateKeyTemplate[templateOffset++], CKA_ID, objId->get(), objId->length());
5367d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    set_attribute(&privateKeyTemplate[templateOffset++], CKA_TOKEN, &bTRUE, sizeof(bTRUE));
5377d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    set_attribute(&privateKeyTemplate[templateOffset++], CKA_CLASS, &privClass, sizeof(privClass));
5387d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    set_attribute(&privateKeyTemplate[templateOffset++], CKA_KEY_TYPE, &rsaType, sizeof(rsaType));
5397d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
5407d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    set_attribute(&privateKeyTemplate[templateOffset++], CKA_DECRYPT, &bTRUE, sizeof(bTRUE));
5417d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    set_attribute(&privateKeyTemplate[templateOffset++], CKA_SIGN, &bTRUE, sizeof(bTRUE));
5427d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
5437d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    set_attribute(&privateKeyTemplate[templateOffset++], CKA_MODULUS, modulus->get(),
5447d863c7f2f5f89205756af35989268a81ca5c581Kenny Root            modulus->length());
5457d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    set_attribute(&privateKeyTemplate[templateOffset++], CKA_PUBLIC_EXPONENT,
5467d863c7f2f5f89205756af35989268a81ca5c581Kenny Root            publicExponent->get(), publicExponent->length());
5477d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    set_attribute(&privateKeyTemplate[templateOffset++], CKA_PRIVATE_EXPONENT,
5487d863c7f2f5f89205756af35989268a81ca5c581Kenny Root            privateExponent->get(), privateExponent->length());
5497d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
5507d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    Unique_ByteArray prime1, prime2, exp1, exp2, coeff;
5517d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    if (has_extra_data) {
5527d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        prime1.reset(bignum_to_array(rsa->p));
5537d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        if (prime1->get() == NULL) {
5547d863c7f2f5f89205756af35989268a81ca5c581Kenny Root            ALOGW("Could not convert prime1");
5557d863c7f2f5f89205756af35989268a81ca5c581Kenny Root            return -1;
5567d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        }
5577d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        set_attribute(&privateKeyTemplate[templateOffset++], CKA_PRIME_1, prime1->get(),
5587d863c7f2f5f89205756af35989268a81ca5c581Kenny Root                prime1->length());
5597d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
5607d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        prime2.reset(bignum_to_array(rsa->q));
5617d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        if (prime2->get() == NULL) {
5627d863c7f2f5f89205756af35989268a81ca5c581Kenny Root            ALOGW("Could not convert prime2");
5637d863c7f2f5f89205756af35989268a81ca5c581Kenny Root            return -1;
5647d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        }
5657d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        set_attribute(&privateKeyTemplate[templateOffset++], CKA_PRIME_2, prime2->get(),
5667d863c7f2f5f89205756af35989268a81ca5c581Kenny Root                prime2->length());
5677d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
5687d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        exp1.reset(bignum_to_array(rsa->dmp1));
5697d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        if (exp1->get() == NULL) {
5707d863c7f2f5f89205756af35989268a81ca5c581Kenny Root            ALOGW("Could not convert exponent 1");
5717d863c7f2f5f89205756af35989268a81ca5c581Kenny Root            return -1;
5727d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        }
5737d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        set_attribute(&privateKeyTemplate[templateOffset++], CKA_EXPONENT_1, exp1->get(),
5747d863c7f2f5f89205756af35989268a81ca5c581Kenny Root                exp1->length());
5757d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
5767d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        exp2.reset(bignum_to_array(rsa->dmq1));
5777d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        if (exp2->get() == NULL) {
5787d863c7f2f5f89205756af35989268a81ca5c581Kenny Root            ALOGW("Could not convert exponent 2");
5797d863c7f2f5f89205756af35989268a81ca5c581Kenny Root            return -1;
5807d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        }
5817d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        set_attribute(&privateKeyTemplate[templateOffset++], CKA_EXPONENT_2, exp2->get(),
5827d863c7f2f5f89205756af35989268a81ca5c581Kenny Root                exp2->length());
5837d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
5847d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        coeff.reset(bignum_to_array(rsa->iqmp));
5857d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        if (coeff->get() == NULL) {
5867d863c7f2f5f89205756af35989268a81ca5c581Kenny Root            ALOGW("Could not convert coefficient");
5877d863c7f2f5f89205756af35989268a81ca5c581Kenny Root            return -1;
5887d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        }
5897d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        set_attribute(&privateKeyTemplate[templateOffset++], CKA_COEFFICIENT, coeff->get(),
5907d863c7f2f5f89205756af35989268a81ca5c581Kenny Root                coeff->length());
5917d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    }
5927d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
5937d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    CK_OBJECT_HANDLE hPrivateKey;
5947d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    rv = C_CreateObject(session.get(),
5957d863c7f2f5f89205756af35989268a81ca5c581Kenny Root            privateKeyTemplate.get(),
5967d863c7f2f5f89205756af35989268a81ca5c581Kenny Root            templateOffset,
5977d863c7f2f5f89205756af35989268a81ca5c581Kenny Root            &hPrivateKey);
5987d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    if (rv != CKR_OK) {
5997d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        ALOGE("Creation of private key failed: 0x%x", rv);
6007d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        return -1;
6017d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    }
6027d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    ObjectHandle privateKey(&session, hPrivateKey);
6037d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
6047d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    ALOGV("public handle = 0x%x, private handle = 0x%x", publicKey.get(), privateKey.get());
6057d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
6067d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    return keyblob_save(objId.get(), key_blob, key_blob_length);
6077d863c7f2f5f89205756af35989268a81ca5c581Kenny Root}
6087d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
6097d863c7f2f5f89205756af35989268a81ca5c581Kenny Rootstatic int tee_get_keypair_public(const struct keymaster_device* dev,
6107d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        const uint8_t* key_blob, const size_t key_blob_length,
6117d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        uint8_t** x509_data, size_t* x509_data_length) {
6127d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
6137d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    CryptoSession session(reinterpret_cast<CK_SESSION_HANDLE>(dev->context));
6147d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
6157d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    ObjectHandle publicKey(&session);
6167d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    ObjectHandle privateKey(&session);
6177d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
6187d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    if (keyblob_restore(&session, key_blob, key_blob_length, &publicKey, &privateKey)) {
6197d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        return -1;
6207d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    }
6217d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
6227d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    if (x509_data == NULL || x509_data_length == NULL) {
6237d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        ALOGW("Provided destination variables were null");
6247d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        return -1;
6257d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    }
6267d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
6277d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    CK_ATTRIBUTE attributes[] = {
6287d863c7f2f5f89205756af35989268a81ca5c581Kenny Root            {CKA_MODULUS,         NULL, 0},
6297d863c7f2f5f89205756af35989268a81ca5c581Kenny Root            {CKA_PUBLIC_EXPONENT, NULL, 0},
6307d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    };
6317d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
6327d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    // Call first to get the sizes of the values.
6337d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    CK_RV rv = C_GetAttributeValue(session.get(), publicKey.get(), attributes,
6347d863c7f2f5f89205756af35989268a81ca5c581Kenny Root            sizeof(attributes)/sizeof(CK_ATTRIBUTE));
6357d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    if (rv != CKR_OK) {
6367d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        ALOGW("Could not query attribute value sizes: 0x%02x", rv);
6377d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        return -1;
6387d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    }
6397d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
6407d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    ByteArray modulus(new CK_BYTE[attributes[0].ulValueLen], attributes[0].ulValueLen);
6417d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    ByteArray exponent(new CK_BYTE[attributes[1].ulValueLen], attributes[1].ulValueLen);
6427d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
6437d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    attributes[0].pValue = modulus.get();
6447d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    attributes[1].pValue = exponent.get();
6457d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
6467d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    rv = C_GetAttributeValue(session.get(), publicKey.get(), attributes,
6477d863c7f2f5f89205756af35989268a81ca5c581Kenny Root            sizeof(attributes) / sizeof(CK_ATTRIBUTE));
6487d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    if (rv != CKR_OK) {
6497d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        ALOGW("Could not query attribute values: 0x%02x", rv);
6507d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        return -1;
6517d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    }
6527d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
6537d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    ALOGV("modulus is %d, exponent is %d", modulus.length(), exponent.length());
6547d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
6557d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    Unique_RSA rsa(RSA_new());
6567d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    if (rsa.get() == NULL) {
6577d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        ALOGE("Could not allocate RSA structure");
6587d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        return -1;
6597d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    }
6607d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
6617d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    rsa->n = BN_bin2bn(reinterpret_cast<const unsigned char*>(modulus.get()), modulus.length(),
6627d863c7f2f5f89205756af35989268a81ca5c581Kenny Root            NULL);
6637d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    if (rsa->n == NULL) {
6647d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        logOpenSSLError("tee_get_keypair_public");
6657d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        return -1;
6667d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    }
6677d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
6687d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    rsa->e = BN_bin2bn(reinterpret_cast<const unsigned char*>(exponent.get()), exponent.length(),
6697d863c7f2f5f89205756af35989268a81ca5c581Kenny Root            NULL);
6707d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    if (rsa->e == NULL) {
6717d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        logOpenSSLError("tee_get_keypair_public");
6727d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        return -1;
6737d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    }
6747d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
6757d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    Unique_EVP_PKEY pkey(EVP_PKEY_new());
6767d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    if (pkey.get() == NULL) {
6777d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        ALOGE("Could not allocate EVP_PKEY structure");
6787d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        return -1;
6797d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    }
6807d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    if (EVP_PKEY_assign_RSA(pkey.get(), rsa.get()) != 1) {
6817d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        logOpenSSLError("tee_get_keypair_public");
6827d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        return -1;
6837d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    }
6847d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    OWNERSHIP_TRANSFERRED(rsa);
6857d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
6867d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    int len = i2d_PUBKEY(pkey.get(), NULL);
6877d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    if (len <= 0) {
6887d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        logOpenSSLError("tee_get_keypair_public");
6897d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        return -1;
6907d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    }
6917d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
6927d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    UniquePtr<uint8_t> key(static_cast<uint8_t*>(malloc(len)));
6937d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    if (key.get() == NULL) {
6947d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        ALOGE("Could not allocate memory for public key data");
6957d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        return -1;
6967d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    }
6977d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
6987d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    unsigned char* tmp = reinterpret_cast<unsigned char*>(key.get());
6997d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    if (i2d_PUBKEY(pkey.get(), &tmp) != len) {
7007d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        logOpenSSLError("tee_get_keypair_public");
7017d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        return -1;
7027d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    }
7037d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
7047d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    ALOGV("Length of x509 data is %d", len);
7057d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    *x509_data_length = len;
7067d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    *x509_data = key.release();
7077d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
7087d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    return 0;
7097d863c7f2f5f89205756af35989268a81ca5c581Kenny Root}
7107d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
7117d863c7f2f5f89205756af35989268a81ca5c581Kenny Rootstatic int tee_delete_keypair(const struct keymaster_device* dev,
7127d863c7f2f5f89205756af35989268a81ca5c581Kenny Root            const uint8_t* key_blob, const size_t key_blob_length) {
7137d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
7147d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    CryptoSession session(reinterpret_cast<CK_SESSION_HANDLE>(dev->context));
7157d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
7167d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    ObjectHandle publicKey(&session);
7177d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    ObjectHandle privateKey(&session);
7187d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
7197d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    if (keyblob_restore(&session, key_blob, key_blob_length, &publicKey, &privateKey)) {
7207d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        return -1;
7217d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    }
7227d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
7237d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    // Delete the private key.
7247d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    CK_RV rv = C_DestroyObject(session.get(), privateKey.get());
7257d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    if (rv != CKR_OK) {
7267d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        ALOGW("Could destroy private key object: 0x%02x", rv);
7277d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        return -1;
7287d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    }
7297d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
7307d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    // Delete the public key.
7317d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    rv = C_DestroyObject(session.get(), publicKey.get());
7327d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    if (rv != CKR_OK) {
7337d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        ALOGW("Could destroy public key object: 0x%02x", rv);
7347d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        return -1;
7357d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    }
7367d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
7377d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    return 0;
7387d863c7f2f5f89205756af35989268a81ca5c581Kenny Root}
7397d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
7407d863c7f2f5f89205756af35989268a81ca5c581Kenny Rootstatic int tee_sign_data(const keymaster_device_t* dev,
7417d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        const void* params,
7427d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        const uint8_t* key_blob, const size_t key_blob_length,
7437d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        const uint8_t* data, const size_t dataLength,
7447d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        uint8_t** signedData, size_t* signedDataLength) {
7457d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    ALOGV("tee_sign_data(%p, %p, %llu, %p, %llu, %p, %p)", dev, key_blob,
7467d863c7f2f5f89205756af35989268a81ca5c581Kenny Root            (unsigned long long) key_blob_length, data, (unsigned long long) dataLength, signedData,
7477d863c7f2f5f89205756af35989268a81ca5c581Kenny Root            signedDataLength);
7487d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
7497d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    if (params == NULL) {
7507d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        ALOGW("Signing params were null");
7517d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        return -1;
7527d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    }
7537d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
7547d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    CryptoSession session(reinterpret_cast<CK_SESSION_HANDLE>(dev->context));
7557d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
7567d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    ObjectHandle publicKey(&session);
7577d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    ObjectHandle privateKey(&session);
7587d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
7597d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    if (keyblob_restore(&session, key_blob, key_blob_length, &publicKey, &privateKey)) {
7607d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        return -1;
7617d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    }
7627d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    ALOGV("public handle = 0x%x, private handle = 0x%x", publicKey.get(), privateKey.get());
7637d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
7647d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    keymaster_rsa_sign_params_t* sign_params = (keymaster_rsa_sign_params_t*) params;
7657d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    if (sign_params->digest_type != DIGEST_NONE) {
7667d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        ALOGW("Cannot handle digest type %d", sign_params->digest_type);
7677d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        return -1;
7687d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    } else if (sign_params->padding_type != PADDING_NONE) {
7697d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        ALOGW("Cannot handle padding type %d", sign_params->padding_type);
7707d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        return -1;
7717d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    }
7727d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
7737d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    CK_MECHANISM rawRsaMechanism = {
7747d863c7f2f5f89205756af35989268a81ca5c581Kenny Root            CKM_RSA_X_509, NULL, 0
7757d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    };
7767d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
7777d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    CK_RV rv = C_SignInit(session.get(), &rawRsaMechanism, privateKey.get());
7787d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    if (rv != CKR_OK) {
7797d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        ALOGV("C_SignInit failed: 0x%x", rv);
7807d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        return -1;
7817d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    }
7827d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
7837d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    CK_BYTE signature[1024];
7847d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    CK_ULONG signatureLength = 1024;
7857d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
7867d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    rv = C_Sign(session.get(), data, dataLength, signature, &signatureLength);
7877d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    if (rv != CKR_OK) {
7887d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        ALOGV("C_SignFinal failed: 0x%x", rv);
7897d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        return -1;
7907d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    }
7917d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
7927d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    UniquePtr<uint8_t[]> finalSignature(new uint8_t[signatureLength]);
7937d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    if (finalSignature.get() == NULL) {
7947d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        ALOGE("Couldn't allocate memory to copy signature");
7957d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        return -1;
7967d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    }
7977d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
7987d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    memcpy(finalSignature.get(), signature, signatureLength);
7997d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
8007d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    *signedData = finalSignature.release();
8017d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    *signedDataLength = static_cast<size_t>(signatureLength);
8027d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
8037d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    ALOGV("tee_sign_data(%p, %p, %llu, %p, %llu, %p, %p) => %p size %llu", dev, key_blob,
8047d863c7f2f5f89205756af35989268a81ca5c581Kenny Root            (unsigned long long) key_blob_length, data, (unsigned long long) dataLength, signedData,
8057d863c7f2f5f89205756af35989268a81ca5c581Kenny Root            signedDataLength, *signedData, (unsigned long long) *signedDataLength);
8067d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
8077d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    return 0;
8087d863c7f2f5f89205756af35989268a81ca5c581Kenny Root}
8097d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
8107d863c7f2f5f89205756af35989268a81ca5c581Kenny Rootstatic int tee_verify_data(const keymaster_device_t* dev,
8117d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        const void* params,
8127d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        const uint8_t* keyBlob, const size_t keyBlobLength,
8137d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        const uint8_t* signedData, const size_t signedDataLength,
8147d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        const uint8_t* signature, const size_t signatureLength) {
8157d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    ALOGV("tee_verify_data(%p, %p, %llu, %p, %llu, %p, %llu)", dev, keyBlob,
8167d863c7f2f5f89205756af35989268a81ca5c581Kenny Root            (unsigned long long) keyBlobLength, signedData, (unsigned long long) signedDataLength,
8177d863c7f2f5f89205756af35989268a81ca5c581Kenny Root            signature, (unsigned long long) signatureLength);
8187d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
8197d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    if (params == NULL) {
8207d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        ALOGW("Verification params were null");
8217d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        return -1;
8227d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    }
8237d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
8247d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    CryptoSession session(reinterpret_cast<CK_SESSION_HANDLE>(dev->context));
8257d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
8267d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    ObjectHandle publicKey(&session);
8277d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    ObjectHandle privateKey(&session);
8287d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
8297d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    if (keyblob_restore(&session, keyBlob, keyBlobLength, &publicKey, &privateKey)) {
8307d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        return -1;
8317d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    }
8327d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    ALOGV("public handle = 0x%x, private handle = 0x%x", publicKey.get(), privateKey.get());
8337d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
8347d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    keymaster_rsa_sign_params_t* sign_params = (keymaster_rsa_sign_params_t*) params;
8357d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    if (sign_params->digest_type != DIGEST_NONE) {
8367d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        ALOGW("Cannot handle digest type %d", sign_params->digest_type);
8377d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        return -1;
8387d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    } else if (sign_params->padding_type != PADDING_NONE) {
8397d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        ALOGW("Cannot handle padding type %d", sign_params->padding_type);
8407d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        return -1;
8417d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    }
8427d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
8437d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    CK_MECHANISM rawRsaMechanism = {
8447d863c7f2f5f89205756af35989268a81ca5c581Kenny Root            CKM_RSA_X_509, NULL, 0
8457d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    };
8467d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
8477d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    CK_RV rv = C_VerifyInit(session.get(), &rawRsaMechanism, publicKey.get());
8487d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    if (rv != CKR_OK) {
8497d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        ALOGV("C_VerifyInit failed: 0x%x", rv);
8507d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        return -1;
8517d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    }
8527d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
8537d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    // This is a bad prototype for this function. C_Verify should have only const args.
8547d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    rv = C_Verify(session.get(), signedData, signedDataLength,
8557d863c7f2f5f89205756af35989268a81ca5c581Kenny Root            const_cast<unsigned char*>(signature), signatureLength);
8567d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    if (rv != CKR_OK) {
8577d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        ALOGV("C_Verify failed: 0x%x", rv);
8587d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        return -1;
8597d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    }
8607d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
8617d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    return 0;
8627d863c7f2f5f89205756af35989268a81ca5c581Kenny Root}
8637d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
8647d863c7f2f5f89205756af35989268a81ca5c581Kenny Root/* Close an opened OpenSSL instance */
8657d863c7f2f5f89205756af35989268a81ca5c581Kenny Rootstatic int tee_close(hw_device_t *dev) {
8667d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    keymaster_device_t *keymaster_dev = (keymaster_device_t *) dev;
8677d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    if (keymaster_dev != NULL) {
8687d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        CK_SESSION_HANDLE handle = reinterpret_cast<CK_SESSION_HANDLE>(keymaster_dev->context);
8697d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        if (handle != CK_INVALID_HANDLE) {
8707d863c7f2f5f89205756af35989268a81ca5c581Kenny Root            C_CloseSession(handle);
8717d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        }
8727d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    }
8737d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
8747d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    CK_RV finalizeRV = C_Finalize(NULL_PTR);
8757d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    if (finalizeRV != CKR_OK) {
8767d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        ALOGE("Error closing the TEE");
8777d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    }
8787d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    free(dev);
8797d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
8807d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    return 0;
8817d863c7f2f5f89205756af35989268a81ca5c581Kenny Root}
8827d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
8837d863c7f2f5f89205756af35989268a81ca5c581Kenny Root/*
8847d863c7f2f5f89205756af35989268a81ca5c581Kenny Root * Generic device handling
8857d863c7f2f5f89205756af35989268a81ca5c581Kenny Root */
8867d863c7f2f5f89205756af35989268a81ca5c581Kenny Rootstatic int tee_open(const hw_module_t* module, const char* name,
8877d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        hw_device_t** device) {
8887d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    if (strcmp(name, KEYSTORE_KEYMASTER) != 0)
8897d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        return -EINVAL;
8907d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
8917d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    Unique_keymaster_device_t dev(new keymaster_device_t);
8927d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    if (dev.get() == NULL)
8937d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        return -ENOMEM;
8947d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
8957d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    dev->common.tag = HARDWARE_DEVICE_TAG;
8967d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    dev->common.version = 1;
8977d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    dev->common.module = (struct hw_module_t*) module;
8987d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    dev->common.close = tee_close;
8997d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
9007d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    dev->generate_keypair = tee_generate_keypair;
9017d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    dev->import_keypair = tee_import_keypair;
9027d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    dev->get_keypair_public = tee_get_keypair_public;
9037d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    dev->delete_keypair = tee_delete_keypair;
9047d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    dev->sign_data = tee_sign_data;
9057d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    dev->verify_data = tee_verify_data;
90690d9cc5b25f6684963bbbd1104b103786401dde6Kenny Root    dev->delete_all = NULL;
9077d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
9087d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    CK_RV initializeRV = C_Initialize(NULL);
9097d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    if (initializeRV != CKR_OK) {
9107d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        ALOGE("Error initializing TEE: 0x%x", initializeRV);
9117d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        return -ENODEV;
9127d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    }
9137d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
9147d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    CK_INFO info;
9157d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    CK_RV infoRV = C_GetInfo(&info);
9167d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    if (infoRV != CKR_OK) {
9177d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        (void) C_Finalize(NULL_PTR);
9187d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        ALOGE("Error getting information about TEE during initialization: 0x%x", infoRV);
9197d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        return -ENODEV;
9207d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    }
9217d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
9227d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    ALOGI("C_GetInfo cryptokiVer=%d.%d manufID=%s flags=%d libDesc=%s libVer=%d.%d\n",
9237d863c7f2f5f89205756af35989268a81ca5c581Kenny Root           info.cryptokiVersion.major, info.cryptokiVersion.minor,
9247d863c7f2f5f89205756af35989268a81ca5c581Kenny Root           info.manufacturerID, info.flags, info.libraryDescription,
9257d863c7f2f5f89205756af35989268a81ca5c581Kenny Root           info.libraryVersion.major, info.libraryVersion.minor);
9267d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
9277d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    CK_SESSION_HANDLE sessionHandle = CK_INVALID_HANDLE;
9287d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
9297d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    CK_RV openSessionRV = C_OpenSession(CKV_TOKEN_USER,
9307d863c7f2f5f89205756af35989268a81ca5c581Kenny Root            CKF_SERIAL_SESSION | CKF_RW_SESSION,
9317d863c7f2f5f89205756af35989268a81ca5c581Kenny Root            NULL,
9327d863c7f2f5f89205756af35989268a81ca5c581Kenny Root            NULL,
9337d863c7f2f5f89205756af35989268a81ca5c581Kenny Root            &sessionHandle);
9347d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
9357d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    if (openSessionRV != CKR_OK || sessionHandle == CK_INVALID_HANDLE) {
9367d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        (void) C_Finalize(NULL_PTR);
9377d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        ALOGE("Error opening primary session with TEE: 0x%x", openSessionRV);
9387d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        return -1;
9397d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    }
9407d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
9417d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    ERR_load_crypto_strings();
9427d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    ERR_load_BIO_strings();
9437d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
9447d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    dev->context = reinterpret_cast<void*>(sessionHandle);
9457d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    *device = reinterpret_cast<hw_device_t*>(dev.release());
9467d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
9477d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    return 0;
9487d863c7f2f5f89205756af35989268a81ca5c581Kenny Root}
9497d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
9507d863c7f2f5f89205756af35989268a81ca5c581Kenny Rootstatic struct hw_module_methods_t keystore_module_methods = {
9517d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    open: tee_open,
9527d863c7f2f5f89205756af35989268a81ca5c581Kenny Root};
9537d863c7f2f5f89205756af35989268a81ca5c581Kenny Root
9547d863c7f2f5f89205756af35989268a81ca5c581Kenny Rootstruct keystore_module HAL_MODULE_INFO_SYM
9557d863c7f2f5f89205756af35989268a81ca5c581Kenny Root__attribute__ ((visibility ("default"))) = {
9567d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    common: {
9577d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        tag: HARDWARE_MODULE_TAG,
9587d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        version_major: 1,
9597d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        version_minor: 0,
9607d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        id: KEYSTORE_HARDWARE_MODULE_ID,
9617d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        name: "Keymaster TEE HAL",
9627d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        author: "The Android Open Source Project",
9637d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        methods: &keystore_module_methods,
9647d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        dso: 0,
9657d863c7f2f5f89205756af35989268a81ca5c581Kenny Root        reserved: {},
9667d863c7f2f5f89205756af35989268a81ca5c581Kenny Root    },
9677d863c7f2f5f89205756af35989268a81ca5c581Kenny Root};
968