Skip to content

Commit 9e9c6d0

Browse files
liaohanqinKT-lcz
authored andcommitted
feat: 使用evp方式实现国密算法
国密算法使用evp方式实现,解决打包问题。 Log: Task: https://pms.uniontech.com/task-view-193403.html Influence: 认证 Change-Id: I2dedcd5641fbda8d3f0f7e798f6b3da736abda30
1 parent 7f654f4 commit 9e9c6d0

4 files changed

Lines changed: 209 additions & 17 deletions

File tree

gm/sm2/dde-sm2.c

Lines changed: 166 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
#include <openssl/ec.h>
99
#include <openssl/bn.h>
1010
#include <openssl/crypto.h>
11-
#include <openssl/sm2.h>
1211

1312
#include "dde-sm2.h"
1413

@@ -86,6 +85,166 @@ static char* get_private_key(EC_KEY *key) {
8685
return ret;
8786
}
8887

88+
/*openssl sm2 cipher evp using*/
89+
static int openssl_evp_sm2_encrypt(EC_KEY *ec_key,
90+
const unsigned char *plain_text, size_t plain_len,
91+
unsigned char *cipher_text, size_t *cipher_len)
92+
{
93+
int ret = 0;
94+
BIO *bp = NULL;
95+
EVP_PKEY* public_evp_key = NULL;
96+
EVP_PKEY_CTX *ctx = NULL;
97+
98+
/*Check the user input.*/
99+
if (plain_text == NULL || plain_len == 0) {
100+
ret = -1;
101+
return ret;
102+
}
103+
104+
//OpenSSL_add_all_algorithms();
105+
bp = BIO_new(BIO_s_mem());
106+
if (bp == NULL) {
107+
printf("BIO_new is failed.\n");
108+
ret = -1;
109+
return ret;
110+
}
111+
112+
if (ec_key == NULL) {
113+
ret = -1;
114+
printf("open_public_key failed to PEM_read_bio_EC_PUBKEY Failed, ret=%d\n", ret);
115+
goto finish;
116+
}
117+
public_evp_key = EVP_PKEY_new();
118+
if (public_evp_key == NULL) {
119+
ret = -1;
120+
printf("open_public_key EVP_PKEY_new failed\n");
121+
goto finish;
122+
}
123+
ret = EVP_PKEY_set1_EC_KEY(public_evp_key, ec_key);
124+
if (ret != 1) {
125+
ret = -1;
126+
printf("EVP_PKEY_set1_EC_KEY failed\n");
127+
goto finish;
128+
}
129+
ret = EVP_PKEY_set_alias_type(public_evp_key, EVP_PKEY_SM2);
130+
if (ret != 1) {
131+
printf("EVP_PKEY_set_alias_type to EVP_PKEY_SM2 failed! ret = %d\n", ret);
132+
ret = -1;
133+
goto finish;
134+
}
135+
/*modifying a EVP_PKEY to use a different set of algorithms than the default.*/
136+
137+
/*do cipher.*/
138+
ctx = EVP_PKEY_CTX_new(public_evp_key, NULL);
139+
if (ctx == NULL) {
140+
ret = -1;
141+
printf("EVP_PKEY_CTX_new failed\n");
142+
goto finish;
143+
}
144+
ret = EVP_PKEY_encrypt_init(ctx);
145+
if (ret < 0) {
146+
printf("sm2_pubkey_encrypt failed to EVP_PKEY_encrypt_init. ret = %d\n", ret);
147+
goto finish;
148+
}
149+
ret = EVP_PKEY_encrypt(ctx, cipher_text, cipher_len, plain_text, plain_len);
150+
if (ret < 0) {
151+
printf("sm2_pubkey_encrypt failed to EVP_PKEY_encrypt. ret = %d\n", ret);
152+
goto finish;
153+
}
154+
ret = 0;
155+
156+
finish:
157+
if (public_evp_key != NULL)
158+
EVP_PKEY_free(public_evp_key);
159+
if (ctx != NULL)
160+
EVP_PKEY_CTX_free(ctx);
161+
if (bp != NULL)
162+
BIO_free(bp);
163+
164+
return ret;
165+
}
166+
167+
/*openssl sm2 decrypt evp using*/
168+
static int openssl_evp_sm2_decrypt(EC_KEY* ec_key,
169+
const unsigned char *cipher_text, size_t cipher_len,
170+
unsigned char *plain_text, size_t *plain_len)
171+
{
172+
int ret = 0;
173+
size_t out_len = 0;
174+
BIO *bp = NULL;
175+
EVP_PKEY* private_evp_key = NULL;
176+
EVP_PKEY_CTX *ctx = NULL;
177+
178+
/*Check the user input.*/
179+
if (cipher_len == 0 || cipher_text == NULL) {
180+
ret = -1;
181+
return ret;
182+
}
183+
184+
//OpenSSL_add_all_algorithms();
185+
bp = BIO_new(BIO_s_mem());
186+
if (bp == NULL) {
187+
printf("BIO_new is failed.\n");
188+
ret = -1;
189+
return ret;
190+
}
191+
192+
if (ec_key == NULL) {
193+
ret = -1;
194+
printf("open_private_key failed to PEM_read_bio_ECPrivateKey Failed, ret=%d\n", ret);
195+
goto finish;
196+
}
197+
private_evp_key = EVP_PKEY_new();
198+
if (private_evp_key == NULL) {
199+
ret = -1;
200+
printf("open_public_key EVP_PKEY_new failed\n");
201+
goto finish;
202+
}
203+
ret = EVP_PKEY_set1_EC_KEY(private_evp_key, ec_key);
204+
if (ret != 1) {
205+
ret = -1;
206+
printf("EVP_PKEY_set1_EC_KEY failed\n");
207+
goto finish;
208+
}
209+
ret = EVP_PKEY_set_alias_type(private_evp_key, EVP_PKEY_SM2);
210+
if (ret != 1) {
211+
printf("EVP_PKEY_set_alias_type to EVP_PKEY_SM2 failed! ret = %d\n", ret);
212+
ret = -1;
213+
goto finish;
214+
}
215+
/*modifying a EVP_PKEY to use a different set of algorithms than the default.*/
216+
217+
/*do cipher.*/
218+
ctx = EVP_PKEY_CTX_new(private_evp_key, NULL);
219+
if (ctx == NULL) {
220+
ret = -1;
221+
printf("EVP_PKEY_CTX_new failed\n");
222+
goto finish;
223+
}
224+
ret = EVP_PKEY_decrypt_init(ctx);
225+
if (ret < 0) {
226+
printf("sm2 private_key decrypt failed to EVP_PKEY_decrypt_init. ret = %d\n", ret);
227+
goto finish;
228+
}
229+
230+
ret = EVP_PKEY_decrypt(ctx, plain_text, plain_len, cipher_text, cipher_len);
231+
if (ret < 0) {
232+
printf("sm2_prikey_decrypt failed to EVP_PKEY_decrypt. ret = %d\n", ret);
233+
goto finish;
234+
}
235+
ret = 0;
236+
finish:
237+
if (private_evp_key != NULL)
238+
EVP_PKEY_free(private_evp_key);
239+
if (ctx != NULL)
240+
EVP_PKEY_CTX_free(ctx);
241+
if (bp != NULL)
242+
BIO_free(bp);
243+
244+
return ret;
245+
}
246+
247+
89248
sm2_context* new_sm2_context() {
90249
EC_KEY* key = gen_ec_key();
91250
if (key == NULL) {
@@ -125,34 +284,34 @@ const char* get_sm2_private_key(sm2_context* context) {
125284
return context->private_key;
126285
}
127286

128-
int get_ciphertext_size(const sm2_context *context, size_t plen) {
287+
int get_ciphertext_size(const sm2_context *context, const uint8_t *ptext, size_t plen) {
129288
size_t ret = 0;
130-
if (1 == sm2_ciphertext_size(context->key, EVP_sm3(), plen, &ret)) {
289+
if (0 == openssl_evp_sm2_encrypt(context->key, ptext, plen, NULL, &ret)) {
131290
return (int)ret;
132291
}
133292

134293
return -1;
135294
}
136295

137-
int get_plaintext_size(const uint8_t *ctext, size_t clen) {
296+
int get_plaintext_size(const sm2_context *context, const uint8_t *ctext, size_t clen) {
138297
size_t ret = 0;
139-
if (1 == sm2_plaintext_size(ctext, clen, &ret)) {
298+
if (0 == openssl_evp_sm2_decrypt(context->key, ctext, clen, NULL, &ret)) {
140299
return (int)ret;
141300
}
142301

143302
return -1;
144303
}
145304

146305
int encrypt(const sm2_context* context, const uint8_t *ptext, size_t psize, uint8_t *ctext, size_t csize) {
147-
if (1 == sm2_encrypt(context->key, EVP_sm3(), ptext, psize, ctext, &csize)) {
306+
if (0 == openssl_evp_sm2_encrypt(context->key, ptext, psize, ctext, &csize)) {
148307
return (int)csize;
149308
}
150309

151310
return -1;
152311
}
153312

154313
int decrypt(const sm2_context* context, const uint8_t *ctext, size_t clen, uint8_t *ptext, size_t psize) {
155-
if (1 == sm2_decrypt(context->key, EVP_sm3(), ctext, clen, ptext, &psize)) {
314+
if (0 == openssl_evp_sm2_decrypt(context->key, ctext, clen, ptext, &psize)) {
156315
return (int)psize;
157316
}
158317

gm/sm2/dde-sm2.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@ void free_sm2_context(sm2_context *context);
1616
const char* get_sm2_public_key(sm2_context *context);
1717
const char* get_sm2_private_key(sm2_context *context);
1818

19-
int get_ciphertext_size(const sm2_context *context, size_t plen);
20-
int get_plaintext_size(const uint8_t *ctext, size_t clen);
19+
int get_ciphertext_size(const sm2_context *context, const uint8_t *ptext, size_t plen);
20+
int get_plaintext_size(const sm2_context *context, const uint8_t *ctext, size_t clen);
2121

2222
int encrypt(const sm2_context *context, const uint8_t *ptext, size_t psize, uint8_t *ctext, size_t csize);
2323
int decrypt(const sm2_context *context, const uint8_t *ctext, size_t csize, uint8_t *ptext, size_t psize);

gm/sm2/sm2.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ func (s *SM2Helper) Encrypt(p []byte) ([]byte, error) {
3737
if len(p) == 0 {
3838
return nil, fmt.Errorf("plaintext size is zero")
3939
}
40-
size := C.get_ciphertext_size(s.context, C.size_t(len(p)))
40+
size := C.get_ciphertext_size(s.context, (*C.uint8_t)(unsafe.Pointer(&p[0])), C.size_t(len(p)))
4141
if size <= 0 {
4242
return nil, fmt.Errorf("get ciphertext size failed")
4343
}
@@ -56,7 +56,7 @@ func (s *SM2Helper) Decrypt(c []byte) ([]byte, error) {
5656
if len(c) == 0 {
5757
return nil, fmt.Errorf("ciphertext size is zero")
5858
}
59-
size := C.get_plaintext_size((*C.uint8_t)(unsafe.Pointer(&c[0])), C.size_t(len(c)))
59+
size := C.get_plaintext_size(s.context, (*C.uint8_t)(unsafe.Pointer(&c[0])), C.size_t(len(c)))
6060
if size <= 0 {
6161
return nil, fmt.Errorf("get plaintext size failed")
6262
}

gm/sm4/sm4.go

Lines changed: 39 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,33 @@
44

55
package sm4
66

7-
// #include <openssl/sm4.h>
8-
// #cgo pkg-config: openssl
7+
/*
8+
#cgo pkg-config: openssl
9+
#include <openssl/evp.h>
10+
11+
static void openssl_evp_sm4_cipher(const unsigned char *key,
12+
unsigned char *out,
13+
unsigned char *in, int inl,
14+
int enc) {
15+
int ret = 0;
16+
EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
17+
if (ctx == NULL) {
18+
return;
19+
}
20+
ret = EVP_CipherInit(ctx, EVP_sm4_ecb(), key, NULL, enc);
21+
if (1 != ret) {
22+
printf("EVP_CipherInit fail... ret = %d \n", ret);
23+
EVP_CIPHER_CTX_free(ctx);
24+
return;
25+
}
26+
ret = EVP_Cipher(ctx, out, in, inl);
27+
if (1 != ret) {
28+
printf("EVP_Cipher fail.. ret = %d \n", ret);
29+
}
30+
31+
EVP_CIPHER_CTX_free(ctx);
32+
}
33+
*/
934
import "C"
1035
import (
1136
"crypto/cipher"
@@ -21,7 +46,7 @@ const (
2146

2247
// A cipher is an instance of SM4 encryption using a particular key.
2348
type sm4Cipher struct {
24-
key C.SM4_KEY
49+
key []byte
2550
}
2651

2752
// NewCipher creates and returns a new cipher.Block.
@@ -35,16 +60,24 @@ func NewCipher(key []byte) (cipher.Block, error) {
3560
break
3661
}
3762
ret := &sm4Cipher{}
38-
C.SM4_set_key((*C.uint8_t)(unsafe.Pointer(&key[0])), &ret.key)
63+
64+
ret.key = make([]byte, k)
65+
copy(ret.key, key)
3966
return ret, nil
4067
}
4168

4269
func (c *sm4Cipher) BlockSize() int { return BlockSize }
4370

4471
func (c *sm4Cipher) Encrypt(dst, src []byte) {
45-
C.SM4_encrypt((*C.uint8_t)(unsafe.Pointer(&src[0])), (*C.uint8_t)(unsafe.Pointer(&dst[0])), &c.key)
72+
C.openssl_evp_sm4_cipher((*C.uint8_t)(unsafe.Pointer(&c.key[0])),
73+
(*C.uint8_t)(unsafe.Pointer(&dst[0])),
74+
(*C.uint8_t)(unsafe.Pointer(&src[0])), C.int(len(src)),
75+
1)
4676
}
4777

4878
func (c *sm4Cipher) Decrypt(dst, src []byte) {
49-
C.SM4_decrypt((*C.uint8_t)(unsafe.Pointer(&src[0])), (*C.uint8_t)(unsafe.Pointer(&dst[0])), &c.key)
79+
C.openssl_evp_sm4_cipher((*C.uint8_t)(unsafe.Pointer(&c.key[0])),
80+
(*C.uint8_t)(unsafe.Pointer(&dst[0])),
81+
(*C.uint8_t)(unsafe.Pointer(&src[0])), C.int(len(src)),
82+
0)
5083
}

0 commit comments

Comments
 (0)