19d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root/*
29d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root * Copyright 2012 The Android Open Source Project
39d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root *
49d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root * Redistribution and use in source and binary forms, with or without
59d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root * modification, are permitted provided that the following conditions
69d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root * are met:
79d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root * 1. Redistributions of source code must retain the above copyright
89d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root *    notice, this list of conditions and the following disclaimer.
99d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root * 2. Redistributions in binary form must reproduce the above copyright
109d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root *    notice, this list of conditions and the following disclaimer in the
119d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root *    documentation and/or other materials provided with the distribution.
129d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root *
139d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY
149d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
159d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
169d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY
179d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
189d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
199d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
209d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
219d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
229d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
239d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root *
249d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root */
259d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root
2626cfc08add3966eca5892e3387cf5ed6dc3068fbKenny Root#include <UniquePtr.h>
279d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root
289d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root//#define LOG_NDEBUG 0
299d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root#define LOG_TAG "OpenSSL-keystore-rsa"
309d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root#include <cutils/log.h>
319d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root
329d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root#include <binder/IServiceManager.h>
339d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root#include <keystore/IKeystoreService.h>
349d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root
359d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root#include <openssl/rsa.h>
369d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root#include <openssl/engine.h>
379d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root
389d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root#include "methods.h"
399d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root
409d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root
419d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Rootusing namespace android;
429d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root
439d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root
449d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Rootint keystore_rsa_priv_enc(int flen, const unsigned char* from, unsigned char* to, RSA* rsa,
459d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root        int padding) {
469d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root    ALOGV("keystore_rsa_priv_enc(%d, %p, %p, %p, %d)", flen, from, to, rsa, padding);
479d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root
489d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root    int num = RSA_size(rsa);
499d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root    UniquePtr<uint8_t> padded(new uint8_t[num]);
509d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root    if (padded.get() == NULL) {
519d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root        ALOGE("could not allocate padded signature");
529d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root        return 0;
539d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root    }
549d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root
559d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root    switch (padding) {
569d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root    case RSA_PKCS1_PADDING:
579d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root        if (!RSA_padding_add_PKCS1_type_1(padded.get(), num, from, flen)) {
589d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root            return 0;
599d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root        }
609d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root        break;
619d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root    case RSA_X931_PADDING:
629d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root        if (!RSA_padding_add_X931(padded.get(), num, from, flen)) {
639d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root            return 0;
649d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root        }
659d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root        break;
669d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root    case RSA_NO_PADDING:
679d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root        if (!RSA_padding_add_none(padded.get(), num, from, flen)) {
689d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root            return 0;
699d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root        }
709d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root        break;
719d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root    default:
729d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root        ALOGE("Unknown padding type: %d", padding);
739d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root        return 0;
749d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root    }
759d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root
769d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root    uint8_t* key_id = reinterpret_cast<uint8_t*>(RSA_get_ex_data(rsa, rsa_key_handle));
779d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root    if (key_id == NULL) {
789d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root        ALOGE("key had no key_id!");
799d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root        return 0;
809d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root    }
819d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root
829d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root    sp<IServiceManager> sm = defaultServiceManager();
839d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root    sp<IBinder> binder = sm->getService(String16("android.security.keystore"));
849d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root    sp<IKeystoreService> service = interface_cast<IKeystoreService>(binder);
859d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root
869d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root    if (service == NULL) {
879d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root        ALOGE("could not contact keystore");
889d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root        return 0;
899d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root    }
909d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root
919d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root    uint8_t* reply = NULL;
929d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root    size_t replyLen;
939d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root    int32_t ret = service->sign(String16(reinterpret_cast<const char*>(key_id)), padded.get(),
949d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root            num, &reply, &replyLen);
959d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root    if (ret < 0) {
969d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root        ALOGW("There was an error during signing: could not connect");
979d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root        free(reply);
989d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root        return 0;
999d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root    } else if (ret != 0) {
1009d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root        ALOGW("Error during signing from keystore: %d", ret);
1019d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root        free(reply);
1029d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root        return 0;
1039d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root    } else if (replyLen <= 0) {
1049d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root        ALOGW("No valid signature returned");
1059d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root        return 0;
1069d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root    }
1079d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root
1089d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root    memcpy(to, reply, replyLen);
1099d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root    free(reply);
1109d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root
1119d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root    ALOGV("rsa=%p keystore_rsa_priv_enc => returning %p len %llu", rsa, to,
1129d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root            (unsigned long long) replyLen);
1139d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root    return static_cast<int>(replyLen);
1149d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root}
1159d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root
1169d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Rootint keystore_rsa_priv_dec(int flen, const unsigned char* from, unsigned char* to, RSA* rsa,
1179d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root        int padding) {
1189d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root    ALOGV("keystore_rsa_priv_dec(%d, %p, %p, %p, %d)", flen, from, to, rsa, padding);
1199d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root
1209d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root    uint8_t* key_id = reinterpret_cast<uint8_t*>(RSA_get_ex_data(rsa, rsa_key_handle));
1219d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root    if (key_id == NULL) {
1229d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root        ALOGE("key had no key_id!");
1239d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root        return 0;
1249d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root    }
1259d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root
1269d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root    sp<IServiceManager> sm = defaultServiceManager();
1279d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root    sp<IBinder> binder = sm->getService(String16("android.security.keystore"));
1289d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root    sp<IKeystoreService> service = interface_cast<IKeystoreService>(binder);
1299d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root
1309d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root    if (service == NULL) {
1319d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root        ALOGE("could not contact keystore");
1329d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root        return 0;
1339d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root    }
1349d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root
1359d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root    int num = RSA_size(rsa);
1369d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root
1379d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root    uint8_t* reply = NULL;
1389d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root    size_t replyLen;
1399d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root    int32_t ret = service->sign(String16(reinterpret_cast<const char*>(key_id)), from,
1409d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root            flen, &reply, &replyLen);
1419d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root    if (ret < 0) {
1429d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root        ALOGW("There was an error during rsa_mod_exp: could not connect");
1439d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root        return 0;
1449d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root    } else if (ret != 0) {
1459d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root        ALOGW("Error during sign from keystore: %d", ret);
1469d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root        return 0;
1479d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root    } else if (replyLen <= 0) {
1489d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root        ALOGW("No valid signature returned");
1499d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root        return 0;
1509d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root    }
1519d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root
1529d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root    /* Trim off the top zero if it's there */
1539d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root    uint8_t* alignedReply;
1549d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root    if (*reply == 0x00) {
1559d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root        alignedReply = reply + 1;
1569d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root        replyLen--;
1579d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root    } else {
1589d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root        alignedReply = reply;
1599d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root    }
1609d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root
1619d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root    int outSize;
1629d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root    switch (padding) {
1639d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root    case RSA_PKCS1_PADDING:
1649d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root        outSize = RSA_padding_check_PKCS1_type_2(to, num, alignedReply, replyLen, num);
1659d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root        break;
1669d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root    case RSA_X931_PADDING:
1679d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root        outSize = RSA_padding_check_X931(to, num, alignedReply, replyLen, num);
1689d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root        break;
1699d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root    case RSA_NO_PADDING:
1709d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root        outSize = RSA_padding_check_none(to, num, alignedReply, replyLen, num);
1719d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root        break;
1729d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root    default:
1739d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root        ALOGE("Unknown padding type: %d", padding);
1749d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root        outSize = -1;
1759d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root        break;
1769d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root    }
1779d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root
1789d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root    free(reply);
1799d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root
18020e90ad94ae64b3c38f411a8d8c2cc8ede778838Colin Cross    ALOGV("rsa=%p keystore_rsa_priv_dec => returning %p len %d", rsa, to, outSize);
1819d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root    return outSize;
1829d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root}
1839d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root
1849d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Rootstatic RSA_METHOD keystore_rsa_meth = {
1859d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root        kKeystoreEngineId,
1869d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root        NULL, /* rsa_pub_enc (wrap) */
1879d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root        NULL, /* rsa_pub_dec (verification) */
1889d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root        keystore_rsa_priv_enc, /* rsa_priv_enc (signing) */
1899d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root        keystore_rsa_priv_dec, /* rsa_priv_dec (unwrap) */
1909d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root        NULL, /* rsa_mod_exp */
1919d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root        NULL, /* bn_mod_exp */
1929d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root        NULL, /* init */
1939d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root        NULL, /* finish */
1949d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root        RSA_FLAG_EXT_PKEY | RSA_FLAG_NO_BLINDING, /* flags */
1959d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root        NULL, /* app_data */
1969d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root        NULL, /* rsa_sign */
1979d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root        NULL, /* rsa_verify */
1989d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root        NULL, /* rsa_keygen */
1999d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root};
2009d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root
2019d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Rootstatic int register_rsa_methods() {
2029d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root    const RSA_METHOD* rsa_meth = RSA_PKCS1_SSLeay();
2039d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root
2049d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root    keystore_rsa_meth.rsa_pub_enc = rsa_meth->rsa_pub_enc;
2059d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root    keystore_rsa_meth.rsa_pub_dec = rsa_meth->rsa_pub_dec;
2069d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root    keystore_rsa_meth.rsa_mod_exp = rsa_meth->rsa_mod_exp;
2079d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root    keystore_rsa_meth.bn_mod_exp = rsa_meth->bn_mod_exp;
2089d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root
2099d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root    return 1;
2109d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root}
2119d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root
2129d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Rootint rsa_pkey_setup(ENGINE *e, EVP_PKEY *pkey, const char *key_id) {
2139d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root    Unique_RSA rsa(EVP_PKEY_get1_RSA(pkey));
2149d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root    if (!RSA_set_ex_data(rsa.get(), rsa_key_handle, reinterpret_cast<void*>(strdup(key_id)))) {
2159d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root        ALOGW("Could not set ex_data for loaded RSA key");
2169d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root        return 0;
2179d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root    }
2189d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root
2199d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root    RSA_set_method(rsa.get(), &keystore_rsa_meth);
2209d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root    RSA_blinding_off(rsa.get());
2219d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root
2229d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root    /*
2236071179a371fcd4c238375068ffd7d3cedea615dKenny Root     * "RSA_set_ENGINE()" should probably be an OpenSSL API. Since it isn't,
2246071179a371fcd4c238375068ffd7d3cedea615dKenny Root     * and EVP_PKEY_free() calls ENGINE_finish(), we need to call ENGINE_init()
2256071179a371fcd4c238375068ffd7d3cedea615dKenny Root     * here.
2269d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root     */
2279d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root    ENGINE_init(e);
2289d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root    rsa->engine = e;
2299d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root    rsa->flags |= RSA_FLAG_EXT_PKEY;
2309d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root
2319d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root    return 1;
2329d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root}
2339d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root
2349d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Rootint rsa_register(ENGINE* e) {
2359d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root    if (!ENGINE_set_RSA(e, &keystore_rsa_meth)
2369d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root            || !register_rsa_methods()) {
2379d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root        ALOGE("Could not set up keystore RSA methods");
2389d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root        return 0;
2399d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root    }
2409d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root
2419d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root    return 1;
2429d422a535cb4170acf46ec9fcb26cd3f428a2dc7Kenny Root}
243