openssl engine 实现SM4 引擎


一 openssl engine基本介绍

Engine机制目的是为了使OpenSSL能够透明地使用第三方提供的软件加密库或者硬件加密设备进行加密。OpenSSL的Engine机制成功地达到了这个目的,这使得OpenSSL已经不仅仅使一个加密库,而是提供了一个通用地加密接口,能够与绝大部分加密库或者加密设备协调工作。当然,要使特定加密库或加密设备更OpenSSL协调工作,需要写少量的接口代码,但是这样的工作量并不大。

二 SM4引擎实现

1 Openssl定义好的主接口

IMPLEMENT_DYNAMIC_BIND_FN(bind)
IMPLEMENT_DYNAMIC_CHECK_FN()

2 定义bind函数

bind函数的定义如下所示:

static int bind(ENGINE *e, const char *id)
{
  int ret = 0;

  if (!ENGINE_set_id(e, engine_id)) {
    fprintf(stderr, "ENGINE_set_id failed\n");
    goto end;
  }
  if (!ENGINE_set_name(e, engine_name)) {
    printf("ENGINE_set_name failed\n");
    goto end;
  }
  if (!ENGINE_set_ciphers(e, ciphers)) {
    printf("ENGINE_set_name failed\n");
    goto end;
  }

  ret = 1;
 end:
  return ret;
}

其中主要是使用openssl的引擎API注册和设置sm4引擎,

3 实现ciphers函数

ciphers函数是配置算法结构初始化函数,其定义如下所示:

static int ciphers(ENGINE *e, const EVP_CIPHER **cipher,
                   const int **nids, int nid)
{
  int ok = 1;
  #if 1
  if (!cipher) {
    /* We are returning a list of supported nids */
    *nids = sm4_nids;
    return (sizeof(sm4_nids) - 1) / sizeof(sm4_nids[0]);
  }
  #endif

  switch (nid) {
  case NID_aes_128_ecb:
    *cipher = &cipher_sm4;
    break;
  default:
    ok = 0;
    *cipher = NULL;
    break;
  }
  return ok;
}

4 定义算法结构evp_cipher_st

定义如下

struct evp_cipher_st cipher_sm4 =
	{
	NID_aes_128_ecb,//int nid;
	16,//int block_size;
	16,//int key_len;		/* Default value for variable length ciphers */
	16,//int iv_len;
	0,//unsigned long flags;	/* Various flags */
	sm4_init,//int (*init)(EVP_CIPHER_CTX *ctx, const unsigned char *key,
		  //  const unsigned char *iv, int enc);	/* init key */
	sm4_func,//int (*do_cipher)(EVP_CIPHER_CTX *ctx, unsigned char *out,
		//	 const unsigned char *in, size_t inl);/* encrypt/decrypt data */
	NULL,//int (*cleanup)(EVP_CIPHER_CTX *); /* cleanup ctx */
	sizeof(sm4_ctx_t),//int ctx_size;		/* how big ctx->cipher_data needs to be */
	NULL,//int (*set_asn1_parameters)(EVP_CIPHER_CTX *, ASN1_TYPE *); /* Populate a ASN1_TYPE with parameters */
	NULL,//int (*get_asn1_parameters)(EVP_CIPHER_CTX *, ASN1_TYPE *); /* Get parameters from a ASN1_TYPE */
	NULL,//int (*ctrl)(EVP_CIPHER_CTX *, int type, int arg, void *ptr); /* Miscellaneous operations */
	NULL,//void *app_data;		/* Application data */
	} /* EVP_CIPHER */;

在算法结构中,定义了如下信息
(1)指明了算法ID,由于我使用的openssl是1.0版本,还不支持sm4算法,目前只能使用aes的id来代替。
(2) 定义了key和iv的长度,都为16字节
(3)定义了sm4_init 函数,用于初始化sm4算法,包括key 和id。
(4) 定义了sm4_func函数,用于sm4算法的加解密的实现。
(5) 定义了sm4_ctx_t 结构的大小,这个结构体中包括了sm4密钥和加解密标志。
(6)其他没有用到的元素都置NULL

5 实现sm4_init 函数体

int sm4_init(EVP_CIPHER_CTX *ctx, const unsigned char *key,
		    const unsigned char *iv, int enc)
{
    sm4_ctx_t *sm4_contex;
    sm4_contex=(sm4_ctx_t *)(ctx->cipher_data);
    memcpy(sm4_contex->key,key,16);
    sm4_contex->enc_dec=enc;
    dump_hex("sm4_init get key",sm4_contex->key,16);
    printf("get enc flag: %d\n",sm4_contex->enc_dec);
}

6 实现sm4_func 函数体

int sm4_func(EVP_CIPHER_CTX *ctx, unsigned char *out,
			 const unsigned char *in, size_t inl)
{
    sm4_ctx_t *sm4_contex;
    sm4_contex=(sm4_ctx_t *)(ctx->cipher_data);
    if(sm4_contex->enc_dec)
    {
        dump_hex("plain data:",in,16);
        SM4_Encrypt(sm4_contex->key,in,out);
        dump_hex("enc data:",out,16);
    }
    else
    {
        dump_hex("cipher data:",in,16);
        SM4_Decrypt(sm4_contex->key,in,out);
        dump_hex("dec data:",out,16);
    }
}

7编译和测试

make  //编译出so文件,这个就是sm4的加密引擎库
make test 调用openssl命令进行测试该引擎

结果如下:

$ make test
openssl engine -t -c `pwd`/./bin/sm4-engine.so
(/home/yaomingyue/work/openssl/test/engine/sm4/v2/./bin/sm4-engine.so) A simple SM4 engine for demonstration purposes
Loaded: (SM4) A simple SM4 engine for demonstration purposes
 [AES-128-ECB]
     [ available ]
echo whatever | openssl enc -aes-128-ecb -e -out out.bin -K 0123456789ABCDEFFEDCBA9876543210 -iv 0123456789ABCDEFFEDCBA9876543210 -engine `pwd`/bin/sm4-engine.so
engine "SM4" set.
sm4_init get key:
1 23 45 67 89 ab cd ef fe dc ba 98 76 54 32 10 
get enc flag: 1
plain data::
77 68 61 74 65 76 65 72 a 7 7 7 7 7 7 7 
enc data::
b6 63 68 23 aa ae f2 a6 e3 4 ac 33 ea 4b b2 2d 
openssl enc -aes-128-ecb -d -in out.bin -K 0123456789ABCDEFFEDCBA9876543210 -engine `pwd`/bin/sm4-engine.so
engine "SM4" set.
sm4_init get key:
1 23 45 67 89 ab cd ef fe dc ba 98 76 54 32 10 
get enc flag: 0
cipher data::
b6 63 68 23 aa ae f2 a6 e3 4 ac 33 ea 4b b2 2d 
dec data::
77 68 61 74 65 76 65 72 a 7 7 7 7 7 7 7 
whatever

本文章相关源码

https://download.csdn.net/download/qq_39952971/30319470

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

viqjeee

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值