Hi. I am trying to build an OpenSSL RSA engine and the first step is to use the "BN_mod_exp_mont" for the RSA modular exponentiation function, in RSA_METHOD structure. ***BEGINNING OF eng_rsax_test.c FILE*** / #include <openssl/opensslconf.h> #include <stdio.h> #include <string.h> #include <openssl/crypto.h> #include <openssl/buffer.h> #include <openssl/engine.h> #ifndef OPENSSL_NO_RSA #include <openssl/rsa.h> #endif #include <openssl/bn.h> #include <openssl/err.h> /* RSAX is available **ONLY* on x86_64 CPUs */ #undef COMPILE_RSAX #if (defined(__x86_64) || defined(__x86_64__) || \ defined(_M_AMD64) || defined (_M_X64)) && !defined(OPENSSL_NO_ASM) #define COMPILE_RSAX static ENGINE *ENGINE_rsax (void); #endif void ENGINE_load_rsax (void) { ENGINE *toadd = ENGINE_rsax(); if(!toadd) return; ENGINE_add(toadd); ENGINE_free(toadd); ERR_clear_error(); } #ifdef COMPILE_RSAX #define E_RSAX_LIB_NAME "rsax engine" static int e_rsax_destroy(ENGINE *e); static int e_rsax_init(ENGINE *e); static int e_rsax_finish(ENGINE *e); static int e_rsax_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void)); #ifndef OPENSSL_NO_RSA /* RSA stuff */ static int e_rsax_rsa_mod_exp(BIGNUM *r, const BIGNUM *I, RSA *rsa, BN_CTX *ctx); static int e_rsax_rsa_finish(RSA *r); #endif static const ENGINE_CMD_DEFN e_rsax_cmd_defns[] = { {0, NULL, NULL, 0} }; #ifndef OPENSSL_NO_RSA /* Our internal RSA_METHOD that we provide pointers to */ static RSA_METHOD e_rsax_rsa = { "Intel RSA-X method", NULL, NULL, NULL, NULL, e_rsax_rsa_mod_exp, NULL, NULL, e_rsax_rsa_finish, RSA_FLAG_CACHE_PUBLIC|RSA_FLAG_CACHE_PRIVATE, NULL, NULL, NULL, NULL }; #endif /* Constants used when creating the ENGINE */ static const char *engine_e_rsax_id = "rsax_dani"; static const char *engine_e_rsax_name = "RSAX engine support"; /* This internal function is used by ENGINE_rsax() */ static int bind_helper(ENGINE *e, const char *id) { printf("%s\n", id); #ifndef OPENSSL_NO_RSA const RSA_METHOD *meth1; #endif if(!ENGINE_set_id(e, engine_e_rsax_id) || !ENGINE_set_name(e, engine_e_rsax_name) || #ifndef OPENSSL_NO_RSA !ENGINE_set_RSA(e, &e_rsax_rsa) || #endif !ENGINE_set_destroy_function(e, e_rsax_destroy) || !ENGINE_set_init_function(e, e_rsax_init) || !ENGINE_set_finish_function(e, e_rsax_finish) || !ENGINE_set_ctrl_function(e, e_rsax_ctrl) || !ENGINE_set_cmd_defns(e, e_rsax_cmd_defns)) return 0; #ifndef OPENSSL_NO_RSA meth1 = RSA_PKCS1_SSLeay(); e_rsax_rsa.rsa_pub_enc = meth1->rsa_pub_enc; e_rsax_rsa.rsa_pub_dec = meth1->rsa_pub_dec; e_rsax_rsa.rsa_priv_enc = meth1->rsa_priv_enc; e_rsax_rsa.rsa_priv_dec = meth1->rsa_priv_dec; e_rsax_rsa.bn_mod_exp = meth1->bn_mod_exp; e_rsax_rsa.finish = meth1->finish; #endif return 1; } IMPLEMENT_DYNAMIC_BIND_FN(bind_helper) IMPLEMENT_DYNAMIC_CHECK_FN() static ENGINE *ENGINE_rsax(void) { ENGINE *ret = ENGINE_new(); if(!ret) return NULL; if(!bind_helper(ret, engine_e_rsax_id)) { ENGINE_free(ret); return NULL; } return ret; } #ifndef OPENSSL_NO_RSA /* Used to attach our own key-data to an RSA structure */ static int rsax_ex_data_idx = -1; #endif static int e_rsax_destroy(ENGINE *e) { return 1; } /* (de)initialisation functions. */ static int e_rsax_init(ENGINE *e) { #ifndef OPENSSL_NO_RSA if (rsax_ex_data_idx == -1) rsax_ex_data_idx = RSA_get_ex_new_index(0, NULL, NULL, NULL, NULL); #endif if (rsax_ex_data_idx == -1) return 0; return 1; } static int e_rsax_finish(ENGINE *e) { return 1; } static int e_rsax_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void)) { int to_return = 1; switch(cmd) { /* The command isn't understood by this engine */ default: to_return = 0; break; } return to_return; } #ifndef OPENSSL_NO_RSA #ifdef _WIN32 typedef unsigned __int64 UINT64; #else typedef unsigned long long UINT64; #endif typedef unsigned short UINT16; struct mod_ctx_512 { UINT64 t[8][8]; UINT64 m[8]; UINT64 m1[8]; /* 2^278 % m */ UINT64 m2[8]; /* 2^640 % m */ UINT64 k1[2]; /* (- 1/m) % 2^128 */ }; typedef struct st_e_rsax_mod_ctx { UINT64 type; union { struct mod_ctx_512 b512; } ctx; } E_RSAX_MOD_CTX; static int e_rsax_rsa_finish(RSA *rsa) { E_RSAX_MOD_CTX *hptr = RSA_get_ex_data(rsa, rsax_ex_data_idx); if(!hptr) return 0; OPENSSL_free(hptr); RSA_set_ex_data(rsa, rsax_ex_data_idx, NULL); return 1; } #if 1 static int e_rsax_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx) { return BN_mod_exp_mont(r0, r0, I, rsa->n, ctx, rsa->_method_mod_p); } #endif #endif /* !OPENSSL_NO_RSA */ #endif /* !COMPILE_RSAX *// ***END OF eng_rsax_test.c FILE*** The engine is built successfully after using these commands: /cc -fPIC -o eng_rsax.o -c eng_rsax_test.c cc -shared -o eng_rsax.so eng_rsax.o -lcrypto/ ... but if I want to test the speed of the rsa implementation with: /openssl speed rsa512 -engine `pwd`/eng_rsax.so/ it fails: /engine "rsax_dani" set. Doing 512 bit private rsa's for 10s: 774848 512 bit private RSA's in 10.01s RSA verify failure. No RSA verify will be done. 140017307215520:error:0407006A:rsa routines:RSA_padding_check_PKCS1_type_1:block type is not 01:rsa_pk1.c:100: 140017307215520:error:04067072:rsa routines:RSA_EAY_PUBLIC_DECRYPT:padding check failed:rsa_eay.c:721: OpenSSL 1.0.1f 6 Jan 2014 built on: Mon Feb 29 18:11:15 UTC 2016 options:bn(64,64) rc4(16x,int) des(idx,cisc,16,int) aes(partial) blowfish(idx)/ So the signing part is working, but the verify part fails. It appears that the PKCS1 paddind is wrong but how can I fix that? Best wishes, Dani Grosu -- View this message in context: http://openssl.6102.n7.nabble.com/OpenSSL-RSA-engine-RSA-verify-failure-tp65447.html Sent from the OpenSSL - User mailing list archive at Nabble.com.