Skip to content

Commit

Permalink
增加TSAPI_和TSAPI_SDF_函数API文档
Browse files Browse the repository at this point in the history
  • Loading branch information
dongbeiouba committed Aug 20, 2024
1 parent 4dd0746 commit bed9c6b
Show file tree
Hide file tree
Showing 2 changed files with 335 additions and 0 deletions.
168 changes: 168 additions & 0 deletions docs/api/tsapi.md
Original file line number Diff line number Diff line change
@@ -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 <openssl/tsapi.h>

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版本中引入。
167 changes: 167 additions & 0 deletions docs/api/tsapi_sdf.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
# 概述

Tongsuo提供的SDF接口,需要结合密码设备使用,实际上封装了密码设备提供的SDF接口,提供对密码设备的统一访问能力。

本文大部分接口定义参考GM/T 0018-2023 密码设备应用接口规范。

少量接口为非标接口,需要搭配特定的密码设备使用。

## 头文件和函数原型

```c
#include <openssl/sdf.h>

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 <string.h>
#include <openssl/crypto.h>
#include <openssl/sdf.h>
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版本中引入。

0 comments on commit bed9c6b

Please sign in to comment.