[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