195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley/* Copyright (c) 2014, Google Inc. 295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * Permission to use, copy, modify, and/or distribute this software for any 495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * purpose with or without fee is hereby granted, provided that the above 595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * copyright notice and this permission notice appear in all copies. 695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 1095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 1195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION 1295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 1395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ 1495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 1595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include <openssl/engine.h> 1695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 1795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include <openssl/dh.h> 1895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include <openssl/dsa.h> 1995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include <openssl/ec_key.h> 2095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include <openssl/mem.h> 2195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include <openssl/rsa.h> 2295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include <openssl/thread.h> 2395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 2495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 2595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleystruct engine_st { 2695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley DH_METHOD *dh_method; 2795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley DSA_METHOD *dsa_method; 2895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley RSA_METHOD *rsa_method; 2995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ECDSA_METHOD *ecdsa_method; 3095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley}; 3195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 32c44d2f4cb8a892a603edbbe710fa82bcd30f9cb5David BenjaminENGINE *ENGINE_new(void) { 3395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley ENGINE *engine = OPENSSL_malloc(sizeof(ENGINE)); 3495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (engine == NULL) { 3595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return NULL; 3695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 3795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 3895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley memset(engine, 0, sizeof(ENGINE)); 3995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return engine; 4095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 4195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 4295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyvoid ENGINE_free(ENGINE *engine) { 4395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (engine->dh_method != NULL) { 4495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley METHOD_unref(engine->dh_method); 4595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 4695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 4795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley OPENSSL_free(engine); 4895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 4995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 5095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley/* set_method takes a pointer to a method and its given size and sets 5195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * |*out_member| to point to a copy of it. The copy is |compiled_size| bytes 5295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * long and has zero padding if needed. */ 5395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleystatic int set_method(void **out_member, const void *method, size_t method_size, 5495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley size_t compiled_size) { 5595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley void *copy = OPENSSL_malloc(compiled_size); 5695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (copy == NULL) { 5795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 0; 5895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 5995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 6095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley memset(copy, 0, compiled_size); 6195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 6295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (method_size > compiled_size) { 6395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley method_size = compiled_size; 6495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 6595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley memcpy(copy, method, method_size); 6695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 6795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley METHOD_unref(*out_member); 6895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *out_member = copy; 6995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 7095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return 1; 7195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 7295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 7395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyint ENGINE_set_DH_method(ENGINE *engine, const DH_METHOD *method, 7495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley size_t method_size) { 7595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return set_method((void **)&engine->dh_method, method, method_size, 7695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley sizeof(DH_METHOD)); 7795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 7895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 7995c29f3cd1f6c08c6c0927868683392eea727ccAdam LangleyDH_METHOD *ENGINE_get_DH_method(const ENGINE *engine) { 8095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return engine->dh_method; 8195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 8295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 8395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyint ENGINE_set_DSA_method(ENGINE *engine, const DSA_METHOD *method, 8495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley size_t method_size) { 8595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return set_method((void **)&engine->dsa_method, method, method_size, 8695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley sizeof(DSA_METHOD)); 8795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 8895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 8995c29f3cd1f6c08c6c0927868683392eea727ccAdam LangleyDSA_METHOD *ENGINE_get_DSA_method(const ENGINE *engine) { 9095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return engine->dsa_method; 9195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 9295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 9395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyint ENGINE_set_RSA_method(ENGINE *engine, const RSA_METHOD *method, 9495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley size_t method_size) { 9595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return set_method((void **)&engine->rsa_method, method, method_size, 9695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley sizeof(RSA_METHOD)); 9795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 9895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 9995c29f3cd1f6c08c6c0927868683392eea727ccAdam LangleyRSA_METHOD *ENGINE_get_RSA_method(const ENGINE *engine) { 10095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return engine->rsa_method; 10195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 10295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 10395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyint ENGINE_set_ECDSA_method(ENGINE *engine, const ECDSA_METHOD *method, 10495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley size_t method_size) { 10595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return set_method((void **)&engine->ecdsa_method, method, method_size, 10695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley sizeof(ECDSA_METHOD)); 10795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 10895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 10995c29f3cd1f6c08c6c0927868683392eea727ccAdam LangleyECDSA_METHOD *ENGINE_get_ECDSA_method(const ENGINE *engine) { 11095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return engine->ecdsa_method; 11195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 11295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 11395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyvoid METHOD_ref(void *method_in) { 11495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley struct openssl_method_common_st *method = method_in; 11595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 11695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (method->is_static) { 11795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return; 11895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 11995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 12095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley CRYPTO_add(&method->references, 1, CRYPTO_LOCK_ENGINE); 12195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 12295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 12395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyvoid METHOD_unref(void *method_in) { 12495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley struct openssl_method_common_st *method = method_in; 12595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 12695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (method == NULL || method->is_static) { 12795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley return; 12895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 12995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley 13095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley if (CRYPTO_add(&method->references, -1, CRYPTO_LOCK_ENGINE) == 0) { 13195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley OPENSSL_free(method); 13295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley } 13395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley} 134