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.
-- 
openssl-users mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-users

Reply via email to