diff --git a/docs/api/tsapi.md b/docs/api/tsapi.md new file mode 100644 index 0000000..cfaf906 --- /dev/null +++ b/docs/api/tsapi.md @@ -0,0 +1,168 @@ +# 概述 + +Tongsuo密码库给应用程序提供的API,包括获取熵、生成随机数、SM2密钥对生成、SM2签名、SM2验签、SM2加密、SM2解密、SM2密钥导入、SM2密钥导出、 +SM2密钥信封导入、SM2密钥信封导出、SM2密钥生成、SM2密钥删除、SM2密钥更新、SM4加密、SM4解密、SM3杂凑等功能。 + +部分密钥管理接口,通常包含index入参,需要密码设备支持,比如密码卡或密码机,TSAPI通常调用密码设备提供的SDF接口来实现。 + +## 头文件和函数原型 + +```c +#include + +unsigned char *TSAPI_GetEntropy(int entropy, size_t *outlen); +void TSAPI_FreeEntropy(unsigned char *ent, size_t len); +char *TSAPI_Version(void); +unsigned char *TSAPI_RandBytes(size_t len); + +# ifndef OPENSSL_NO_SM2 +EVP_PKEY *TSAPI_SM2Keygen(void); +# ifndef OPENSSL_NO_SM3 +unsigned char *TSAPI_SM2Sign(EVP_PKEY *key, const unsigned char *tbs, + size_t tbslen, size_t *siglen); +int TSAPI_SM2Verify(EVP_PKEY *key, const unsigned char *tbs, size_t tbslen, + const unsigned char *sig, size_t siglen); +# endif +unsigned char *TSAPI_SM2Encrypt(EVP_PKEY *key, const unsigned char *in, + size_t inlen, size_t *outlen); +unsigned char *TSAPI_SM2Decrypt(EVP_PKEY *key, const unsigned char *in, + size_t inlen, size_t *outlen); +unsigned char *TSAPI_SM2EncryptWithISK(int isk, const unsigned char *in, + size_t inlen, size_t *outlen); +unsigned char *TSAPI_SM2DecryptWithISK(int isk, const unsigned char *in, + size_t inlen, size_t *outlen); +unsigned char *TSAPI_ECCCipher_to_SM2Ciphertext(const OSSL_ECCCipher *ecc, + size_t *ciphertext_len); +OSSL_ECCCipher *TSAPI_SM2Ciphertext_to_ECCCipher(const unsigned char *ciphertext, + size_t ciphertext_len); +int TSAPI_ImportSM2Key(int index, int sign, const char *user, + const char *password, const EVP_PKEY *sm2_pkey); +EVP_PKEY *TSAPI_ExportSM2KeyWithIndex(int index, int sign, const char *user, + const char *password); +OSSL_ECCrefPublicKey *TSAPI_EVP_PKEY_get_ECCrefPublicKey(const EVP_PKEY *pkey); +OSSL_ECCrefPrivateKey *TSAPI_EVP_PKEY_get_ECCrefPrivateKey(const EVP_PKEY *pkey); +EVP_PKEY *TSAPI_EVP_PKEY_new_from_ECCrefKey(const OSSL_ECCrefPublicKey *pubkey, + const OSSL_ECCrefPrivateKey *privkey); +int TSAPI_ImportSM2KeyWithEvlp(int index, int sign, const char *user, + const char *password, unsigned char *key, + size_t keylen, unsigned char *dek, + size_t deklen); +int TSAPI_ExportSM2KeyWithEvlp(int index, int sign, const char *user, + const char *password, EVP_PKEY *sm2_pubkey, + unsigned char **priv, size_t *privlen, + unsigned char **pub, size_t *publen, + unsigned char **outevlp, size_t *outevlplen); +int TSAPI_GenerateSM2KeyWithIndex(int index, int sign, const char *user, const char *password); +int TSAPI_DelSm2KeyWithIndex(int index, int sign, const char *user, + const char *password); +int TSAPI_UpdateSm2KeyWithIndex(int index, int sign, const char *user, + const char *password); +EVP_PKEY *TSAPI_ExportSM2PubKeyWithIndex(int index, int sign); +# endif + +# ifndef OPENSSL_NO_SM4 +unsigned char *TSAPI_SM4Encrypt(int mode, const unsigned char *key, + size_t keylen, int isk, + const unsigned char *iv, + const unsigned char *in, size_t inlen, + size_t *outlen); +unsigned char *TSAPI_SM4Decrypt(int mode, const unsigned char *key, + size_t keylen, int isk, + const unsigned char *iv, + const unsigned char *in, size_t inlen, + size_t *outlen); +# endif +# ifndef OPENSSL_NO_SM3 +unsigned char *TSAPI_SM3(const void *data, size_t datalen, size_t *outlen); +# endif +``` + +## 函数说明 + +TSAPI_GetEntropy()用户获取具有entropy熵值的熵,输出缓冲区的长度为*outlen, outlen不能为NULL。TSAPI_GetEntropy()返回的缓冲区需要通过调 +用TSAPI_FreeEntropy()释放。 + +TSAPI_FreeEntropy()用于释放TSAPI_GetEntropy()返回的缓冲区,len应该是缓冲区ent的实际长度。 + +TSAPI_Version()返回Tongsuo的版本号字符串,注意:返回的字符串是动态分配的,需要调用OPENSSL_free()释放。 + +TSAPI_RandBytes()生成len字节的随机数;返回的缓冲区需要通过调用OPENSSL_free()释放。 + +TSAPI_SM2Keygen()生成一个SM2密钥对,返回的EVP_PKEY对象需要通过调用EVP_PKEY_free()释放。 + +TSAPI_SM2Sign()使用SM2密钥key对长度为tbslen的数据tbs进行签名,返回签名值,签名值的长度通过*siglen返回,返回的缓冲区需要通过调用 +OPENSSL_free()释放。 + +TSAPI_SM2Verify()使用SM2密钥key对长度为tbslen的数据tbs,长度为siglen的签名sig进行验证,返回1表示验证成功,0表示验证失败。 + +TSAPI_SM2Encrypt()使用SM2密钥key对长度为inlen的数据in进行加密,返回加密后的数据,加密后的数据长度通过*outlen返回,返回的缓冲区需要通过调 +用OPENSSL_free()释放。 + +TSAPI_SM2Decrypt()使用SM2密钥key对长度为inlen的数据in进行解密,返回解密后的数据,解密后的数据长度通过*outlen返回,返回的缓冲区需要通过调 +用OPENSSL_free()释放。 + +TSAPI_SM2EncryptWithISK()使用索引为isk的SM2密钥对长度为inlen的数据in进行加密,返回加密后的数据,加密后的数据长度通过*outlen返回,返回的 +缓冲区需要通过调用OPENSSL_free()释放。 + +TSAPI_SM2DecryptWithISK()使用索引为isk的SM2密钥对长度为inlen的数据in进行解密,返回解密后的数据,解密后的数据长度通过*outlen返回,返回的 +缓冲区需要通过调用OPENSSL_free()释放。 + +TSAPI_ECCCipher_to_SM2Ciphertext()将OSSL_ECCCipher对象ecc转换为SM2密文,返回SM2密文,SM2密文的长度通过ciphertext_len返回,返回的 +缓冲区需要调用OPENSSL_free()释放。 + +TSAPI_SM2Ciphertext_to_ECCCipher()将SM2密文ciphertext转换为OSSL_ECCCipher对象,返回OSSL_ECCCipher对象;返回的OSSL_ECCCipher对 +象需要调用OPENSSL_free()释放。 + +TSAPI_ImportSM2Key()将EVP_PKEY对象sm2_pkey导入到索引为index的SM2密码设备中,sign为1表示签名私钥,为0表示加密公钥,user和password为密 +码设备的用户名和密码。 + +TSAPI_ExportSM2KeyWithIndex()从索引为index的SM2密码设备中导出密钥,sign为1表示导出签名私钥,为0表示导出加密公钥,user和password为密码 +设备的用户名和密码。 + +TSAPI_EVP_PKEY_get_ECCrefPublicKey()从EVP_PKEY对象pkey中获取OSSL_ECCrefPublicKey对象;返回的对象需要调用OPENSSL_free()释放。 + +TSAPI_EVP_PKEY_get_ECCrefPrivateKey()从EVP_PKEY对象pkey中获取OSSL_ECCrefPrivateKey对象;返回的对象需要调用OPENSSL_free()释放。 + +TSAPI_EVP_PKEY_new_from_ECCrefKey()从OSSL_ECCrefPublicKey对象pubkey和OSSL_ECCrefPrivateKey对象privkey创建EVP_PKEY对象;返回的 +对象需要调用EVP_PKEY_free()释放。 + +TSAPI_ImportSM2KeyWithEvlp()通过信封方式导入SM2密钥,导入的密钥key长度为keylen,这里的密钥key为密文,使用dek加密,dek长度为deklen,加 +密算法为SM4,dek使用设备加密密钥加密(SM2私钥)。导入后的索引为index;sign为1表示签名私钥,为0表示加密公钥,user和password为密码设备的用户 +名和密码。 + +TSAPI_ExportSM2KeyWithEvlp()通过信封方式导出SM2密钥,导出的密钥索引为index,sign为1表示签名私钥,为0表示加密公钥,user和password为密码 +设备的用户名和密码;返回的信封数据outevlp,长度保存在*outevlplen,需要调用OPENSSL_free()释放;返回的公私钥数据pub和priv,长度保存在 +*publen和*privlen,需要调用OPENSSL_free()释放。信封outevlp中包含加密SM2密钥的对称密钥,对称密钥使用sm2_pubkey加密。 + +TSAPI_ImportSM2KeyWithEvlp()和TSAPI_ExportSM2KeyWithEvlp()是密码设备实现相关的,需要密码设备支持,并且成对使用。 + +TSAPI_GenerateSM2KeyWithIndex()生成一个SM2密钥对,索引为index,sign为1表示签名私钥,为0表示加密公钥,user和password为密码设备的用户名 +和密码。 + +TSAPI_DelSm2KeyWithIndex()删除索引为index的SM2密钥,sign为1表示签名私钥,为0表示加密公钥,user和password为密码设备的用户名和密码。 + +TSAPI_UpdateSm2KeyWithIndex()更新索引为index的SM2密钥,sign为1表示签名私钥,为0表示加密公钥,user和password为密码设备的用户名和密码。 + +TSAPI_ExportSM2PubKeyWithIndex()导出索引为index的SM2公钥,sign为1表示签名私钥,为0表示加密公钥。 + +TSAPI_SM4Encrypt()使用SM4算法对长度为inlen的数据in进行加密,key为密钥,keylen为密钥长度,mode为加密模式,iv为初始向量;isk内部加密密钥 +的索引,如果isk小于0,即索引无效时,key为明文,否则当isk >=0时,key为密文,表示key使用isk代表的SM2公钥加密;返回加密后的数据,加密后的数据 +长度通过*outlen返回,返回的缓冲区需要通过调用OPENSSL_free()释放。 + +TSAPI_SM4Decrypt()使用SM4算法对长度为inlen的数据in进行解密,key为密钥,keylen为密钥长度,mode为解密模式,iv为初始向量;isk内部加密密钥 +的索引,如果isk小于0,即索引无效时,key为明文,否则当isk >=0时,key为密文,表示key使用isk代表的SM2公钥解密;返回解密后的数据,解密后的数据 +长度通过*outlen返回,返回的缓冲区需要通过调用OPENSSL_free()释放。 + +TSAPI_SM3()计算长度为datalen的数据data的SM3杂凑值,返回SM3杂凑值,杂凑值的长度通过*outlen返回,返回的缓冲区需要通过调用OPENSSL_free() +释放。 + +## 返回值说明 + +返回int类型的函数,返回值为1表示成功,0表示失败。 + +返回指针类型的函数,比如unsigned char *, EVP_PKEY *,OSSL_ECCCipher *,OSSL_ECCrefPublicKey *,OSSL_ECCrefPrivateKey *等, +返回NULL表示失败,非NULL表示成功。 + +## 历史 + +TSAPI_*函数在Tongsuo 8.5.0版本中引入。 diff --git a/docs/api/tsapi_sdf.md b/docs/api/tsapi_sdf.md new file mode 100644 index 0000000..d4f14d2 --- /dev/null +++ b/docs/api/tsapi_sdf.md @@ -0,0 +1,167 @@ +# 概述 + +Tongsuo提供的SDF接口,需要结合密码设备使用,实际上封装了密码设备提供的SDF接口,提供对密码设备的统一访问能力。 + +本文大部分接口定义参考GM/T 0018-2023 密码设备应用接口规范。 + +少量接口为非标接口,需要搭配特定的密码设备使用。 + +## 头文件和函数原型 + +```c +#include + +int TSAPI_SDF_OpenDevice(void **phDeviceHandle); +int TSAPI_SDF_CloseDevice(void *hDeviceHandle); +int TSAPI_SDF_OpenSession(void *hDeviceHandle, void **phSessionHandle); +int TSAPI_SDF_CloseSession(void *hSessionHandle); +int TSAPI_SDF_GenerateRandom(void *hSessionHandle, unsigned int uiLength, + unsigned char *pucRandom); +int TSAPI_SDF_GetPrivateKeyAccessRight(void *hSessionHandle, + unsigned int uiKeyIndex, + unsigned char *pucPassword, + unsigned int uiPwdLength); +int TSAPI_SDF_ReleasePrivateKeyAccessRight(void *hSessionHandle, + unsigned int uiKeyIndex); +int TSAPI_SDF_ImportKeyWithISK_ECC(void *hSessionHandle, + unsigned int uiISKIndex, + OSSL_ECCCipher *pucKey, + void **phKeyHandle); +int TSAPI_SDF_ImportKeyWithKEK(void *hSessionHandle, unsigned int uiAlgID, + unsigned int uiKEKIndex, unsigned char *pucKey, unsigned int puiKeyLength, + void **phKeyHandle); +int TSAPI_SDF_ExportSignPublicKey_ECC(void *hSessionHandle, + unsigned int uiKeyIndex, + OSSL_ECCrefPublicKey *pucPublicKey); +int TSAPI_SDF_ExportEncPublicKey_ECC(void *hSessionHandle, + unsigned int uiKeyIndex, + OSSL_ECCrefPublicKey *pucPublicKey); +int TSAPI_SDF_DestroyKey(void *hSessionHandle, void *hKeyHandle); +int TSAPI_SDF_InternalEncrypt_ECC(void *hSessionHandle, unsigned int uiISKIndex, + unsigned char *pucData, + unsigned int uiDataLength, + OSSL_ECCCipher *pucEncData); +int TSAPI_SDF_InternalDecrypt_ECC(void *hSessionHandle, unsigned int uiISKIndex, + OSSL_ECCCipher *pucEncData, + unsigned char *pucData, + unsigned int *puiDataLength); +int TSAPI_SDF_Encrypt(void *hSessionHandle, void *hKeyHandle, + unsigned int uiAlgID, unsigned char *pucIV, unsigned char *pucData, + unsigned int uiDataLength, unsigned char *pucEncData, + unsigned int *puiEncDataLength); +int TSAPI_SDF_Decrypt(void *hSessionHandle, void *hKeyHandle, + unsigned int uiAlgID, unsigned char *pucIV, unsigned char *pucEncData, + unsigned int uiEncDataLength, unsigned char *pucData, + unsigned int *puiDataLength); +int TSAPI_SDF_CalculateMAC(void *hSessionHandle, void *hKeyHandle, + unsigned int uiAlgID, unsigned char *pucIV, unsigned char *pucData, + unsigned int uiDataLength, unsigned char *pucMac, + unsigned int *puiMACLength); +int TSAPI_SDF_GenerateKey(void *hSessionHandle, uint8_t type, uint8_t no_kek, + uint32_t len, void **pkey_handle); +int TSAPI_SDF_InternalSign_ECC(void *hSessionHandle, unsigned int uiISKIndex, + unsigned char *pucData, + unsigned int uiDataLength, + OSSL_ECCSignature *pucSignature); + +``` + +## 函数说明 + +TSAPI_SDF_OpenDevice()函数用于打开密码设备,获取密码设备句柄,设备句柄保存在*phDeviceHandle中。 + +TSAPI_SDF_CloseDevice()函数用于关闭密码设备。 + +TSAPI_SDF_OpenSession()函数用于打开会话,获取会话句柄,会话句柄保存在*phSessionHandle中。 + +TSAPI_SDF_CloseSession()函数用于关闭会话。 + +TSAPI_SDF_GenerateRandom()函数用于生成随机数,uiLength为随机数长度,生成的随机数保存在pucRandom缓冲区中。 + +TSAPI_SDF_GetPrivateKeyAccessRight()函数用于获取私钥访问权限,uiKeyIndex为私钥索引,pucPassword为私钥密码,uiPwdLength为密码长度。 + +TSAPI_SDF_ReleasePrivateKeyAccessRight()函数用于释放私钥访问权限。 + +TSAPI_SDF_ImportKeyWithISK_ECC()函数用于导入ECC密钥,uiISKIndex为密钥索引,pucKey为密钥,phKeyHandle保存密钥句柄。 + +TSAPI_SDF_ImportKeyWithKEK()函数用于导入密钥,uiAlgID为密钥算法ID,uiKEKIndex为KEK索引,pucKey为密钥,puiKeyLength为密钥长度, +phKeyHandle保存密钥句柄。 + +TSAPI_SDF_ExportSignPublicKey_ECC()函数用于导出签名公钥,uiKeyIndex为密钥索引,pucPublicKey保存公钥。 + +TSAPI_SDF_ExportEncPublicKey_ECC()函数用于导出加密公钥,uiKeyIndex为密钥索引,pucPublicKey保存公钥。 + +TSAPI_SDF_DestroyKey()函数用于销毁密钥。 + +TSAPI_SDF_InternalEncrypt_ECC()函数用于内部加密,uiISKIndex为密钥索引,pucData为待加密数据,uiDataLength为数据长度,pucEncData保存 +加密数据。 + +TSAPI_SDF_InternalDecrypt_ECC()函数用于内部解密,uiISKIndex为密钥索引,pucEncData为待解密数据,pucData保存解密数据,puiDataLength +保存解密数据长度。 + +TSAPI_SDF_Encrypt()函数用于加密,pucIV为初始化向量,pucData为待加密数据,uiDataLength为数据长度,pucEncData保存加密数据, +puiEncDataLength保存加密数据长度。 + +TSAPI_SDF_Decrypt()函数用于解密,pucIV为初始化向量,pucEncData为待解密数据,uiEncDataLength为数据长度,pucData保存解密数据, +puiDataLength保存解密数据长度。 + +TSAPI_SDF_CalculateMAC()函数用于计算MAC,pucIV为初始化向量,pucData为待计算MAC数据,uiDataLength为数据长度,pucMac保存MAC, +puiMACLength保存MAC长度。 + +TSAPI_SDF_GenerateKey()函数用于生成密钥,type为密钥类型,no_kek为KEK索引,len为密钥长度,pkey_handle保存密钥句柄。 + +TSAPI_SDF_InternalSign_ECC()函数用于内部签名,uiISKIndex为密钥索引,pucData为待签名数据,uiDataLength为数据长度,pucSignature保存 +签名。 + +## 返回值说明 + +TSAPI_SDF_*函数返回值为0(OSSL_SDR_OK)表示成功,其他值表示错误码,具体的错误码见sdf.h。 + +错误码定义参考GM/T 0018-2023 密码设备应用接口规范 附录A.1。 + +## 示例 + +示例:使用密码设备上的SM2加密公钥加密数据。 + +```c +#include +#include +#include + +int main() +{ + unsigned int isk = 1; + unsigned char in[] = "hello world"; + unsigned int inlen = strlen(in); + void *hDeviceHandle = NULL; + void *hSessionHandle = NULL; + OSSL_ECCCipher *ecc = NULL; + + if (TSAPI_SDF_OpenDevice(&hDeviceHandle) != OSSL_SDR_OK) + return NULL; + + if (TSAPI_SDF_OpenSession(hDeviceHandle, &hSessionHandle) != OSSL_SDR_OK) + goto end; + + ecc = OPENSSL_zalloc(sizeof(OSSL_ECCCipher) + inlen); + if (ecc == NULL) + goto end; + + if (TSAPI_SDF_InternalEncrypt_ECC(hSessionHandle, isk, in, inlen, ecc) + != OSSL_SDR_OK) + goto end; + + // ecc contains the encrypted data + +end: + OPENSSL_free(ecc); + TSAPI_SDF_CloseSession(hSessionHandle); + TSAPI_SDF_CloseDevice(hDeviceHandle); + + return 0; +} +``` + +## 历史 + +TSAPI_*函数在Tongsuo 8.5.0版本中引入。