diff --git a/CMakeLists.txt b/CMakeLists.txt index bf4a0ac4..931c3f65 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -75,6 +75,7 @@ set(tools tools/sm4.c tools/sm3.c tools/sm3hmac.c + tools/sm3xmss_keygen.c tools/sm2keygen.c tools/sm2sign.c tools/sm2verify.c @@ -285,7 +286,7 @@ if (ENABLE_SM3_XMSS) message(STATUS "ENABLE_SM3_XMSS is ON") list(APPEND src src/sm3_xmss.c) - option(ENABLE_SM3_XMSS_CROSSCHECK "Enable XMSS SHA-256 cross-check" ON) + option(ENABLE_SM3_XMSS_CROSSCHECK "Enable XMSS SHA-256 cross-check" OFF) if (ENABLE_SM3_XMSS_CROSSCHECK) message(STATUS "ENABLE_SM3_XMSS_CROSSCHECK is ON") add_definitions(-DENABLE_SM3_XMSS_CROSSCHECK) @@ -331,6 +332,7 @@ if (ENABLE_CHACHA20) endif() + option(ENABLE_INTEL_RDRAND "Enable Intel RDRAND instructions" OFF) option(ENABLE_INTEL_RDSEED "Enable Intel RDSEED instructions" OFF) @@ -361,12 +363,20 @@ if (ENABLE_INTEL_RDRAND) endif() +option(ENABLE_SM4_CBC_MAC "Enable SM4-CBC-MAC" OFF) +if (ENABLE_SM4_CBC_MAC) + message(STATUS "ENABLE_SM4_CBC_MAC is ON") + list(APPEND src src/sm4_cbc_mac.c) + list(APPEND tests sm4_cbc_mac) + list(APPEND demos sm4_cbc_mac_demo) +endif() + + option(ENABLE_GMT_0105_RNG "Enable GM/T 0105 Software RNG" OFF) if (ENABLE_GMT_0105_RNG) - message(STATUS "ENABLE_GMT_0105_RNG") - list(APPEND src src/sm3_rng.c src/sm4_cbc_mac.c src/sm4_rng.c) - list(APPEND tests sm3_rng sm4_cbc_mac sm4_rng) - list(APPEND demos sm4_cbc_mac_demo) + message(STATUS "ENABLE_GMT_0105_RNG is ON") + list(APPEND src src/sm3_rng.c src/sm4_rng.c) + list(APPEND tests sm3_rng sm4_rng) endif() @@ -400,6 +410,9 @@ endif() add_library(gmssl ${src}) + + + if (WIN32) target_link_libraries(gmssl -lws2_32) elseif (APPLE) @@ -421,6 +434,16 @@ SET_TARGET_PROPERTIES(gmssl PROPERTIES VERSION 3.1 SOVERSION 3) install(TARGETS gmssl ARCHIVE DESTINATION lib LIBRARY DESTINATION lib RUNTIME DESTINATION bin) install(DIRECTORY ${CMAKE_SOURCE_DIR}/include/gmssl DESTINATION include) + +option(ENABLE_SOFT_SDF "Enable Software SDF Implementation" OFF) +if (ENABLE_SOFT_SDF) + message(STATUS "ENABLE_SOFT_SDF is ON") + add_library(soft_sdf SHARED src/sdf/soft_sdf.c) + target_link_libraries(soft_sdf PRIVATE gmssl) + set_target_properties(soft_sdf PROPERTIES VERSION 3.1 SOVERSION 3) +endif() + + if (NOT ${CMAKE_SYSTEM_NAME} STREQUAL "iOS") add_library(sdf_dummy SHARED src/sdf/sdf_dummy.c) diff --git a/src/sdf/sdf.h b/src/sdf/sdf.h index af56440b..e882a72c 100755 --- a/src/sdf/sdf.h +++ b/src/sdf/sdf.h @@ -1,5 +1,5 @@ /* - * Copyright 2014-2022 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2023 The GmSSL Project. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. @@ -7,459 +7,462 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ -/* - * SDF API is a cryptographic API for PCI-E cards defined in standard - * GM/T 0018-2012: Interface Specifications of Cryptography Device Application - * - * Note: this header file follows the specification of GM/T 0018-2012. As we - * know, some vendors provide header files with some differences, especially - * the definations of data structures. So be sure to check the file provided by - * vendors and compare with this one. - * - * The implementations of SDF API from different vendors might have different - * behaviors on the same function. The comments in this file will show - * information and warnings on these issues. If the application developer use - * the GmSSL implementation, see `crypto/gmapi/sdf_lcl.h` for more information. - */ - -#ifndef HEADER_SDF_H -#define HEADER_SDF_H - -#include -#include "../sgd.h" - - -#ifdef __cplusplus -extern "C" { -#endif - - - -#pragma pack(1) -typedef struct DeviceInfo_st { - unsigned char IssuerName[40]; - unsigned char DeviceName[16]; - unsigned char DeviceSerial[16]; /* 8-char date + - * 3-char batch num + - * 5-char serial num - */ - unsigned int DeviceVersion; - unsigned int StandardVersion; - unsigned int AsymAlgAbility[2]; /* AsymAlgAbility[0] = algors - * AsymAlgAbility[1] = modulus lens - */ - unsigned int SymAlgAbility; - unsigned int HashAlgAbility; - unsigned int BufferSize; -} DEVICEINFO; - -typedef struct RSArefPublicKey_st { - unsigned int bits; - unsigned char m[RSAref_MAX_LEN]; - unsigned char e[RSAref_MAX_LEN]; -} RSArefPublicKey; - -typedef struct RSArefPrivateKey_st { - unsigned int bits; - unsigned char m[RSAref_MAX_LEN]; - unsigned char e[RSAref_MAX_LEN]; - unsigned char d[RSAref_MAX_LEN]; - unsigned char prime[2][RSAref_MAX_PLEN]; - unsigned char pexp[2][RSAref_MAX_PLEN]; - unsigned char coef[RSAref_MAX_PLEN]; -} RSArefPrivateKey; - -typedef struct ECCrefPublicKey_st { - unsigned int bits; - unsigned char x[ECCref_MAX_LEN]; - unsigned char y[ECCref_MAX_LEN]; -} ECCrefPublicKey; - -typedef struct ECCrefPrivateKey_st { - unsigned int bits; - unsigned char K[ECCref_MAX_LEN]; -} ECCrefPrivateKey; - -typedef struct ECCCipher_st { - unsigned char x[ECCref_MAX_LEN]; - unsigned char y[ECCref_MAX_LEN]; - unsigned char M[32]; - unsigned int L; - unsigned char C[1]; -} ECCCipher; - -typedef struct ECCSignature_st { - unsigned char r[ECCref_MAX_LEN]; - unsigned char s[ECCref_MAX_LEN]; -} ECCSignature; - -typedef struct SDF_ENVELOPEDKEYBLOB { - unsigned long Version; - unsigned long ulSymmAlgID; - ECCCipher ECCCipehrBlob; - ECCrefPublicKey PubKey; - unsigned char cbEncryptedPrivKey[64]; -} EnvelopedKeyBlob, *PEnvelopedKeyBlob; -#pragma pack() - -int SDF_OpenDevice( - void **phDeviceHandle); - -int SDF_CloseDevice( - void *hDeviceHandle); - -int SDF_OpenSession( - void *hDeviceHandle, - void **phSessionHandle); - -int SDF_CloseSession( - void *hSessionHandle); - -int SDF_GetDeviceInfo( - void *hSessionHandle, - DEVICEINFO *pstDeviceInfo); - -int SDF_GenerateRandom( - void *hSessionHandle, - unsigned int uiLength, - unsigned char *pucRandom); - -int SDF_GetPrivateKeyAccessRight( - void *hSessionHandle, - unsigned int uiKeyIndex, - unsigned char *pucPassword, - unsigned int uiPwdLength); - -int SDF_ReleasePrivateKeyAccessRight( - void *hSessionHandle, - unsigned int uiKeyIndex); - -int SDF_ExportSignPublicKey_RSA( - void *hSessionHandle, - unsigned int uiKeyIndex, - RSArefPublicKey *pucPublicKey); - -int SDF_ExportEncPublicKey_RSA( - void *hSessionHandle, - unsigned int uiKeyIndex, - RSArefPublicKey *pucPublicKey); - -int SDF_GenerateKeyPair_RSA( - void *hSessionHandle, - unsigned int uiKeyBits, - RSArefPublicKey *pucPublicKey, - RSArefPrivateKey *pucPrivateKey); - -int SDF_GenerateKeyWithIPK_RSA( - void *hSessionHandle, - unsigned int uiIPKIndex, - unsigned int uiKeyBits, - unsigned char *pucKey, - unsigned int *puiKeyLength, - void **phKeyHandle); - -int SDF_GenerateKeyWithEPK_RSA( - void *hSessionHandle, - unsigned int uiKeyBits, - RSArefPublicKey *pucPublicKey, - unsigned char *pucKey, - unsigned int *puiKeyLength, - void **phKeyHandle); - -int SDF_ImportKeyWithISK_RSA( - void *hSessionHandle, - unsigned int uiISKIndex, - unsigned char *pucKey, - unsigned int uiKeyLength, - void **phKeyHandle); - -int SDF_ExchangeDigitEnvelopeBaseOnRSA( - void *hSessionHandle, - unsigned int uiKeyIndex, - RSArefPublicKey *pucPublicKey, - unsigned char *pucDEInput, - unsigned int uiDELength, - unsigned char *pucDEOutput, - unsigned int *puiDELength); - -int SDF_ExportSignPublicKey_ECC( - void *hSessionHandle, - unsigned int uiKeyIndex, - ECCrefPublicKey *pucPublicKey); - -int SDF_ExportEncPublicKey_ECC( - void *hSessionHandle, - unsigned int uiKeyIndex, - ECCrefPublicKey *pucPublicKey); - -int SDF_GenerateKeyPair_ECC( - void *hSessionHandle, - unsigned int uiAlgID, - unsigned int uiKeyBits, - ECCrefPublicKey *pucPublicKey, - ECCrefPrivateKey *pucPrivateKey); - -int SDF_GenerateKeyWithIPK_ECC( - void *hSessionHandle, - unsigned int uiIPKIndex, - unsigned int uiKeyBits, - ECCCipher *pucKey, - void **phKeyHandle); - -int SDF_GenerateKeyWithEPK_ECC( - void *hSessionHandle, - unsigned int uiKeyBits, - unsigned int uiAlgID, - ECCrefPublicKey *pucPublicKey, - ECCCipher *pucKey, - void **phKeyHandle); - -int SDF_ImportKeyWithISK_ECC( - void *hSessionHandle, - unsigned int uiISKIndex, - ECCCipher *pucKey, - void **phKeyHandle); - -int SDF_GenerateAgreementDataWithECC( - void *hSessionHandle, - unsigned int uiISKIndex, - unsigned int uiKeyBits, - unsigned char *pucSponsorID, - unsigned int uiSponsorIDLength, - ECCrefPublicKey *pucSponsorPublicKey, - ECCrefPublicKey *pucSponsorTmpPublicKey, - void **phAgreementHandle); - -int SDF_GenerateKeyWithECC( - void *hSessionHandle, - unsigned char *pucResponseID, - unsigned int uiResponseIDLength, - ECCrefPublicKey *pucResponsePublicKey, - ECCrefPublicKey *pucResponseTmpPublicKey, - void *hAgreementHandle, - void **phKeyHandle); - -int SDF_GenerateAgreementDataAndKeyWithECC( - void *hSessionHandle, - unsigned int uiISKIndex, - unsigned int uiKeyBits, - unsigned char *pucResponseID, - unsigned int uiResponseIDLength, - unsigned char *pucSponsorID, - unsigned int uiSponsorIDLength, - ECCrefPublicKey *pucSponsorPublicKey, - ECCrefPublicKey *pucSponsorTmpPublicKey, - ECCrefPublicKey *pucResponsePublicKey, - ECCrefPublicKey *pucResponseTmpPublicKey, - void **phKeyHandle); - -int SDF_ExchangeDigitEnvelopeBaseOnECC( - void *hSessionHandle, - unsigned int uiKeyIndex, - unsigned int uiAlgID, - ECCrefPublicKey *pucPublicKey, - ECCCipher *pucEncDataIn, - ECCCipher *pucEncDataOut); - -int SDF_GenerateKeyWithKEK( - void *hSessionHandle, - unsigned int uiKeyBits, - unsigned int uiAlgID, - unsigned int uiKEKIndex, - unsigned char *pucKey, - unsigned int *puiKeyLength, - void **phKeyHandle); - -int SDF_ImportKeyWithKEK( - void *hSessionHandle, - unsigned int uiAlgID, - unsigned int uiKEKIndex, - unsigned char *pucKey, - unsigned int uiKeyLength, - void **phKeyHandle); - -int SDF_DestroyKey( - void *hSessionHandle, - void *hKeyHandle); - -int SDF_ExternalPublicKeyOperation_RSA( - void *hSessionHandle, - RSArefPublicKey *pucPublicKey, - unsigned char *pucDataInput, - unsigned int uiInputLength, - unsigned char *pucDataOutput, - unsigned int *puiOutputLength); - -int SDF_InternalPublicKeyOperation_RSA( - void *hSessionHandle, - unsigned int uiKeyIndex, - unsigned char *pucDataInput, - unsigned int uiInputLength, - unsigned char *pucDataOutput, - unsigned int *puiOutputLength); - -int SDF_InternalPrivateKeyOperation_RSA( - void *hSessionHandle, - unsigned int uiKeyIndex, - unsigned char *pucDataInput, - unsigned int uiInputLength, - unsigned char *pucDataOutput, - unsigned int *puiOutputLength); - -int SDF_ExternalVerify_ECC( - void *hSessionHandle, - unsigned int uiAlgID, - ECCrefPublicKey *pucPublicKey, - unsigned char *pucDataInput, - unsigned int uiInputLength, - ECCSignature *pucSignature); - -int SDF_InternalSign_ECC( - void *hSessionHandle, - unsigned int uiISKIndex, - unsigned char *pucData, - unsigned int uiDataLength, - ECCSignature *pucSignature); - -int SDF_InternalVerify_ECC( - void *hSessionHandle, - unsigned int uiIPKIndex, - unsigned char *pucData, - unsigned int uiDataLength, - ECCSignature *pucSignature); - -int SDF_ExternalEncrypt_ECC( - void *hSessionHandle, - unsigned int uiAlgID, - ECCrefPublicKey *pucPublicKey, - unsigned char *pucData, - unsigned int uiDataLength, - ECCCipher *pucEncData); - -int SDF_InternalEncrypt_ECC( - void *hSessionHandle, - unsigned int uiIPKIndex, - unsigned int uiAlgID, - unsigned char *pucData, - unsigned int uiDataLength, - ECCCipher *pucEncData); - -int SDF_InternalDecrypt_ECC( - void *hSessionHandle, - unsigned int uiISKIndex, - unsigned int uiAlgID, - ECCCipher *pucEncData, - unsigned char *pucData, - unsigned int *uiDataLength); - -int 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 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 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 SDF_HashInit( - void *hSessionHandle, - unsigned int uiAlgID, - ECCrefPublicKey *pucPublicKey, - unsigned char *pucID, - unsigned int uiIDLength); - -int SDF_HashUpdate( - void *hSessionHandle, - unsigned char *pucData, - unsigned int uiDataLength); - -int SDF_HashFinal(void *hSessionHandle, - unsigned char *pucHash, - unsigned int *puiHashLength); - -int SDF_CreateFile( - void *hSessionHandle, - unsigned char *pucFileName, - unsigned int uiNameLen, /* max 128-byte */ - unsigned int uiFileSize); - -int SDF_ReadFile( - void *hSessionHandle, - unsigned char *pucFileName, - unsigned int uiNameLen, - unsigned int uiOffset, - unsigned int *puiReadLength, - unsigned char *pucBuffer); - -int SDF_WriteFile( - void *hSessionHandle, - unsigned char *pucFileName, - unsigned int uiNameLen, - unsigned int uiOffset, - unsigned int uiWriteLength, - unsigned char *pucBuffer); - -int SDF_DeleteFile( - void *hSessionHandle, - unsigned char *pucFileName, - unsigned int uiNameLen); - -#define SDR_OK 0x0 -#define SDR_BASE 0x01000000 -#define SDR_UNKNOWERR (SDR_BASE + 0x00000001) -#define SDR_NOTSUPPORT (SDR_BASE + 0x00000002) -#define SDR_COMMFAIL (SDR_BASE + 0x00000003) -#define SDR_HARDFAIL (SDR_BASE + 0x00000004) -#define SDR_OPENDEVICE (SDR_BASE + 0x00000005) -#define SDR_OPENSESSION (SDR_BASE + 0x00000006) -#define SDR_PARDENY (SDR_BASE + 0x00000007) -#define SDR_KEYNOTEXIST (SDR_BASE + 0x00000008) -#define SDR_ALGNOTSUPPORT (SDR_BASE + 0x00000009) -#define SDR_ALGMODNOTSUPPORT (SDR_BASE + 0x0000000A) -#define SDR_PKOPERR (SDR_BASE + 0x0000000B) -#define SDR_SKOPERR (SDR_BASE + 0x0000000C) -#define SDR_SIGNERR (SDR_BASE + 0x0000000D) -#define SDR_VERIFYERR (SDR_BASE + 0x0000000E) -#define SDR_SYMOPERR (SDR_BASE + 0x0000000F) -#define SDR_STEPERR (SDR_BASE + 0x00000010) -#define SDR_FILESIZEERR (SDR_BASE + 0x00000011) -#define SDR_FILENOEXIST (SDR_BASE + 0x00000012) -#define SDR_FILEOFSERR (SDR_BASE + 0x00000013) -#define SDR_KEYTYPEERR (SDR_BASE + 0x00000014) -#define SDR_KEYERR (SDR_BASE + 0x00000015) -#define SDR_ENCDATAERR (SDR_BASE + 0x00000016) -#define SDR_RANDERR (SDR_BASE + 0x00000017) -#define SDR_PRKRERR (SDR_BASE + 0x00000018) -#define SDR_MACERR (SDR_BASE + 0x00000019) -#define SDR_FILEEXSITS (SDR_BASE + 0x0000001A) -#define SDR_FILEWERR (SDR_BASE + 0x0000001B) -#define SDR_NOBUFFER (SDR_BASE + 0x0000001C) -#define SDR_INARGERR (SDR_BASE + 0x0000001D) -#define SDR_OUTARGERR (SDR_BASE + 0x0000001E) - - -#ifdef __cplusplus -} -#endif -#endif +/* + * SDF API is a cryptographic API for PCI-E cards defined in standard + * GM/T 0018-2012: Interface Specifications of Cryptography Device Application + * + * Note: this header file follows the specification of GM/T 0018-2012. As we + * know, some vendors provide header files with some differences, especially + * the definations of data structures. So be sure to check the file provided by + * vendors and compare with this one. + * + * The implementations of SDF API from different vendors might have different + * behaviors on the same function. The comments in this file will show + * information and warnings on these issues. If the application developer use + * the GmSSL implementation, see `crypto/gmapi/sdf_lcl.h` for more information. + */ + +#ifndef HEADER_SDF_H +#define HEADER_SDF_H + +#include +#include "../sgd.h" + + +#ifdef __cplusplus +extern "C" { +#endif + + + +#pragma pack(1) +typedef struct DeviceInfo_st { + unsigned char IssuerName[40]; + unsigned char DeviceName[16]; + unsigned char DeviceSerial[16]; /* 8-char date + + * 3-char batch num + + * 5-char serial num + */ + unsigned int DeviceVersion; + unsigned int StandardVersion; + unsigned int AsymAlgAbility[2]; /* AsymAlgAbility[0] = algors + * AsymAlgAbility[1] = modulus lens + */ + unsigned int SymAlgAbility; + unsigned int HashAlgAbility; + unsigned int BufferSize; +} DEVICEINFO; + +typedef struct RSArefPublicKey_st { + unsigned int bits; + unsigned char m[RSAref_MAX_LEN]; + unsigned char e[RSAref_MAX_LEN]; +} RSArefPublicKey; + +typedef struct RSArefPrivateKey_st { + unsigned int bits; + unsigned char m[RSAref_MAX_LEN]; + unsigned char e[RSAref_MAX_LEN]; + unsigned char d[RSAref_MAX_LEN]; + unsigned char prime[2][RSAref_MAX_PLEN]; + unsigned char pexp[2][RSAref_MAX_PLEN]; + unsigned char coef[RSAref_MAX_PLEN]; +} RSArefPrivateKey; + +typedef struct ECCrefPublicKey_st { + unsigned int bits; + unsigned char x[ECCref_MAX_LEN]; + unsigned char y[ECCref_MAX_LEN]; +} ECCrefPublicKey; + +typedef struct ECCrefPrivateKey_st { + unsigned int bits; + unsigned char K[ECCref_MAX_LEN]; +} ECCrefPrivateKey; + +typedef struct ECCCipher_st { + unsigned char x[ECCref_MAX_LEN]; + unsigned char y[ECCref_MAX_LEN]; + unsigned char M[32]; + unsigned int L; + unsigned char C[1]; + // Extend sizeof(C) to SM2_MAX_PLAINTEXT_SIZE + // gmssl/sm2.h: SM2_MAX_PLAINTEXT_SIZE = 255 + unsigned char C_[254]; +} ECCCipher; + +typedef struct ECCSignature_st { + unsigned char r[ECCref_MAX_LEN]; + unsigned char s[ECCref_MAX_LEN]; +} ECCSignature; + +typedef struct SDF_ENVELOPEDKEYBLOB { + unsigned long Version; + unsigned long ulSymmAlgID; + ECCCipher ECCCipehrBlob; + ECCrefPublicKey PubKey; + unsigned char cbEncryptedPrivKey[64]; +} EnvelopedKeyBlob, *PEnvelopedKeyBlob; +#pragma pack() + +int SDF_OpenDevice( + void **phDeviceHandle); + +int SDF_CloseDevice( + void *hDeviceHandle); + +int SDF_OpenSession( + void *hDeviceHandle, + void **phSessionHandle); + +int SDF_CloseSession( + void *hSessionHandle); + +int SDF_GetDeviceInfo( + void *hSessionHandle, + DEVICEINFO *pstDeviceInfo); + +int SDF_GenerateRandom( + void *hSessionHandle, + unsigned int uiLength, + unsigned char *pucRandom); + +int SDF_GetPrivateKeyAccessRight( + void *hSessionHandle, + unsigned int uiKeyIndex, + unsigned char *pucPassword, + unsigned int uiPwdLength); + +int SDF_ReleasePrivateKeyAccessRight( + void *hSessionHandle, + unsigned int uiKeyIndex); + +int SDF_ExportSignPublicKey_RSA( + void *hSessionHandle, + unsigned int uiKeyIndex, + RSArefPublicKey *pucPublicKey); + +int SDF_ExportEncPublicKey_RSA( + void *hSessionHandle, + unsigned int uiKeyIndex, + RSArefPublicKey *pucPublicKey); + +int SDF_GenerateKeyPair_RSA( + void *hSessionHandle, + unsigned int uiKeyBits, + RSArefPublicKey *pucPublicKey, + RSArefPrivateKey *pucPrivateKey); + +int SDF_GenerateKeyWithIPK_RSA( + void *hSessionHandle, + unsigned int uiIPKIndex, + unsigned int uiKeyBits, + unsigned char *pucKey, + unsigned int *puiKeyLength, + void **phKeyHandle); + +int SDF_GenerateKeyWithEPK_RSA( + void *hSessionHandle, + unsigned int uiKeyBits, + RSArefPublicKey *pucPublicKey, + unsigned char *pucKey, + unsigned int *puiKeyLength, + void **phKeyHandle); + +int SDF_ImportKeyWithISK_RSA( + void *hSessionHandle, + unsigned int uiISKIndex, + unsigned char *pucKey, + unsigned int uiKeyLength, + void **phKeyHandle); + +int SDF_ExchangeDigitEnvelopeBaseOnRSA( + void *hSessionHandle, + unsigned int uiKeyIndex, + RSArefPublicKey *pucPublicKey, + unsigned char *pucDEInput, + unsigned int uiDELength, + unsigned char *pucDEOutput, + unsigned int *puiDELength); + +int SDF_ExportSignPublicKey_ECC( + void *hSessionHandle, + unsigned int uiKeyIndex, + ECCrefPublicKey *pucPublicKey); + +int SDF_ExportEncPublicKey_ECC( + void *hSessionHandle, + unsigned int uiKeyIndex, + ECCrefPublicKey *pucPublicKey); + +int SDF_GenerateKeyPair_ECC( + void *hSessionHandle, + unsigned int uiAlgID, + unsigned int uiKeyBits, + ECCrefPublicKey *pucPublicKey, + ECCrefPrivateKey *pucPrivateKey); + +int SDF_GenerateKeyWithIPK_ECC( + void *hSessionHandle, + unsigned int uiIPKIndex, + unsigned int uiKeyBits, + ECCCipher *pucKey, + void **phKeyHandle); + +int SDF_GenerateKeyWithEPK_ECC( + void *hSessionHandle, + unsigned int uiKeyBits, + unsigned int uiAlgID, + ECCrefPublicKey *pucPublicKey, + ECCCipher *pucKey, + void **phKeyHandle); + +int SDF_ImportKeyWithISK_ECC( + void *hSessionHandle, + unsigned int uiISKIndex, + ECCCipher *pucKey, + void **phKeyHandle); + +int SDF_GenerateAgreementDataWithECC( + void *hSessionHandle, + unsigned int uiISKIndex, + unsigned int uiKeyBits, + unsigned char *pucSponsorID, + unsigned int uiSponsorIDLength, + ECCrefPublicKey *pucSponsorPublicKey, + ECCrefPublicKey *pucSponsorTmpPublicKey, + void **phAgreementHandle); + +int SDF_GenerateKeyWithECC( + void *hSessionHandle, + unsigned char *pucResponseID, + unsigned int uiResponseIDLength, + ECCrefPublicKey *pucResponsePublicKey, + ECCrefPublicKey *pucResponseTmpPublicKey, + void *hAgreementHandle, + void **phKeyHandle); + +int SDF_GenerateAgreementDataAndKeyWithECC( + void *hSessionHandle, + unsigned int uiISKIndex, + unsigned int uiKeyBits, + unsigned char *pucResponseID, + unsigned int uiResponseIDLength, + unsigned char *pucSponsorID, + unsigned int uiSponsorIDLength, + ECCrefPublicKey *pucSponsorPublicKey, + ECCrefPublicKey *pucSponsorTmpPublicKey, + ECCrefPublicKey *pucResponsePublicKey, + ECCrefPublicKey *pucResponseTmpPublicKey, + void **phKeyHandle); + +int SDF_ExchangeDigitEnvelopeBaseOnECC( + void *hSessionHandle, + unsigned int uiKeyIndex, + unsigned int uiAlgID, + ECCrefPublicKey *pucPublicKey, + ECCCipher *pucEncDataIn, + ECCCipher *pucEncDataOut); + +int SDF_GenerateKeyWithKEK( + void *hSessionHandle, + unsigned int uiKeyBits, + unsigned int uiAlgID, + unsigned int uiKEKIndex, + unsigned char *pucKey, + unsigned int *puiKeyLength, + void **phKeyHandle); + +int SDF_ImportKeyWithKEK( + void *hSessionHandle, + unsigned int uiAlgID, + unsigned int uiKEKIndex, + unsigned char *pucKey, + unsigned int uiKeyLength, + void **phKeyHandle); + +int SDF_DestroyKey( + void *hSessionHandle, + void *hKeyHandle); + +int SDF_ExternalPublicKeyOperation_RSA( + void *hSessionHandle, + RSArefPublicKey *pucPublicKey, + unsigned char *pucDataInput, + unsigned int uiInputLength, + unsigned char *pucDataOutput, + unsigned int *puiOutputLength); + +int SDF_InternalPublicKeyOperation_RSA( + void *hSessionHandle, + unsigned int uiKeyIndex, + unsigned char *pucDataInput, + unsigned int uiInputLength, + unsigned char *pucDataOutput, + unsigned int *puiOutputLength); + +int SDF_InternalPrivateKeyOperation_RSA( + void *hSessionHandle, + unsigned int uiKeyIndex, + unsigned char *pucDataInput, + unsigned int uiInputLength, + unsigned char *pucDataOutput, + unsigned int *puiOutputLength); + +int SDF_ExternalVerify_ECC( + void *hSessionHandle, + unsigned int uiAlgID, + ECCrefPublicKey *pucPublicKey, + unsigned char *pucDataInput, + unsigned int uiInputLength, + ECCSignature *pucSignature); + +int SDF_InternalSign_ECC( + void *hSessionHandle, + unsigned int uiISKIndex, + unsigned char *pucData, + unsigned int uiDataLength, + ECCSignature *pucSignature); + +int SDF_InternalVerify_ECC( + void *hSessionHandle, + unsigned int uiIPKIndex, + unsigned char *pucData, + unsigned int uiDataLength, + ECCSignature *pucSignature); + +int SDF_ExternalEncrypt_ECC( + void *hSessionHandle, + unsigned int uiAlgID, + ECCrefPublicKey *pucPublicKey, + unsigned char *pucData, + unsigned int uiDataLength, + ECCCipher *pucEncData); + +int SDF_InternalEncrypt_ECC( + void *hSessionHandle, + unsigned int uiIPKIndex, + unsigned int uiAlgID, + unsigned char *pucData, + unsigned int uiDataLength, + ECCCipher *pucEncData); + +int SDF_InternalDecrypt_ECC( + void *hSessionHandle, + unsigned int uiISKIndex, + unsigned int uiAlgID, + ECCCipher *pucEncData, + unsigned char *pucData, + unsigned int *uiDataLength); + +int 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 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 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 SDF_HashInit( + void *hSessionHandle, + unsigned int uiAlgID, + ECCrefPublicKey *pucPublicKey, + unsigned char *pucID, + unsigned int uiIDLength); + +int SDF_HashUpdate( + void *hSessionHandle, + unsigned char *pucData, + unsigned int uiDataLength); + +int SDF_HashFinal(void *hSessionHandle, + unsigned char *pucHash, + unsigned int *puiHashLength); + +int SDF_CreateFile( + void *hSessionHandle, + unsigned char *pucFileName, + unsigned int uiNameLen, /* max 128-byte */ + unsigned int uiFileSize); + +int SDF_ReadFile( + void *hSessionHandle, + unsigned char *pucFileName, + unsigned int uiNameLen, + unsigned int uiOffset, + unsigned int *puiReadLength, + unsigned char *pucBuffer); + +int SDF_WriteFile( + void *hSessionHandle, + unsigned char *pucFileName, + unsigned int uiNameLen, + unsigned int uiOffset, + unsigned int uiWriteLength, + unsigned char *pucBuffer); + +int SDF_DeleteFile( + void *hSessionHandle, + unsigned char *pucFileName, + unsigned int uiNameLen); + +#define SDR_OK 0x0 +#define SDR_BASE 0x01000000 +#define SDR_UNKNOWERR (SDR_BASE + 0x00000001) +#define SDR_NOTSUPPORT (SDR_BASE + 0x00000002) +#define SDR_COMMFAIL (SDR_BASE + 0x00000003) +#define SDR_HARDFAIL (SDR_BASE + 0x00000004) +#define SDR_OPENDEVICE (SDR_BASE + 0x00000005) +#define SDR_OPENSESSION (SDR_BASE + 0x00000006) +#define SDR_PARDENY (SDR_BASE + 0x00000007) +#define SDR_KEYNOTEXIST (SDR_BASE + 0x00000008) +#define SDR_ALGNOTSUPPORT (SDR_BASE + 0x00000009) +#define SDR_ALGMODNOTSUPPORT (SDR_BASE + 0x0000000A) +#define SDR_PKOPERR (SDR_BASE + 0x0000000B) +#define SDR_SKOPERR (SDR_BASE + 0x0000000C) +#define SDR_SIGNERR (SDR_BASE + 0x0000000D) +#define SDR_VERIFYERR (SDR_BASE + 0x0000000E) +#define SDR_SYMOPERR (SDR_BASE + 0x0000000F) +#define SDR_STEPERR (SDR_BASE + 0x00000010) +#define SDR_FILESIZEERR (SDR_BASE + 0x00000011) +#define SDR_FILENOEXIST (SDR_BASE + 0x00000012) +#define SDR_FILEOFSERR (SDR_BASE + 0x00000013) +#define SDR_KEYTYPEERR (SDR_BASE + 0x00000014) +#define SDR_KEYERR (SDR_BASE + 0x00000015) +#define SDR_ENCDATAERR (SDR_BASE + 0x00000016) +#define SDR_RANDERR (SDR_BASE + 0x00000017) +#define SDR_PRKRERR (SDR_BASE + 0x00000018) +#define SDR_MACERR (SDR_BASE + 0x00000019) +#define SDR_FILEEXSITS (SDR_BASE + 0x0000001A) +#define SDR_FILEWERR (SDR_BASE + 0x0000001B) +#define SDR_NOBUFFER (SDR_BASE + 0x0000001C) +#define SDR_INARGERR (SDR_BASE + 0x0000001D) +#define SDR_OUTARGERR (SDR_BASE + 0x0000001E) + + +#ifdef __cplusplus +} +#endif +#endif diff --git a/src/sdf/soft_sdf.c b/src/sdf/soft_sdf.c new file mode 100755 index 00000000..87e5195f --- /dev/null +++ b/src/sdf/soft_sdf.c @@ -0,0 +1,2335 @@ +/* + * Copyright 2014-2023 The GmSSL Project. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * + * http://www.apache.org/licenses/LICENSE-2.0 + */ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include "../sgd.h" +#include "sdf.h" + +#define SDR_GMSSLERR (SDR_BASE + 0x00000100) + + + +#define SOFTSDF_MAX_KEY_SIZE 64 + +struct SOFTSDF_KEY { + uint8_t key[SOFTSDF_MAX_KEY_SIZE]; + size_t key_size; + struct SOFTSDF_KEY *next; +}; + +typedef struct SOFTSDF_KEY SOFTSDF_KEY; + + +struct SOFTSDF_CONTAINER { + unsigned int key_index; + SM2_KEY sign_key; + SM2_KEY enc_key; + struct SOFTSDF_CONTAINER *next; +}; +typedef struct SOFTSDF_CONTAINER SOFTSDF_CONTAINER; + +struct SOFTSDF_SESSION { + SOFTSDF_CONTAINER *container_list; + SOFTSDF_KEY *key_list; + SM3_CTX sm3_ctx; + struct SOFTSDF_SESSION *next; +}; +typedef struct SOFTSDF_SESSION SOFTSDF_SESSION; + +struct SOFTSDF_DEVICE { + SOFTSDF_SESSION *session_list; +}; +typedef struct SOFTSDF_DEVICE SOFTSDF_DEVICE; + +SOFTSDF_DEVICE *deviceHandle = NULL; + + + +#define FILENAME_MAX_LEN 256 + + + +int SDF_OpenDevice( + void **phDeviceHandle) +{ + if (phDeviceHandle == NULL) { + error_print(); + return SDR_INARGERR; + } + + if (deviceHandle != NULL) { + error_print(); + return SDR_OPENDEVICE; + } + + deviceHandle = (SOFTSDF_DEVICE *)malloc(sizeof(SOFTSDF_DEVICE)); + if (deviceHandle == NULL) { + error_print(); + return SDR_OPENDEVICE; + } + memset(deviceHandle, 0, sizeof(SOFTSDF_DEVICE)); + + *phDeviceHandle = deviceHandle; + return SDR_OK; +} + +int SDF_CloseDevice( + void *hDeviceHandle) +{ + if (hDeviceHandle != deviceHandle) { + error_print(); + return SDR_INARGERR; + } + + if (deviceHandle != NULL) { + while (deviceHandle->session_list) { + if (SDF_CloseSession(deviceHandle->session_list) != SDR_OK) { + error_print(); + } + } + } + + memset(deviceHandle, 0, sizeof(SOFTSDF_DEVICE)); + free(deviceHandle); + deviceHandle = NULL; + + return SDR_OK; +} + + +int SDF_OpenSession( + void *hDeviceHandle, + void **phSessionHandle) +{ + SOFTSDF_SESSION *session; + + if (hDeviceHandle == NULL || hDeviceHandle != deviceHandle) { + error_print(); + return SDR_INARGERR; + } + + if (phSessionHandle == NULL) { + error_print(); + return SDR_INARGERR; + } + + if (!(session = (SOFTSDF_SESSION *)malloc(sizeof(*session)))) { + error_print(); + return SDR_GMSSLERR; + } + memset(session, 0, sizeof(*session)); + + // append session to session_list + if (deviceHandle->session_list == NULL) { + deviceHandle->session_list = session; + } else { + SOFTSDF_SESSION *current = deviceHandle->session_list; + while (current->next != NULL) { + current = current->next; + } + current->next = session; + } + + *phSessionHandle = session; + return SDR_OK; +} + +int SDF_CloseSession( + void *hSessionHandle) +{ + SOFTSDF_SESSION *current_session; + SOFTSDF_SESSION *next_session; + SOFTSDF_SESSION *prev_session; + SOFTSDF_CONTAINER *current_container; + SOFTSDF_CONTAINER *next_container; + SOFTSDF_KEY *current_key; + SOFTSDF_KEY *next_key; + + if (deviceHandle == NULL) { + error_print(); + return SDR_INARGERR; + } + + if (hSessionHandle == NULL) { + error_print(); + return SDR_INARGERR; + } + + // find hSessionHandle in session_list + current_session = deviceHandle->session_list; + prev_session = NULL; + while (current_session != NULL && current_session != hSessionHandle) { + prev_session = current_session; + current_session = current_session->next; + } + if (current_session == NULL) { + error_print(); + return SDR_INARGERR; + } + + // free container_list + current_container = current_session->container_list; + while (current_container != NULL) { + next_container = current_container->next; + memset(current_container, 0, sizeof(*current_container)); + free(current_container); + current_container = next_container; + } + + // free key_list + current_key = current_session->key_list; + while (current_key != NULL) { + next_key = current_key->next; + memset(current_key, 0, sizeof(*current_key)); + free(current_key); + current_key = next_key; + } + + // delete current_session from session_list + if (prev_session == NULL) { + deviceHandle->session_list = current_session->next; + } else { + prev_session->next = current_session->next; + } + memset(current_session, 0, sizeof(*current_session)); + free(current_session); + + return SDR_OK; +} + +#define SOFTSDF_DEV_DATE "20231227" +#define SOFTSDF_DEV_BATCH_NUM "001" +#define SOFTSDF_DEV_SERIAL_NUM "00123" +#define SOFTSDF_DEV_SERIAL SOFTSDF_DEV_DATE \ + SOFTSDF_DEV_BATCH_NUM \ + SOFTSDF_DEV_SERIAL_NUM + +int SDF_GetDeviceInfo( + void *hSessionHandle, + DEVICEINFO *pstDeviceInfo) +{ + SOFTSDF_SESSION *session; + + if (deviceHandle == NULL) { + error_print(); + return SDR_STEPERR; + } + + if (hSessionHandle == NULL) { + error_print(); + return SDR_INARGERR; + } + session = deviceHandle->session_list; + while (session != NULL && session != hSessionHandle) { + session = session->next; + } + if (session == NULL) { + error_print(); + return SDR_INARGERR; + } + + if (pstDeviceInfo == NULL) { + error_print(); + return SDR_INARGERR; + } + + memset(pstDeviceInfo, 0, sizeof(*pstDeviceInfo)); + strncpy((char *)pstDeviceInfo->IssuerName, "GmSSL Project (http://gmssl.org)", + sizeof(pstDeviceInfo->IssuerName)); + strncpy((char *)pstDeviceInfo->DeviceName, "Soft SDF", + sizeof(pstDeviceInfo->DeviceName)); + strncpy((char *)pstDeviceInfo->DeviceSerial, SOFTSDF_DEV_SERIAL, + sizeof(pstDeviceInfo->DeviceSerial)); + pstDeviceInfo->DeviceVersion = 1; + pstDeviceInfo->StandardVersion = 1; + pstDeviceInfo->AsymAlgAbility[0] = SGD_SM2_1|SGD_SM2_3; + pstDeviceInfo->AsymAlgAbility[1] = 256; + pstDeviceInfo->SymAlgAbility = SGD_SM4|SGD_CBC|SGD_MAC; + pstDeviceInfo->HashAlgAbility = SGD_SM3; + pstDeviceInfo->BufferSize = 256*1024; + + return SDR_OK; +} + +int SDF_GenerateRandom( + void *hSessionHandle, + unsigned int uiLength, + unsigned char *pucRandom) +{ + SOFTSDF_SESSION *session; + + if (deviceHandle == NULL) { + error_print(); + return SDR_STEPERR; + } + + if (hSessionHandle == NULL) { + error_puts("Invalid session handle"); + return SDR_INARGERR; + } + session = deviceHandle->session_list; + while (session != NULL && session != hSessionHandle) { + session = session->next; + } + if (session == NULL) { + error_print(); + return SDR_INARGERR; + } + + if (pucRandom == NULL || uiLength == 0) { + error_puts("Invalid output buffer or length"); + return SDR_INARGERR; + } + if (uiLength > RAND_BYTES_MAX_SIZE) { + error_print(); + return SDR_INARGERR; + } + + if (rand_bytes(pucRandom, uiLength) != 1) { + error_print(); + return SDR_GMSSLERR; + } + + return SDR_OK; +} + +int SDF_GetPrivateKeyAccessRight( + void *hSessionHandle, + unsigned int uiKeyIndex, + unsigned char *pucPassword, + unsigned int uiPwdLength) +{ + int ret = SDR_OK; + SOFTSDF_SESSION *session; + SOFTSDF_CONTAINER *container = NULL; + char *pass = NULL; + char filename[FILENAME_MAX_LEN]; + FILE *file = NULL; + + if (deviceHandle == NULL) { + error_print(); + return SDR_STEPERR; + } + + if (hSessionHandle == NULL) { + error_puts("Invalid session handle"); + return SDR_INARGERR; + } + session = deviceHandle->session_list; + while (session != NULL && session != hSessionHandle) { + session = session->next; + } + if (session == NULL) { + error_print(); + return SDR_INARGERR; + } + + if (pucPassword == NULL || uiPwdLength == 0) { + error_puts("Invalid password or password length"); + return SDR_INARGERR; + } + pass = (char *)malloc(uiPwdLength + 1); + if (pass == NULL) { + error_print(); + return SDR_NOBUFFER; + } + memcpy(pass, pucPassword, uiPwdLength); + pass[uiPwdLength] = 0; + if (strlen(pass) != uiPwdLength) { + error_print(); + ret = SDR_INARGERR; + goto end; + } + + // create container + container = (SOFTSDF_CONTAINER *)malloc(sizeof(*container)); + if (container == NULL) { + error_print(); + ret = SDR_NOBUFFER; + goto end; + } + memset(container, 0, sizeof(*container)); + container->key_index = uiKeyIndex; + + // load sign_key + snprintf(filename, FILENAME_MAX_LEN, "sm2sign-%u.pem", uiKeyIndex); + file = fopen(filename, "r"); + if (file == NULL) { + perror("Error opening file"); + ret = SDR_KEYNOTEXIST; + goto end; + } + if (sm2_private_key_info_decrypt_from_pem(&container->sign_key, pass, file) != 1) { + error_print(); + ret = SDR_GMSSLERR; + goto end; + } + fclose(file); + + // load enc_key + snprintf(filename, FILENAME_MAX_LEN, "sm2enc-%u.pem", uiKeyIndex); + file = fopen(filename, "r"); + if (file == NULL) { + perror("Error opening file"); + ret = SDR_KEYNOTEXIST; + goto end; + } + if (sm2_private_key_info_decrypt_from_pem(&container->enc_key, pass, file) != 1) { + error_print(); + ret = SDR_GMSSLERR; + goto end; + } + + // append container to container_list + if (session->container_list == NULL) { + session->container_list = container; + } else { + SOFTSDF_CONTAINER *current = session->container_list; + while (current->next != NULL) { + current = current->next; + } + current->next = container; + } + + container = NULL; + ret = SDR_OK; +end: + if (container) { + memset(container, 0, sizeof(*container)); + free(container); + } + if (pass) { + memset(pass, 0, uiPwdLength); + free(pass); + } + if (file) fclose(file); + return ret; +} + +int SDF_ReleasePrivateKeyAccessRight( + void *hSessionHandle, + unsigned int uiKeyIndex) +{ + SOFTSDF_SESSION *session; + SOFTSDF_CONTAINER *current_container; + SOFTSDF_CONTAINER *prev_container; + + if (deviceHandle == NULL) { + error_print(); + return SDR_STEPERR; + } + + if (hSessionHandle == NULL) { + error_puts("Invalid session handle"); + return SDR_INARGERR; + } + session = deviceHandle->session_list; + while (session != NULL && session != hSessionHandle) { + session = session->next; + } + if (session == NULL) { + error_print(); + return SDR_INARGERR; + } + + // delete container in container_list with uiKeyIndex + current_container = session->container_list; + prev_container = NULL; + while (current_container != NULL && current_container->key_index != uiKeyIndex) { + prev_container = current_container; + current_container = current_container->next; + } + if (current_container == NULL) { + error_print(); + return SDR_INARGERR; + } + if (prev_container == NULL) { + session->container_list = current_container->next; + } else { + prev_container->next = current_container->next; + } + memset(current_container, 0, sizeof(*current_container)); + free(current_container); + + return SDR_OK; +} + +int SDF_ExportSignPublicKey_RSA( + void *hSessionHandle, + unsigned int uiKeyIndex, + RSArefPublicKey *pucPublicKey) +{ + error_print(); + return SDR_NOTSUPPORT; +} + +int SDF_ExportEncPublicKey_RSA( + void *hSessionHandle, + unsigned int uiKeyIndex, + RSArefPublicKey *pucPublicKey) +{ + error_print(); + return SDR_NOTSUPPORT; +} + +int SDF_GenerateKeyPair_RSA( + void *hSessionHandle, + unsigned int uiKeyBits, + RSArefPublicKey *pucPublicKey, + RSArefPrivateKey *pucPrivateKey) +{ + error_print(); + return SDR_NOTSUPPORT; +} + +int SDF_GenerateKeyWithIPK_RSA( + void *hSessionHandle, + unsigned int uiIPKIndex, + unsigned int uiKeyBits, + unsigned char *pucKey, + unsigned int *puiKeyLength, + void **phKeyHandle) +{ + error_print(); + return SDR_NOTSUPPORT; +} + +int SDF_GenerateKeyWithEPK_RSA( + void *hSessionHandle, + unsigned int uiKeyBits, + RSArefPublicKey *pucPublicKey, + unsigned char *pucKey, + unsigned int *puiKeyLength, + void **phKeyHandle) +{ + error_print(); + return SDR_NOTSUPPORT; +} + +int SDF_ImportKeyWithISK_RSA( + void *hSessionHandle, + unsigned int uiISKIndex, + unsigned char *pucKey, + unsigned int uiKeyLength, + void **phKeyHandle) +{ + error_print(); + return SDR_NOTSUPPORT; +} + +int SDF_ExchangeDigitEnvelopeBaseOnRSA( + void *hSessionHandle, + unsigned int uiKeyIndex, + RSArefPublicKey *pucPublicKey, + unsigned char *pucDEInput, + unsigned int uiDELength, + unsigned char *pucDEOutput, + unsigned int *puiDELength) +{ + error_print(); + return SDR_NOTSUPPORT; +} + + +int SDF_ExportSignPublicKey_ECC( + void *hSessionHandle, + unsigned int uiKeyIndex, + ECCrefPublicKey *pucPublicKey) +{ + SOFTSDF_SESSION *session; + SOFTSDF_CONTAINER *container; + + if (deviceHandle == NULL) { + error_print(); + return SDR_STEPERR; + } + + if (hSessionHandle == NULL) { + error_puts("Invalid session handle"); + return SDR_INARGERR; + } + session = deviceHandle->session_list; + while (session != NULL && session != hSessionHandle) { + session = session->next; + } + if (session == NULL) { + error_print(); + return SDR_INARGERR; + } + + container = session->container_list; + while (container != NULL && container->key_index != uiKeyIndex) { + container = container->next; + } + if (container == NULL) { + error_print(); + return SDR_INARGERR; + } + + if (pucPublicKey == NULL) { + error_print(); + return SDR_INARGERR; + } + + memset(pucPublicKey, 0, sizeof(*pucPublicKey)); + pucPublicKey->bits = 256; + memcpy(pucPublicKey->x + ECCref_MAX_LEN - 32, container->sign_key.public_key.x, 32); + memcpy(pucPublicKey->y + ECCref_MAX_LEN - 32, container->sign_key.public_key.y, 32); + + return SDR_OK; +} + +int SDF_ExportEncPublicKey_ECC( + void *hSessionHandle, + unsigned int uiKeyIndex, + ECCrefPublicKey *pucPublicKey) +{ + SOFTSDF_SESSION *session; + SOFTSDF_CONTAINER *container; + + if (deviceHandle == NULL) { + error_print(); + return SDR_STEPERR; + } + + if (hSessionHandle == NULL) { + error_puts("Invalid session handle"); + return SDR_INARGERR; + } + session = deviceHandle->session_list; + while (session != NULL && session != hSessionHandle) { + session = session->next; + } + if (session == NULL) { + error_print(); + return SDR_INARGERR; + } + + container = session->container_list; + while (container != NULL && container->key_index != uiKeyIndex) { + container = container->next; + } + if (container == NULL) { + error_print(); + return SDR_INARGERR; + } + + if (pucPublicKey == NULL) { + error_print(); + return SDR_INARGERR; + } + + memset(pucPublicKey, 0, sizeof(*pucPublicKey)); + pucPublicKey->bits = 256; + memcpy(pucPublicKey->x + ECCref_MAX_LEN - 32, container->enc_key.public_key.x, 32); + memcpy(pucPublicKey->y + ECCref_MAX_LEN - 32, container->enc_key.public_key.y, 32); + + return SDR_OK; +} + +int SDF_GenerateKeyPair_ECC( + void *hSessionHandle, + unsigned int uiAlgID, + unsigned int uiKeyBits, + ECCrefPublicKey *pucPublicKey, + ECCrefPrivateKey *pucPrivateKey) +{ + SOFTSDF_SESSION *session; + SM2_KEY sm2_key; + + if (deviceHandle == NULL) { + error_print(); + return SDR_STEPERR; + } + + if (hSessionHandle == NULL) { + error_puts("Invalid session handle"); + return SDR_INARGERR; + } + session = deviceHandle->session_list; + while (session != NULL && session != hSessionHandle) { + session = session->next; + } + if (session == NULL) { + error_print(); + return SDR_INARGERR; + } + + if (uiAlgID != SGD_SM2_1 || uiAlgID != SGD_SM2_3) { + error_print(); + return SDR_INARGERR; + } + + if (uiKeyBits != 256) { + error_print(); + return SDR_INARGERR; + } + + if (pucPublicKey == NULL || pucPrivateKey == NULL) { + error_print(); + return SDR_INARGERR; + } + + if (sm2_key_generate(&sm2_key) != 1) { + error_print(); + return SDR_GMSSLERR; + } + + memset(pucPublicKey, 0, sizeof(*pucPublicKey)); + pucPublicKey->bits = 256; + memcpy(pucPublicKey->x + ECCref_MAX_LEN - 32, sm2_key.public_key.x, 32); + memcpy(pucPublicKey->y + ECCref_MAX_LEN - 32, sm2_key.public_key.y, 32); + + memset(pucPrivateKey, 0, sizeof(*pucPrivateKey)); + pucPrivateKey->bits = 256; + memcpy(pucPrivateKey->K + ECCref_MAX_LEN - 32, sm2_key.private_key, 32); + + memset(&sm2_key, 0, sizeof(sm2_key)); + return SDR_OK; +} + +int SDF_GenerateKeyWithIPK_ECC( + void *hSessionHandle, + unsigned int uiIPKIndex, + unsigned int uiKeyBits, + ECCCipher *pucKey, + void **phKeyHandle) +{ + SOFTSDF_SESSION *session; + SOFTSDF_CONTAINER *container; + SOFTSDF_KEY *key; + SM2_CIPHERTEXT ctxt; + + if (deviceHandle == NULL) { + error_print(); + return SDR_STEPERR; + } + + if (hSessionHandle == NULL) { + error_puts("Invalid session handle"); + return SDR_INARGERR; + } + session = deviceHandle->session_list; + while (session != NULL && session != hSessionHandle) { + session = session->next; + } + if (session == NULL) { + error_print(); + return SDR_INARGERR; + } + + container = session->container_list; + while (container != NULL && container->key_index != uiIPKIndex) { + container = container->next; + } + if (container == NULL) { + error_print(); + return SDR_INARGERR; + } + + if (uiKeyBits%8 != 0 || uiKeyBits/8 > SOFTSDF_MAX_KEY_SIZE) { + error_print(); + return SDR_INARGERR; + } + + if (pucKey == NULL) { + error_print(); + return SDR_INARGERR; + } + + if (phKeyHandle == NULL) { + error_print(); + return SDR_INARGERR; + } + + // generate key + key = (SOFTSDF_KEY *)malloc(sizeof(*key)); + if (key == NULL) { + error_print(); + return SDR_NOBUFFER; + } + memset(key, 0, sizeof(*key)); + if (rand_bytes(key->key, uiKeyBits/8) != 1) { + error_print(); + free(key); + return SDR_GMSSLERR; + } + key->key_size = uiKeyBits/8; + + // encrypt key with container + if (sm2_do_encrypt(&container->enc_key, key->key, key->key_size, &ctxt) != 1) { + error_print(); + free(key); + return SDR_GMSSLERR; + } + memset(pucKey, 0, sizeof(*pucKey)); + memcpy(pucKey->x + ECCref_MAX_LEN - 32, ctxt.point.x, 32); + memcpy(pucKey->y + ECCref_MAX_LEN - 32, ctxt.point.y, 32); + memcpy(pucKey->M, ctxt.hash, 32); + pucKey->L = ctxt.ciphertext_size; + memcpy(pucKey->C, ctxt.ciphertext, ctxt.ciphertext_size); + + // append key to key_list + if (session->key_list == NULL) { + session->key_list = key; + } else { + SOFTSDF_KEY *current = session->key_list; + while (current->next != NULL) { + current = current->next; + } + current->next = key; + } + + *phKeyHandle = key; + return SDR_OK; +} + +int SDF_GenerateKeyWithEPK_ECC( + void *hSessionHandle, + unsigned int uiKeyBits, + unsigned int uiAlgID, + ECCrefPublicKey *pucPublicKey, + ECCCipher *pucKey, + void **phKeyHandle) +{ + SOFTSDF_SESSION *session; + SM2_KEY sm2_key; + SOFTSDF_KEY *key; + SM2_CIPHERTEXT ctxt; + + if (deviceHandle == NULL) { + error_print(); + return SDR_STEPERR; + } + + if (hSessionHandle == NULL) { + error_puts("Invalid session handle"); + return SDR_INARGERR; + } + session = deviceHandle->session_list; + while (session != NULL && session != hSessionHandle) { + session = session->next; + } + if (session == NULL) { + error_print(); + return SDR_INARGERR; + } + + if (uiKeyBits%8 != 0 || uiKeyBits/8 > SOFTSDF_MAX_KEY_SIZE) { + error_print(); + return SDR_INARGERR; + } + + if (uiAlgID != SGD_SM2_3) { + error_print(); + return SDR_INARGERR; + } + + if (pucPublicKey == NULL || pucKey == NULL || phKeyHandle == NULL) { + error_print(); + return SDR_INARGERR; + } + + // load public key + memset(&sm2_key, 0, sizeof(sm2_key)); + memcpy(sm2_key.public_key.x, pucPublicKey->x + ECCref_MAX_LEN - 32, 32); + memcpy(sm2_key.public_key.y, pucPublicKey->y + ECCref_MAX_LEN - 32, 32); + if (sm2_point_is_on_curve(&sm2_key.public_key) != 1) { + error_print(); + return SDR_INARGERR; + } + + // generate key + key = (SOFTSDF_KEY *)malloc(sizeof(*key)); + if (key == NULL) { + error_print(); + return SDR_NOBUFFER; + } + memset(key, 0, sizeof(*key)); + if (rand_bytes(key->key, uiKeyBits/8) != 1) { + error_print(); + free(key); + return SDR_GMSSLERR; + } + key->key_size = uiKeyBits/8; + + // encrypt key with external public key + if (sm2_do_encrypt(&sm2_key, key->key, key->key_size, &ctxt) != 1) { + error_print(); + free(key); + return SDR_GMSSLERR; + } + memset(pucKey, 0, sizeof(*pucKey)); + memcpy(pucKey->x + ECCref_MAX_LEN - 32, ctxt.point.x, 32); + memcpy(pucKey->y + ECCref_MAX_LEN - 32, ctxt.point.y, 32); + memcpy(pucKey->M, ctxt.hash, 32); + pucKey->L = ctxt.ciphertext_size; + memcpy(pucKey->C, ctxt.ciphertext, ctxt.ciphertext_size); + + *phKeyHandle = key; + return SDR_OK; +} + +int SDF_ImportKeyWithISK_ECC( + void *hSessionHandle, + unsigned int uiISKIndex, + ECCCipher *pucKey, + void **phKeyHandle) +{ + SOFTSDF_SESSION *session; + SOFTSDF_CONTAINER *container; + SM2_CIPHERTEXT ctxt; + SOFTSDF_KEY *key; + + if (deviceHandle == NULL) { + error_print(); + return SDR_STEPERR; + } + + if (hSessionHandle == NULL) { + error_puts("Invalid session handle"); + return SDR_INARGERR; + } + session = deviceHandle->session_list; + while (session != NULL && session != hSessionHandle) { + session = session->next; + } + if (session == NULL) { + error_print(); + return SDR_INARGERR; + } + + container = session->container_list; + while (container != NULL && container->key_index != uiISKIndex) { + container = container->next; + } + if (container == NULL) { + error_print(); + return SDR_INARGERR; + } + + if (pucKey == NULL) { + error_print(); + return SDR_INARGERR; + } + if (pucKey->L > SM2_MAX_PLAINTEXT_SIZE) { + error_print(); + return SDR_INARGERR; + } + if (pucKey->L > SOFTSDF_MAX_KEY_SIZE) { + error_print(); + return SDR_INARGERR; + } + + if (phKeyHandle == NULL) { + error_print(); + return SDR_INARGERR; + } + + // create key + key = (SOFTSDF_KEY *)malloc(sizeof(*key)); + if (key == NULL) { + error_print(); + return SDR_NOBUFFER; + } + memset(key, 0, sizeof(*key)); + + // decrypt key + memset(&ctxt, 0, sizeof(ctxt)); + memcpy(ctxt.point.x, pucKey->x + ECCref_MAX_LEN - 32, 32); + memcpy(ctxt.point.y, pucKey->y + ECCref_MAX_LEN - 32, 32); + memcpy(ctxt.hash, pucKey->M, 32); + memcpy(ctxt.ciphertext, pucKey->C, pucKey->L); + ctxt.ciphertext_size = pucKey->L; + + if (sm2_do_decrypt(&container->enc_key, &ctxt, key->key, &key->key_size) != 1) { + error_print(); + free(key); + return SDR_GMSSLERR; + } + + // append key to key_list + if (session->key_list == NULL) { + session->key_list = key; + } else { + SOFTSDF_KEY *current = session->key_list; + while (current->next != NULL) { + current = current->next; + } + current->next = key; + } + + *phKeyHandle = key; + return SDR_OK; +} + +int SDF_GenerateAgreementDataWithECC( + void *hSessionHandle, + unsigned int uiISKIndex, + unsigned int uiKeyBits, + unsigned char *pucSponsorID, + unsigned int uiSponsorIDLength, + ECCrefPublicKey *pucSponsorPublicKey, + ECCrefPublicKey *pucSponsorTmpPublicKey, + void **phAgreementHandle) +{ + error_print(); + return SDR_NOTSUPPORT; +} + +int SDF_GenerateKeyWithECC( + void *hSessionHandle, + unsigned char *pucResponseID, + unsigned int uiResponseIDLength, + ECCrefPublicKey *pucResponsePublicKey, + ECCrefPublicKey *pucResponseTmpPublicKey, + void *hAgreementHandle, + void **phKeyHandle) +{ + error_print(); + return SDR_NOTSUPPORT; +} + +int SDF_GenerateAgreementDataAndKeyWithECC( + void *hSessionHandle, + unsigned int uiISKIndex, + unsigned int uiKeyBits, + unsigned char *pucResponseID, + unsigned int uiResponseIDLength, + unsigned char *pucSponsorID, + unsigned int uiSponsorIDLength, + ECCrefPublicKey *pucSponsorPublicKey, + ECCrefPublicKey *pucSponsorTmpPublicKey, + ECCrefPublicKey *pucResponsePublicKey, + ECCrefPublicKey *pucResponseTmpPublicKey, + void **phKeyHandle) +{ + error_print(); + return SDR_NOTSUPPORT; +} + +int SDF_ExchangeDigitEnvelopeBaseOnECC( + void *hSessionHandle, + unsigned int uiKeyIndex, + unsigned int uiAlgID, + ECCrefPublicKey *pucPublicKey, + ECCCipher *pucEncDataIn, + ECCCipher *pucEncDataOut) +{ + error_print(); + return SDR_NOTSUPPORT; +} + +int SDF_GenerateKeyWithKEK( + void *hSessionHandle, + unsigned int uiKeyBits, + unsigned int uiAlgID, // SGD_SM4_CBC, 用于加密生成的密钥 + unsigned int uiKEKIndex, // 这是一个本地文件 + unsigned char *pucKey, // CBC秘闻 + unsigned int *puiKeyLength, + void **phKeyHandle) +{ + SOFTSDF_SESSION *session; + char filename[FILENAME_MAX_LEN]; + FILE *file; + uint8_t kek[16]; + SM4_KEY sm4_key; + uint8_t *iv; + uint8_t *enced; + size_t enced_len; + SOFTSDF_KEY *key; + + if (deviceHandle == NULL) { + error_print(); + return SDR_STEPERR; + } + + if (hSessionHandle == NULL) { + error_print(); + return SDR_INARGERR; + } + session = deviceHandle->session_list; + while (session != NULL && session != hSessionHandle) { + session = session->next; + } + if (session == NULL) { + error_print(); + return SDR_INARGERR; + } + + if (uiKeyBits % 8 != 0 || uiKeyBits/8 > SOFTSDF_MAX_KEY_SIZE) { + error_print(); + return SDR_INARGERR; + } + + if (uiAlgID != SGD_SM4_CBC) { + error_print(); + return SDR_INARGERR; + } + + // load KEK file with index + snprintf(filename, FILENAME_MAX_LEN, "kek-%u.key", uiKEKIndex); + file = fopen(filename, "rb"); + if (file == NULL) { + error_print(); + return SDR_KEYNOTEXIST; + } + if (fread(kek, 1, sizeof(kek), file) != sizeof(kek)) { + error_print(); + fclose(file); + return SDR_INARGERR; + } + fclose(file); + + if (pucKey == NULL || puiKeyLength == NULL) { + error_print(); + return SDR_INARGERR; + } + + if (phKeyHandle == NULL) { + error_print(); + return SDR_INARGERR; + } + + // generate key + key = (SOFTSDF_KEY *)malloc(sizeof(SOFTSDF_KEY)); + if (key == NULL) { + error_print(); + return SDR_GMSSLERR; + } + memset(key, 0, sizeof(*key)); + + iv = pucKey; + enced = pucKey + SM4_BLOCK_SIZE; + + if (rand_bytes(iv, SM4_BLOCK_SIZE) != 1) { + error_print(); + return SDR_GMSSLERR; + } + + key->key_size = uiKeyBits/8; + if (rand_bytes(key->key, key->key_size) != 1) { + error_print(); + free(key); + return SDR_GMSSLERR; + } + + sm4_set_encrypt_key(&sm4_key, kek); + if (sm4_cbc_padding_encrypt(&sm4_key, iv, key->key, key->key_size, enced, &enced_len) != 1) { + error_print(); + memset(&sm4_key, 0, sizeof(sm4_key)); + free(key); + return SDR_GMSSLERR; + } + memset(&sm4_key, 0, sizeof(sm4_key)); + *puiKeyLength = enced_len; + + // append key to key_list + if (session->key_list == NULL) { + session->key_list = key; + } else { + SOFTSDF_KEY *current = session->key_list; + while (current->next != NULL) { + current = current->next; + } + current->next = key; + } + + *phKeyHandle = key; + return SDR_OK; +} + +int SDF_ImportKeyWithKEK( + void *hSessionHandle, + unsigned int uiAlgID, // 这是对称加密算法,应该使用什么算法呢?实际上我们整个只支持一个带填充的SM4_CBC + unsigned int uiKEKIndex, + unsigned char *pucKey, + unsigned int uiKeyLength, + void **phKeyHandle) +{ + SOFTSDF_SESSION *session; + char filename[FILENAME_MAX_LEN]; + FILE *file; + uint8_t kek[16]; + SM4_KEY sm4_key; + const uint8_t *iv; + const uint8_t *enced; + size_t enced_len; + SOFTSDF_KEY *key; + + if (deviceHandle == NULL) { + error_print(); + return SDR_STEPERR; + } + + if (hSessionHandle == NULL) { + error_print(); + return SDR_INARGERR; + } + session = deviceHandle->session_list; + while (session != NULL && session != hSessionHandle) { + session = session->next; + } + if (session == NULL) { + error_print(); + return SDR_INARGERR; + } + + if (uiAlgID != SGD_SM4_CBC) { + error_print(); + return SDR_INARGERR; + } + + // load KEK file with index + snprintf(filename, FILENAME_MAX_LEN, "kek-%u.key", uiKEKIndex); + file = fopen(filename, "rb"); + if (file == NULL) { + error_print(); + return SDR_KEYNOTEXIST; + } + if (fread(kek, 1, sizeof(kek), file) != sizeof(kek)) { + error_print(); + fclose(file); + return SDR_INARGERR; + } + fclose(file); + + + // decrypt SM4-CBC encrypted pucKey + if (pucKey == NULL || uiKeyLength <= SM4_BLOCK_SIZE) { + error_print(); + return SDR_INARGERR; + } + if (uiKeyLength > SM4_BLOCK_SIZE + SOFTSDF_MAX_KEY_SIZE) { + error_print(); + return SDR_INARGERR; + } + + key = (SOFTSDF_KEY *)malloc(sizeof(SOFTSDF_KEY)); + if (key == NULL) { + error_print(); + return SDR_GMSSLERR; + } + memset(key, 0, sizeof(*key)); + + iv = pucKey; + enced = pucKey + SM4_BLOCK_SIZE; + enced_len = uiKeyLength - SM4_BLOCK_SIZE; + + sm4_set_decrypt_key(&sm4_key, kek); + if (sm4_cbc_padding_decrypt(&sm4_key, iv, enced, enced_len, key->key, &key->key_size) != 1) { + error_print(); + memset(&sm4_key, 0, sizeof(sm4_key)); + free(key); + return SDR_GMSSLERR; + } + memset(&sm4_key, 0, sizeof(sm4_key)); + + // append key to key_list + if (session->key_list == NULL) { + session->key_list = key; + } else { + SOFTSDF_KEY *current = session->key_list; + while (current->next != NULL) { + current = current->next; + } + current->next = key; + } + + *phKeyHandle = key; + return SDR_OK; +} + +int SDF_DestroyKey( + void *hSessionHandle, + void *hKeyHandle) +{ + SOFTSDF_SESSION *session; + SOFTSDF_KEY *current; + SOFTSDF_KEY *prev; + + if (deviceHandle == NULL) { + error_print(); + return SDR_STEPERR; + } + + if (hSessionHandle == NULL) { + error_print(); + return SDR_INARGERR; + } + session = deviceHandle->session_list; + while (session != NULL && session != hSessionHandle) { + session = session->next; + } + if (session == NULL) { + error_print(); + return SDR_INARGERR; + } + + if (hKeyHandle == NULL) { + error_print(); + return SDR_INARGERR; + } + + current = session->key_list; + prev = NULL; + while (current != NULL && current != (SOFTSDF_KEY *)hKeyHandle) { + prev = current; + current = current->next; + } + if (current == NULL) { + error_print(); + return SDR_KEYNOTEXIST; + } + if (prev == NULL) { + session->key_list = current->next; + } else { + prev->next = current->next; + } + memset(current, 0, sizeof(SOFTSDF_KEY)); + free(current); + + return SDR_OK; +} + +int SDF_ExternalPublicKeyOperation_RSA( + void *hSessionHandle, + RSArefPublicKey *pucPublicKey, + unsigned char *pucDataInput, + unsigned int uiInputLength, + unsigned char *pucDataOutput, + unsigned int *puiOutputLength) +{ + error_print(); + return SDR_NOTSUPPORT; +} + +int SDF_ExternalPrivateKeyOperation_RSA( + void *hSessionHandle, + RSArefPrivateKey *pucPrivateKey, + unsigned char *pucDataInput, + unsigned int uiInputLength, + unsigned char *pucDataOutput, + unsigned int *puiOutputLength) +{ + error_print(); + return SDR_NOTSUPPORT; +} + +int SDF_InternalPrivateKeyOperation_RSA( + void *hSessionHandle, + unsigned int uiKeyIndex, + unsigned char *pucDataInput, + unsigned int uiInputLength, + unsigned char *pucDataOutput, + unsigned int *puiOutputLength) +{ + error_print(); + return SDR_NOTSUPPORT; +} + +int SDF_ExternalVerify_ECC( + void *hSessionHandle, + unsigned int uiAlgID, + ECCrefPublicKey *pucPublicKey, + unsigned char *pucDataInput, + unsigned int uiInputLength, + ECCSignature *pucSignature) +{ + SOFTSDF_SESSION *session; + SM2_KEY sm2_key; + SM2_SIGNATURE sig; + unsigned int i; + + if (deviceHandle == NULL) { + error_print(); + return SDR_STEPERR; + } + + if (hSessionHandle == NULL) { + error_print(); + return SDR_INARGERR; + } + session = deviceHandle->session_list; + while (session != NULL && session != hSessionHandle) { + session = session->next; + } + if (session == NULL) { + error_print(); + return SDR_INARGERR; + } + + if (uiAlgID != SGD_SM2_1) { + error_print(); + return SDR_INARGERR; + } + + if (pucPublicKey == NULL) { + error_print(); + return SDR_INARGERR; + } + + if (pucPublicKey->bits != 256) { + error_print(); + return SDR_INARGERR; + } + + memset(&sm2_key, 0, sizeof(sm2_key)); + memcpy(sm2_key.public_key.x, pucPublicKey->x + ECCref_MAX_LEN - 32, 32); + memcpy(sm2_key.public_key.y, pucPublicKey->y + ECCref_MAX_LEN - 32, 32); + if (sm2_point_is_on_curve(&sm2_key.public_key) != 1) { + error_print(); + return SDR_INARGERR; + } + + if (pucDataInput == NULL || uiInputLength != 32) { + error_print(); + return SDR_INARGERR; + } + + if (pucSignature == NULL) { + error_print(); + return SDR_INARGERR; + } + for (i = 0; i < ECCref_MAX_LEN - 32; i++) { + if (pucSignature->r[i] != 0) { + error_print(); + return SDR_INARGERR; + } + } + for (i = 0; i < ECCref_MAX_LEN - 32; i++) { + if (pucSignature->s[i] != 0) { + error_print(); + return SDR_INARGERR; + } + } + + memcpy(sig.r, pucSignature->r + ECCref_MAX_LEN - 32, 32); + memcpy(sig.s, pucSignature->s + ECCref_MAX_LEN - 32, 32); + + if (sm2_do_verify(&sm2_key, pucDataInput, &sig) != 1) { + error_print(); + return SDR_VERIFYERR; + } + + return SDR_OK; +} + +int SDF_InternalSign_ECC( + void *hSessionHandle, + unsigned int uiISKIndex, + unsigned char *pucData, + unsigned int uiDataLength, + ECCSignature *pucSignature) +{ + SOFTSDF_SESSION *session; + SOFTSDF_CONTAINER *container; + SM2_SIGNATURE sig; + + if (deviceHandle == NULL) { + error_print(); + return SDR_STEPERR; + } + + if (!hSessionHandle) { + error_print(); + return SDR_INARGERR; + } + session = deviceHandle->session_list; + while (session != NULL && session != hSessionHandle) { + session = session->next; + } + if (session == NULL) { + error_print(); + return SDR_INARGERR; + } + + // find container with key index + container = session->container_list; + while (container != NULL && container->key_index != uiISKIndex) { + container = container->next; + } + if (container == NULL) { + error_print(); + return SDR_INARGERR; + } + + if (pucData == NULL || uiDataLength != SM3_DIGEST_SIZE) { + error_print(); + return SDR_INARGERR; + } + + if (pucSignature == NULL) { + error_print(); + return SDR_INARGERR; + } + + if (sm2_do_sign(&container->sign_key, pucData, &sig) != 1) { + error_print(); + return SDR_GMSSLERR; + } + + memset(pucSignature, 0, sizeof(*pucSignature)); + memcpy(pucSignature->r + ECCref_MAX_LEN - 32, sig.r, 32); + memcpy(pucSignature->s + ECCref_MAX_LEN - 32, sig.s, 32); + + return SDR_OK; +} + +int SDF_InternalVerify_ECC( + void *hSessionHandle, + unsigned int uiIPKIndex, + unsigned char *pucData, + unsigned int uiDataLength, + ECCSignature *pucSignature) +{ + SOFTSDF_SESSION *session; + SOFTSDF_CONTAINER *container; + SM2_SIGNATURE sig; + unsigned int i; + + if (deviceHandle == NULL) { + error_print(); + return SDR_STEPERR; + } + + if (!hSessionHandle) { + error_print(); + return SDR_INARGERR; + } + session = deviceHandle->session_list; + while (session != NULL && session != hSessionHandle) { + session = session->next; + } + if (session == NULL) { + error_print(); + return SDR_INARGERR; + } + + // find container with key index + container = session->container_list; + while (container != NULL && container->key_index != uiIPKIndex) { + container = container->next; + } + if (container == NULL) { + error_print(); + return SDR_INARGERR; + } + + if (pucData == NULL || uiDataLength != SM3_DIGEST_SIZE) { + error_print(); + return SDR_INARGERR; + } + + if (pucSignature == NULL) { + error_print(); + return SDR_INARGERR; + } + for (i = 0; i < ECCref_MAX_LEN - 32; i++) { + if (pucSignature->r[i] != 0) { + error_print(); + return SDR_INARGERR; + } + } + for (i = 0; i < ECCref_MAX_LEN - 32; i++) { + if (pucSignature->s[i] != 0) { + error_print(); + return SDR_INARGERR; + } + } + + memcpy(sig.r, pucSignature->r + ECCref_MAX_LEN - 32, 32); + memcpy(sig.s, pucSignature->s + ECCref_MAX_LEN - 32, 32); + + if (sm2_do_verify(&container->sign_key, pucData, &sig) != 1) { + error_print(); + return SDR_VERIFYERR; + } + + return SDR_OK; +} + +int SDF_ExternalEncrypt_ECC( + void *hSessionHandle, + unsigned int uiAlgID, + ECCrefPublicKey *pucPublicKey, + unsigned char *pucData, + unsigned int uiDataLength, + ECCCipher *pucEncData) +{ + SOFTSDF_SESSION *session; + SM2_KEY sm2_key; + SM2_CIPHERTEXT ctxt; + unsigned int i; + + if (deviceHandle == NULL) { + error_print(); + return SDR_STEPERR; + } + + if (!hSessionHandle) { + error_print(); + return SDR_INARGERR; + } + session = deviceHandle->session_list; + while (session != NULL && session != hSessionHandle) { + session = session->next; + } + if (session == NULL) { + error_print(); + return SDR_INARGERR; + } + + if (uiAlgID != SGD_SM2_3) { + error_print(); + return SDR_INARGERR; + } + + if (pucPublicKey == NULL) { + error_print(); + return SDR_INARGERR; + } + + if (pucPublicKey->bits != 256) { + error_print(); + return SDR_INARGERR; + } + for (i = 0; i < ECCref_MAX_LEN - 32; i++) { + if (pucPublicKey->x[i] != 0) { + error_print(); + return SDR_INARGERR; + } + } + for (i = 0; i < ECCref_MAX_LEN - 32; i++) { + if (pucPublicKey->y[i] != 0) { + error_print(); + return SDR_INARGERR; + } + } + + memset(&sm2_key, 0, sizeof(sm2_key)); + memcpy(sm2_key.public_key.x, pucPublicKey->x + ECCref_MAX_LEN - 32, 32); + memcpy(sm2_key.public_key.y, pucPublicKey->y + ECCref_MAX_LEN - 32, 32); + + if (!pucData) { + error_print(); + return SDR_INARGERR; + } + + if(uiDataLength <=0 || uiDataLength > SM2_MAX_PLAINTEXT_SIZE) { + error_print(); + return SDR_INARGERR; + } + + if (sm2_do_encrypt(&sm2_key, pucData, uiDataLength, &ctxt) != 1) { + error_print(); + return SDR_GMSSLERR; + } + + memset(pucEncData, 0, sizeof(*pucEncData)); + memcpy(pucEncData->x + ECCref_MAX_LEN - 32, ctxt.point.x, 32); + memcpy(pucEncData->y + ECCref_MAX_LEN - 32, ctxt.point.y, 32); + memcpy(pucEncData->M, ctxt.hash, 32); + pucEncData->L = ctxt.ciphertext_size; + memcpy(pucEncData->C, ctxt.ciphertext, ctxt.ciphertext_size); + + return SDR_OK; +} + +int SDF_Encrypt( + void *hSessionHandle, + void *hKeyHandle, + unsigned int uiAlgID, + unsigned char *pucIV, + unsigned char *pucData, + unsigned int uiDataLength, + unsigned char *pucEncData, + unsigned int *puiEncDataLength) +{ + SOFTSDF_SESSION *session; + SOFTSDF_KEY *key; + SM4_KEY sm4_key; + size_t outlen; + + if (deviceHandle == NULL) { + error_print(); + return SDR_STEPERR; + } + + if (!hSessionHandle) { + error_print(); + return SDR_INARGERR; + } + session = deviceHandle->session_list; + while (session != NULL && session != hSessionHandle) { + session = session->next; + } + if (session == NULL) { + error_print(); + return SDR_INARGERR; + } + + if (hKeyHandle == NULL) { + error_print(); + return SDR_INARGERR; + } + key = session->key_list; + while (key != NULL && key != (SOFTSDF_KEY *)hKeyHandle) { + key = key->next; + } + if (key == NULL) { + error_print(); + return SDR_INARGERR; + } + if (key->key_size < SM4_KEY_SIZE) { + error_print(); + return SDR_INARGERR; + } + + if (uiAlgID != SGD_SM4_CBC) { + error_print(); + return SDR_INARGERR; + } + + if (pucIV == NULL) { + error_print(); + return SDR_INARGERR; + } + + if (pucData == NULL) { + error_print(); + return SDR_INARGERR; + } + + if (puiEncDataLength == NULL) { + error_print(); + return SDR_INARGERR; + } + + // FIXME: calculate *puiEncDataLength if pucEncData is NULL + if (pucEncData == NULL) { + error_print(); + return SDR_INARGERR; + } + + + sm4_set_encrypt_key(&sm4_key, key->key); + if (sm4_cbc_padding_encrypt(&sm4_key, pucIV, pucData, uiDataLength, pucEncData, &outlen) != 1) { + error_print(); + memset(&sm4_key, 0, sizeof(sm4_key)); + return SDR_GMSSLERR; + } + memset(&sm4_key, 0, sizeof(sm4_key)); + + *puiEncDataLength = (unsigned int)outlen; + return SDR_OK; +} + +int SDF_Decrypt( + void *hSessionHandle, + void *hKeyHandle, + unsigned int uiAlgID, + unsigned char *pucIV, + unsigned char *pucEncData, + unsigned int uiEncDataLength, + unsigned char *pucData, + unsigned int *puiDataLength) +{ + SOFTSDF_SESSION *session; + SOFTSDF_KEY *key; + SM4_KEY sm4_key; + size_t outlen; + + if (deviceHandle == NULL) { + error_print(); + return SDR_STEPERR; + } + + if (!hSessionHandle) { + error_print(); + return SDR_INARGERR; + } + session = deviceHandle->session_list; + while (session != NULL && session != hSessionHandle) { + session = session->next; + } + if (session == NULL) { + error_print(); + return SDR_INARGERR; + } + + if (hKeyHandle == NULL) { + error_print(); + return SDR_INARGERR; + } + key = session->key_list; + while (key != NULL && key != (SOFTSDF_KEY *)hKeyHandle) { + key = key->next; + } + if (key == NULL) { + error_print(); + return SDR_INARGERR; + } + if (key->key_size < SM4_KEY_SIZE) { + error_print(); + return SDR_INARGERR; + } + + if (uiAlgID != SGD_SM4_CBC) { + error_print(); + return SDR_INARGERR; + } + + if (pucIV == NULL) { + error_print(); + return SDR_INARGERR; + } + + if (pucEncData == NULL) { + error_print(); + return SDR_INARGERR; + } + + if (puiDataLength == NULL) { + error_print(); + return SDR_INARGERR; + } + + // FIXME: calculate *puiDataLength if pucData is NULL + if (pucData == NULL) { + error_print(); + return SDR_INARGERR; + } + + sm4_set_decrypt_key(&sm4_key, key->key); + if (sm4_cbc_padding_decrypt(&sm4_key, pucIV, pucEncData, uiEncDataLength, pucData, &outlen) != 1) { + error_print(); + memset(&sm4_key, 0, sizeof(sm4_key)); + return SDR_GMSSLERR; + } + memset(&sm4_key, 0, sizeof(sm4_key)); + + *puiDataLength = (unsigned int)outlen; + return SDR_OK; +} + +int SDF_CalculateMAC( + void *hSessionHandle, + void *hKeyHandle, + unsigned int uiAlgID, + unsigned char *pucIV, + unsigned char *pucData, + unsigned int uiDataLength, + unsigned char *pucMAC, + unsigned int *puiMACLength) +{ + SOFTSDF_SESSION *session; + SOFTSDF_KEY *key; + + if (deviceHandle == NULL) { + error_print(); + return SDR_STEPERR; + } + + if (hSessionHandle == NULL) { + error_print(); + return SDR_INARGERR; + } + session = deviceHandle->session_list; + while (session != NULL && session != hSessionHandle) { + session = session->next; + } + if (session == NULL) { + error_print(); + return SDR_INARGERR; + } + + if (hKeyHandle == NULL) { + error_print(); + return SDR_INARGERR; + } + key = session->key_list; + while (key != NULL && key != (SOFTSDF_KEY *)hKeyHandle) { + key = key->next; + } + if (key == NULL) { + error_print(); + return SDR_INARGERR; + } + + if (pucIV != NULL) { + error_print(); + return SDR_INARGERR; + } + + if (pucData == NULL || uiDataLength <= 0) { + error_print(); + return SDR_INARGERR; + } + + if (puiMACLength == NULL) { + error_print(); + return SDR_INARGERR; + } + + if (uiAlgID == SGD_SM3) { + SM3_HMAC_CTX hmac_ctx; + + if (key->key_size < 12) { + error_print(); + return SDR_INARGERR; + } + + *puiMACLength = SM3_HMAC_SIZE; + + if (!pucMAC) { + return SDR_OK; + } + + sm3_hmac_init(&hmac_ctx, key->key, key->key_size); + sm3_hmac_update(&hmac_ctx, pucData, uiDataLength); + sm3_hmac_finish(&hmac_ctx, pucMAC); + + memset(&hmac_ctx, 0, sizeof(hmac_ctx)); + + } else if (uiAlgID == SGD_SM4_MAC) { + SM4_CBC_MAC_CTX cbc_mac_ctx; + + if (key->key_size < SM4_KEY_SIZE) { + error_print(); + return SDR_INARGERR; + } + *puiMACLength = SM4_CBC_MAC_SIZE; + + if (!pucMAC) { + return SDR_OK; + } + + sm4_cbc_mac_init(&cbc_mac_ctx, key->key); + sm4_cbc_mac_update(&cbc_mac_ctx, pucData, uiDataLength); + sm4_cbc_mac_finish(&cbc_mac_ctx, pucMAC); + + memset(&cbc_mac_ctx, 0, sizeof(cbc_mac_ctx)); + + } else { + error_print(); + return SDR_INARGERR; + } + + return SDR_OK; +} + +// 这个函数真正涉及Session! +int SDF_HashInit( + void *hSessionHandle, + unsigned int uiAlgID, + ECCrefPublicKey *pucPublicKey, + unsigned char *pucID, + unsigned int uiIDLength) +{ + SOFTSDF_SESSION *session; + + if (deviceHandle == NULL) { + error_print(); + return SDR_STEPERR; + } + + if (hSessionHandle == NULL) { + error_print(); + return SDR_INARGERR; + } + session = deviceHandle->session_list; + while (session != NULL && session != hSessionHandle) { + session = session->next; + } + if (session == NULL) { + error_print(); + return SDR_INARGERR; + } + + if (uiAlgID != SGD_SM3) { + error_print(); + return SDR_INARGERR; + } + + // FIXME: check step or return SDR_STEPERR; + sm3_init(&session->sm3_ctx); + + if (pucPublicKey != NULL) { + SM2_POINT point; + uint8_t z[32]; + + if (pucID == NULL || uiIDLength <= 0) { + error_print(); + return SDR_INARGERR; + } + + if (sm2_compute_z(z, &point, (const char *)pucID, uiIDLength) != 1) { + error_print(); + return SDR_GMSSLERR; + } + sm3_update(&session->sm3_ctx, z, sizeof(z)); + } + + return SDR_OK; +} + +int SDF_HashUpdate( + void *hSessionHandle, + unsigned char *pucData, + unsigned int uiDataLength) +{ + SOFTSDF_SESSION *session; + + if (deviceHandle == NULL) { + error_print(); + return SDR_STEPERR; + } + + if (hSessionHandle == NULL) { + error_print(); + return SDR_INARGERR; + } + session = deviceHandle->session_list; + while (session != NULL && session != hSessionHandle) { + session = session->next; + } + if (session == NULL) { + error_print(); + return SDR_INARGERR; + } + + if (pucData == NULL || uiDataLength <= 0) { + error_print(); + return SDR_INARGERR; + } + + sm3_update(&session->sm3_ctx, pucData, uiDataLength); + + return SDR_OK; +} + +int SDF_HashFinal(void *hSessionHandle, + unsigned char *pucHash, + unsigned int *puiHashLength) +{ + SOFTSDF_SESSION *session; + + if (deviceHandle == NULL) { + error_print(); + return SDR_STEPERR; + } + + if (hSessionHandle == NULL) { + error_print(); + return SDR_INARGERR; + } + session = deviceHandle->session_list; + while (session != NULL && session != hSessionHandle) { + session = session->next; + } + if (session == NULL) { + error_print(); + return SDR_INARGERR; + } + + if (pucHash == NULL || puiHashLength == NULL) { + error_print(); + return SDR_INARGERR; + } + + sm3_finish(&session->sm3_ctx, pucHash); + + *puiHashLength = SM3_DIGEST_SIZE; + return SDR_OK; +} + +int SDF_CreateFile( + void *hSessionHandle, + unsigned char *pucFileName, + unsigned int uiNameLen, + unsigned int uiFileSize) +{ + SOFTSDF_SESSION *session; + char filename[FILENAME_MAX_LEN]; + FILE *file = NULL; + uint8_t buf[1024] = {0}; + size_t i; + + if (deviceHandle == NULL) { + error_print(); + return SDR_STEPERR; + } + + if (hSessionHandle == NULL) { + error_print(); + return SDR_INARGERR; + } + session = deviceHandle->session_list; + while (session != NULL && session != hSessionHandle) { + session = session->next; + } + if (session == NULL) { + error_print(); + return SDR_INARGERR; + } + + if (pucFileName == NULL) { + error_print(); + return SDR_INARGERR; + } + if (uiNameLen <= 0 || uiNameLen >= FILENAME_MAX_LEN - 5) { + error_print(); + return SDR_INARGERR; + } + memcpy(filename, pucFileName, uiNameLen); + filename[uiNameLen] = 0; + if (strlen(filename) != uiNameLen) { + error_print(); + return SDR_INARGERR; + } + strcat(filename, ".file"); + + if (uiFileSize > 64 * 1024) { + error_print(); + return SDR_INARGERR; + } + + file = fopen(filename, "wb"); + if (file == NULL) { + error_puts("Failed to create file"); + return SDR_GMSSLERR; + } + for (i = 0; i < uiFileSize/sizeof(buf); i++) { + fwrite(buf, 1, sizeof(buf), file); + } + fwrite(buf, 1, uiFileSize % sizeof(buf), file); + fclose(file); + + return SDR_OK; +} + +int SDF_ReadFile( + void *hSessionHandle, + unsigned char *pucFileName, + unsigned int uiNameLen, + unsigned int uiOffset, + unsigned int *puiReadLength, + unsigned char *pucBuffer) +{ + SOFTSDF_SESSION *session; + char filename[FILENAME_MAX_LEN]; + FILE *file = NULL; + size_t bytesRead; + + if (deviceHandle == NULL) { + error_print(); + return SDR_STEPERR; + } + + if (hSessionHandle == NULL) { + error_print(); + return SDR_INARGERR; + } + session = deviceHandle->session_list; + while (session != NULL && session != hSessionHandle) { + session = session->next; + } + if (session == NULL) { + error_print(); + return SDR_INARGERR; + } + + if (pucFileName == NULL) { + error_print(); + return SDR_INARGERR; + } + if (uiNameLen <= 0 || uiNameLen >= FILENAME_MAX_LEN - 5) { + error_print(); + return SDR_INARGERR; + } + memcpy(filename, pucFileName, uiNameLen); + filename[uiNameLen] = 0; + if (strlen(filename) != uiNameLen) { + error_print(); + return SDR_INARGERR; + } + strcat(filename, ".file"); + + if (puiReadLength == NULL || *puiReadLength <= 0) { + error_print(); + return SDR_INARGERR; + } + + if (pucBuffer == NULL) { + error_print(); + return SDR_INARGERR; + } + + file = fopen(filename, "rb"); + if (file == NULL) { + error_print(); + return SDR_GMSSLERR; + } + if (fseek(file, uiOffset, SEEK_SET) != 0) { + fclose(file); + error_print(); + return SDR_GMSSLERR; + } + bytesRead = fread(pucBuffer, 1, *puiReadLength, file); + if (bytesRead == 0) { + error_print(); + fclose(file); + return SDR_GMSSLERR; + } + fclose(file); + + *puiReadLength = bytesRead; + return SDR_OK; +} + +int SDF_WriteFile( + void *hSessionHandle, + unsigned char *pucFileName, + unsigned int uiNameLen, + unsigned int uiOffset, + unsigned int uiWriteLength, + unsigned char *pucBuffer) +{ + SOFTSDF_SESSION *session; + char filename[FILENAME_MAX_LEN]; + FILE *file = NULL; + size_t bytesWritten; + + if (deviceHandle == NULL) { + error_print(); + return SDR_STEPERR; + } + + if (hSessionHandle == NULL) { + error_print(); + return SDR_INARGERR; + } + session = deviceHandle->session_list; + while (session != NULL && session != hSessionHandle) { + session = session->next; + } + if (session == NULL) { + error_print(); + return SDR_INARGERR; + } + + if (pucFileName == NULL) { + error_print(); + return SDR_INARGERR; + } + if (uiNameLen <= 0 || uiNameLen >= FILENAME_MAX_LEN - 5) { + error_print(); + return SDR_INARGERR; + } + memcpy(filename, pucFileName, uiNameLen); + filename[uiNameLen] = 0; + if (strlen(filename) != uiNameLen) { + error_print(); + return SDR_INARGERR; + } + strcat(filename, ".file"); + + if (uiWriteLength <= 0) { + error_print(); + return SDR_INARGERR; + } + if (uiWriteLength > 64 * 1024) { + error_print(); + return SDR_INARGERR; + } + + if (pucBuffer == NULL) { + error_print(); + return SDR_INARGERR; + } + + file = fopen(filename, "wb"); + if (file == NULL) { + error_print(); + return SDR_GMSSLERR; + } + if (fseek(file, uiOffset, SEEK_SET) != 0) { + error_print(); + fclose(file); + return SDR_GMSSLERR; + } + bytesWritten = fwrite(pucBuffer, 1, uiWriteLength, file); + if (bytesWritten != uiWriteLength) { + error_print(); + fclose(file); + return SDR_GMSSLERR; + } + fclose(file); + + return SDR_OK; +} + +int SDF_DeleteFile( + void *hSessionHandle, + unsigned char *pucFileName, + unsigned int uiNameLen) +{ + SOFTSDF_SESSION *session; + char filename[FILENAME_MAX_LEN]; + + if (deviceHandle == NULL) { + error_print(); + return SDR_STEPERR; + } + + if (hSessionHandle == NULL) { + error_print(); + return SDR_INARGERR; + } + session = deviceHandle->session_list; + while (session != NULL && session != hSessionHandle) { + session = session->next; + } + if (session == NULL) { + error_print(); + return SDR_INARGERR; + } + + if (pucFileName == NULL) { + error_print(); + return SDR_INARGERR; + } + if (uiNameLen <= 0 || uiNameLen >= FILENAME_MAX_LEN - 5) { + error_print(); + return SDR_INARGERR; + } + memcpy(filename, pucFileName, uiNameLen); + filename[uiNameLen] = 0; + if (strlen(filename) != uiNameLen) { + error_print(); + return SDR_INARGERR; + } + strcat(filename, ".file"); + + if (remove(filename) != 0) { + error_print(); + return SDR_GMSSLERR; + } + + return SDR_OK; +} diff --git a/src/sgd.h b/src/sgd.h index a602fe81..6656178e 100644 --- a/src/sgd.h +++ b/src/sgd.h @@ -65,9 +65,9 @@ #define SGD_RSA_SIGN (SGD_RSA|SGD_PK_SIGN) // FIXME: correct? #define SGD_RSA_ENC (SGD_RSA|SGD_PK_ENC) // FIXME: correct? #define SGD_SM2 0x00020100 -#define SGD_SM2_1 0x00020200 -#define SGD_SM2_2 0x00020400 -#define SGD_SM2_3 0x00020800 +#define SGD_SM2_1 0x00020200 // SM2 Signature Scheme +#define SGD_SM2_2 0x00020400 // SM2 Key Exchange Protocol +#define SGD_SM2_3 0x00020800 // SM2 Encryption Scheme /* hash */ #define SGD_SM3 0x00000001