From c3970428acd44f805721558692d7940c1fd6ac4d Mon Sep 17 00:00:00 2001 From: "Mark J. Cox" Date: Mon, 12 Nov 2001 20:28:09 +0000 Subject: [PATCH] Back-port of Broadcom engine code from 0.9.7 to 0.9.6, but with a few patches taken from Red Hat Linux 7.2. Original code from Broadcom with patches and backport by Nalin, more backport to fix warnings and const changes by Mark Submitted by: Mark Cox Reviewed by: PR: --- CHANGES | 4 + crypto/engine/Makefile.ssl | 26 +- crypto/engine/engine.h | 10 + crypto/engine/engine_err.c | 8 + crypto/engine/engine_int.h | 4 + crypto/engine/engine_list.c | 4 + crypto/engine/hw_ubsec.c | 902 +++++++++++++++----------- crypto/engine/vendor_defns/hw_ubsec.h | 6 + 8 files changed, 578 insertions(+), 386 deletions(-) diff --git a/CHANGES b/CHANGES index 292116be64..784c938ca6 100644 --- a/CHANGES +++ b/CHANGES @@ -4,6 +4,10 @@ Changes between 0.9.6b and 0.9.6c [XX xxx XXXX] + *) Add support for Broadcom crypto accelerator cards, backported + from 0.9.7. + [Broadcom, Nalin Dahyabhai , Mark Cox] + *) Add support for SureWare crypto accelerator cards from Baltimore Technologies. (Use engine 'sureware') [Baltimore Technologies and Mark Cox] diff --git a/crypto/engine/Makefile.ssl b/crypto/engine/Makefile.ssl index 8c6964b9d3..1e50aa4000 100644 --- a/crypto/engine/Makefile.ssl +++ b/crypto/engine/Makefile.ssl @@ -23,9 +23,11 @@ APPS= LIB=$(TOP)/libcrypto.a LIBSRC= engine_err.c engine_lib.c engine_list.c engine_openssl.c \ - hw_atalla.c hw_cswift.c hw_ncipher.c hw_aep.c hw_sureware.c + hw_atalla.c hw_cswift.c hw_ncipher.c hw_aep.c hw_sureware.c \ + hw_ubsec.c LIBOBJ= engine_err.o engine_lib.o engine_list.o engine_openssl.o \ - hw_atalla.o hw_cswift.o hw_ncipher.o hw_aep.o hw_sureware.o + hw_atalla.o hw_cswift.o hw_ncipher.o hw_aep.o hw_sureware.o \ + hw_ubsec.o SRC= $(LIBSRC) @@ -259,3 +261,23 @@ hw_sureware.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h hw_sureware.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h hw_sureware.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h hw_sureware.o: ../cryptlib.h engine.h engine_int.h vendor_defns/sureware.h +hw_ubsec.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h +hw_ubsec.o: ../../include/openssl/blowfish.h ../../include/openssl/bn.h +hw_ubsec.o: ../../include/openssl/buffer.h ../../include/openssl/cast.h +hw_ubsec.o: ../../include/openssl/crypto.h ../../include/openssl/des.h +hw_ubsec.o: ../../include/openssl/dh.h ../../include/openssl/dsa.h +hw_ubsec.o: ../../include/openssl/dso.h ../../include/openssl/e_os.h +hw_ubsec.o: ../../include/openssl/e_os2.h ../../include/openssl/engine.h +hw_ubsec.o: ../../include/openssl/err.h ../../include/openssl/evp.h +hw_ubsec.o: ../../include/openssl/idea.h ../../include/openssl/lhash.h +hw_ubsec.o: ../../include/openssl/md2.h ../../include/openssl/md4.h +hw_ubsec.o: ../../include/openssl/md5.h ../../include/openssl/mdc2.h +hw_ubsec.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h +hw_ubsec.o: ../../include/openssl/opensslconf.h +hw_ubsec.o: ../../include/openssl/opensslv.h ../../include/openssl/rand.h +hw_ubsec.o: ../../include/openssl/rc2.h ../../include/openssl/rc4.h +hw_ubsec.o: ../../include/openssl/rc5.h ../../include/openssl/ripemd.h +hw_ubsec.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h +hw_ubsec.o: ../../include/openssl/sha.h ../../include/openssl/stack.h +hw_ubsec.o: ../../include/openssl/symhacks.h ../cryptlib.h engine_int.h +hw_ubsec.o: vendor_defns/hw_ubsec.h diff --git a/crypto/engine/engine.h b/crypto/engine/engine.h index e9baceda74..56a6d4cf99 100644 --- a/crypto/engine/engine.h +++ b/crypto/engine/engine.h @@ -377,6 +377,16 @@ void ERR_load_ENGINE_strings(void); #define ENGINE_F_SUREWAREHK_DH_GEN_KEY 210 #define ENGINE_F_SUREWAREHK_DSA_DO_SIGN 211 #define ENGINE_F_SUREWAREHK_MOD_EXP 212 +#define ENGINE_F_UBSEC_CTRL 176 +#define ENGINE_F_UBSEC_DSA_SIGN 163 +#define ENGINE_F_UBSEC_DSA_VERIFY 164 +#define ENGINE_F_UBSEC_FINISH 165 +#define ENGINE_F_UBSEC_INIT 166 +#define ENGINE_F_UBSEC_MOD_EXP 167 +#define ENGINE_F_UBSEC_RSA_MOD_EXP 168 +#define ENGINE_F_UBSEC_RSA_MOD_EXP_CRT 169 +#define ENGINE_F_UBSEC_DH_COMPUTE_KEY 171 +#define ENGINE_F_UBSEC_RNG_BYTES 172 /* Reason codes. */ diff --git a/crypto/engine/engine_err.c b/crypto/engine/engine_err.c index aff8642302..6d3d051566 100644 --- a/crypto/engine/engine_err.c +++ b/crypto/engine/engine_err.c @@ -132,6 +132,14 @@ static ERR_STRING_DATA ENGINE_str_functs[]= {ERR_PACK(0,ENGINE_F_HWCRHK_RAND_BYTES,0), "HWCRHK_RAND_BYTES"}, {ERR_PACK(0,ENGINE_F_HWCRHK_RSA_MOD_EXP,0), "HWCRHK_RSA_MOD_EXP"}, {ERR_PACK(0,ENGINE_F_LOG_MESSAGE,0), "LOG_MESSAGE"}, +{ERR_PACK(0,ENGINE_F_UBSEC_CTRL,0), "UBSEC_CTRL"}, +{ERR_PACK(0,ENGINE_F_UBSEC_DSA_SIGN,0), "UBSEC_DSA_SIGN"}, +{ERR_PACK(0,ENGINE_F_UBSEC_DSA_VERIFY,0), "UBSEC_DSA_VERIFY"}, +{ERR_PACK(0,ENGINE_F_UBSEC_FINISH,0), "UBSEC_FINISH"}, +{ERR_PACK(0,ENGINE_F_UBSEC_INIT,0), "UBSEC_INIT"}, +{ERR_PACK(0,ENGINE_F_UBSEC_MOD_EXP,0), "UBSEC_MOD_EXP"}, +{ERR_PACK(0,ENGINE_F_UBSEC_RSA_MOD_EXP,0), "UBSEC_RSA_MOD_EXP"}, +{ERR_PACK(0,ENGINE_F_UBSEC_RSA_MOD_EXP_CRT,0), "UBSEC_RSA_MOD_EXP_CRT"}, {0,NULL} }; diff --git a/crypto/engine/engine_int.h b/crypto/engine/engine_int.h index a1ae3df882..42df105978 100644 --- a/crypto/engine/engine_int.h +++ b/crypto/engine/engine_int.h @@ -161,6 +161,10 @@ ENGINE *ENGINE_aep(); ENGINE *ENGINE_sureware(); #endif /* !NO_HW_SUREWARE */ +#ifndef NO_HW_UBSEC +/* Returns a structure of ubsec methods. */ +ENGINE *ENGINE_ubsec(); +#endif /* !NO_HW_UBSEC */ #endif /* !NO_HW */ #ifdef __cplusplus diff --git a/crypto/engine/engine_list.c b/crypto/engine/engine_list.c index f9ce5447e9..977ef3dc5f 100644 --- a/crypto/engine/engine_list.c +++ b/crypto/engine/engine_list.c @@ -206,6 +206,10 @@ static int engine_internal_check(void) if(!engine_list_add(ENGINE_sureware())) return 0; #endif /* !NO_HW_SUREWARE */ +#ifndef NO_HW_UBSEC + if(!engine_list_add(ENGINE_ubsec())) + return 0; +#endif /* !NO_HW_UBSEC */ #endif /* !NO_HW */ engine_list_flag = 1; return 1; diff --git a/crypto/engine/hw_ubsec.c b/crypto/engine/hw_ubsec.c index b2c60bcd50..80a3c3cca9 100644 --- a/crypto/engine/hw_ubsec.c +++ b/crypto/engine/hw_ubsec.c @@ -5,7 +5,7 @@ * Cloned shamelessly by Joe Tardo. */ /* ==================================================================== - * Copyright (c) 1999-2001 The OpenSSL Project. All rights reserved. + * Copyright (c) 1999 The OpenSSL Project. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -62,30 +62,33 @@ #include #include "cryptlib.h" #include +#include +#include "engine_int.h" #include #ifndef OPENSSL_NO_HW #ifndef OPENSSL_NO_HW_UBSEC +#undef NOT_USED + #ifdef FLAT_INC #include "hw_ubsec.h" #else #include "vendor_defns/hw_ubsec.h" #endif -static int ubsec_destroy(ENGINE *e); -static int ubsec_init(ENGINE *e); -static int ubsec_finish(ENGINE *e); -static int ubsec_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)()); -static int ubsec_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, +static int ubsec_init(void); +static int ubsec_finish(void); +static int ubsec_ctrl(int cmd, long i, void *p, void (*f)()); +static int ubsec_mod_exp(BIGNUM *r, BIGNUM *a, const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx); -static int ubsec_mod_exp_crt(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, +static int ubsec_mod_exp_crt(BIGNUM *r, BIGNUM *a, const BIGNUM *p, const BIGNUM *q, const BIGNUM *dp, const BIGNUM *dq, const BIGNUM *qinv, BN_CTX *ctx); #ifndef OPENSSL_NO_RSA -static int ubsec_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa); +static int ubsec_rsa_mod_exp(BIGNUM *r0, BIGNUM *I, RSA *rsa); #endif -static int ubsec_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, +static int ubsec_mod_exp_mont(BIGNUM *r, BIGNUM *a, const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx); #ifndef OPENSSL_NO_DSA #if NOT_USED @@ -101,10 +104,10 @@ static int ubsec_dsa_verify(const unsigned char *dgst, int dgst_len, DSA_SIG *sig, DSA *dsa); #endif #ifndef OPENSSL_NO_DH -static int ubsec_mod_exp_dh(const DH *dh, BIGNUM *r, const BIGNUM *a, +static int ubsec_mod_exp_dh(DH *dh, BIGNUM *r, BIGNUM *a, const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx); -static int ubsec_dh_compute_key(unsigned char *key,const BIGNUM *pub_key,DH *dh); +static int ubsec_dh_compute_key(unsigned char *key,BIGNUM *pub_key,DH *dh); static int ubsec_dh_generate_key(DH *dh); #endif @@ -112,16 +115,7 @@ static int ubsec_dh_generate_key(DH *dh); static int ubsec_rand_bytes(unsigned char *buf, int num); static int ubsec_rand_status(void); #endif - -#define UBSEC_CMD_SO_PATH ENGINE_CMD_BASE -static const ENGINE_CMD_DEFN ubsec_cmd_defns[] = { - {UBSEC_CMD_SO_PATH, - "SO_PATH", - "Specifies the path to the 'ubsec' shared library", - ENGINE_CMD_FLAG_STRING}, - {0, NULL, NULL, 0} - }; - + #ifndef OPENSSL_NO_RSA /* Our internal RSA_METHOD that we provide pointers to */ static RSA_METHOD ubsec_rsa = @@ -147,15 +141,15 @@ static RSA_METHOD ubsec_rsa = static DSA_METHOD ubsec_dsa = { "UBSEC DSA method", - ubsec_dsa_do_sign, /* dsa_do_sign */ - NULL, /* dsa_sign_setup */ - ubsec_dsa_verify, /* dsa_do_verify */ - NULL, /* ubsec_dsa_mod_exp */ /* dsa_mod_exp */ - NULL, /* ubsec_mod_exp_dsa */ /* bn_mod_exp */ - NULL, /* init */ - NULL, /* finish */ - 0, /* flags */ - NULL /* app_data */ + ubsec_dsa_do_sign, /* dsa_do_sign */ + NULL, /* dsa_sign_setup */ + ubsec_dsa_verify, /* dsa_do_verify */ + NULL, /* ubsec_dsa_mod_exp */ /* dsa_mod_exp */ + NULL, /* ubsec_mod_exp_dsa */ /* bn_mod_exp */ + NULL, /* init */ + NULL, /* finish */ + 0, /* flags */ + NULL /* app_data */ }; #endif @@ -174,110 +168,62 @@ static DH_METHOD ubsec_dh = }; #endif -#ifndef OPENSSL_NO_ERR -/* Error function codes for use in ubsec operation */ -#define UBSEC_F_UBSEC_INIT 100 -#define UBSEC_F_UBSEC_FINISH 101 -#define UBSEC_F_UBSEC_CTRL 102 -#define UBSEC_F_UBSEC_MOD_EXP 103 -#define UBSEC_F_UBSEC_RSA_MOD_EXP 104 -#define UBSEC_F_UBSEC_RSA_MOD_EXP_CRT 105 -#define UBSEC_F_UBSEC_DSA_SIGN 106 -#define UBSEC_F_UBSEC_DSA_VERIFY 107 -/* Error reason codes */ -#define UBSEC_R_ALREADY_LOADED 108 -#define UBSEC_R_DSO_FAILURE 109 -#define UBSEC_R_UNIT_FAILURE 110 -#define UBSEC_R_NOT_LOADED 111 -#define UBSEC_R_CTRL_COMMAND_NOT_IMPLEMENTED 112 -#define UBSEC_R_SIZE_TOO_LARGE_OR_TOO_SMALL 113 -#define UBSEC_R_BN_EXPAND_FAIL 114 -#define UBSEC_R_REQUEST_FAILED 115 -#define UBSEC_R_MISSING_KEY_COMPONENTS 116 -static ERR_STRING_DATA ubsec_str_functs[] = - { - /* This first element is changed to match the dynamic 'lib' number */ -{ERR_PACK(0,0,0), "ubsec engine code"}, -{ERR_PACK(0,UBSEC_F_UBSEC_INIT,0), "ubsec_init"}, -{ERR_PACK(0,UBSEC_F_UBSEC_FINISH,0), "ubsec_finish"}, -{ERR_PACK(0,UBSEC_F_UBSEC_CTRL,0), "ubsec_ctrl"}, -{ERR_PACK(0,UBSEC_F_UBSEC_MOD_EXP,0), "ubsec_mod_exp"}, -{ERR_PACK(0,UBSEC_F_UBSEC_RSA_MOD_EXP,0), "ubsec_rsa_mod_exp"}, -{ERR_PACK(0,UBSEC_F_UBSEC_RSA_MOD_EXP_CRT,0), "ubsec_rsa_mod_exp_crt"}, -{ERR_PACK(0,UBSEC_F_UBSEC_DSA_SIGN,0), "ubsec_dsa_sign"}, -{ERR_PACK(0,UBSEC_F_UBSEC_DSA_VERIFY,0), "ubsec_dsa_verify"}, -/* Error reason codes */ -{UBSEC_R_ALREADY_LOADED ,"already loaded"}, -{UBSEC_R_DSO_FAILURE ,"DSO failure"}, -{UBSEC_R_UNIT_FAILURE ,"unit failure"}, -{UBSEC_R_NOT_LOADED ,"not loaded"}, -{UBSEC_R_CTRL_COMMAND_NOT_IMPLEMENTED ,"ctrl command not implemented"}, -{UBSEC_R_SIZE_TOO_LARGE_OR_TOO_SMALL ,"size too large or too small"}, -{UBSEC_R_BN_EXPAND_FAIL ,"bn_expand fail"}, -{UBSEC_R_REQUEST_FAILED ,"request failed"}, -{UBSEC_R_MISSING_KEY_COMPONENTS ,"missing key components"}, -{0,NULL} - }; -/* The library number we obtain dynamically from the ERR code */ -static int ubsec_err_lib = -1; -#define UBSECerr(f,r) ERR_PUT_error(ubsec_err_lib,(f),(r),__FILE__,__LINE__) -static void ubsec_load_error_strings(void) - { - if(ubsec_err_lib < 0) - { - if((ubsec_err_lib = ERR_get_next_error_library()) <= 0) - return; - ubsec_str_functs[0].error = ERR_PACK(ubsec_err_lib,0,0); - ERR_load_strings(ubsec_err_lib, ubsec_str_functs); - } - } -static void ubsec_unload_error_strings(void) - { - if(ubsec_err_lib >= 0) - { - ERR_unload_strings(ubsec_err_lib, ubsec_str_functs); - ubsec_err_lib = -1; - } - } -#else -#define UBSECerr(f,r) /* NOP */ -static void ubsec_load_error_strings(void) { } /* NOP */ -static void ubsec_unload_error_strings(void) { } /* NOP */ +#ifdef NOT_USED +/* Our internal RAND_METHOD that we provide pointers to */ +static RAND_METHOD ubsec_rand = { + NULL, /*void (*seed)(const void *buf, int num);*/ + ubsec_rand_bytes, /*int (*bytes)(unsigned char *buf, int num);*/ + NULL, /*void (*cleanup)(void);*/ + NULL, /*void (*add)(const void *buf, int num, double entropy);*/ + ubsec_rand_bytes, /*int (*pseudorand)(unsigned char *buf, int num);*/ + NULL, /*int (*status)(void);*/ +}; #endif /* Constants used when creating the ENGINE */ static const char *engine_ubsec_id = "ubsec"; static const char *engine_ubsec_name = "UBSEC hardware engine support"; -/* This internal function is used by ENGINE_ubsec() and possibly by the - * "dynamic" ENGINE support too */ -static int bind_helper(ENGINE *e) +/* As this is only ever called once, there's no need for locking + * (indeed - the lock will already be held by our caller!!!) */ +ENGINE *ENGINE_ubsec() { + #ifndef OPENSSL_NO_RSA const RSA_METHOD *meth1; #endif + #ifndef OPENSSL_NO_DH #ifndef HAVE_UBSEC_DH const DH_METHOD *meth3; #endif /* HAVE_UBSEC_DH */ #endif - if(!ENGINE_set_id(e, engine_ubsec_id) || - !ENGINE_set_name(e, engine_ubsec_name) || + + ENGINE *ret = ENGINE_new(); + + if(!ret) + return NULL; + + if(!ENGINE_set_id(ret, engine_ubsec_id) || + !ENGINE_set_name(ret, engine_ubsec_name) || #ifndef OPENSSL_NO_RSA - !ENGINE_set_RSA(e, &ubsec_rsa) || + !ENGINE_set_RSA(ret, &ubsec_rsa) || #endif #ifndef OPENSSL_NO_DSA - !ENGINE_set_DSA(e, &ubsec_dsa) || + !ENGINE_set_DSA(ret, &ubsec_dsa) || #endif #ifndef OPENSSL_NO_DH - !ENGINE_set_DH(e, &ubsec_dh) || + !ENGINE_set_DH(ret, &ubsec_dh) || #endif - !ENGINE_set_destroy_function(e, ubsec_destroy) || - !ENGINE_set_init_function(e, ubsec_init) || - !ENGINE_set_finish_function(e, ubsec_finish) || - !ENGINE_set_ctrl_function(e, ubsec_ctrl) || - !ENGINE_set_cmd_defns(e, ubsec_cmd_defns)) - return 0; + !ENGINE_set_BN_mod_exp(ret, ubsec_mod_exp) || + !ENGINE_set_BN_mod_exp_crt(ret, ubsec_mod_exp_crt) || + !ENGINE_set_init_function(ret, ubsec_init) || + !ENGINE_set_finish_function(ret, ubsec_finish) || + !ENGINE_set_ctrl_function(ret, ubsec_ctrl)) + { + ENGINE_free(ret); + return NULL; + } #ifndef OPENSSL_NO_RSA /* We know that the "PKCS1_SSLeay()" functions hook properly @@ -302,35 +248,10 @@ static int bind_helper(ENGINE *e) ubsec_dh.compute_key = meth3->compute_key; #endif /* HAVE_UBSEC_DH */ #endif - - /* Ensure the ubsec error handling is set up */ - ubsec_load_error_strings(); - return 1; - } - -static ENGINE *engine_ubsec(void) - { - ENGINE *ret = ENGINE_new(); - if(!ret) - return NULL; - if(!bind_helper(ret)) - { - ENGINE_free(ret); - return NULL; - } + return ret; } -void ENGINE_load_ubsec(void) - { - /* Copied from eng_[openssl|dyn].c */ - ENGINE *toadd = engine_ubsec(); - if(!toadd) return; - ENGINE_add(toadd); - ENGINE_free(toadd); - ERR_clear_error(); - } - /* This is a process-global DSO handle used for loading and unloading * the UBSEC library. NB: This is only set (or unset) during an * init() or finish() call (reference counts permitting) and they're @@ -351,23 +272,24 @@ static t_UBSEC_diffie_hellman_generate_ioctl *p_UBSEC_diffie_hellman_generate_ioctl = NULL; static t_UBSEC_diffie_hellman_agree_ioctl *p_UBSEC_diffie_hellman_agree_ioctl = NULL; #endif -/* #ifndef OPENSSL_NO_RSA */ static t_UBSEC_rsa_mod_exp_ioctl *p_UBSEC_rsa_mod_exp_ioctl = NULL; static t_UBSEC_rsa_mod_exp_crt_ioctl *p_UBSEC_rsa_mod_exp_crt_ioctl = NULL; -/* #endif */ #ifndef OPENSSL_NO_DSA static t_UBSEC_dsa_sign_ioctl *p_UBSEC_dsa_sign_ioctl = NULL; static t_UBSEC_dsa_verify_ioctl *p_UBSEC_dsa_verify_ioctl = NULL; #endif static t_UBSEC_math_accelerate_ioctl *p_UBSEC_math_accelerate_ioctl = NULL; static t_UBSEC_rng_ioctl *p_UBSEC_rng_ioctl = NULL; +static t_UBSEC_max_key_len_ioctl *p_UBSEC_max_key_len_ioctl = NULL; + +static int max_key_len = 1024; /* ??? */ /* * These are the static string constants for the DSO file name and the function * symbol names to bind to. */ -static const char *UBSEC_LIBNAME = "ubsec"; +static const char *UBSEC_LIBNAME = "libubsec.so"; static const char *UBSEC_F1 = "ubsec_bytes_to_bits"; static const char *UBSEC_F2 = "ubsec_bits_to_bytes"; static const char *UBSEC_F3 = "ubsec_open"; @@ -386,16 +308,10 @@ static const char *UBSEC_F10 = "dsa_verify_ioctl"; #endif static const char *UBSEC_F11 = "math_accelerate_ioctl"; static const char *UBSEC_F12 = "rng_ioctl"; - -/* Destructor (complements the "ENGINE_ubsec()" constructor) */ -static int ubsec_destroy(ENGINE *e) - { - ubsec_unload_error_strings(); - return 1; - } +static const char *UBSEC_F13 = "ubsec_max_key_len_ioctl"; /* (de)initialisation functions. */ -static int ubsec_init(ENGINE *e) +static int ubsec_init(void) { t_UBSEC_ubsec_bytes_to_bits *p1; t_UBSEC_ubsec_bits_to_bytes *p2; @@ -405,21 +321,20 @@ static int ubsec_init(ENGINE *e) t_UBSEC_diffie_hellman_generate_ioctl *p5; t_UBSEC_diffie_hellman_agree_ioctl *p6; #endif -/* #ifndef OPENSSL_NO_RSA */ t_UBSEC_rsa_mod_exp_ioctl *p7; t_UBSEC_rsa_mod_exp_crt_ioctl *p8; -/* #endif */ #ifndef OPENSSL_NO_DSA t_UBSEC_dsa_sign_ioctl *p9; t_UBSEC_dsa_verify_ioctl *p10; #endif t_UBSEC_math_accelerate_ioctl *p11; t_UBSEC_rng_ioctl *p12; - int fd = 0; + t_UBSEC_max_key_len_ioctl *p13; + int fd; if(ubsec_dso != NULL) { - UBSECerr(UBSEC_F_UBSEC_INIT, UBSEC_R_ALREADY_LOADED); + ENGINEerr(ENGINE_F_UBSEC_INIT, ENGINE_R_ALREADY_LOADED); goto err; } /* @@ -428,7 +343,7 @@ static int ubsec_init(ENGINE *e) ubsec_dso = DSO_load(NULL, UBSEC_LIBNAME, NULL, 0); if(ubsec_dso == NULL) { - UBSECerr(UBSEC_F_UBSEC_INIT, UBSEC_R_DSO_FAILURE); + ENGINEerr(ENGINE_F_UBSEC_INIT, ENGINE_R_DSO_FAILURE); goto err; } @@ -437,25 +352,20 @@ static int ubsec_init(ENGINE *e) !(p2 = (t_UBSEC_ubsec_bits_to_bytes *) DSO_bind_func(ubsec_dso, UBSEC_F2)) || !(p3 = (t_UBSEC_ubsec_open *) DSO_bind_func(ubsec_dso, UBSEC_F3)) || !(p4 = (t_UBSEC_ubsec_close *) DSO_bind_func(ubsec_dso, UBSEC_F4)) || -#ifndef OPENSSL_NO_DH !(p5 = (t_UBSEC_diffie_hellman_generate_ioctl *) DSO_bind_func(ubsec_dso, UBSEC_F5)) || !(p6 = (t_UBSEC_diffie_hellman_agree_ioctl *) DSO_bind_func(ubsec_dso, UBSEC_F6)) || -#endif -/* #ifndef OPENSSL_NO_RSA */ !(p7 = (t_UBSEC_rsa_mod_exp_ioctl *) DSO_bind_func(ubsec_dso, UBSEC_F7)) || !(p8 = (t_UBSEC_rsa_mod_exp_crt_ioctl *) DSO_bind_func(ubsec_dso, UBSEC_F8)) || -/* #endif */ -#ifndef OPENSSL_NO_DSA !(p9 = (t_UBSEC_dsa_sign_ioctl *) DSO_bind_func(ubsec_dso, UBSEC_F9)) || !(p10 = (t_UBSEC_dsa_verify_ioctl *) DSO_bind_func(ubsec_dso, UBSEC_F10)) || -#endif !(p11 = (t_UBSEC_math_accelerate_ioctl *) DSO_bind_func(ubsec_dso, UBSEC_F11)) || - !(p12 = (t_UBSEC_rng_ioctl *) DSO_bind_func(ubsec_dso, UBSEC_F12))) + !(p12 = (t_UBSEC_rng_ioctl *) DSO_bind_func(ubsec_dso, UBSEC_F12)) || + !(p13 = (t_UBSEC_max_key_len_ioctl*) DSO_bind_func(ubsec_dso, UBSEC_F13))) { - UBSECerr(UBSEC_F_UBSEC_INIT, UBSEC_R_DSO_FAILURE); + ENGINEerr(ENGINE_F_UBSEC_INIT, ENGINE_R_DSO_FAILURE); goto err; } @@ -478,17 +388,23 @@ static int ubsec_init(ENGINE *e) #endif p_UBSEC_math_accelerate_ioctl = p11; p_UBSEC_rng_ioctl = p12; + p_UBSEC_max_key_len_ioctl = p13; /* Perform an open to see if there's actually any unit running. */ - if ((fd = p_UBSEC_ubsec_open(UBSEC_KEY_DEVICE_NAME)) > 0) - { - p_UBSEC_ubsec_close(fd); - return 1; + if ((fd = p_UBSEC_ubsec_open(UBSEC_KEY_DEVICE_NAME)) <= 0) + { + ENGINEerr(ENGINE_F_UBSEC_INIT, ENGINE_R_UNIT_FAILURE); + goto err; } - else - { - UBSECerr(UBSEC_F_UBSEC_INIT, UBSEC_R_UNIT_FAILURE); + if (p_UBSEC_max_key_len_ioctl(fd, &max_key_len) != 0) + { + ENGINEerr(ENGINE_F_UBSEC_INIT, ENGINE_R_UNIT_FAILURE); + p_UBSEC_ubsec_close(fd); + goto err; } + + p_UBSEC_ubsec_close(fd); + return 1; err: if(ubsec_dso) @@ -511,20 +427,21 @@ err: #endif p_UBSEC_math_accelerate_ioctl = NULL; p_UBSEC_rng_ioctl = NULL; + p_UBSEC_max_key_len_ioctl = NULL; return 0; } -static int ubsec_finish(ENGINE *e) +static int ubsec_finish(void ) { if(ubsec_dso == NULL) { - UBSECerr(UBSEC_F_UBSEC_FINISH, UBSEC_R_NOT_LOADED); + ENGINEerr(ENGINE_F_UBSEC_FINISH, ENGINE_R_NOT_LOADED); return 0; } if(!DSO_free(ubsec_dso)) { - UBSECerr(UBSEC_F_UBSEC_FINISH, UBSEC_R_DSO_FAILURE); + ENGINEerr(ENGINE_F_UBSEC_FINISH, ENGINE_R_DSO_FAILURE); return 0; } ubsec_dso = NULL; @@ -546,139 +463,129 @@ static int ubsec_finish(ENGINE *e) #endif p_UBSEC_math_accelerate_ioctl = NULL; p_UBSEC_rng_ioctl = NULL; + p_UBSEC_max_key_len_ioctl = NULL; return 1; } -static int ubsec_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)()) +static int ubsec_ctrl(int cmd, long i, void *p, void (*f)()) { - int initialised = ((ubsec_dso == NULL) ? 0 : 1); switch(cmd) { - case UBSEC_CMD_SO_PATH: - if(p == NULL) - { - UBSECerr(UBSEC_F_UBSEC_CTRL,ERR_R_PASSED_NULL_PARAMETER); - return 0; - } - if(initialised) - { - UBSECerr(UBSEC_F_UBSEC_CTRL,UBSEC_R_ALREADY_LOADED); - return 0; - } - UBSEC_LIBNAME = (const char *)p; - return 1; default: break; } - UBSECerr(UBSEC_F_UBSEC_CTRL,UBSEC_R_CTRL_COMMAND_NOT_IMPLEMENTED); + ENGINEerr(ENGINE_F_UBSEC_CTRL,ENGINE_R_CTRL_COMMAND_NOT_IMPLEMENTED); return 0; } -static int ubsec_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, +static int ubsec_mod_exp(BIGNUM *r, BIGNUM *a, const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx) { - int y_len = 0; + int ret = 0; + int r_len = 0; int fd; if(ubsec_dso == NULL) - { - UBSECerr(UBSEC_F_UBSEC_MOD_EXP, UBSEC_R_NOT_LOADED); - return 0; - } - - /* Check if hardware can't handle this argument. */ - y_len = BN_num_bits(m); - if (y_len > 1024) { - UBSECerr(UBSEC_F_UBSEC_MOD_EXP, UBSEC_R_SIZE_TOO_LARGE_OR_TOO_SMALL); - return 0; - } - - if(!bn_wexpand(r, m->top)) - { - UBSECerr(UBSEC_F_UBSEC_MOD_EXP, UBSEC_R_BN_EXPAND_FAIL); - return 0; - } - memset(r->d, 0, BN_num_bytes(m)); + { + ENGINEerr(ENGINE_F_UBSEC_MOD_EXP, ENGINE_R_NOT_LOADED); + goto err; + } - if ((fd = p_UBSEC_ubsec_open(UBSEC_KEY_DEVICE_NAME)) <= 0) { - fd = 0; - UBSECerr(UBSEC_F_UBSEC_INIT, UBSEC_R_UNIT_FAILURE); - return 0; - } + r_len = BN_num_bits(m); - if (p_UBSEC_rsa_mod_exp_ioctl(fd, (unsigned char *)a->d, BN_num_bits(a), - (unsigned char *)m->d, BN_num_bits(m), (unsigned char *)p->d, - BN_num_bits(p), (unsigned char *)r->d, &y_len) != 0) - { - UBSECerr(UBSEC_F_UBSEC_MOD_EXP, UBSEC_R_REQUEST_FAILED); - return 0; - } + /* Perform in software if modulus is too large for hardware. */ - p_UBSEC_ubsec_close(fd); + if (r_len > max_key_len) + { + ENGINE *e; + ENGINEerr(ENGINE_F_UBSEC_MOD_EXP, ENGINE_R_SIZE_TOO_LARGE_OR_TOO_SMALL); + e = ENGINE_openssl(); + ret = e->bn_mod_exp(r, a, p, m, ctx); + goto err; + } - r->top = (BN_num_bits(m)+BN_BITS2-1)/BN_BITS2; - return 1; - } + if (!bn_wexpand(r, m->top)) + { + ENGINEerr(ENGINE_F_UBSEC_MOD_EXP, ENGINE_R_BN_EXPAND_FAIL); + goto err; + } + bzero(r->d, BN_num_bytes(m)); + + if ((fd = p_UBSEC_ubsec_open(UBSEC_KEY_DEVICE_NAME)) <= 0) + { + ENGINE *e; + ENGINEerr(ENGINE_F_UBSEC_INIT, ENGINE_R_UNIT_FAILURE); + e = ENGINE_openssl(); + ret = e->bn_mod_exp(r, a, p, m, ctx); + goto err; + } -#ifndef OPENSSL_NO_RSA -static int ubsec_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa) - { - BN_CTX *ctx; - int to_return = 0; + if (p_UBSEC_rsa_mod_exp_ioctl(fd, + (unsigned char *)a->d, BN_num_bits(a), + (unsigned char *)m->d, BN_num_bits(m), + (unsigned char *)p->d, BN_num_bits(p), + (unsigned char *)r->d, &r_len) != 0) + { + /* Hardware's a no go, failover to software */ + ENGINE *e; - if((ctx = BN_CTX_new()) == NULL) - goto err; + ENGINEerr(ENGINE_F_UBSEC_MOD_EXP, ENGINE_R_REQUEST_FAILED); + p_UBSEC_ubsec_close(fd); - if(!rsa->p || !rsa->q || !rsa->dmp1 || !rsa->dmq1 || !rsa->iqmp) - { - UBSECerr(UBSEC_F_UBSEC_RSA_MOD_EXP, UBSEC_R_MISSING_KEY_COMPONENTS); + e = ENGINE_openssl(); + ret = e->bn_mod_exp(r, a, p, m, ctx); goto err; } + + p_UBSEC_ubsec_close(fd); - /* - * Do in software if argument is too large for hardware. - */ - if ((BN_num_bits(rsa->p)+BN_num_bits(rsa->q)) > 1024) { - const RSA_METHOD *meth = RSA_PKCS1_SSLeay(); - to_return = (*meth->rsa_mod_exp)(r0, I, rsa); - } else { - to_return = ubsec_mod_exp_crt(r0, I, rsa->p, rsa->q, rsa->dmp1, - rsa->dmq1, rsa->iqmp, ctx); - } + r->top = (BN_num_bits(m)+BN_BITS2-1)/BN_BITS2; + + ret = 1; err: - if(ctx) - BN_CTX_free(ctx); - return to_return; + return ret; } -#endif -static int ubsec_mod_exp_crt(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, +static int ubsec_mod_exp_crt(BIGNUM *r, BIGNUM *a, const BIGNUM *p, const BIGNUM *q, const BIGNUM *dp, const BIGNUM *dq, const BIGNUM *qinv, BN_CTX *ctx) - { + { + int y_len, m_len, - fd; + fd, + ret = 0; m_len = BN_num_bytes(p) + BN_num_bytes(q) + 1; y_len = BN_num_bits(p) + BN_num_bits(q); - /* Check if hardware can't handle this argument. */ - if (y_len > 1024) { - UBSECerr(UBSEC_F_UBSEC_MOD_EXP, UBSEC_R_SIZE_TOO_LARGE_OR_TOO_SMALL); - return 0; - } + /* Perform in software if modulus is too large for hardware. */ - if (!bn_wexpand(r, p->top + q->top + 1)) { - UBSECerr(UBSEC_F_UBSEC_RSA_MOD_EXP_CRT, UBSEC_R_BN_EXPAND_FAIL); - return 0; - } + if (y_len > max_key_len) + { + ENGINE *e; - if ((fd = p_UBSEC_ubsec_open(UBSEC_KEY_DEVICE_NAME)) <= 0) { - fd = 0; - UBSECerr(UBSEC_F_UBSEC_INIT, UBSEC_R_UNIT_FAILURE); - return 0; - } + ENGINEerr(ENGINE_F_UBSEC_RSA_MOD_EXP_CRT, ENGINE_R_SIZE_TOO_LARGE_OR_TOO_SMALL); + e = ENGINE_openssl(); + ret = e->bn_mod_exp_crt(r, a, p, q, dp, dq, qinv, ctx); + + goto err; + } + + if (!bn_wexpand(r, p->top + q->top + 1)) + { + ENGINEerr(ENGINE_F_UBSEC_RSA_MOD_EXP_CRT, ENGINE_R_BN_EXPAND_FAIL); + goto err; + } + + if ((fd = p_UBSEC_ubsec_open(UBSEC_KEY_DEVICE_NAME)) <= 0) + { + ENGINE *e; + ENGINEerr(ENGINE_F_UBSEC_INIT, ENGINE_R_UNIT_FAILURE); + e = ENGINE_openssl(); + ret = e->bn_mod_exp_crt(r, a, p, q, dp, dq, qinv, ctx); + goto err; + } if (p_UBSEC_rsa_mod_exp_crt_ioctl(fd, (unsigned char *)a->d, BN_num_bits(a), @@ -687,16 +594,66 @@ static int ubsec_mod_exp_crt(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, (unsigned char *)p->d, BN_num_bits(p), (unsigned char *)dq->d, BN_num_bits(dq), (unsigned char *)q->d, BN_num_bits(q), - (unsigned char *)r->d, &y_len) != 0) { - UBSECerr(UBSEC_F_UBSEC_MOD_EXP, UBSEC_R_REQUEST_FAILED); - return 0; - } + (unsigned char *)r->d, &y_len) != 0) + { + ENGINE *e; + p_UBSEC_ubsec_close(fd); + ENGINEerr(ENGINE_F_UBSEC_RSA_MOD_EXP_CRT, ENGINE_R_UNIT_FAILURE); + e = ENGINE_openssl(); + ret = e->bn_mod_exp_crt(r, a, p, q, dp, dq, qinv, ctx); - p_UBSEC_ubsec_close(fd); + goto err; + } + p_UBSEC_ubsec_close(fd); + r->top = (BN_num_bits(p) + BN_num_bits(q) + BN_BITS2 - 1)/BN_BITS2; - return 1; -} + + ret = 1; + err: + return(ret); + } + +#ifndef OPENSSL_NO_RSA +static int ubsec_rsa_mod_exp(BIGNUM *r0, BIGNUM *I, RSA *rsa) + { + BN_CTX *ctx; + int ret = 0; + + if ((ctx = BN_CTX_new()) == NULL) goto err; + + if (!rsa->p || !rsa->q || !rsa->dmp1 || !rsa->dmq1 || !rsa->iqmp) + { + ENGINEerr(ENGINE_F_UBSEC_RSA_MOD_EXP, ENGINE_R_MISSING_KEY_COMPONENTS); + goto err; + } + + /* Perform in software if the key is too large for hardware. */ + + if ((BN_num_bits(rsa->p) > (max_key_len / 2)) && + (BN_num_bits(rsa->q) > (max_key_len / 2 ))) + { + const RSA_METHOD *meth; + meth = RSA_PKCS1_SSLeay(); + ret = meth->rsa_mod_exp(r0, I, rsa); + } + else + { + ret = ubsec_mod_exp_crt(r0, + I, + rsa->p, + rsa->q, + rsa->dmp1, + rsa->dmq1, + rsa->iqmp, + ctx); + } + +err: + if (ctx) BN_CTX_free(ctx); + return ret; + } +#endif #ifndef OPENSSL_NO_DSA #if NOT_USED @@ -705,19 +662,19 @@ static int ubsec_dsa_mod_exp(DSA *dsa, BIGNUM *rr, BIGNUM *a1, BN_CTX *ctx, BN_MONT_CTX *in_mont) { BIGNUM t; - int to_return = 0; + int ret = 0; BN_init(&t); /* let rr = a1 ^ p1 mod m */ - if (!ubsec_mod_exp(rr,a1,p1,m,ctx)) goto end; + if (!ubsec_mod_exp(rr,a1,p1,m,ctx)) goto err; /* let t = a2 ^ p2 mod m */ - if (!ubsec_mod_exp(&t,a2,p2,m,ctx)) goto end; + if (!ubsec_mod_exp(&t,a2,p2,m,ctx)) goto err; /* let rr = rr * t mod m */ - if (!BN_mod_mul(rr,rr,&t,m,ctx)) goto end; - to_return = 1; -end: + if (!BN_mod_mul(rr,rr,&t,m,ctx)) goto err; + ret = 1; +err: BN_free(&t); - return to_return; + return ret; } static int ubsec_mod_exp_dsa(DSA *dsa, BIGNUM *r, BIGNUM *a, @@ -732,80 +689,89 @@ static int ubsec_mod_exp_dsa(DSA *dsa, BIGNUM *r, BIGNUM *a, /* * This function is aliased to mod_exp (with the mont stuff dropped). */ -static int ubsec_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, +static int ubsec_mod_exp_mont(BIGNUM *r, BIGNUM *a, const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx) - { +{ int ret = 0; + #ifndef OPENSSL_NO_RSA - /* Do in software if the key is too large for the hardware. */ - if (BN_num_bits(m) > 1024) - { - const RSA_METHOD *meth = RSA_PKCS1_SSLeay(); - ret = (*meth->bn_mod_exp)(r, a, p, m, ctx, m_ctx); - } - else -#endif - { + /* Perform in software if the modulus is too large for hardware. */ + + if (BN_num_bits(m) > max_key_len) + { + const RSA_METHOD *meth; + meth = RSA_PKCS1_SSLeay(); + ret = meth->bn_mod_exp(r, a, p, m, ctx, m_ctx); + } + else +#endif + { ret = ubsec_mod_exp(r, a, p, m, ctx); - } + } return ret; - } - -#ifndef OPENSSL_NO_DH -/* This function is aliased to mod_exp (with the dh and mont dropped). */ -static int ubsec_mod_exp_dh(const DH *dh, BIGNUM *r, const BIGNUM *a, - const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, - BN_MONT_CTX *m_ctx) - { - return ubsec_mod_exp(r, a, p, m, ctx); - } -#endif +} #ifndef OPENSSL_NO_DSA static DSA_SIG *ubsec_dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa) { - DSA_SIG *to_return = NULL; - int s_len = 160, r_len = 160, d_len, fd; - BIGNUM m, *r=NULL, *s=NULL; + DSA_SIG *ret = NULL; + int s_len = 160, + r_len = 160, + d_len, + fd; + BIGNUM m, + *r = NULL, + *s = NULL; BN_init(&m); - s = BN_new(); r = BN_new(); - if ((s == NULL) || (r==NULL)) - goto err; + if ((s == NULL) || (r==NULL)) goto err; d_len = p_UBSEC_ubsec_bytes_to_bits((unsigned char *)dgst, dlen); if(!bn_wexpand(r, (160+BN_BITS2-1)/BN_BITS2) || (!bn_wexpand(s, (160+BN_BITS2-1)/BN_BITS2))) { - UBSECerr(UBSEC_F_UBSEC_DSA_SIGN, UBSEC_R_BN_EXPAND_FAIL); + ENGINEerr(ENGINE_F_UBSEC_DSA_SIGN, ENGINE_R_BN_EXPAND_FAIL); goto err; } if (BN_bin2bn(dgst,dlen,&m) == NULL) { - UBSECerr(UBSEC_F_UBSEC_DSA_SIGN, UBSEC_R_BN_EXPAND_FAIL); + ENGINEerr(ENGINE_F_UBSEC_DSA_SIGN, ENGINE_R_BN_EXPAND_FAIL); goto err; } - if ((fd = p_UBSEC_ubsec_open(UBSEC_KEY_DEVICE_NAME)) <= 0) { - fd = 0; - UBSECerr(UBSEC_F_UBSEC_INIT, UBSEC_R_UNIT_FAILURE); - return 0; - } + if ((fd = p_UBSEC_ubsec_open(UBSEC_KEY_DEVICE_NAME)) <= 0) + { + const DSA_METHOD *meth; + ENGINEerr(ENGINE_F_UBSEC_INIT, ENGINE_R_UNIT_FAILURE); + meth = DSA_OpenSSL(); + ret = meth->dsa_do_sign(dgst, dlen, dsa); + goto err; + } + + if (p_UBSEC_dsa_sign_ioctl(fd, + 0, /* compute hash before signing */ + (unsigned char *)dgst, d_len, + NULL, 0, /* compute random value */ + (unsigned char *)dsa->p->d, BN_num_bits(dsa->p), + (unsigned char *)dsa->q->d, BN_num_bits(dsa->q), + (unsigned char *)dsa->g->d, BN_num_bits(dsa->g), + (unsigned char *)dsa->priv_key->d, BN_num_bits(dsa->priv_key), + (unsigned char *)r->d, &r_len, + (unsigned char *)s->d, &s_len ) != 0) + { + /* Hardware's a no go, failover to software */ + const DSA_METHOD *meth; + + ENGINEerr(ENGINE_F_UBSEC_DSA_SIGN, ENGINE_R_REQUEST_FAILED); + p_UBSEC_ubsec_close(fd); + + meth = DSA_OpenSSL(); + ret = meth->dsa_do_sign(dgst, dlen, dsa); - if (p_UBSEC_dsa_sign_ioctl(fd, 0, /* compute hash before signing */ - (unsigned char *)dgst, d_len, - NULL, 0, /* compute random value */ - (unsigned char *)dsa->p->d, BN_num_bits(dsa->p), - (unsigned char *)dsa->q->d, BN_num_bits(dsa->q), - (unsigned char *)dsa->g->d, BN_num_bits(dsa->g), - (unsigned char *)dsa->priv_key->d, BN_num_bits(dsa->priv_key), - (unsigned char *)r->d, &r_len, - (unsigned char *)s->d, &s_len ) != 0) { - UBSECerr(UBSEC_F_UBSEC_DSA_SIGN, UBSEC_R_REQUEST_FAILED); goto err; } @@ -814,36 +780,38 @@ static DSA_SIG *ubsec_dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa) r->top = (160+BN_BITS2-1)/BN_BITS2; s->top = (160+BN_BITS2-1)/BN_BITS2; - to_return = DSA_SIG_new(); - if(to_return == NULL) { - UBSECerr(UBSEC_F_UBSEC_DSA_SIGN, UBSEC_R_BN_EXPAND_FAIL); + ret = DSA_SIG_new(); + if(ret == NULL) { + ENGINEerr(ENGINE_F_UBSEC_DSA_SIGN, ENGINE_R_BN_EXPAND_FAIL); goto err; } - to_return->r = r; - to_return->s = s; - + ret->r = r; + ret->s = s; err: - if (!to_return) { + if (!ret) + { if (r) BN_free(r); if (s) BN_free(s); - } + } BN_clear_free(&m); - return to_return; + return ret; } static int ubsec_dsa_verify(const unsigned char *dgst, int dgst_len, DSA_SIG *sig, DSA *dsa) { - int v_len, d_len; - int to_return = 0; - int fd; - BIGNUM v; + int v_len, + d_len, + ret = 0, + fd; + BIGNUM v; BN_init(&v); - if(!bn_wexpand(&v, dsa->p->top)) { - UBSECerr(UBSEC_F_UBSEC_DSA_VERIFY ,UBSEC_R_BN_EXPAND_FAIL); + if (!bn_wexpand(&v, dsa->p->top)) + { + ENGINEerr(ENGINE_F_UBSEC_DSA_VERIFY ,ENGINE_R_BN_EXPAND_FAIL); goto err; } @@ -851,50 +819,231 @@ static int ubsec_dsa_verify(const unsigned char *dgst, int dgst_len, d_len = p_UBSEC_ubsec_bytes_to_bits((unsigned char *)dgst, dgst_len); - if ((fd = p_UBSEC_ubsec_open(UBSEC_KEY_DEVICE_NAME)) <= 0) { - fd = 0; - UBSECerr(UBSEC_F_UBSEC_INIT, UBSEC_R_UNIT_FAILURE); - return 0; - } + if ((fd = p_UBSEC_ubsec_open(UBSEC_KEY_DEVICE_NAME)) <= 0) + { + const DSA_METHOD *meth; + ENGINEerr(ENGINE_F_UBSEC_INIT, ENGINE_R_UNIT_FAILURE); + meth = DSA_OpenSSL(); + ret = meth->dsa_do_verify(dgst, dgst_len, sig, dsa); + goto err; + } + + if (p_UBSEC_dsa_verify_ioctl(fd, + 0, /* compute hash before signing */ + (unsigned char *)dgst, d_len, + (unsigned char *)dsa->p->d, BN_num_bits(dsa->p), + (unsigned char *)dsa->q->d, BN_num_bits(dsa->q), + (unsigned char *)dsa->g->d, BN_num_bits(dsa->g), + (unsigned char *)dsa->pub_key->d, BN_num_bits(dsa->pub_key), + (unsigned char *)sig->r->d, BN_num_bits(sig->r), + (unsigned char *)sig->s->d, BN_num_bits(sig->s), + (unsigned char *)v.d, &v_len) != 0) + { + /* Hardware's a no go, failover to software */ + const DSA_METHOD *meth; + + ENGINEerr(ENGINE_F_UBSEC_DSA_VERIFY , ENGINE_R_REQUEST_FAILED); + p_UBSEC_ubsec_close(fd); + + meth = DSA_OpenSSL(); + ret = meth->dsa_do_verify(dgst, dgst_len, sig, dsa); - if (p_UBSEC_dsa_verify_ioctl(fd, 0, /* compute hash before signing */ - (unsigned char *)dgst, d_len, - (unsigned char *)dsa->p->d, BN_num_bits(dsa->p), - (unsigned char *)dsa->q->d, BN_num_bits(dsa->q), - (unsigned char *)dsa->g->d, BN_num_bits(dsa->g), - (unsigned char *)dsa->pub_key->d, BN_num_bits(dsa->pub_key), - (unsigned char *)sig->r->d, BN_num_bits(sig->r), - (unsigned char *)sig->s->d, BN_num_bits(sig->s), - (unsigned char *)v.d, &v_len) != 0) { - UBSECerr(UBSEC_F_UBSEC_DSA_VERIFY , UBSEC_R_REQUEST_FAILED); goto err; - } + } p_UBSEC_ubsec_close(fd); - to_return = 1; + ret = 1; err: BN_clear_free(&v); - return to_return; + return ret; } #endif #ifndef OPENSSL_NO_DH -static int ubsec_dh_compute_key (unsigned char *key,const BIGNUM *pub_key,DH *dh) +/* + * This function is aliased to mod_exp. + */ +static int ubsec_mod_exp_dh(DH *dh, + BIGNUM *r, + BIGNUM *a, + const BIGNUM *p, + const BIGNUM *m, + BN_CTX *ctx, + BN_MONT_CTX *m_ctx) { - return 0; + return ubsec_mod_exp(r, a, p, m, ctx); } +#endif -static int ubsec_dh_generate_key (DH *dh) - { - return 0; +static int ubsec_dh_compute_key (unsigned char *key,BIGNUM *pub_key,DH *dh) + { + int ret = -1, + k_len, + fd; + + k_len = BN_num_bits(dh->p); + + if ((fd = p_UBSEC_ubsec_open(UBSEC_KEY_DEVICE_NAME)) <= 0) + { + const DH_METHOD *meth; + ENGINEerr(ENGINE_F_UBSEC_INIT, ENGINE_R_UNIT_FAILURE); + meth = DH_OpenSSL(); + ret = meth->compute_key(key, pub_key, dh); + goto err; + } + + if (p_UBSEC_diffie_hellman_agree_ioctl(fd, + (unsigned char *)dh->priv_key->d, BN_num_bits(dh->priv_key), + (unsigned char *)pub_key->d, BN_num_bits(pub_key), + (unsigned char *)dh->p->d, BN_num_bits(dh->p), + key, &k_len) != 0) + { + /* Hardware's a no go, failover to software */ + const DH_METHOD *meth; + ENGINEerr(ENGINE_F_UBSEC_DH_COMPUTE_KEY, ENGINE_R_REQUEST_FAILED); + p_UBSEC_ubsec_close(fd); + + meth = DH_OpenSSL(); + ret = meth->compute_key(key, pub_key, dh); + + goto err; + } + + p_UBSEC_ubsec_close(fd); + + ret = p_UBSEC_ubsec_bits_to_bytes(k_len); +err: + return ret; } -#endif -#ifdef NOT_USED -static int ubsec_rand_bytes(unsigned char *buf, int num) - { - return 0; +static int ubsec_dh_generate_key (DH *dh) + { + int ret = 0, + random_bits = 0, + pub_key_len = 0, + priv_key_len = 0, + fd; + BIGNUM *pub_key = NULL; + BIGNUM *priv_key = NULL; + + /* + * How many bits should Random x be? dh_key.c + * sets the range from 0 to num_bits(modulus) ??? + */ + + if (dh->priv_key == NULL) + { + priv_key = BN_new(); + if (priv_key == NULL) goto err; + priv_key_len = BN_num_bits(dh->p); + bn_wexpand(priv_key, dh->p->top); + do + if (!BN_rand_range(priv_key, dh->p)) goto err; + while (BN_is_zero(priv_key)); + random_bits = BN_num_bits(priv_key); + } + else + { + priv_key = dh->priv_key; + } + + if (dh->pub_key == NULL) + { + pub_key = BN_new(); + pub_key_len = BN_num_bits(dh->p); + bn_wexpand(pub_key, dh->p->top); + if(pub_key == NULL) goto err; + } + else + { + pub_key = dh->pub_key; + } + + if ((fd = p_UBSEC_ubsec_open(UBSEC_KEY_DEVICE_NAME)) <= 0) + { + const DH_METHOD *meth; + ENGINEerr(ENGINE_F_UBSEC_INIT, ENGINE_R_UNIT_FAILURE); + meth = DH_OpenSSL(); + ret = meth->generate_key(dh); + goto err; + } + + if (p_UBSEC_diffie_hellman_generate_ioctl(fd, + (unsigned char *)priv_key->d, &priv_key_len, + (unsigned char *)pub_key->d, &pub_key_len, + (unsigned char *)dh->g->d, BN_num_bits(dh->g), + (unsigned char *)dh->p->d, BN_num_bits(dh->p), + 0, 0, random_bits) != 0) + { + /* Hardware's a no go, failover to software */ + const DH_METHOD *meth; + + ENGINEerr(ENGINE_F_UBSEC_DH_COMPUTE_KEY, ENGINE_R_REQUEST_FAILED); + p_UBSEC_ubsec_close(fd); + + meth = DH_OpenSSL(); + ret = meth->generate_key(dh); + + goto err; + } + + p_UBSEC_ubsec_close(fd); + + dh->pub_key = pub_key; + dh->pub_key->top = (pub_key_len + BN_BITS2-1) / BN_BITS2; + dh->priv_key = priv_key; + dh->priv_key->top = (priv_key_len + BN_BITS2-1) / BN_BITS2; + + ret = 1; +err: + return ret; + } + +#if NOT_USED +static int ubsec_rand_bytes(unsigned char * buf, + int num) + { + int ret = 0, + fd; + + if ((fd = p_UBSEC_ubsec_open(UBSEC_KEY_DEVICE_NAME)) <= 0) + { + const RAND_METHOD *meth; + ENGINEerr(ENGINE_F_UBSEC_INIT, ENGINE_R_UNIT_FAILURE); + num = p_UBSEC_ubsec_bits_to_bytes(num); + meth = RAND_SSLeay(); + meth->seed(buf, num); + ret = meth->bytes(buf, num); + goto err; + } + + num *= 8; /* bytes to bits */ + + if (p_UBSEC_rng_ioctl(fd, + UBSEC_RNG_DIRECT, + buf, + &num) != 0) + { + /* Hardware's a no go, failover to software */ + const RAND_METHOD *meth; + + ENGINEerr(ENGINE_F_UBSEC_RNG_BYTES, ENGINE_R_REQUEST_FAILED); + p_UBSEC_ubsec_close(fd); + + num = p_UBSEC_ubsec_bits_to_bytes(num); + meth = RAND_SSLeay(); + meth->seed(buf, num); + ret = meth->bytes(buf, num); + + goto err; + } + + p_UBSEC_ubsec_close(fd); + + ret = 1; +err: + return(ret); } static int ubsec_rand_status(void) @@ -903,20 +1052,5 @@ static int ubsec_rand_status(void) } #endif -/* This stuff is needed if this ENGINE is being compiled into a self-contained - * shared-library. */ -#ifdef ENGINE_DYNAMIC_SUPPORT -static int bind_fn(ENGINE *e, const char *id) - { - if(id && (strcmp(id, engine_ubsec_id) != 0)) - return 0; - if(!bind_helper(e)) - return 0; - return 1; - } -IMPLEMENT_DYNAMIC_CHECK_FN() -IMPLEMENT_DYNAMIC_BIND_FN(bind_fn) -#endif /* ENGINE_DYNAMIC_SUPPORT */ - #endif /* !OPENSSL_NO_HW_UBSEC */ #endif /* !OPENSSL_NO_HW */ diff --git a/crypto/engine/vendor_defns/hw_ubsec.h b/crypto/engine/vendor_defns/hw_ubsec.h index 37c830c1e8..23b0de7697 100644 --- a/crypto/engine/vendor_defns/hw_ubsec.h +++ b/crypto/engine/vendor_defns/hw_ubsec.h @@ -35,6 +35,10 @@ #define UBSEC_MATH_MODREM 0x0010 #define UBSEC_MATH_MODINV 0x0020 +/* RNG command types. */ +#define UBSEC_RNG_DIRECT 0x0001 +#define UBSEC_RNG_SHA1 0x0002 + typedef long ubsec_MathCommand_t; typedef long ubsec_RNGCommand_t; @@ -97,3 +101,5 @@ typedef int t_UBSEC_math_accelerate_ioctl(int fd, ubsec_MathCommand_t command, typedef int t_UBSEC_rng_ioctl(int fd, ubsec_RNGCommand_t command, unsigned char *Result, int *Result_len); +typedef int t_UBSEC_max_key_len_ioctl(int fd, int *max_key_len); + -- 2.25.1