私がしたいことを、以下に最小、完全、および検証可能な例があります。
基本的には、いくつかの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
@Dani Grosuそれは賞金を集める素晴らしい驚きでした。私はそれがどのように判明したかを聞くことに興味があります。 –
私は、 'RSA_METHOD'構造体の' rsa_mod_exp'メンバーには適していない 'BN_mod_exp'を使い間違えていました。私は 'rsa_mod_exp'がpkcs1パディングを扱っていると思います。私の質問は「どうすればこの[...]エラーを取り除くことができますか」という答えが働いたので、あなたは賞金を集めました。 –
@JimFloodには、すべてのエンジン関数が静的const RSA_METHOD'をファイル全体で使うのではなく、新しいRSA_METHODをmodexp関数の中で宣言する理由がありますか?たとえば、単に "Hello"を出力した後、エンジンのRSA_METHOD関数のすべてをデフォルトのRSA_METHOD関数に転送するRSAエンジンを作成したいのであれば、実際には 'const RSA_METHOD * meth = RSA_PKCS1_SSLeay() ; 'そう?すべてのエンジン機能にそれを含めるのではなく?申し訳ありませんが、これは愚かな質問ですが、今私に関係があります。 – Brett