[openssl-users] OpenSSL RSA engine - RSA verify failure

danigrosu dni.grosu at gmail.com
Tue Apr 5 14:41:59 UTC 2016


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.


More information about the openssl-users mailing list