170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root/*
270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root * Copyright (C) 2012 The Android Open Source Project
370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root *
470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root * Licensed under the Apache License, Version 2.0 (the "License");
570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root * you may not use this file except in compliance with the License.
670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root * You may obtain a copy of the License at
770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root *
870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root *      http://www.apache.org/licenses/LICENSE-2.0
970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root *
1070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root * Unless required by applicable law or agreed to in writing, software
1170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root * distributed under the License is distributed on an "AS IS" BASIS,
1270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root * See the License for the specific language governing permissions and
1470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root * limitations under the License.
1570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root */
1670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root#include <errno.h>
1770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root#include <string.h>
1870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root#include <stdint.h>
1970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
2007438c8d7256d3788dac323b4d0055f201e0bec9Kenny Root#include <keystore/keystore.h>
21822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root
2270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root#include <hardware/hardware.h>
2370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root#include <hardware/keymaster.h>
2470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
2570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root#include <openssl/evp.h>
2670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root#include <openssl/bio.h>
2770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root#include <openssl/rsa.h>
2870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root#include <openssl/err.h>
2970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root#include <openssl/x509.h>
3070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
3198c2f8fcc1263a9d94adac66994fffc96c0df699Colin Cross#include <utils/UniquePtr.h>
3270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
3370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root// For debugging
3470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root//#define LOG_NDEBUG 0
3570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
3670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root#define LOG_TAG "OpenSSLKeyMaster"
3770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root#include <cutils/log.h>
3870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
3970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Rootstruct BIGNUM_Delete {
4070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    void operator()(BIGNUM* p) const {
4170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        BN_free(p);
4270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
4370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root};
4470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Roottypedef UniquePtr<BIGNUM, BIGNUM_Delete> Unique_BIGNUM;
4570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
4670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Rootstruct EVP_PKEY_Delete {
4770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    void operator()(EVP_PKEY* p) const {
4870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        EVP_PKEY_free(p);
4970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
5070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root};
5170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Roottypedef UniquePtr<EVP_PKEY, EVP_PKEY_Delete> Unique_EVP_PKEY;
5270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
5370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Rootstruct PKCS8_PRIV_KEY_INFO_Delete {
5470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    void operator()(PKCS8_PRIV_KEY_INFO* p) const {
5570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        PKCS8_PRIV_KEY_INFO_free(p);
5670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
5770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root};
5870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Roottypedef UniquePtr<PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO_Delete> Unique_PKCS8_PRIV_KEY_INFO;
5970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
6096427baf0094d50047049d329b0779c3c910402cKenny Rootstruct DSA_Delete {
6196427baf0094d50047049d329b0779c3c910402cKenny Root    void operator()(DSA* p) const {
6296427baf0094d50047049d329b0779c3c910402cKenny Root        DSA_free(p);
6396427baf0094d50047049d329b0779c3c910402cKenny Root    }
6496427baf0094d50047049d329b0779c3c910402cKenny Root};
6596427baf0094d50047049d329b0779c3c910402cKenny Roottypedef UniquePtr<DSA, DSA_Delete> Unique_DSA;
6696427baf0094d50047049d329b0779c3c910402cKenny Root
6796427baf0094d50047049d329b0779c3c910402cKenny Rootstruct EC_KEY_Delete {
6896427baf0094d50047049d329b0779c3c910402cKenny Root    void operator()(EC_KEY* p) const {
6996427baf0094d50047049d329b0779c3c910402cKenny Root        EC_KEY_free(p);
7096427baf0094d50047049d329b0779c3c910402cKenny Root    }
7196427baf0094d50047049d329b0779c3c910402cKenny Root};
7296427baf0094d50047049d329b0779c3c910402cKenny Roottypedef UniquePtr<EC_KEY, EC_KEY_Delete> Unique_EC_KEY;
7396427baf0094d50047049d329b0779c3c910402cKenny Root
7470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Rootstruct RSA_Delete {
7570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    void operator()(RSA* p) const {
7670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        RSA_free(p);
7770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
7870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root};
7970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Roottypedef UniquePtr<RSA, RSA_Delete> Unique_RSA;
8070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
8170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Roottypedef UniquePtr<keymaster_device_t> Unique_keymaster_device_t;
8270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
8370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root/**
8470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root * Many OpenSSL APIs take ownership of an argument on success but don't free the argument
8570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root * on failure. This means we need to tell our scoped pointers when we've transferred ownership,
8670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root * without triggering a warning by not using the result of release().
8770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root */
8870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root#define OWNERSHIP_TRANSFERRED(obj) \
8970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    typeof (obj.release()) _dummy __attribute__((unused)) = obj.release()
9070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
9170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
9270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root/*
9370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root * Checks this thread's OpenSSL error queue and logs if
9470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root * necessary.
9570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root */
9670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Rootstatic void logOpenSSLError(const char* location) {
9770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    int error = ERR_get_error();
9870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
9970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    if (error != 0) {
10070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        char message[256];
10170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        ERR_error_string_n(error, message, sizeof(message));
10270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        ALOGE("OpenSSL error in %s %d: %s", location, error, message);
10370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
10470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
10570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    ERR_clear_error();
10670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    ERR_remove_state(0);
10770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root}
10870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
10970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Rootstatic int wrap_key(EVP_PKEY* pkey, int type, uint8_t** keyBlob, size_t* keyBlobLength) {
11096427baf0094d50047049d329b0779c3c910402cKenny Root    /*
11196427baf0094d50047049d329b0779c3c910402cKenny Root     *  Find the length of each size. Public key is not needed anymore but must be kept for
11296427baf0094d50047049d329b0779c3c910402cKenny Root     * alignment purposes.
11396427baf0094d50047049d329b0779c3c910402cKenny Root     */
11496427baf0094d50047049d329b0779c3c910402cKenny Root    int publicLen = 0;
11570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    int privateLen = i2d_PrivateKey(pkey, NULL);
11670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
11796427baf0094d50047049d329b0779c3c910402cKenny Root    if (privateLen <= 0) {
11896427baf0094d50047049d329b0779c3c910402cKenny Root        ALOGE("private key size was too big");
11970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        return -1;
12070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
12170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
12270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    /* int type + int size + private key data + int size + public key data */
123822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root    *keyBlobLength = get_softkey_header_size() + sizeof(int) + sizeof(int) + privateLen
124822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root            + sizeof(int) + publicLen;
12570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
12696427baf0094d50047049d329b0779c3c910402cKenny Root    UniquePtr<unsigned char> derData(new unsigned char[*keyBlobLength]);
12770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    if (derData.get() == NULL) {
12870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        ALOGE("could not allocate memory for key blob");
12970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        return -1;
13070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
13170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    unsigned char* p = derData.get();
13270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
133822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root    /* Write the magic value for software keys. */
134822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root    p = add_softkey_header(p, *keyBlobLength);
135822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root
13670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    /* Write key type to allocated buffer */
13770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    for (int i = sizeof(int) - 1; i >= 0; i--) {
13870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        *p++ = (type >> (8*i)) & 0xFF;
13970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
14070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
14170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    /* Write public key to allocated buffer */
14270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    for (int i = sizeof(int) - 1; i >= 0; i--) {
14370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        *p++ = (publicLen >> (8*i)) & 0xFF;
14470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
14570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
14670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    /* Write private key to allocated buffer */
14770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    for (int i = sizeof(int) - 1; i >= 0; i--) {
14870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        *p++ = (privateLen >> (8*i)) & 0xFF;
14970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
15070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    if (i2d_PrivateKey(pkey, &p) != privateLen) {
15170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        logOpenSSLError("wrap_key");
15270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        return -1;
15370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
15470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
15570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    *keyBlob = derData.release();
15670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
15770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    return 0;
15870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root}
15970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
16070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Rootstatic EVP_PKEY* unwrap_key(const uint8_t* keyBlob, const size_t keyBlobLength) {
16170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    long publicLen = 0;
16270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    long privateLen = 0;
16370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    const uint8_t* p = keyBlob;
16470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    const uint8_t *const end = keyBlob + keyBlobLength;
16570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
16670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    if (keyBlob == NULL) {
16770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        ALOGE("supplied key blob was NULL");
16870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        return NULL;
16970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
17070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
17170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    // Should be large enough for:
172822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root    // int32 magic, int32 type, int32 pubLen, char* pub, int32 privLen, char* priv
173822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root    if (keyBlobLength < (get_softkey_header_size() + sizeof(int) + sizeof(int) + 1
174822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root            + sizeof(int) + 1)) {
17570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        ALOGE("key blob appears to be truncated");
17670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        return NULL;
17770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
17870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
179822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root    if (!is_softkey(p, keyBlobLength)) {
180822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        ALOGE("cannot read key; it was not made by this keymaster");
181822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root        return NULL;
182822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root    }
183822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root    p += get_softkey_header_size();
184822c3a99d930e9299e2fad2fb3e0ff91b119b95aKenny Root
18570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    int type = 0;
18670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    for (size_t i = 0; i < sizeof(int); i++) {
18770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        type = (type << 8) | *p++;
18870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
18970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
19070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    for (size_t i = 0; i < sizeof(int); i++) {
19170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        publicLen = (publicLen << 8) | *p++;
19270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
19370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    if (p + publicLen > end) {
19470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        ALOGE("public key length encoding error: size=%ld, end=%d", publicLen, end - p);
19570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        return NULL;
19670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
19770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
19896427baf0094d50047049d329b0779c3c910402cKenny Root    p += publicLen;
19970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    if (end - p < 2) {
20070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        ALOGE("private key truncated");
20170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        return NULL;
20270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
20370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    for (size_t i = 0; i < sizeof(int); i++) {
20470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        privateLen = (privateLen << 8) | *p++;
20570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
20670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    if (p + privateLen > end) {
20770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        ALOGE("private key length encoding error: size=%ld, end=%d", privateLen, end - p);
20870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        return NULL;
20970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
21096427baf0094d50047049d329b0779c3c910402cKenny Root
21196427baf0094d50047049d329b0779c3c910402cKenny Root    Unique_EVP_PKEY pkey(EVP_PKEY_new());
21296427baf0094d50047049d329b0779c3c910402cKenny Root    if (pkey.get() == NULL) {
21396427baf0094d50047049d329b0779c3c910402cKenny Root        logOpenSSLError("unwrap_key");
21496427baf0094d50047049d329b0779c3c910402cKenny Root        return NULL;
21596427baf0094d50047049d329b0779c3c910402cKenny Root    }
21696427baf0094d50047049d329b0779c3c910402cKenny Root    EVP_PKEY* tmp = pkey.get();
21796427baf0094d50047049d329b0779c3c910402cKenny Root
21896427baf0094d50047049d329b0779c3c910402cKenny Root    if (d2i_PrivateKey(type, &tmp, &p, privateLen) == NULL) {
21996427baf0094d50047049d329b0779c3c910402cKenny Root        logOpenSSLError("unwrap_key");
22096427baf0094d50047049d329b0779c3c910402cKenny Root        return NULL;
22196427baf0094d50047049d329b0779c3c910402cKenny Root    }
22270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
22370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    return pkey.release();
22470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root}
22570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
22696427baf0094d50047049d329b0779c3c910402cKenny Rootstatic int generate_dsa_keypair(EVP_PKEY* pkey, const keymaster_dsa_keygen_params_t* dsa_params)
22796427baf0094d50047049d329b0779c3c910402cKenny Root{
22896427baf0094d50047049d329b0779c3c910402cKenny Root    if (dsa_params->key_size < 512) {
22996427baf0094d50047049d329b0779c3c910402cKenny Root        ALOGI("Requested DSA key size is too small (<512)");
23096427baf0094d50047049d329b0779c3c910402cKenny Root        return -1;
23196427baf0094d50047049d329b0779c3c910402cKenny Root    }
23270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
23396427baf0094d50047049d329b0779c3c910402cKenny Root    Unique_DSA dsa(DSA_new());
23496427baf0094d50047049d329b0779c3c910402cKenny Root
23596427baf0094d50047049d329b0779c3c910402cKenny Root    if (dsa_params->generator_len == 0 ||
23696427baf0094d50047049d329b0779c3c910402cKenny Root            dsa_params->prime_p_len == 0 ||
23796427baf0094d50047049d329b0779c3c910402cKenny Root            dsa_params->prime_q_len == 0 ||
23896427baf0094d50047049d329b0779c3c910402cKenny Root            dsa_params->generator == NULL||
23996427baf0094d50047049d329b0779c3c910402cKenny Root            dsa_params->prime_p == NULL ||
24096427baf0094d50047049d329b0779c3c910402cKenny Root            dsa_params->prime_q == NULL) {
24196427baf0094d50047049d329b0779c3c910402cKenny Root        if (DSA_generate_parameters_ex(dsa.get(), dsa_params->key_size, NULL, 0, NULL, NULL,
24296427baf0094d50047049d329b0779c3c910402cKenny Root                NULL) != 1) {
24396427baf0094d50047049d329b0779c3c910402cKenny Root            logOpenSSLError("generate_dsa_keypair");
24496427baf0094d50047049d329b0779c3c910402cKenny Root            return -1;
24596427baf0094d50047049d329b0779c3c910402cKenny Root        }
24696427baf0094d50047049d329b0779c3c910402cKenny Root    } else {
24796427baf0094d50047049d329b0779c3c910402cKenny Root        dsa->g = BN_bin2bn(dsa_params->generator,
24896427baf0094d50047049d329b0779c3c910402cKenny Root                dsa_params->generator_len,
24996427baf0094d50047049d329b0779c3c910402cKenny Root                NULL);
25096427baf0094d50047049d329b0779c3c910402cKenny Root        if (dsa->g == NULL) {
25196427baf0094d50047049d329b0779c3c910402cKenny Root            logOpenSSLError("generate_dsa_keypair");
25296427baf0094d50047049d329b0779c3c910402cKenny Root            return -1;
25396427baf0094d50047049d329b0779c3c910402cKenny Root        }
25496427baf0094d50047049d329b0779c3c910402cKenny Root
25596427baf0094d50047049d329b0779c3c910402cKenny Root        dsa->p = BN_bin2bn(dsa_params->prime_p,
25696427baf0094d50047049d329b0779c3c910402cKenny Root                   dsa_params->prime_p_len,
25796427baf0094d50047049d329b0779c3c910402cKenny Root                   NULL);
25896427baf0094d50047049d329b0779c3c910402cKenny Root        if (dsa->p == NULL) {
25996427baf0094d50047049d329b0779c3c910402cKenny Root            logOpenSSLError("generate_dsa_keypair");
26096427baf0094d50047049d329b0779c3c910402cKenny Root            return -1;
26196427baf0094d50047049d329b0779c3c910402cKenny Root        }
26296427baf0094d50047049d329b0779c3c910402cKenny Root
26396427baf0094d50047049d329b0779c3c910402cKenny Root        dsa->q = BN_bin2bn(dsa_params->prime_q,
26496427baf0094d50047049d329b0779c3c910402cKenny Root                   dsa_params->prime_q_len,
26596427baf0094d50047049d329b0779c3c910402cKenny Root                   NULL);
26696427baf0094d50047049d329b0779c3c910402cKenny Root        if (dsa->q == NULL) {
26796427baf0094d50047049d329b0779c3c910402cKenny Root            logOpenSSLError("generate_dsa_keypair");
26896427baf0094d50047049d329b0779c3c910402cKenny Root            return -1;
26996427baf0094d50047049d329b0779c3c910402cKenny Root        }
27096427baf0094d50047049d329b0779c3c910402cKenny Root    }
27196427baf0094d50047049d329b0779c3c910402cKenny Root
27296427baf0094d50047049d329b0779c3c910402cKenny Root    if (DSA_generate_key(dsa.get()) != 1) {
27396427baf0094d50047049d329b0779c3c910402cKenny Root        logOpenSSLError("generate_dsa_keypair");
27470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        return -1;
27596427baf0094d50047049d329b0779c3c910402cKenny Root    }
27696427baf0094d50047049d329b0779c3c910402cKenny Root
27796427baf0094d50047049d329b0779c3c910402cKenny Root    if (EVP_PKEY_assign_DSA(pkey, dsa.get()) == 0) {
27896427baf0094d50047049d329b0779c3c910402cKenny Root        logOpenSSLError("generate_dsa_keypair");
27996427baf0094d50047049d329b0779c3c910402cKenny Root        return -1;
28096427baf0094d50047049d329b0779c3c910402cKenny Root    }
28196427baf0094d50047049d329b0779c3c910402cKenny Root    OWNERSHIP_TRANSFERRED(dsa);
28296427baf0094d50047049d329b0779c3c910402cKenny Root
28396427baf0094d50047049d329b0779c3c910402cKenny Root    return 0;
28496427baf0094d50047049d329b0779c3c910402cKenny Root}
28596427baf0094d50047049d329b0779c3c910402cKenny Root
28696427baf0094d50047049d329b0779c3c910402cKenny Rootstatic int generate_ec_keypair(EVP_PKEY* pkey, const keymaster_ec_keygen_params_t* ec_params)
28796427baf0094d50047049d329b0779c3c910402cKenny Root{
28896427baf0094d50047049d329b0779c3c910402cKenny Root    EC_GROUP* group;
28996427baf0094d50047049d329b0779c3c910402cKenny Root    switch (ec_params->field_size) {
29096427baf0094d50047049d329b0779c3c910402cKenny Root    case 192:
29196427baf0094d50047049d329b0779c3c910402cKenny Root        group = EC_GROUP_new_by_curve_name(NID_X9_62_prime192v1);
29296427baf0094d50047049d329b0779c3c910402cKenny Root        break;
29396427baf0094d50047049d329b0779c3c910402cKenny Root    case 224:
29496427baf0094d50047049d329b0779c3c910402cKenny Root        group = EC_GROUP_new_by_curve_name(NID_secp224r1);
29596427baf0094d50047049d329b0779c3c910402cKenny Root        break;
29696427baf0094d50047049d329b0779c3c910402cKenny Root    case 256:
29796427baf0094d50047049d329b0779c3c910402cKenny Root        group = EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1);
29896427baf0094d50047049d329b0779c3c910402cKenny Root        break;
29996427baf0094d50047049d329b0779c3c910402cKenny Root    case 384:
30096427baf0094d50047049d329b0779c3c910402cKenny Root        group = EC_GROUP_new_by_curve_name(NID_secp384r1);
30196427baf0094d50047049d329b0779c3c910402cKenny Root        break;
30296427baf0094d50047049d329b0779c3c910402cKenny Root    case 521:
30396427baf0094d50047049d329b0779c3c910402cKenny Root        group = EC_GROUP_new_by_curve_name(NID_secp521r1);
30496427baf0094d50047049d329b0779c3c910402cKenny Root        break;
30596427baf0094d50047049d329b0779c3c910402cKenny Root    default:
30696427baf0094d50047049d329b0779c3c910402cKenny Root        group = NULL;
30796427baf0094d50047049d329b0779c3c910402cKenny Root        break;
30896427baf0094d50047049d329b0779c3c910402cKenny Root    }
30996427baf0094d50047049d329b0779c3c910402cKenny Root
31096427baf0094d50047049d329b0779c3c910402cKenny Root    if (group == NULL) {
31196427baf0094d50047049d329b0779c3c910402cKenny Root        logOpenSSLError("generate_ec_keypair");
31270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        return -1;
31370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
31470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
31596427baf0094d50047049d329b0779c3c910402cKenny Root    EC_GROUP_set_point_conversion_form(group, POINT_CONVERSION_UNCOMPRESSED);
31696427baf0094d50047049d329b0779c3c910402cKenny Root    EC_GROUP_set_asn1_flag(group, OPENSSL_EC_NAMED_CURVE);
31770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
31896427baf0094d50047049d329b0779c3c910402cKenny Root    /* initialize EC key */
31996427baf0094d50047049d329b0779c3c910402cKenny Root    Unique_EC_KEY eckey(EC_KEY_new());
32096427baf0094d50047049d329b0779c3c910402cKenny Root    if (eckey.get() == NULL) {
32196427baf0094d50047049d329b0779c3c910402cKenny Root        logOpenSSLError("generate_ec_keypair");
32296427baf0094d50047049d329b0779c3c910402cKenny Root        return -1;
32396427baf0094d50047049d329b0779c3c910402cKenny Root    }
32496427baf0094d50047049d329b0779c3c910402cKenny Root
32596427baf0094d50047049d329b0779c3c910402cKenny Root    if (EC_KEY_set_group(eckey.get(), group) != 1) {
32696427baf0094d50047049d329b0779c3c910402cKenny Root        logOpenSSLError("generate_ec_keypair");
32796427baf0094d50047049d329b0779c3c910402cKenny Root        return -1;
32896427baf0094d50047049d329b0779c3c910402cKenny Root    }
32996427baf0094d50047049d329b0779c3c910402cKenny Root
33096427baf0094d50047049d329b0779c3c910402cKenny Root    if (EC_KEY_generate_key(eckey.get()) != 1
33196427baf0094d50047049d329b0779c3c910402cKenny Root            || EC_KEY_check_key(eckey.get()) < 0) {
33296427baf0094d50047049d329b0779c3c910402cKenny Root        logOpenSSLError("generate_ec_keypair");
33396427baf0094d50047049d329b0779c3c910402cKenny Root        return -1;
33496427baf0094d50047049d329b0779c3c910402cKenny Root    }
33596427baf0094d50047049d329b0779c3c910402cKenny Root
33696427baf0094d50047049d329b0779c3c910402cKenny Root    if (EVP_PKEY_assign_EC_KEY(pkey, eckey.get()) == 0) {
33796427baf0094d50047049d329b0779c3c910402cKenny Root        logOpenSSLError("generate_ec_keypair");
33896427baf0094d50047049d329b0779c3c910402cKenny Root        return -1;
33996427baf0094d50047049d329b0779c3c910402cKenny Root    }
34096427baf0094d50047049d329b0779c3c910402cKenny Root    OWNERSHIP_TRANSFERRED(eckey);
34196427baf0094d50047049d329b0779c3c910402cKenny Root
34296427baf0094d50047049d329b0779c3c910402cKenny Root    return 0;
34396427baf0094d50047049d329b0779c3c910402cKenny Root}
34496427baf0094d50047049d329b0779c3c910402cKenny Root
34596427baf0094d50047049d329b0779c3c910402cKenny Rootstatic int generate_rsa_keypair(EVP_PKEY* pkey, const keymaster_rsa_keygen_params_t* rsa_params)
34696427baf0094d50047049d329b0779c3c910402cKenny Root{
34770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    Unique_BIGNUM bn(BN_new());
34870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    if (bn.get() == NULL) {
34996427baf0094d50047049d329b0779c3c910402cKenny Root        logOpenSSLError("generate_rsa_keypair");
35070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        return -1;
35170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
35270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
35370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    if (BN_set_word(bn.get(), rsa_params->public_exponent) == 0) {
35496427baf0094d50047049d329b0779c3c910402cKenny Root        logOpenSSLError("generate_rsa_keypair");
35570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        return -1;
35670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
35770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
35870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    /* initialize RSA */
35970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    Unique_RSA rsa(RSA_new());
36070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    if (rsa.get() == NULL) {
36196427baf0094d50047049d329b0779c3c910402cKenny Root        logOpenSSLError("generate_rsa_keypair");
36270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        return -1;
36370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
36470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
36570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    if (!RSA_generate_key_ex(rsa.get(), rsa_params->modulus_size, bn.get(), NULL)
36670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root            || RSA_check_key(rsa.get()) < 0) {
36796427baf0094d50047049d329b0779c3c910402cKenny Root        logOpenSSLError("generate_rsa_keypair");
36870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        return -1;
36970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
37070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
37196427baf0094d50047049d329b0779c3c910402cKenny Root    if (EVP_PKEY_assign_RSA(pkey, rsa.get()) == 0) {
37296427baf0094d50047049d329b0779c3c910402cKenny Root        logOpenSSLError("generate_rsa_keypair");
37396427baf0094d50047049d329b0779c3c910402cKenny Root        return -1;
37496427baf0094d50047049d329b0779c3c910402cKenny Root    }
37596427baf0094d50047049d329b0779c3c910402cKenny Root    OWNERSHIP_TRANSFERRED(rsa);
37696427baf0094d50047049d329b0779c3c910402cKenny Root
37796427baf0094d50047049d329b0779c3c910402cKenny Root    return 0;
37896427baf0094d50047049d329b0779c3c910402cKenny Root}
37996427baf0094d50047049d329b0779c3c910402cKenny Root
38017208e0de5a42722901d803118745cca25fd10c1Kenny Root__attribute__ ((visibility ("default")))
38117208e0de5a42722901d803118745cca25fd10c1Kenny Rootint openssl_generate_keypair(const keymaster_device_t*,
38296427baf0094d50047049d329b0779c3c910402cKenny Root        const keymaster_keypair_t key_type, const void* key_params,
38396427baf0094d50047049d329b0779c3c910402cKenny Root        uint8_t** keyBlob, size_t* keyBlobLength) {
38470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    Unique_EVP_PKEY pkey(EVP_PKEY_new());
38570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    if (pkey.get() == NULL) {
38670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        logOpenSSLError("openssl_generate_keypair");
38770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        return -1;
38870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
38970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
39096427baf0094d50047049d329b0779c3c910402cKenny Root    if (key_params == NULL) {
39196427baf0094d50047049d329b0779c3c910402cKenny Root        ALOGW("key_params == null");
39296427baf0094d50047049d329b0779c3c910402cKenny Root        return -1;
39396427baf0094d50047049d329b0779c3c910402cKenny Root    } else if (key_type == TYPE_DSA) {
39496427baf0094d50047049d329b0779c3c910402cKenny Root        const keymaster_dsa_keygen_params_t* dsa_params =
39596427baf0094d50047049d329b0779c3c910402cKenny Root                (const keymaster_dsa_keygen_params_t*) key_params;
39696427baf0094d50047049d329b0779c3c910402cKenny Root        generate_dsa_keypair(pkey.get(), dsa_params);
39796427baf0094d50047049d329b0779c3c910402cKenny Root    } else if (key_type == TYPE_EC) {
39896427baf0094d50047049d329b0779c3c910402cKenny Root        const keymaster_ec_keygen_params_t* ec_params =
39996427baf0094d50047049d329b0779c3c910402cKenny Root                (const keymaster_ec_keygen_params_t*) key_params;
40096427baf0094d50047049d329b0779c3c910402cKenny Root        generate_ec_keypair(pkey.get(), ec_params);
40196427baf0094d50047049d329b0779c3c910402cKenny Root    } else if (key_type == TYPE_RSA) {
40296427baf0094d50047049d329b0779c3c910402cKenny Root        const keymaster_rsa_keygen_params_t* rsa_params =
40396427baf0094d50047049d329b0779c3c910402cKenny Root                (const keymaster_rsa_keygen_params_t*) key_params;
40496427baf0094d50047049d329b0779c3c910402cKenny Root        generate_rsa_keypair(pkey.get(), rsa_params);
40596427baf0094d50047049d329b0779c3c910402cKenny Root    } else {
40696427baf0094d50047049d329b0779c3c910402cKenny Root        ALOGW("Unsupported key type %d", key_type);
40770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        return -1;
40870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
40970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
41096427baf0094d50047049d329b0779c3c910402cKenny Root    if (wrap_key(pkey.get(), EVP_PKEY_type(pkey->type), keyBlob, keyBlobLength)) {
41170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        return -1;
41270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
41370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
41470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    return 0;
41570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root}
41670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
41717208e0de5a42722901d803118745cca25fd10c1Kenny Root__attribute__ ((visibility ("default")))
41817208e0de5a42722901d803118745cca25fd10c1Kenny Rootint openssl_import_keypair(const keymaster_device_t*,
41970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        const uint8_t* key, const size_t key_length,
42070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        uint8_t** key_blob, size_t* key_blob_length) {
42170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    if (key == NULL) {
42270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        ALOGW("input key == NULL");
42370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        return -1;
42470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    } else if (key_blob == NULL || key_blob_length == NULL) {
42570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        ALOGW("output key blob or length == NULL");
42670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        return -1;
42770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
42870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
42970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    Unique_PKCS8_PRIV_KEY_INFO pkcs8(d2i_PKCS8_PRIV_KEY_INFO(NULL, &key, key_length));
43070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    if (pkcs8.get() == NULL) {
43170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        logOpenSSLError("openssl_import_keypair");
43270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        return -1;
43370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
43470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
43570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    /* assign to EVP */
43670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    Unique_EVP_PKEY pkey(EVP_PKCS82PKEY(pkcs8.get()));
43770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    if (pkey.get() == NULL) {
43870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        logOpenSSLError("openssl_import_keypair");
43970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        return -1;
44070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
44170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    OWNERSHIP_TRANSFERRED(pkcs8);
44270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
44370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    if (wrap_key(pkey.get(), EVP_PKEY_type(pkey->type), key_blob, key_blob_length)) {
44470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        return -1;
44570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
44670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
44770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    return 0;
44870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root}
44970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
45017208e0de5a42722901d803118745cca25fd10c1Kenny Root__attribute__ ((visibility ("default")))
45117208e0de5a42722901d803118745cca25fd10c1Kenny Rootint openssl_get_keypair_public(const struct keymaster_device*,
45270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        const uint8_t* key_blob, const size_t key_blob_length,
45370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        uint8_t** x509_data, size_t* x509_data_length) {
45470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
45570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    if (x509_data == NULL || x509_data_length == NULL) {
45670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        ALOGW("output public key buffer == NULL");
45770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        return -1;
45870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
45970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
46070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    Unique_EVP_PKEY pkey(unwrap_key(key_blob, key_blob_length));
46170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    if (pkey.get() == NULL) {
46270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        return -1;
46370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
46470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
46570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    int len = i2d_PUBKEY(pkey.get(), NULL);
46670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    if (len <= 0) {
46770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        logOpenSSLError("openssl_get_keypair_public");
46870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        return -1;
46970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
47070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
47170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    UniquePtr<uint8_t> key(static_cast<uint8_t*>(malloc(len)));
47270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    if (key.get() == NULL) {
47370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        ALOGE("Could not allocate memory for public key data");
47470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        return -1;
47570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
47670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
47770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    unsigned char* tmp = reinterpret_cast<unsigned char*>(key.get());
47870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    if (i2d_PUBKEY(pkey.get(), &tmp) != len) {
47970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        logOpenSSLError("openssl_get_keypair_public");
48070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        return -1;
48170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
48270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
48370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    ALOGV("Length of x509 data is %d", len);
48470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    *x509_data_length = len;
48570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    *x509_data = key.release();
48670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
48770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    return 0;
48870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root}
48970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
49096427baf0094d50047049d329b0779c3c910402cKenny Rootstatic int sign_dsa(EVP_PKEY* pkey, keymaster_dsa_sign_params_t* sign_params, const uint8_t* data,
49196427baf0094d50047049d329b0779c3c910402cKenny Root        const size_t dataLength, uint8_t** signedData, size_t* signedDataLength) {
49296427baf0094d50047049d329b0779c3c910402cKenny Root    if (sign_params->digest_type != DIGEST_NONE) {
49396427baf0094d50047049d329b0779c3c910402cKenny Root        ALOGW("Cannot handle digest type %d", sign_params->digest_type);
49496427baf0094d50047049d329b0779c3c910402cKenny Root        return -1;
49596427baf0094d50047049d329b0779c3c910402cKenny Root    }
49670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
49796427baf0094d50047049d329b0779c3c910402cKenny Root    Unique_DSA dsa(EVP_PKEY_get1_DSA(pkey));
49896427baf0094d50047049d329b0779c3c910402cKenny Root    if (dsa.get() == NULL) {
49996427baf0094d50047049d329b0779c3c910402cKenny Root        logOpenSSLError("openssl_sign_dsa");
50096427baf0094d50047049d329b0779c3c910402cKenny Root        return -1;
50196427baf0094d50047049d329b0779c3c910402cKenny Root    }
50270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
50396427baf0094d50047049d329b0779c3c910402cKenny Root    unsigned int dsaSize = DSA_size(dsa.get());
50496427baf0094d50047049d329b0779c3c910402cKenny Root    UniquePtr<uint8_t> signedDataPtr(reinterpret_cast<uint8_t*>(malloc(dsaSize)));
50596427baf0094d50047049d329b0779c3c910402cKenny Root    if (signedDataPtr.get() == NULL) {
50696427baf0094d50047049d329b0779c3c910402cKenny Root        logOpenSSLError("openssl_sign_dsa");
50770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        return -1;
50896427baf0094d50047049d329b0779c3c910402cKenny Root    }
50996427baf0094d50047049d329b0779c3c910402cKenny Root
51096427baf0094d50047049d329b0779c3c910402cKenny Root    unsigned char* tmp = reinterpret_cast<unsigned char*>(signedDataPtr.get());
51196427baf0094d50047049d329b0779c3c910402cKenny Root    if (DSA_sign(0, data, dataLength, tmp, &dsaSize, dsa.get()) <= 0) {
51296427baf0094d50047049d329b0779c3c910402cKenny Root        logOpenSSLError("openssl_sign_dsa");
51370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        return -1;
51470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
51570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
51696427baf0094d50047049d329b0779c3c910402cKenny Root    *signedDataLength = dsaSize;
51796427baf0094d50047049d329b0779c3c910402cKenny Root    *signedData = signedDataPtr.release();
51896427baf0094d50047049d329b0779c3c910402cKenny Root
51996427baf0094d50047049d329b0779c3c910402cKenny Root    return 0;
52096427baf0094d50047049d329b0779c3c910402cKenny Root}
52196427baf0094d50047049d329b0779c3c910402cKenny Root
52296427baf0094d50047049d329b0779c3c910402cKenny Rootstatic int sign_ec(EVP_PKEY* pkey, keymaster_ec_sign_params_t* sign_params, const uint8_t* data,
52396427baf0094d50047049d329b0779c3c910402cKenny Root        const size_t dataLength, uint8_t** signedData, size_t* signedDataLength) {
52496427baf0094d50047049d329b0779c3c910402cKenny Root    if (sign_params->digest_type != DIGEST_NONE) {
52596427baf0094d50047049d329b0779c3c910402cKenny Root        ALOGW("Cannot handle digest type %d", sign_params->digest_type);
52696427baf0094d50047049d329b0779c3c910402cKenny Root        return -1;
52796427baf0094d50047049d329b0779c3c910402cKenny Root    }
52896427baf0094d50047049d329b0779c3c910402cKenny Root
52996427baf0094d50047049d329b0779c3c910402cKenny Root    Unique_EC_KEY eckey(EVP_PKEY_get1_EC_KEY(pkey));
53096427baf0094d50047049d329b0779c3c910402cKenny Root    if (eckey.get() == NULL) {
53196427baf0094d50047049d329b0779c3c910402cKenny Root        logOpenSSLError("openssl_sign_ec");
53296427baf0094d50047049d329b0779c3c910402cKenny Root        return -1;
53396427baf0094d50047049d329b0779c3c910402cKenny Root    }
53496427baf0094d50047049d329b0779c3c910402cKenny Root
53596427baf0094d50047049d329b0779c3c910402cKenny Root    unsigned int ecdsaSize = ECDSA_size(eckey.get());
53696427baf0094d50047049d329b0779c3c910402cKenny Root    UniquePtr<uint8_t> signedDataPtr(reinterpret_cast<uint8_t*>(malloc(ecdsaSize)));
53796427baf0094d50047049d329b0779c3c910402cKenny Root    if (signedDataPtr.get() == NULL) {
53896427baf0094d50047049d329b0779c3c910402cKenny Root        logOpenSSLError("openssl_sign_ec");
53970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        return -1;
54070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
54170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
54296427baf0094d50047049d329b0779c3c910402cKenny Root    unsigned char* tmp = reinterpret_cast<unsigned char*>(signedDataPtr.get());
54396427baf0094d50047049d329b0779c3c910402cKenny Root    if (ECDSA_sign(0, data, dataLength, tmp, &ecdsaSize, eckey.get()) <= 0) {
54496427baf0094d50047049d329b0779c3c910402cKenny Root        logOpenSSLError("openssl_sign_ec");
54570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        return -1;
54670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
54770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
54896427baf0094d50047049d329b0779c3c910402cKenny Root    *signedDataLength = ecdsaSize;
54996427baf0094d50047049d329b0779c3c910402cKenny Root    *signedData = signedDataPtr.release();
55096427baf0094d50047049d329b0779c3c910402cKenny Root
55196427baf0094d50047049d329b0779c3c910402cKenny Root    return 0;
55296427baf0094d50047049d329b0779c3c910402cKenny Root}
55396427baf0094d50047049d329b0779c3c910402cKenny Root
55496427baf0094d50047049d329b0779c3c910402cKenny Root
55596427baf0094d50047049d329b0779c3c910402cKenny Rootstatic int sign_rsa(EVP_PKEY* pkey, keymaster_rsa_sign_params_t* sign_params, const uint8_t* data,
55696427baf0094d50047049d329b0779c3c910402cKenny Root        const size_t dataLength, uint8_t** signedData, size_t* signedDataLength) {
55770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    if (sign_params->digest_type != DIGEST_NONE) {
55870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        ALOGW("Cannot handle digest type %d", sign_params->digest_type);
55970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        return -1;
56070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    } else if (sign_params->padding_type != PADDING_NONE) {
56170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        ALOGW("Cannot handle padding type %d", sign_params->padding_type);
56270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        return -1;
56370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
56470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
56596427baf0094d50047049d329b0779c3c910402cKenny Root    Unique_RSA rsa(EVP_PKEY_get1_RSA(pkey));
56670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    if (rsa.get() == NULL) {
56796427baf0094d50047049d329b0779c3c910402cKenny Root        logOpenSSLError("openssl_sign_rsa");
56870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        return -1;
56970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
57070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
57170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    UniquePtr<uint8_t> signedDataPtr(reinterpret_cast<uint8_t*>(malloc(dataLength)));
57270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    if (signedDataPtr.get() == NULL) {
57396427baf0094d50047049d329b0779c3c910402cKenny Root        logOpenSSLError("openssl_sign_rsa");
57470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        return -1;
57570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
57670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
57770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    unsigned char* tmp = reinterpret_cast<unsigned char*>(signedDataPtr.get());
57870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    if (RSA_private_encrypt(dataLength, data, tmp, rsa.get(), RSA_NO_PADDING) <= 0) {
57996427baf0094d50047049d329b0779c3c910402cKenny Root        logOpenSSLError("openssl_sign_rsa");
58070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        return -1;
58170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
58270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
58370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    *signedDataLength = dataLength;
58470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    *signedData = signedDataPtr.release();
58596427baf0094d50047049d329b0779c3c910402cKenny Root
58670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    return 0;
58770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root}
58870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
58917208e0de5a42722901d803118745cca25fd10c1Kenny Root__attribute__ ((visibility ("default")))
59017208e0de5a42722901d803118745cca25fd10c1Kenny Rootint openssl_sign_data(const keymaster_device_t*,
59170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        const void* params,
59270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        const uint8_t* keyBlob, const size_t keyBlobLength,
59396427baf0094d50047049d329b0779c3c910402cKenny Root        const uint8_t* data, const size_t dataLength,
59496427baf0094d50047049d329b0779c3c910402cKenny Root        uint8_t** signedData, size_t* signedDataLength) {
59596427baf0094d50047049d329b0779c3c910402cKenny Root    if (data == NULL) {
59696427baf0094d50047049d329b0779c3c910402cKenny Root        ALOGW("input data to sign == NULL");
59796427baf0094d50047049d329b0779c3c910402cKenny Root        return -1;
59896427baf0094d50047049d329b0779c3c910402cKenny Root    } else if (signedData == NULL || signedDataLength == NULL) {
59996427baf0094d50047049d329b0779c3c910402cKenny Root        ALOGW("output signature buffer == NULL");
60070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        return -1;
60170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
60270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
60370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    Unique_EVP_PKEY pkey(unwrap_key(keyBlob, keyBlobLength));
60470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    if (pkey.get() == NULL) {
60570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        return -1;
60670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
60770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
60896427baf0094d50047049d329b0779c3c910402cKenny Root    int type = EVP_PKEY_type(pkey->type);
60996427baf0094d50047049d329b0779c3c910402cKenny Root    if (type == EVP_PKEY_DSA) {
61096427baf0094d50047049d329b0779c3c910402cKenny Root        keymaster_dsa_sign_params_t* sign_params = (keymaster_dsa_sign_params_t*) params;
61196427baf0094d50047049d329b0779c3c910402cKenny Root        return sign_dsa(pkey.get(), sign_params, data, dataLength, signedData, signedDataLength);
61296427baf0094d50047049d329b0779c3c910402cKenny Root    } else if (type == EVP_PKEY_EC) {
61396427baf0094d50047049d329b0779c3c910402cKenny Root        keymaster_ec_sign_params_t* sign_params = (keymaster_ec_sign_params_t*) params;
61496427baf0094d50047049d329b0779c3c910402cKenny Root        return sign_ec(pkey.get(), sign_params, data, dataLength, signedData, signedDataLength);
61596427baf0094d50047049d329b0779c3c910402cKenny Root    } else if (type == EVP_PKEY_RSA) {
61696427baf0094d50047049d329b0779c3c910402cKenny Root        keymaster_rsa_sign_params_t* sign_params = (keymaster_rsa_sign_params_t*) params;
61796427baf0094d50047049d329b0779c3c910402cKenny Root        return sign_rsa(pkey.get(), sign_params, data, dataLength, signedData, signedDataLength);
61896427baf0094d50047049d329b0779c3c910402cKenny Root    } else {
61996427baf0094d50047049d329b0779c3c910402cKenny Root        ALOGW("Unsupported key type");
62070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        return -1;
62170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
62296427baf0094d50047049d329b0779c3c910402cKenny Root}
62370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
62496427baf0094d50047049d329b0779c3c910402cKenny Rootstatic int verify_dsa(EVP_PKEY* pkey, keymaster_dsa_sign_params_t* sign_params,
62596427baf0094d50047049d329b0779c3c910402cKenny Root        const uint8_t* signedData, const size_t signedDataLength, const uint8_t* signature,
62696427baf0094d50047049d329b0779c3c910402cKenny Root        const size_t signatureLength) {
62796427baf0094d50047049d329b0779c3c910402cKenny Root    if (sign_params->digest_type != DIGEST_NONE) {
62896427baf0094d50047049d329b0779c3c910402cKenny Root        ALOGW("Cannot handle digest type %d", sign_params->digest_type);
62996427baf0094d50047049d329b0779c3c910402cKenny Root        return -1;
63096427baf0094d50047049d329b0779c3c910402cKenny Root    }
63196427baf0094d50047049d329b0779c3c910402cKenny Root
63296427baf0094d50047049d329b0779c3c910402cKenny Root    Unique_DSA dsa(EVP_PKEY_get1_DSA(pkey));
63396427baf0094d50047049d329b0779c3c910402cKenny Root    if (dsa.get() == NULL) {
63496427baf0094d50047049d329b0779c3c910402cKenny Root        logOpenSSLError("openssl_verify_dsa");
63596427baf0094d50047049d329b0779c3c910402cKenny Root        return -1;
63696427baf0094d50047049d329b0779c3c910402cKenny Root    }
63796427baf0094d50047049d329b0779c3c910402cKenny Root
63896427baf0094d50047049d329b0779c3c910402cKenny Root    if (DSA_verify(0, signedData, signedDataLength, signature, signatureLength, dsa.get()) <= 0) {
63996427baf0094d50047049d329b0779c3c910402cKenny Root        logOpenSSLError("openssl_verify_dsa");
64096427baf0094d50047049d329b0779c3c910402cKenny Root        return -1;
64196427baf0094d50047049d329b0779c3c910402cKenny Root    }
64296427baf0094d50047049d329b0779c3c910402cKenny Root
64396427baf0094d50047049d329b0779c3c910402cKenny Root    return 0;
64496427baf0094d50047049d329b0779c3c910402cKenny Root}
64596427baf0094d50047049d329b0779c3c910402cKenny Root
64696427baf0094d50047049d329b0779c3c910402cKenny Rootstatic int verify_ec(EVP_PKEY* pkey, keymaster_ec_sign_params_t* sign_params,
64796427baf0094d50047049d329b0779c3c910402cKenny Root        const uint8_t* signedData, const size_t signedDataLength, const uint8_t* signature,
64896427baf0094d50047049d329b0779c3c910402cKenny Root        const size_t signatureLength) {
64996427baf0094d50047049d329b0779c3c910402cKenny Root    if (sign_params->digest_type != DIGEST_NONE) {
65096427baf0094d50047049d329b0779c3c910402cKenny Root        ALOGW("Cannot handle digest type %d", sign_params->digest_type);
65196427baf0094d50047049d329b0779c3c910402cKenny Root        return -1;
65296427baf0094d50047049d329b0779c3c910402cKenny Root    }
65396427baf0094d50047049d329b0779c3c910402cKenny Root
65496427baf0094d50047049d329b0779c3c910402cKenny Root    Unique_EC_KEY eckey(EVP_PKEY_get1_EC_KEY(pkey));
65596427baf0094d50047049d329b0779c3c910402cKenny Root    if (eckey.get() == NULL) {
65696427baf0094d50047049d329b0779c3c910402cKenny Root        logOpenSSLError("openssl_verify_ec");
65796427baf0094d50047049d329b0779c3c910402cKenny Root        return -1;
65896427baf0094d50047049d329b0779c3c910402cKenny Root    }
65996427baf0094d50047049d329b0779c3c910402cKenny Root
66096427baf0094d50047049d329b0779c3c910402cKenny Root    if (ECDSA_verify(0, signedData, signedDataLength, signature, signatureLength, eckey.get()) <= 0) {
66196427baf0094d50047049d329b0779c3c910402cKenny Root        logOpenSSLError("openssl_verify_ec");
66296427baf0094d50047049d329b0779c3c910402cKenny Root        return -1;
66396427baf0094d50047049d329b0779c3c910402cKenny Root    }
66496427baf0094d50047049d329b0779c3c910402cKenny Root
66596427baf0094d50047049d329b0779c3c910402cKenny Root    return 0;
66696427baf0094d50047049d329b0779c3c910402cKenny Root}
66796427baf0094d50047049d329b0779c3c910402cKenny Root
66896427baf0094d50047049d329b0779c3c910402cKenny Rootstatic int verify_rsa(EVP_PKEY* pkey, keymaster_rsa_sign_params_t* sign_params,
66996427baf0094d50047049d329b0779c3c910402cKenny Root        const uint8_t* signedData, const size_t signedDataLength, const uint8_t* signature,
67096427baf0094d50047049d329b0779c3c910402cKenny Root        const size_t signatureLength) {
67170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    if (sign_params->digest_type != DIGEST_NONE) {
67270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        ALOGW("Cannot handle digest type %d", sign_params->digest_type);
67370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        return -1;
67470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    } else if (sign_params->padding_type != PADDING_NONE) {
67570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        ALOGW("Cannot handle padding type %d", sign_params->padding_type);
67670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        return -1;
67770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    } else if (signatureLength != signedDataLength) {
67870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        ALOGW("signed data length must be signature length");
67970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        return -1;
68070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
68170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
68296427baf0094d50047049d329b0779c3c910402cKenny Root    Unique_RSA rsa(EVP_PKEY_get1_RSA(pkey));
68370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    if (rsa.get() == NULL) {
68470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        logOpenSSLError("openssl_verify_data");
68570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        return -1;
68670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
68770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
68870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    UniquePtr<uint8_t> dataPtr(reinterpret_cast<uint8_t*>(malloc(signedDataLength)));
68970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    if (dataPtr.get() == NULL) {
69070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        logOpenSSLError("openssl_verify_data");
69170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        return -1;
69270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
69370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
69470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    unsigned char* tmp = reinterpret_cast<unsigned char*>(dataPtr.get());
69570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    if (!RSA_public_decrypt(signatureLength, signature, tmp, rsa.get(), RSA_NO_PADDING)) {
69670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        logOpenSSLError("openssl_verify_data");
69770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        return -1;
69870e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
69970e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
70070e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    int result = 0;
70170e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    for (size_t i = 0; i < signedDataLength; i++) {
70270e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root        result |= tmp[i] ^ signedData[i];
70370e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    }
70470e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
70570e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root    return result == 0 ? 0 : -1;
70670e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root}
70770e3a86abd2c412d602a018967c01c177eb6cf4eKenny Root
70817208e0de5a42722901d803118745cca25fd10c1Kenny Root__attribute__ ((visibility ("default")))
70917208e0de5a42722901d803118745cca25fd10c1Kenny Rootint openssl_verify_data(const keymaster_device_t*,
71096427baf0094d50047049d329b0779c3c910402cKenny Root        const void* params,
71196427baf0094d50047049d329b0779c3c910402cKenny Root        const uint8_t* keyBlob, const size_t keyBlobLength,
71296427baf0094d50047049d329b0779c3c910402cKenny Root        const uint8_t* signedData, const size_t signedDataLength,
71396427baf0094d50047049d329b0779c3c910402cKenny Root        const uint8_t* signature, const size_t signatureLength) {
71496427baf0094d50047049d329b0779c3c910402cKenny Root
71596427baf0094d50047049d329b0779c3c910402cKenny Root    if (signedData == NULL || signature == NULL) {
71696427baf0094d50047049d329b0779c3c910402cKenny Root        ALOGW("data or signature buffers == NULL");
71796427baf0094d50047049d329b0779c3c910402cKenny Root        return -1;
71896427baf0094d50047049d329b0779c3c910402cKenny Root    }
71996427baf0094d50047049d329b0779c3c910402cKenny Root
72096427baf0094d50047049d329b0779c3c910402cKenny Root    Unique_EVP_PKEY pkey(unwrap_key(keyBlob, keyBlobLength));
72196427baf0094d50047049d329b0779c3c910402cKenny Root    if (pkey.get() == NULL) {
72296427baf0094d50047049d329b0779c3c910402cKenny Root        return -1;
72396427baf0094d50047049d329b0779c3c910402cKenny Root    }
72496427baf0094d50047049d329b0779c3c910402cKenny Root
72596427baf0094d50047049d329b0779c3c910402cKenny Root    int type = EVP_PKEY_type(pkey->type);
72617208e0de5a42722901d803118745cca25fd10c1Kenny Root    if (type == EVP_PKEY_DSA) {
72717208e0de5a42722901d803118745cca25fd10c1Kenny Root        keymaster_dsa_sign_params_t* sign_params = (keymaster_dsa_sign_params_t*) params;
72817208e0de5a42722901d803118745cca25fd10c1Kenny Root        return verify_dsa(pkey.get(), sign_params, signedData, signedDataLength, signature,
72917208e0de5a42722901d803118745cca25fd10c1Kenny Root                signatureLength);
73017208e0de5a42722901d803118745cca25fd10c1Kenny Root    } else if (type == EVP_PKEY_RSA) {
73196427baf0094d50047049d329b0779c3c910402cKenny Root        keymaster_rsa_sign_params_t* sign_params = (keymaster_rsa_sign_params_t*) params;
73296427baf0094d50047049d329b0779c3c910402cKenny Root        return verify_rsa(pkey.get(), sign_params, signedData, signedDataLength, signature,
73396427baf0094d50047049d329b0779c3c910402cKenny Root                signatureLength);
73496427baf0094d50047049d329b0779c3c910402cKenny Root    } else if (type == EVP_PKEY_EC) {
73596427baf0094d50047049d329b0779c3c910402cKenny Root        keymaster_ec_sign_params_t* sign_params = (keymaster_ec_sign_params_t*) params;
73696427baf0094d50047049d329b0779c3c910402cKenny Root        return verify_ec(pkey.get(), sign_params, signedData, signedDataLength, signature,
73796427baf0094d50047049d329b0779c3c910402cKenny Root                signatureLength);
73896427baf0094d50047049d329b0779c3c910402cKenny Root    } else {
73996427baf0094d50047049d329b0779c3c910402cKenny Root        ALOGW("Unsupported key type %d", type);
74096427baf0094d50047049d329b0779c3c910402cKenny Root        return -1;
74196427baf0094d50047049d329b0779c3c910402cKenny Root    }
74296427baf0094d50047049d329b0779c3c910402cKenny Root}
743