1/* 2 * Copyright 2012 The Android Open Source Project 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 15 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 16 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY 17 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 18 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 19 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 20 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 21 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 22 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 23 * 24 */ 25 26#include <UniquePtr.h> 27 28//#define LOG_NDEBUG 0 29#define LOG_TAG "OpenSSL-keystore-rsa" 30#include <cutils/log.h> 31 32#include <binder/IServiceManager.h> 33#include <keystore/IKeystoreService.h> 34 35#include <openssl/rsa.h> 36#include <openssl/engine.h> 37 38#include "methods.h" 39 40 41using namespace android; 42 43 44int keystore_rsa_priv_enc(int flen, const unsigned char* from, unsigned char* to, RSA* rsa, 45 int padding) { 46 ALOGV("keystore_rsa_priv_enc(%d, %p, %p, %p, %d)", flen, from, to, rsa, padding); 47 48 int num = RSA_size(rsa); 49 UniquePtr<uint8_t> padded(new uint8_t[num]); 50 if (padded.get() == NULL) { 51 ALOGE("could not allocate padded signature"); 52 return 0; 53 } 54 55 switch (padding) { 56 case RSA_PKCS1_PADDING: 57 if (!RSA_padding_add_PKCS1_type_1(padded.get(), num, from, flen)) { 58 return 0; 59 } 60 break; 61 case RSA_X931_PADDING: 62 if (!RSA_padding_add_X931(padded.get(), num, from, flen)) { 63 return 0; 64 } 65 break; 66 case RSA_NO_PADDING: 67 if (!RSA_padding_add_none(padded.get(), num, from, flen)) { 68 return 0; 69 } 70 break; 71 default: 72 ALOGE("Unknown padding type: %d", padding); 73 return 0; 74 } 75 76 uint8_t* key_id = reinterpret_cast<uint8_t*>(RSA_get_ex_data(rsa, rsa_key_handle)); 77 if (key_id == NULL) { 78 ALOGE("key had no key_id!"); 79 return 0; 80 } 81 82 sp<IServiceManager> sm = defaultServiceManager(); 83 sp<IBinder> binder = sm->getService(String16("android.security.keystore")); 84 sp<IKeystoreService> service = interface_cast<IKeystoreService>(binder); 85 86 if (service == NULL) { 87 ALOGE("could not contact keystore"); 88 return 0; 89 } 90 91 uint8_t* reply = NULL; 92 size_t replyLen; 93 int32_t ret = service->sign(String16(reinterpret_cast<const char*>(key_id)), padded.get(), 94 num, &reply, &replyLen); 95 if (ret < 0) { 96 ALOGW("There was an error during signing: could not connect"); 97 free(reply); 98 return 0; 99 } else if (ret != 0) { 100 ALOGW("Error during signing from keystore: %d", ret); 101 free(reply); 102 return 0; 103 } else if (replyLen <= 0) { 104 ALOGW("No valid signature returned"); 105 return 0; 106 } 107 108 memcpy(to, reply, replyLen); 109 free(reply); 110 111 ALOGV("rsa=%p keystore_rsa_priv_enc => returning %p len %llu", rsa, to, 112 (unsigned long long) replyLen); 113 return static_cast<int>(replyLen); 114} 115 116int keystore_rsa_priv_dec(int flen, const unsigned char* from, unsigned char* to, RSA* rsa, 117 int padding) { 118 ALOGV("keystore_rsa_priv_dec(%d, %p, %p, %p, %d)", flen, from, to, rsa, padding); 119 120 uint8_t* key_id = reinterpret_cast<uint8_t*>(RSA_get_ex_data(rsa, rsa_key_handle)); 121 if (key_id == NULL) { 122 ALOGE("key had no key_id!"); 123 return 0; 124 } 125 126 sp<IServiceManager> sm = defaultServiceManager(); 127 sp<IBinder> binder = sm->getService(String16("android.security.keystore")); 128 sp<IKeystoreService> service = interface_cast<IKeystoreService>(binder); 129 130 if (service == NULL) { 131 ALOGE("could not contact keystore"); 132 return 0; 133 } 134 135 int num = RSA_size(rsa); 136 137 uint8_t* reply = NULL; 138 size_t replyLen; 139 int32_t ret = service->sign(String16(reinterpret_cast<const char*>(key_id)), from, 140 flen, &reply, &replyLen); 141 if (ret < 0) { 142 ALOGW("There was an error during rsa_mod_exp: could not connect"); 143 return 0; 144 } else if (ret != 0) { 145 ALOGW("Error during sign from keystore: %d", ret); 146 return 0; 147 } else if (replyLen <= 0) { 148 ALOGW("No valid signature returned"); 149 return 0; 150 } 151 152 /* Trim off the top zero if it's there */ 153 uint8_t* alignedReply; 154 if (*reply == 0x00) { 155 alignedReply = reply + 1; 156 replyLen--; 157 } else { 158 alignedReply = reply; 159 } 160 161 int outSize; 162 switch (padding) { 163 case RSA_PKCS1_PADDING: 164 outSize = RSA_padding_check_PKCS1_type_2(to, num, alignedReply, replyLen, num); 165 break; 166 case RSA_X931_PADDING: 167 outSize = RSA_padding_check_X931(to, num, alignedReply, replyLen, num); 168 break; 169 case RSA_NO_PADDING: 170 outSize = RSA_padding_check_none(to, num, alignedReply, replyLen, num); 171 break; 172 default: 173 ALOGE("Unknown padding type: %d", padding); 174 outSize = -1; 175 break; 176 } 177 178 free(reply); 179 180 ALOGV("rsa=%p keystore_rsa_priv_dec => returning %p len %d", rsa, to, outSize); 181 return outSize; 182} 183 184static RSA_METHOD keystore_rsa_meth = { 185 kKeystoreEngineId, 186 NULL, /* rsa_pub_enc (wrap) */ 187 NULL, /* rsa_pub_dec (verification) */ 188 keystore_rsa_priv_enc, /* rsa_priv_enc (signing) */ 189 keystore_rsa_priv_dec, /* rsa_priv_dec (unwrap) */ 190 NULL, /* rsa_mod_exp */ 191 NULL, /* bn_mod_exp */ 192 NULL, /* init */ 193 NULL, /* finish */ 194 RSA_FLAG_EXT_PKEY | RSA_FLAG_NO_BLINDING, /* flags */ 195 NULL, /* app_data */ 196 NULL, /* rsa_sign */ 197 NULL, /* rsa_verify */ 198 NULL, /* rsa_keygen */ 199}; 200 201static int register_rsa_methods() { 202 const RSA_METHOD* rsa_meth = RSA_PKCS1_SSLeay(); 203 204 keystore_rsa_meth.rsa_pub_enc = rsa_meth->rsa_pub_enc; 205 keystore_rsa_meth.rsa_pub_dec = rsa_meth->rsa_pub_dec; 206 keystore_rsa_meth.rsa_mod_exp = rsa_meth->rsa_mod_exp; 207 keystore_rsa_meth.bn_mod_exp = rsa_meth->bn_mod_exp; 208 209 return 1; 210} 211 212int rsa_pkey_setup(ENGINE *e, EVP_PKEY *pkey, const char *key_id) { 213 Unique_RSA rsa(EVP_PKEY_get1_RSA(pkey)); 214 if (!RSA_set_ex_data(rsa.get(), rsa_key_handle, reinterpret_cast<void*>(strdup(key_id)))) { 215 ALOGW("Could not set ex_data for loaded RSA key"); 216 return 0; 217 } 218 219 RSA_set_method(rsa.get(), &keystore_rsa_meth); 220 RSA_blinding_off(rsa.get()); 221 222 /* 223 * "RSA_set_ENGINE()" should probably be an OpenSSL API. Since it isn't, 224 * and EVP_PKEY_free() calls ENGINE_finish(), we need to call ENGINE_init() 225 * here. 226 */ 227 ENGINE_init(e); 228 rsa->engine = e; 229 rsa->flags |= RSA_FLAG_EXT_PKEY; 230 231 return 1; 232} 233 234int rsa_register(ENGINE* e) { 235 if (!ENGINE_set_RSA(e, &keystore_rsa_meth) 236 || !register_rsa_methods()) { 237 ALOGE("Could not set up keystore RSA methods"); 238 return 0; 239 } 240 241 return 1; 242} 243