From fe885b939c13c715633e4c05df8811a1ea7ca079 Mon Sep 17 00:00:00 2001 From: "tassl@tass.com.cn" Date: Sun, 23 Aug 2020 22:33:23 +0800 Subject: [PATCH] Update to V_1.4 see ~/tassl_demo/README for more details. --- Configurations/unix-Makefile.tmpl | 11 ++ README | 2 +- apps/enc.c | 7 +- apps/pkcs7.c | 6 +- crypto/ec/ecdsa_sign.c | 11 +- crypto/evp/cmeth_lib.c | 11 ++ crypto/evp/evp_enc.c | 19 +++ crypto/evp/m_sigver.c | 2 +- crypto/include/internal/evp_int.h | 5 + include/openssl/ec.h | 8 +- include/openssl/evp.h | 10 ++ include/openssl/opensslv.h | 2 +- include/openssl/ssl.h | 1 - ssl/s3_lib.c | 5 +- ssl/statem/statem_clnt.c | 24 ++- ssl/statem/statem_srvr.c | 5 +- tassl_demo/README.txt | 8 + tassl_demo/card_engine/mk.sh | 16 ++ tassl_demo/card_engine/sm2_evp_dec.c | 120 +++++++++++++++ .../card_engine/sm2_evp_digest_sign_verify.c | 120 +++++++++++++++ tassl_demo/card_engine/sm2_evp_enc_dec.c | 142 ++++++++++++++++++ tassl_demo/card_engine/sm2_evp_keygen.c | 97 ++++++++++++ tassl_demo/card_engine/sm4_evp.c | 78 ++++++++++ tassl_demo/crypto/sm4_evp.c | 109 +++----------- util/libcrypto.num | 2 + util/libssl.num | 3 +- 26 files changed, 708 insertions(+), 116 deletions(-) create mode 100644 tassl_demo/card_engine/mk.sh create mode 100644 tassl_demo/card_engine/sm2_evp_dec.c create mode 100644 tassl_demo/card_engine/sm2_evp_digest_sign_verify.c create mode 100644 tassl_demo/card_engine/sm2_evp_enc_dec.c create mode 100644 tassl_demo/card_engine/sm2_evp_keygen.c create mode 100644 tassl_demo/card_engine/sm4_evp.c diff --git a/Configurations/unix-Makefile.tmpl b/Configurations/unix-Makefile.tmpl index a407e94f..f95671ea 100644 --- a/Configurations/unix-Makefile.tmpl +++ b/Configurations/unix-Makefile.tmpl @@ -477,6 +477,17 @@ install_tass: sed -i '1i\INC_DIR=$(INSTALLTOP)/include' $(CRYPTO_MK_FILE).sh sed -i '1i\LIB_DIR=$(INSTALLTOP)/lib' $(CRYPTO_MK_FILE).sh sed -i '1i\#!/bin/sh' $(CRYPTO_MK_FILE).sh + + echo ${INSTALLTOP}/lib > ${INSTALLTOP}/bin/tassl.conf + cp ${INSTALLTOP}/bin/tassl.conf /etc/ld.so.conf.d + ldconfig + + echo 'cp ${INSTALLTOP}/bin/tassl.conf /etc/ld.so.conf.d' >${INSTALLTOP}/bin/tass_init.sh + echo 'ldconfig' >>${INSTALLTOP}/bin/tass_init.sh + chmod u+x ${INSTALLTOP}/bin/tass_init.sh + + echo 'export LD_LIBRARY_PATH=${INSTALLTOP}/lib:$$LD_LIBRARY_PATH' >${INSTALLTOP}/bin/setting + install_ssldirs: @$(PERL) $(SRCDIR)/util/mkdir-p.pl $(DESTDIR)$(OPENSSLDIR)/certs diff --git a/README b/README index ad4d2e58..fbb35656 100644 --- a/README +++ b/README @@ -93,4 +93,4 @@ cryptographic code. - ./Configure linux-x86_64 --prefix=/root/tasshsm_engine/tassl --shared + ./Configure linux-x86_64 --prefix=/root/tasscard_engine/tassl --shared diff --git a/apps/enc.c b/apps/enc.c index 8e5a57d3..9278f97f 100644 --- a/apps/enc.c +++ b/apps/enc.c @@ -70,7 +70,7 @@ const OPTIONS enc_options[] = { {"bufsize", OPT_BUFSIZE, 's', "Buffer size"}, {"k", OPT_K, 's', "Passphrase"}, {"kfile", OPT_KFILE, '<', "Read passphrase from file"}, - {"K", OPT_UPPER_K, 's', "Raw key, in hex"}, + {"K", OPT_UPPER_K, 's', "Raw key, in hex.If use -engine tasscard_sm4,this is key index in decimal format"}, {"S", OPT_UPPER_S, 's', "Salt, in hex"}, {"iv", OPT_IV, 's', "IV in hex"}, {"md", OPT_MD, 's', "Use specified digest to create a key from the passphrase"}, @@ -534,7 +534,7 @@ int enc_main(int argc, char **argv) BIO_get_cipher_ctx(benc, &ctx); - if (!EVP_CipherInit_ex(ctx, cipher, NULL, NULL, NULL, enc)) { + if (!EVP_CipherInit_ex(ctx, cipher, e, NULL, NULL, enc)) { BIO_printf(bio_err, "Error setting cipher %s\n", EVP_CIPHER_name(cipher)); ERR_print_errors(bio_err); @@ -655,7 +655,8 @@ static int set_hex(const char *in, unsigned char *out, int size) BIO_printf(bio_err, "hex string is too long, ignoring excess\n"); n = i; /* ignore exceeding part */ } else if (n < i) { - BIO_printf(bio_err, "hex string is too short, padding with zero bytes to length\n"); + if(n != 2) + BIO_printf(bio_err, "hex string is too short, padding with zero bytes to length\n"); } memset(out, 0, size); diff --git a/apps/pkcs7.c b/apps/pkcs7.c index a35794df..9bd31259 100644 --- a/apps/pkcs7.c +++ b/apps/pkcs7.c @@ -525,7 +525,7 @@ int pkcs7_main(int argc, char **argv) if(informat == FORMAT_BASE64_GM009_7_4){ //in_len -= 15; //jump the header of sequence:30820xxx 3009 06072A811CCF550168 oid:1-2-156-10197-1-104(SM4) if(atoi(in_sign_key_index)>=0 && atoi(in_sign_key_index) <=64){ - printf("do nothing, use the card ENGINE_convert_private_key do all the parse!\n"); + //printf("do nothing, use the card ENGINE_convert_private_key do all the parse!\n"); }else{ memcpy(t_buf, in_buf+15, 2); //3079 iSymLen = *(unsigned char *)(t_buf+1); //the t_buf[1] bytes len, like 0x79. @@ -546,7 +546,7 @@ int pkcs7_main(int argc, char **argv) goto end; } } - if(atoi(in_sign_key_index)>=0 && atoi(in_sign_key_index) <=64){ + if(in_sign_key_index && atoi(in_sign_key_index)>=0 && atoi(in_sign_key_index) <=64){ }else{ /* 11111-Parse the ciphered sm4 key by the sm2 sign private key */ @@ -627,7 +627,7 @@ int pkcs7_main(int argc, char **argv) /* 33333-write the enc key to outfile*/ if(e){ - if(atoi(in_enc_key_index)>=0 && atoi(in_enc_key_index) <=64){ //input the enc key index, import the enc key to tasscard + if(in_enc_key_index && atoi(in_enc_key_index)>=0 && atoi(in_enc_key_index) <=64){ //input the enc key index, import the enc key to tasscard //use the in_buf[in_len] store the in_sign_key_index in_buf[in_len] = atoi(in_sign_key_index); ENGINE_convert_private_key(e, (const char *)in_buf, in_len, NULL, in_enc_key_index); diff --git a/crypto/ec/ecdsa_sign.c b/crypto/ec/ecdsa_sign.c index 590b6c18..8e72e42d 100644 --- a/crypto/ec/ecdsa_sign.c +++ b/crypto/ec/ecdsa_sign.c @@ -36,10 +36,13 @@ int ECDSA_sign(int type, const unsigned char *dgst, int dlen, unsigned char *sig, unsigned int *siglen, EC_KEY *eckey) { #ifndef OPENSSL_NO_CNSM - - if (EC_GROUP_get_curve_name(EC_KEY_get0_group(eckey)) == NID_sm2) - return sm2_sign(dgst, dlen, sig, siglen, eckey); -#endif + if (EC_GROUP_get_curve_name(EC_KEY_get0_group(eckey)) == NID_sm2){ + if ((EC_KEY_get_flags(eckey) & EC_FLAG_TASS_CUSTOM_SIGN) && eckey->meth->sign != NULL) + return eckey->meth->sign(type, dgst, dlen, sig, siglen, NULL, NULL, eckey); + else + return sm2_sign(dgst, dlen, sig, siglen, eckey); + } +#endif return ECDSA_sign_ex(type, dgst, dlen, sig, siglen, NULL, NULL, eckey); } diff --git a/crypto/evp/cmeth_lib.c b/crypto/evp/cmeth_lib.c index e2295c4d..37955abf 100644 --- a/crypto/evp/cmeth_lib.c +++ b/crypto/evp/cmeth_lib.c @@ -58,6 +58,17 @@ int EVP_CIPHER_meth_set_impl_ctx_size(EVP_CIPHER *cipher, int ctx_size) return 1; } +#ifndef OPENSSL_NO_CNSM +int EVP_CIPHER_meth_set_keygen(EVP_CIPHER *cipher, + int (*keygen) (EVP_CIPHER_CTX *ctx, + const unsigned char *key, + const unsigned char *index)) +{ + cipher->keygen = keygen; + return 1; +} +#endif + int EVP_CIPHER_meth_set_init(EVP_CIPHER *cipher, int (*init) (EVP_CIPHER_CTX *ctx, const unsigned char *key, diff --git a/crypto/evp/evp_enc.c b/crypto/evp/evp_enc.c index 05dd791b..14fd2a69 100644 --- a/crypto/evp/evp_enc.c +++ b/crypto/evp/evp_enc.c @@ -48,6 +48,25 @@ void EVP_CIPHER_CTX_free(EVP_CIPHER_CTX *ctx) OPENSSL_free(ctx); } +#ifndef OPENSSL_NO_CNSM +int EVP_CipherKeygen(EVP_CIPHER_CTX *ctx, ENGINE *impl, int nid, const unsigned char *key, const unsigned char *index) +{ + const EVP_CIPHER *ret; + if(impl){ + ENGINE_CIPHERS_PTR fn = NULL; + fn = ENGINE_get_ciphers(impl); + if(fn){ + fn(impl, &ret, NULL, nid); + if(ret) + return ret->keygen(ctx, key, index); + }else + return 1; + } + else + return 1; +} +#endif + int EVP_CipherInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, const unsigned char *key, const unsigned char *iv, int enc) { diff --git a/crypto/evp/m_sigver.c b/crypto/evp/m_sigver.c index 794c30c4..998e7575 100644 --- a/crypto/evp/m_sigver.c +++ b/crypto/evp/m_sigver.c @@ -85,7 +85,7 @@ static int do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, #ifndef OPENSSL_NO_CNSM if (ctx->pctx->pkey->type == EVP_PKEY_EC) { - if (EC_GROUP_get_curve_name(EC_KEY_get0_group(ctx->pctx->pkey->pkey.ec)) == NID_sm2) + if (EC_GROUP_get_curve_name(EC_KEY_get0_group(ctx->pctx->pkey->pkey.ec)) == NID_sm2 && !(EC_KEY_get_flags(ctx->pctx->pkey->pkey.ec) & EC_FLAG_TASS_NO_Z_SIGN)) { /*Need Set SM2 Sign And Verify Extra Data: Add Message Z*/ unsigned char ex_dgst[EVP_MAX_MD_SIZE]; diff --git a/crypto/include/internal/evp_int.h b/crypto/include/internal/evp_int.h index d86aed36..ef0d223e 100644 --- a/crypto/include/internal/evp_int.h +++ b/crypto/include/internal/evp_int.h @@ -154,6 +154,11 @@ struct evp_cipher_st { int (*ctrl) (EVP_CIPHER_CTX *, int type, int arg, void *ptr); /* Application data */ void *app_data; +#ifndef OPENSSL_NO_CNSM + /* init key */ + int (*keygen) (EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *index); +#endif } /* EVP_CIPHER */ ; /* Macros to code block cipher wrappers */ diff --git a/include/openssl/ec.h b/include/openssl/ec.h index 5f7c6e06..fd1f168e 100644 --- a/include/openssl/ec.h +++ b/include/openssl/ec.h @@ -818,9 +818,11 @@ int ECPKParameters_print_fp(FILE *fp, const EC_GROUP *x, int off); # define EC_FLAG_FIPS_CHECKED 0x2 # define EC_FLAG_COFACTOR_ECDH 0x1000 #ifndef OPENSSL_NO_CNSM -# define EC_FLAG_TASSHSM_ENGINE 0x10000 -# define EC_FLAG_TASSHSMRSA_ENGINE 0x20000 -# define EC_FLAG_TASSCARD_ENGINE 0x1000000 +# define EC_FLAG_TASSHSM_ENGINE 0x10000 +# define EC_FLAG_TASSHSMRSA_ENGINE 0x20000 +# define EC_FLAG_TASS_CUSTOM_SIGN 0x100000 +# define EC_FLAG_TASS_NO_Z_SIGN 0x200000 +# define EC_FLAG_TASSCARD_ENGINE 0x1000000 #endif diff --git a/include/openssl/evp.h b/include/openssl/evp.h index 47e41411..9eb5ebce 100644 --- a/include/openssl/evp.h +++ b/include/openssl/evp.h @@ -189,6 +189,12 @@ void EVP_CIPHER_meth_free(EVP_CIPHER *cipher); int EVP_CIPHER_meth_set_iv_length(EVP_CIPHER *cipher, int iv_len); int EVP_CIPHER_meth_set_flags(EVP_CIPHER *cipher, unsigned long flags); int EVP_CIPHER_meth_set_impl_ctx_size(EVP_CIPHER *cipher, int ctx_size); +#ifndef OPENSSL_NO_CNSM +int EVP_CIPHER_meth_set_keygen(EVP_CIPHER *cipher, + int (*keygen) (EVP_CIPHER_CTX *ctx, + const unsigned char *key, + const unsigned char *index)); +#endif int EVP_CIPHER_meth_set_init(EVP_CIPHER *cipher, int (*init) (EVP_CIPHER_CTX *ctx, const unsigned char *key, @@ -605,6 +611,10 @@ __owur int EVP_DecryptFinal(EVP_CIPHER_CTX *ctx, unsigned char *outm, /*__owur*/ int EVP_DecryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *outm, int *outl); +#ifndef OPENSSL_NO_CNSM +__owur int EVP_CipherKeygen(EVP_CIPHER_CTX *ctx, ENGINE *impl, int nid, + const unsigned char *key, const unsigned char *index); +#endif __owur int EVP_CipherInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, const unsigned char *key, const unsigned char *iv, int enc); diff --git a/include/openssl/opensslv.h b/include/openssl/opensslv.h index 191444b7..c9b4017a 100644 --- a/include/openssl/opensslv.h +++ b/include/openssl/opensslv.h @@ -40,7 +40,7 @@ extern "C" { * major minor fix final patch/beta) */ # define OPENSSL_VERSION_NUMBER 0x1010102fL -# define OPENSSL_VERSION_TEXT "OpenSSL 1.1.1b Tassl 1.3 25 May 2020" +# define OPENSSL_VERSION_TEXT "OpenSSL 1.1.1b Tassl 1.4 23 Aug 2020" /*- * The macros below are to be used for shared library (.so, .dll, ...) diff --git a/include/openssl/ssl.h b/include/openssl/ssl.h index a63a150e..51198499 100644 --- a/include/openssl/ssl.h +++ b/include/openssl/ssl.h @@ -1602,7 +1602,6 @@ __owur int SSL_set_sm2_group_id_custom(uint16_t id); __owur int SSL_CTX_use_enc_certificate_file(SSL_CTX *ctx, const char *file, int type); __owur int SSL_CTX_use_enc_certificate(SSL_CTX *ctx, X509 *x); -__owur int SSL_CTX_use_enc_certificate_chain_file(SSL_CTX *ctx, const char *file); #endif __owur int SSL_CTX_use_certificate_file(SSL_CTX *ctx, const char *file, int type); diff --git a/ssl/s3_lib.c b/ssl/s3_lib.c index 55d263e8..7ed0dc33 100644 --- a/ssl/s3_lib.c +++ b/ssl/s3_lib.c @@ -5036,7 +5036,10 @@ int ssl_derive_SM2(SSL *s, EVP_PKEY *privkey, EVP_PKEY *pubkey, int gensecret) } /*查找第一个数据加密功能的证书,作为加密证书使用,跟排列顺序无关*/ - for(i=0; isession->peer_chain); i++){ + //for(i=0; isession->peer_chain); i++){ + + /*从链表最后开始,查找第一个数据加密功能的证书,作为加密证书使用,跟排列顺序无关*/ + for(i=sk_X509_num(s->session->peer_chain)-1; i>=0; i--){ if((X509_get_extension_flags(sk_X509_value(s->session->peer_chain, i)) & EXFLAG_KUSAGE) && (X509_get_key_usage(sk_X509_value(s->session->peer_chain, i)) & X509v3_KU_DATA_ENCIPHERMENT)) break; } diff --git a/ssl/statem/statem_clnt.c b/ssl/statem/statem_clnt.c index fe84ced8..aced497e 100644 --- a/ssl/statem/statem_clnt.c +++ b/ssl/statem/statem_clnt.c @@ -2220,7 +2220,8 @@ static int tls_process_ske_ecdhe(SSL *s, PACKET *pkt, EVP_PKEY **pkey) SSL_R_LENGTH_TOO_SHORT); return 0; } - if(curve_id == 0) + //At present, because there is no definite explanation, when the protocol is CNTLS, the default 249 will be used as sm2 curve ID + if( s->version == SM1_1_VERSION && curve_id != 249) curve_id = 249; //if none curve id ,set it to sm2 249 defined by tass /* * Check curve is named curve type and one of our preferences, if not @@ -2347,9 +2348,8 @@ MSG_PROCESS_RETURN tls_process_key_exchange(SSL *s, PACKET *pkt) goto err; sm2_certs_len = 0; - /*查找第一个数据加密功能的证书,作为加密证书使用,跟排列顺序无关*/ - for(i=0; isession->peer_chain); i++){ - + /*从链表最后开始,查找第一个数据加密功能的证书,作为加密证书使用,跟排列顺序无关*/ + for(i=sk_X509_num(s->session->peer_chain)-1; i>=0; i--){ if((X509_get_extension_flags(sk_X509_value(s->session->peer_chain, i)) & EXFLAG_KUSAGE) && (X509_get_key_usage(sk_X509_value(s->session->peer_chain, i)) & X509v3_KU_DATA_ENCIPHERMENT)) break; } @@ -3175,8 +3175,8 @@ static int tls_construct_cke_sm2ecc(SSL *s, WPACKET *pkt) return 0; } - /*查找第一个数据加密功能的证书,作为加密证书使用,跟排列顺序无关*/ - for(i=0; isession->peer_chain); i++){ + /*从链表最后开始,查找第一个数据加密功能的证书,作为加密证书使用,跟排列顺序无关*/ + for(i=sk_X509_num(s->session->peer_chain)-1; i>=0; i--){ if((X509_get_extension_flags(sk_X509_value(s->session->peer_chain, i)) & EXFLAG_KUSAGE) && (X509_get_key_usage(sk_X509_value(s->session->peer_chain, i)) & X509v3_KU_DATA_ENCIPHERMENT)) break; } @@ -3229,13 +3229,23 @@ static int tls_construct_cke_sm2ecc(SSL *s, WPACKET *pkt) ERR_R_EVP_LIB); goto err; } - + + /* if (!WPACKET_allocate_bytes(pkt, enclen, &encdata) || EVP_PKEY_encrypt(pctx, encdata, &enclen, pms, pmslen) <= 0) { SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_CKE_SM2ECC, SSL_R_BAD_RSA_ENCRYPT); goto err; + }*/ + if (!WPACKET_reserve_bytes(pkt, enclen, &encdata) + || EVP_PKEY_encrypt(pctx, encdata, &enclen, pms, pmslen) <= 0) { + SSLfatal(s, SSL_AD_INTERNAL_ERROR, SSL_F_TLS_CONSTRUCT_CKE_SM2ECC, + SSL_R_BAD_RSA_ENCRYPT); + goto err; } + pkt->written += enclen; //签名时分配的字节数为最大的022100,所以真正签名完成时要设置真实数值,因为有的服务端不认后面带00的加密密文 + pkt->curr += enclen; + EVP_PKEY_CTX_free(pctx); pctx = NULL; diff --git a/ssl/statem/statem_srvr.c b/ssl/statem/statem_srvr.c index 0703b139..3c549894 100644 --- a/ssl/statem/statem_srvr.c +++ b/ssl/statem/statem_srvr.c @@ -2681,10 +2681,11 @@ int tls_construct_server_key_exchange(SSL *s, WPACKET *pkt) /* Get NID of appropriate shared curve */ curve_id = tls1_shared_group(s, -2); if (curve_id == 0) { - SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, + curve_id = 249; //modify by TASS Gujq for guomiju test, cause they use the 00 for sm2 + /*SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE, SSL_F_TLS_CONSTRUCT_SERVER_KEY_EXCHANGE, SSL_R_UNSUPPORTED_ELLIPTIC_CURVE); - goto err; + goto err;*/ } s->s3->tmp.pkey = ssl_generate_pkey_group(s, curve_id); /* Generate a new key for this curve */ diff --git a/tassl_demo/README.txt b/tassl_demo/README.txt index 2bcc0cb6..eab4407a 100644 --- a/tassl_demo/README.txt +++ b/tassl_demo/README.txt @@ -1,8 +1,16 @@ +20200823_V_1.4: +1.淇敼鏌ユ壘鍔犲瘑璇佷功閫昏緫锛氫粠璇佷功閾剧殑鏈鍚庝竴涓紑濮嬫煡鎵,鎵惧埌绗竴涓甫鏈夋暟鎹姞瀵嗗姛鑳界殑璇佷功鍚庯紝浣滀负鍔犲瘑璇佷功銆 +2.淇敼client_key_exchange鏃讹紝绛惧悕鏃跺垎閰嶇殑瀛楄妭鏁颁负鏈澶х殑022100锛屾墍浠ョ湡姝g鍚嶅畬鎴愭椂瑕佽缃湡瀹炴暟鍊硷紝鍥犱负鏈夌殑鏈嶅姟绔笉璁ゅ悗闈㈠甫00鐨勫姞瀵嗗瘑鏂囥 + 20200526_V_1.3: 1:浼樺寲鍙栧姞瀵嗚瘉涔︾殑閫昏緫锛屽湪璇佷功鏍堜腑鏌ユ壘绗竴涓叿鏈夋暟鎹姞瀵嗙殑鐢ㄩ旂殑璇佷功浣滀负鍔犲瘑璇佷功銆 2:灞忚斀鎺夊綋鍥藉瘑鐗堟湰涓0x0101鏃讹紝涓嶈杩涜downgrade锛岄槻姝sl_fill_hello_random()闅忔満鏁扮殑鏈鍚8瀛楄妭琚~鍏呬负鍥哄畾鍊笺 3:榛樿鐨剆m2 curve_id涓00锛 濡傛灉鐢249鍒欐潯浠剁紪璇 -DSTD_CURVE_ID; 榛樿鐨剆m2绉橀挜鍗忓晢鐢╖B+ZA鐨勯『搴忥紝濡傛灉闇瑕侀鍊掞紝鏉′欢缂栬瘧-DSTD_ZAZB. 4.淇敼tls_construct_cke_sm2dh()涓紝浣跨敤绛惧悕绉侀挜鐨勫紩鎿庢潵浜х敓涓存椂绉橀挜瀵癸紝濡傛灉涓嶅瓨鍦紝鍒欎娇鐢ㄨ蒋绠楁硶浜х敓銆 +5.澧炲姞ECDSA_sign涓綋eckey瀛樺湪sign鏂规硶锛屼笖璁剧疆浜咵C_FLAG_TASS_CUSTOM_SIGN鏍囧織鍚庯紝璋冪敤eckey涓殑鏂规硶銆 +6.澧炲姞鏀寔SSL鎻℃墜鏃惰繘琛岃8绛炬爣蹇楋紝EC_FLAG_TASS_NO_Z_SIGN,閫氳繃EC_KEY_set_flags()璁剧疆銆 +7.openssl sm4-cbc鏀寔閫氳繃-K 40鎸囧畾浣跨敤tasscard_sm4寮曟搸杩涜鍔犺В瀵嗛氳繃40鍙风储寮曠殑绉橀挜銆 +8.澧炲姞card_engine 鐩綍锛屾彁渚涜皟鐢ㄥ崱鐨勪緥瀛愩 20200328_V_1.2: 1:璋冩暣鍙橀噺澹版槑浣嶇疆锛屾敮鎸乄indows涓64浣嶇紪璇戙 diff --git a/tassl_demo/card_engine/mk.sh b/tassl_demo/card_engine/mk.sh new file mode 100644 index 00000000..facf1e6e --- /dev/null +++ b/tassl_demo/card_engine/mk.sh @@ -0,0 +1,16 @@ +#!/bin/sh +LIB_DIR=/root/tasscard_engine/tassl/lib +INC_DIR=/root/tasscard_engine/tassl/include +PROGRAMES="sm2_evp_keygen sm2_evp_dec sm2_evp_enc_dec sm2_evp_digest_sign_verify sm4_evp" + +if [ $1"X" == "cleanX" ]; then +printf "cleaning the programe %s.....\n" $PROGRAMES + rm -rf ${PROGRAMES} +else +printf "compiling the programe.....\n" +gcc -ggdb3 -O0 -o sm2_evp_keygen sm2_evp_keygen.c -I${INC_DIR} -L${LIB_DIR} -lssl -L${LIB_DIR} -lcrypto -ldl -lpthread +gcc -ggdb3 -O0 -o sm2_evp_dec sm2_evp_dec.c -I${INC_DIR} -L${LIB_DIR} -lssl -L${LIB_DIR} -lcrypto -ldl -lpthread +gcc -ggdb3 -O0 -o sm2_evp_enc_dec sm2_evp_enc_dec.c -I${INC_DIR} -L${LIB_DIR} -lssl -L${LIB_DIR} -lcrypto -ldl -lpthread +gcc -ggdb3 -O0 -o sm2_evp_digest_sign_verify sm2_evp_digest_sign_verify.c -I${INC_DIR} -L${LIB_DIR} -lssl -L${LIB_DIR} -lcrypto -ldl -lpthread +gcc -ggdb3 -O0 -o sm4_evp sm4_evp.c -I${INC_DIR} -L${LIB_DIR} -lssl -L${LIB_DIR} -lcrypto -ldl -lpthread +fi diff --git a/tassl_demo/card_engine/sm2_evp_dec.c b/tassl_demo/card_engine/sm2_evp_dec.c new file mode 100644 index 00000000..c724b08f --- /dev/null +++ b/tassl_demo/card_engine/sm2_evp_dec.c @@ -0,0 +1,120 @@ +#include +#include +#include +#include +#include "openssl/evp.h" +#include "openssl/ec.h" +#include "openssl/engine.h" + + +int h2b(char *hex_in, char *bin_out) +{ + int i,ret; + char tmpbuf[3] = {0}; + char *ptr = hex_in; + + for(i = 0; i +#include +#include +#include +#include "openssl/evp.h" +#include "openssl/ec.h" +#include "openssl/engine.h" + + +int main(int argc, char *argv[]) +{ + EVP_PKEY *pkey = NULL; + EVP_PKEY *pkey_card = NULL; + EVP_MD_CTX *md_ctx = NULL; + unsigned char *sig = NULL; + unsigned char *out = NULL; + size_t len; + int loop; + + + if (argc < 3) + { + printf("Usage: \n\t%s key_index message\n", argv[0]); + exit(0); + } + + OpenSSL_add_all_algorithms(); + ENGINE_load_builtin_engines(); + + /*1111111 初始化引擎 */ + const char *engine_name_sm2 = "tasscard_sm2"; + ENGINE *tasscardsm2_e = NULL; + + if ((tasscardsm2_e = ENGINE_by_id(engine_name_sm2)) == NULL) { + printf("ENGINE load id=[%s] fail!\n", engine_name_sm2); + exit(0); + } + else{ + ENGINE_init(tasscardsm2_e); + } + + + /*222222 通过引擎索引加载签名私钥 */ + pkey_card = ENGINE_load_private_key(tasscardsm2_e, argv[1], NULL, NULL); + if(pkey_card == NULL){ + printf("ENGINE_load_private_key fail, key_index =[%s]\n", argv[1]); + goto err; + } + + + /*333333 签名 */ + len = EVP_PKEY_size(pkey_card); + sig = OPENSSL_malloc(len); + if (!sig) + { + printf("Alloc Memory Error.\n"); + goto err; + } + + md_ctx = EVP_MD_CTX_create(); + if (!md_ctx) + { + printf("Error of Create EVP_MD_CTX Object Error.\n"); + goto err; + } + + EVP_MD_CTX_init(md_ctx); + if (EVP_DigestSignInit(md_ctx, NULL, EVP_sm3(), NULL, pkey_card) != 1) + { + printf("Init DigestSign CTX Error.\n"); + goto err; + } + + EVP_DigestSignUpdate(md_ctx, argv[2], strlen(argv[2])); + EVP_DigestSignFinal(md_ctx, sig, &len); + + printf("[%s] SM2 Signature: [", argv[2]); + for (loop = 0; loop < len; loop++) + printf("%02X", sig[loop] & 0xff); + printf("]\n"); + + EVP_MD_CTX_destroy(md_ctx); + + + /*444444 延签 */ + md_ctx = EVP_MD_CTX_create(); + if (!md_ctx) + goto err; + + EVP_MD_CTX_init(md_ctx); + if (EVP_DigestVerifyInit(md_ctx, NULL, EVP_sm3(), NULL, pkey_card) != 1) + { + printf("Init DigestVerify CTX Error.\n"); + goto err; + } + + EVP_DigestVerifyUpdate(md_ctx, argv[2], strlen(argv[2])); + loop = EVP_DigestVerifyFinal(md_ctx, (const unsigned char *)sig, len); + if (loop <= 0) + { + printf("EVP_DigestVerify Error.\n"); + } + else + { + printf("EVP_DigestVerify Successed.\n"); + } + +err: + if (pkey_card) EVP_PKEY_free(pkey_card); + if (md_ctx) EVP_MD_CTX_destroy(md_ctx); + if (sig) OPENSSL_free(sig); + if (out) OPENSSL_free(out); + + if(tasscardsm2_e){ + ENGINE_finish(tasscardsm2_e); + ENGINE_free(tasscardsm2_e); + } + + return 0; +} diff --git a/tassl_demo/card_engine/sm2_evp_enc_dec.c b/tassl_demo/card_engine/sm2_evp_enc_dec.c new file mode 100644 index 00000000..4f38b412 --- /dev/null +++ b/tassl_demo/card_engine/sm2_evp_enc_dec.c @@ -0,0 +1,142 @@ +#include +#include +#include +#include +#include "openssl/evp.h" +#include "openssl/ec.h" +#include "openssl/engine.h" + +int main(int argc, char *argv[]) +{ + EVP_PKEY *pkey_card = NULL; + EVP_PKEY_CTX *pctx = NULL; + EVP_PKEY_CTX *pctx_dec = NULL; + size_t cipher_len; + size_t plain_len; + unsigned char *cipher = NULL; + unsigned char *plain = NULL; + int retval; + + if (argc < 3) + { + printf("Usage: \n\t%s key_index text\n", argv[0]); + return 0; + } + + ENGINE_load_builtin_engines(); + + /*111111 初始化引擎*/ + const char *engine_name_sm2 = "tasscard_sm2"; + ENGINE *tasscardsm2_e = NULL; + + if ((tasscardsm2_e = ENGINE_by_id(engine_name_sm2)) == NULL) { + printf("ENGINE load id=[%s] fail!\n", engine_name_sm2); + exit(0); + } + else{ + ENGINE_init(tasscardsm2_e); + } + + /*222222 通过引擎索引号加载私钥 */ + pkey_card = ENGINE_load_private_key(tasscardsm2_e, argv[1], NULL, NULL); + if(pkey_card == NULL){ + printf("ENGINE_load_private_key fail, key_index =[%s]\n", argv[1]); + goto err; + } + + /*333333 加密 */ + pctx = EVP_PKEY_CTX_new(pkey_card, NULL); + if (!pctx) + { + printf("Create EVP_PKEY_CTX Error.\n"); + goto err; + } + + if (EVP_PKEY_encrypt_init(pctx) <= 0) + { + printf("Error Of EVP_PKEY_encrypt_init.\n"); + goto err; + } + + EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_TYPE_CRYPT, EVP_PKEY_CTRL_MD, 0, (void *)EVP_sm3()); + + /*Calculate Cipher Text Length*/ + if (EVP_PKEY_encrypt(pctx, NULL, &cipher_len, (const unsigned char *)argv[2], (size_t)strlen(argv[2])) != 1) + { + printf("Calculate SM2 Cipher text length error.\n"); + goto err; + } + + cipher = OPENSSL_malloc(cipher_len); + if (!cipher) + { + printf("Error Of Alloc memory.\n"); + goto err; + } + + if (EVP_PKEY_encrypt(pctx, cipher, &cipher_len, (const unsigned char *)argv[2], (size_t)strlen(argv[2])) != 1) + { + printf("EVP_PKEY_encrypt error.\n"); + goto err; + } + + printf("[%s] SM2 Encrypt Cipher Text:\n\tLength: [%ld]\n\tContent: [", argv[2], cipher_len); + for (retval = 0; retval < cipher_len; retval++) + printf("%02X", cipher[retval] & 0xff); + printf("]\n"); + + + /*444444 解密 */ + pctx_dec = EVP_PKEY_CTX_new(pkey_card, NULL); + if (!pctx_dec) + { + printf("Create EVP_PKEY_CTX Error.\n"); + goto err; + } + + if (EVP_PKEY_decrypt_init(pctx_dec) <= 0) + { + printf("Error Of EVP_PKEY_encrypt_init.\n"); + goto err; + } + + /*Set SM2 Encrypt EVP_MD. If it not set, SM2 default is EVP_sm3(), Other curve default is sha1*/ + EVP_PKEY_CTX_ctrl(pctx_dec, -1, EVP_PKEY_OP_TYPE_CRYPT, EVP_PKEY_CTRL_MD, 0, (void *)EVP_sm3()); + + /*Calculate plain text length*/ + if (EVP_PKEY_decrypt(pctx_dec, NULL, &plain_len, (const unsigned char *)cipher, cipher_len) != 1) + { + printf("Calculate SM2 plain text length error.\n"); + goto err; + } + + plain = OPENSSL_malloc(plain_len+1); + if (!plain) + { + printf("Error Of Alloc Memory.\n"); + goto err; + } + + memset(plain, 0, plain_len); + if (EVP_PKEY_decrypt(pctx_dec, plain, &plain_len, (const unsigned char *)cipher, cipher_len) != 1) + { + printf("Error Of EVP_PKEY_decrypt.\n"); + goto err; + } + plain[plain_len] = '\0'; + + printf("[%s] SM2 Decrypt plain Text:\n\tLength: [%ld]\n\tContent: [%s]\n", argv[2], plain_len, (char *)plain); + +err: + if (pkey_card) EVP_PKEY_free(pkey_card); + if (pctx) EVP_PKEY_CTX_free(pctx); + if (pctx_dec) EVP_PKEY_CTX_free(pctx_dec); + if (cipher) OPENSSL_free(cipher); + if (plain) OPENSSL_free(plain); + + if(tasscardsm2_e){ + ENGINE_finish(tasscardsm2_e); + ENGINE_free(tasscardsm2_e); + } + return 0; +} diff --git a/tassl_demo/card_engine/sm2_evp_keygen.c b/tassl_demo/card_engine/sm2_evp_keygen.c new file mode 100644 index 00000000..3de90515 --- /dev/null +++ b/tassl_demo/card_engine/sm2_evp_keygen.c @@ -0,0 +1,97 @@ +/* + * Written by Gujq for the TaSSL project. + */ + +#include +#include +#include +#include +#include "openssl/evp.h" +#include "openssl/ec.h" +#include "openssl/engine.h" + +int main(int argc, char *argv[]) +{ + const EC_GROUP *group = NULL; + EVP_PKEY *pkey = NULL; + EVP_PKEY_CTX *pctx = NULL; + unsigned char *out = NULL; + size_t len; + int loop; + + if (argc < 2) + { + printf("Usage: %s key_index\n", argv[0]); + exit(0); + } + + OpenSSL_add_all_algorithms(); + ENGINE_load_builtin_engines(); + + /*111111 初始化引擎*/ + const char *engine_name_sm2 = "tasscard_sm2"; + ENGINE *tasscardsm2_e = NULL; + + if ((tasscardsm2_e = ENGINE_by_id(engine_name_sm2)) == NULL) { + printf("ENGINE load id=[%s] fail!\n", engine_name_sm2); + exit(0); + } + else{ + ENGINE_init(tasscardsm2_e); + } + + /*222222 通过卡引擎生成密钥对,以索引号存放在卡中*/ + pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_SM2, tasscardsm2_e); + if (!pctx) + { + printf("Create EVP_PKEY_CTX Object error.\n"); + goto err; + } + + EVP_PKEY_keygen_init(pctx); + if (!EVP_PKEY_CTX_set_sm2_paramgen_curve_nid(pctx, NID_sm2)) + { + printf("Set EC curve name error.\n"); + goto err; + } + + if (!EVP_PKEY_CTX_set_ec_param_enc(pctx, OPENSSL_EC_NAMED_CURVE)) + { + printf("Set EC curve is named curve error.\n"); + goto err; + } + + EVP_PKEY_CTX_set_app_data(pctx, (void*)argv[1]); + + if (EVP_PKEY_keygen(pctx, &pkey) != 1) + { + printf("Generate SM2 key error.\n"); + goto err; + } + + /*OUTPUT EVP PKEY*/ + len = i2d_PublicKey(pkey, &out); + if (len <= 0) + { + printf("Output SM2 Public Key Error.\n"); + goto err; + } + + printf("Generated SM2 PUB Key: ["); + for (loop = 0; loop < len; loop++) + printf("%02X", out[loop] & 0xff); + printf("]\n"); + + +err: + if (pkey) EVP_PKEY_free(pkey); + if (pctx) EVP_PKEY_CTX_free(pctx); + if (out) OPENSSL_free(out); + + if(tasscardsm2_e){ + ENGINE_finish(tasscardsm2_e); + ENGINE_free(tasscardsm2_e); + } + + return 0; +} diff --git a/tassl_demo/card_engine/sm4_evp.c b/tassl_demo/card_engine/sm4_evp.c new file mode 100644 index 00000000..00967621 --- /dev/null +++ b/tassl_demo/card_engine/sm4_evp.c @@ -0,0 +1,78 @@ +#include +#include +#include +#include +#include +#include +#include "openssl/ssl.h" +#include "openssl/err.h" +#include "openssl/sm4.h" +#include "openssl/engine.h" + + +int main(int argc, char **argv) +{ + unsigned char iv[] = "1234567812345678"; + EVP_CIPHER_CTX *ctx = NULL; + unsigned char outbuf[1024] = {0}; + char *inbuf = "1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890"; + int outlen = 0; + int tmplen = 0; + + if (argc < 2) + { + printf("Usage: \n\t%s key_index\n", argv[0]); + return 0; + } + + + OpenSSL_add_all_algorithms(); + SSL_load_error_strings(); + const char *engine_name_sm4 = "tasscard_sm4"; + ENGINE *tasscardsm4_e = NULL; + + if ((tasscardsm4_e = ENGINE_by_id(engine_name_sm4)) == NULL) { + printf("ENGINE load id=[%s] fail!\n", engine_name_sm4); + exit(0); + } + else{ + ENGINE_init(tasscardsm4_e); + ENGINE_register_ciphers(tasscardsm4_e); + ENGINE_set_default_RAND(tasscardsm4_e); + } + + + if((ctx = EVP_CIPHER_CTX_new()) == NULL){ + printf("ctx new fail!\n"); + exit(0); + } + EVP_CIPHER_CTX_init(ctx); + + //浣跨敤寮曟搸锛屽湪鍔犲瘑鍗′腑鐢熸垚50鍙稴M4绉橀挜锛屽苟鍒濆鍖 + EVP_CipherKeygen(ctx, tasscardsm4_e, NID_sm4_cbc, NULL, argv[1]); + EVP_CipherInit_ex(ctx, EVP_sm4_cbc(), tasscardsm4_e, argv[1], iv, 1); + + if(!EVP_CipherUpdate(ctx, outbuf, &outlen, inbuf, strlen(inbuf))) + { + printf("EVP_CipherUpdate fail!\n"); + return 0; + } + + if(!EVP_EncryptFinal_ex(ctx, outbuf + outlen, &tmplen)) + { + printf("EVP_EncryptFinal_ex fail!\n"); + return 0; + } + outlen += tmplen; + + printf("Cipherd by SM4:"); + int i =0; + for(i=0; i #include #include #include #include #include -#include +#include "openssl/ssl.h" +#include "openssl/err.h" #include "openssl/sm4.h" +#include "openssl/engine.h" -uint32_t run; - -void time_out(int sig) -{ - signal(SIGALRM, time_out); - run = 0; -} -const char *test1result = "\x68\x1E\xDF\x34\xD2\x06\x96\x5E\x86\xB3\xE9\x4F\x53\x6E\x42\x46"; -const char *test2result = "\x59\x52\x98\xC7\xC6\xFD\x27\x1F\x04\x02\xF8\x04\xC3\x3D\x3F\x66"; int main(int argc, char **argv) { - unsigned char key[] = "0123456789"; - unsigned char iv[] = "12345678"; + unsigned char key[] = "1234567890123456"; + unsigned char iv[] = "1234567812345678"; EVP_CIPHER_CTX *ctx = NULL; unsigned char outbuf[1024] = {0}; char *inbuf = "1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890"; int outlen = 0; int tmplen = 0; - if((ctx = EVP_CIPHER_CTX_new()) == NULL){ - printf("ctx new fail!\n"); - exit(0); + printf("ctx new fail!\n"); + exit(0); } - EVP_CIPHER_CTX_init(ctx); - EVP_CipherInit_ex(ctx, EVP_sm4_ecb(), NULL, key, iv, 1); - - //EVP_CIPHER_CTX_set_key_length(ctx, 10); - //瀹屾瘯鍙冩暟璁剧疆銆傝繘琛宬ey鍜孖V鐨勮缃 - //EVP_CipherInit_ex(ctx, NULL, NULL, key, iv, do_encrypt); + EVP_CipherInit_ex(ctx, EVP_sm4_cbc(), NULL, key, iv, 1); if(!EVP_CipherUpdate(ctx, outbuf, &outlen, inbuf, strlen(inbuf))) { - /*鍑洪敊澶勭悊 */ - return 0; + printf("EVP_CipherUpdate fail!\n"); + return 0; } if(!EVP_EncryptFinal_ex(ctx, outbuf + outlen, &tmplen)) - { - /* 鍑洪敊澶勭悊*/ - return 0; - } + { + printf("EVP_EncryptFinal_ex fail!\n"); + return 0; + } outlen += tmplen; - + printf("Cipherd by SM4:"); + int i =0; + for(i=0; i