2016-04-04 30 views
2

私がしたいことを、以下に最小、完全、および検証可能な例があります。
基本的には、いくつかのCUDAコードを統合するOpenSSL RSAエンジンを実装したいと考えています。 CUDA部分はべき乗剰余演算を行うべきですが、この例では重要ではありませんので、コードを簡略化するためにBN_mod_exp(engine.cファイルmodexp関数を参照)を使用しました。私は、現在のコードは、私のプロジェクトの簡易版で、それはこれらのコマンドでは非常に簡単にコンパイル/構築することができます:OpenSSL RSAエンジン - RSA検証エラー

gcc -fPIC -I/usr/local/cuda/include -c engine.c 
nvcc --compiler-options '-fPIC' -c my_cuda.cu -lcrypto 
g++ -L/usr/local/cuda/lib64 -shared -o gpu.so engine.o my_cuda.o -lcuda -lcudart 
openssl engine -t -c `pwd`/gpu.so 

...最後のコマンドの出力は、RSAエンジンが利用可能であることを述べている

/*engine.c*/ 

#include <openssl/opensslconf.h> 

#include <stdio.h> 
#include <string.h> 
#include <openssl/crypto.h> 
#include <openssl/buffer.h> 
#include <openssl/engine.h> 

#include <openssl/rsa.h> 

#include <openssl/bn.h> 
#include <openssl/err.h> 
#include "my_cuda.h" 

/* Constants used when creating the ENGINE */ 
static const char *engine_e_rsax_id = "rsa_gpu"; 
static const char *engine_e_rsax_name = "RSAX engine support"; 
static int modexp(BIGNUM *r, const BIGNUM *I, RSA *rsa, BN_CTX *ctx);// r = r^I mod rsa->n 
static int e_rsax_rsa_finish(RSA *r); 
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)); 

static const ENGINE_CMD_DEFN e_rsax_cmd_defns[] = { 
    {0, NULL, NULL, 0} 
}; 

static ENGINE *ENGINE_rsax (void); 
void ENGINE_load_rsax (void) 
    { 
/* On non-x86 CPUs it just returns. */ 
    ENGINE *toadd = ENGINE_rsax(); 
    if(!toadd) return; 
    ENGINE_add(toadd); 
    ENGINE_free(toadd); 
    ERR_clear_error(); 
    } 


static RSA_METHOD e_rsax_rsa = 
{ 
    "Intel RSA-X method", 
    NULL, 
    NULL, 
    NULL, 
    NULL, 
    modexp, 
    NULL, 
    NULL, 
    NULL, 
    RSA_FLAG_CACHE_PUBLIC|RSA_FLAG_CACHE_PRIVATE, 
    NULL, 
    NULL, 
    NULL 
}; 

/* This internal function is used by ENGINE_rsax() */ 
static int bind_helper(ENGINE *e, const char *id) 
    { 
     printf("%s\n", id); 

    const RSA_METHOD *meth1; 

    if(!ENGINE_set_id(e, engine_e_rsax_id) || 
      !ENGINE_set_name(e, engine_e_rsax_name) || 

      !ENGINE_set_RSA(e, &e_rsax_rsa) || 

      !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; 


    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; 

    return 1; 
    } 

    /* Used to attach our own key-data to an RSA structure */ 
static int rsax_ex_data_idx = -1; 


static int e_rsax_destroy(ENGINE *e) 
{ 
    return 1; 
} 

/* (de)initialisation functions. */ 
static int e_rsax_init(ENGINE *e) 
{ 

    if (rsax_ex_data_idx == -1) 
     rsax_ex_data_idx = RSA_get_ex_new_index(0, 
      NULL, 
      NULL, NULL, NULL); 

    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; 
} 

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; 
} 

static int modexp(BIGNUM *r, const BIGNUM *I, RSA *rsa, BN_CTX *ctx)// r = r^I mod rsa->n 
{ 
    modexp512(); 
    return BN_mod_exp(r, r, I, rsa->n, ctx); 
} 

...次の2つのファイルは、デモ目的としたものであり、

/*my_cuda.cu*/ 
#include <cuda_runtime.h> 
#include <stdio.h> 
extern "C" { 
#include "my_cuda.h" 
} 

__global__ void dummy_gpu_kernel(){ 
    // stuff here 
} 
extern "C" 
void modexp512(){ 
    dummy_gpu_kernel<<<1,1>>>(); 
} 

...

01私のプロジェクトを再生しています
/*my_cuda.h*/ 
#ifndef MY_DUMMY 
#define MY_DUMMY 

void modexp512(); 

#endif 

は、今私は

$ openssl speed rsa512 -engine `pwd`/gpu.so 

を使用して、いくつかの速度のテストをしたいと私は

/full/path/gpu.so 
engine "rsa_gpu" set. 
Doing 512 bit private rsa's for 10s: 575412 512 bit private RSA's in 10.02s 
RSA verify failure. No RSA verify will be done. 
140592781633184:error:0407006A:rsa routines:RSA_padding_check_PKCS1_type_1:block type is not 01:rsa_pk1.c:100: 
140592781633184: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) 
compiler: cc -fPIC -DOPENSSL_PIC -DOPENSSL_THREADS -D_REENTRANT -DDSO_DLFCN -DHAVE_DLFCN_H -m64 -DL_ENDIAN -DTERMIO -g -O2 -fstack-protector --param=ssp-buffer-size=4 -Wformat -Werror=format-security -D_FORTIFY_SOURCE=2 -Wl,-Bsymbolic-functions -Wl,-z,relro -Wa,--noexecstack -Wall -DMD32_REG_T=int -DOPENSSL_IA32_SSE2 -DOPENSSL_BN_ASM_MONT -DOPENSSL_BN_ASM_MONT5 -DOPENSSL_BN_ASM_GF2m -DSHA1_ASM -DSHA256_ASM -DSHA512_ASM -DMD5_ASM -DAES_ASM -DVPAES_ASM -DBSAES_ASM -DWHIRLPOOL_ASM -DGHASH_ASM 

次のエラーが表示された私は成功せず、インターネット上でこれらのエラーで検索しました。私の質問です:どのように私はこの "RSAの検証の失敗を取り除くことができます。ないRSAの検証が行われます。エラー? OpenSSLは私の実装や何かを信用しないようです。
私は以前の投稿を削除しました。これは、コンパイルと検証ができなかったからです。この例は、OpenSSLとCUDA [オプション]がインストールされているすべての人が検証できます。しかし、CUDAの一部は、この例では重要ではありませんし、誰かがそれを試してみたいと考えているので、彼/彼女はengine.cファイルから#include "my_cuda.h"modexp512();をコメントアウトし、それに応じてビルドプロセスを変更することがあり、それは次のようになります。

gcc -fPIC -c engine.c 
g++ -shared -o gpu.so -lcrypto engine.o 

と同じコマンドを試してください

$ openssl speed rsa512 -engine `pwd`/gpu.so 

答えて

5

私は面白いと思ったので、私はこれをちょっと試しました。私はあなたが何か悪いことをしているとは確信していません。私はrsa->_method_mod_nが使用されるべきか定かではないが、私はこれを使用してmodexpを置き換える:

static int modexp(BIGNUM *r, const BIGNUM *I, RSA *rsa, BN_CTX *ctx) 
{ 
    const RSA_METHOD *meth = RSA_PKCS1_SSLeay(); 
    return meth->rsa_mod_exp(r, I, rsa, ctx); 
} 

、それがうまく働いたし、この:

static int modexp(BIGNUM *r, const BIGNUM *I, RSA *rsa, BN_CTX *ctx) 
{ 
    const RSA_METHOD *meth = RSA_PKCS1_SSLeay(); 
    return meth->bn_mod_exp(r, (const BIGNUM*) r, I, rsa->n, ctx, rsa->_method_mod_n); 
} 

、あなたが説明するように、それは正確に失敗しました。

どちらの場合でも、私はopensslソースの読者として使用するべきであることを示唆しているので、このメソッドのOpenSSL関数を使用しています。

+0

@Dani Grosuそれは賞金を集める素晴らしい驚きでした。私はそれがどのように判明したかを聞くことに興味があります。 –

+0

私は、 'RSA_METHOD'構造体の' rsa_mod_exp'メンバーには適していない 'BN_mod_exp'を使い間違えていました。私は 'rsa_mod_exp'がpkcs1パディングを扱っていると思います。私の質問は「どうすればこの[...]エラーを取り除くことができますか」という答えが働いたので、あなたは賞金を集めました。 –

+0

@JimFloodには、すべてのエンジン関数が静的const RSA_METHOD'をファイル全体で使うのではなく、新しいRSA_METHODをmodexp関数の中で宣言する理由がありますか?たとえば、単に "Hello"を出力した後、エンジンのRSA_METHOD関数のすべてをデフォルトのRSA_METHOD関数に転送するRSAエンジンを作成したいのであれば、実際には 'const RSA_METHOD * meth = RSA_PKCS1_SSLeay() ; 'そう?すべてのエンジン機能にそれを含めるのではなく?申し訳ありませんが、これは愚かな質問ですが、今私に関係があります。 – Brett

関連する問題