mirror of
https://github.com/guanzhi/GmSSL.git
synced 2026-06-17 02:14:01 +08:00
update gm apis
This commit is contained in:
@@ -1,17 +1,2 @@
|
||||
LIBS=../../libcrypto
|
||||
SOURCE[../../libcrypto]=\
|
||||
sdf_dev.c \
|
||||
sdf_ec.c \
|
||||
sdf_enc.c \
|
||||
sdf_err.c \
|
||||
sdf_errstr.c \
|
||||
sdf_ext.c \
|
||||
sdf_file.c \
|
||||
sdf_hash.c \
|
||||
sdf_key.c \
|
||||
sdf_key2.c \
|
||||
sdf_lib.c \
|
||||
sdf_mac.c \
|
||||
sdf_rand.c \
|
||||
sdf_rsa.c \
|
||||
sdf_session.c
|
||||
SOURCE[../../libcrypto]=sdf_err.c sdf_lib.c sdf_meth.c
|
||||
|
||||
@@ -1,119 +0,0 @@
|
||||
/* ====================================================================
|
||||
* Copyright (c) 2016 The GmSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the GmSSL Project.
|
||||
* (http://gmssl.org/)"
|
||||
*
|
||||
* 4. The name "GmSSL Project" must not be used to endorse or promote
|
||||
* products derived from this software without prior written
|
||||
* permission. For written permission, please contact
|
||||
* guanzhi1980@gmail.com.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "GmSSL"
|
||||
* nor may "GmSSL" appear in their names without prior written
|
||||
* permission of the GmSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the GmSSL Project
|
||||
* (http://gmssl.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE GmSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GmSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES
|
||||
* LOSS OF USE, DATA, OR PROFITS OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/gmsdf.h>
|
||||
#include <openssl/engine.h>
|
||||
#include "sdf_lcl.h"
|
||||
|
||||
char *deviceHandle = "SDF Device Handle";
|
||||
|
||||
int SDF_OpenDevice(
|
||||
void **phDeviceHandle)
|
||||
{
|
||||
if (!phDeviceHandle) {
|
||||
SDFerr(SDF_F_SDF_OPENDEVICE, ERR_R_PASSED_NULL_PARAMETER);
|
||||
return SDR_OUTARGERR;
|
||||
}
|
||||
|
||||
#ifndef OPENSSL_NO_ENGINE
|
||||
ENGINE_load_builtin_engines();
|
||||
#endif
|
||||
|
||||
*phDeviceHandle = deviceHandle;
|
||||
return SDR_OK;
|
||||
}
|
||||
|
||||
int SDF_CloseDevice(
|
||||
void *hDeviceHandle)
|
||||
{
|
||||
if (hDeviceHandle != deviceHandle) {
|
||||
SDFerr(SDF_F_SDF_CLOSEDEVICE, SDF_R_INVALID_DEVICE_HANDLE);
|
||||
return SDR_INARGERR;
|
||||
}
|
||||
#ifndef OPENSSL_NO_ENGINE
|
||||
ENGINE_cleanup();
|
||||
#endif
|
||||
return SDR_OK;
|
||||
}
|
||||
|
||||
int SDF_GetDeviceInfo(
|
||||
void *hSessionHandle,
|
||||
DEVICEINFO *pstDeviceInfo)
|
||||
{
|
||||
SDF_SESSION *session = (SDF_SESSION *)hSessionHandle;
|
||||
|
||||
if (!hSessionHandle || !pstDeviceInfo) {
|
||||
SDFerr(SDF_F_SDF_GETDEVICEINFO, ERR_R_PASSED_NULL_PARAMETER);
|
||||
return SDR_INARGERR;
|
||||
}
|
||||
if (session->magic != SDF_SESSION_MAGIC) {
|
||||
SDFerr(SDF_F_SDF_GETDEVICEINFO, SDF_R_INVALID_SESSION_HANDLE);
|
||||
return SDR_INARGERR;
|
||||
}
|
||||
|
||||
memset(pstDeviceInfo, 0, sizeof(*pstDeviceInfo));
|
||||
strncpy((char *)pstDeviceInfo->IssuerName, "GmSSL Project (http://gmssl.org)", 40);
|
||||
strncpy((char *)pstDeviceInfo->DeviceName, "GmSSL Soft SDF", 16);
|
||||
strncpy((char *)pstDeviceInfo->DeviceSerial, "201608020010123", 16);
|
||||
pstDeviceInfo->DeviceVersion = 2;
|
||||
pstDeviceInfo->StandardVersion = 1;
|
||||
pstDeviceInfo->AsymAlgAbility[0] = SGD_RSA|SGD_SM2_1;
|
||||
pstDeviceInfo->AsymAlgAbility[1] = SGD_RSA|SGD_SM2_3;
|
||||
pstDeviceInfo->SymAlgAbility = SGD_SM1|SGD_SSF33|SGD_SM4|SGD_ZUC;
|
||||
pstDeviceInfo->HashAlgAbility = SGD_SM3|SGD_SHA1|SGD_SHA256;
|
||||
pstDeviceInfo->BufferSize = 0;
|
||||
|
||||
return SDR_OK;
|
||||
}
|
||||
|
||||
@@ -1,918 +0,0 @@
|
||||
/* ====================================================================
|
||||
* Copyright (c) 2016 The GmSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the GmSSL Project.
|
||||
* (http://gmssl.org/)"
|
||||
*
|
||||
* 4. The name "GmSSL Project" must not be used to endorse or promote
|
||||
* products derived from this software without prior written
|
||||
* permission. For written permission, please contact
|
||||
* guanzhi1980@gmail.com.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "GmSSL"
|
||||
* nor may "GmSSL" appear in their names without prior written
|
||||
* permission of the GmSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the GmSSL Project
|
||||
* (http://gmssl.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE GmSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GmSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <openssl/ec.h>
|
||||
#include <openssl/sm2.h>
|
||||
#include <openssl/gmapi.h>
|
||||
#include <openssl/gmsdf.h>
|
||||
#include "sdf_lcl.h"
|
||||
|
||||
/*
|
||||
* For all the ECC signing/verification, the to be signed data `pucData`
|
||||
* should be the digest of the message, instead of the original message. If
|
||||
* the application requires a GM standard signature with the hashed identity
|
||||
* `Z`, then `SDF_HashInit` must be called with the `pucPublicKey` and
|
||||
* `pucID` provided.
|
||||
*/
|
||||
|
||||
/*
|
||||
* some of these functions require an `uiAlgID` to specify the algorithm.
|
||||
* Currently only `SGD_SM2_1` and `SGD_SM2_3` should be used. Maybe for some
|
||||
* implementations might also support international algorithms such as ECDSA
|
||||
* and ECIES.
|
||||
*/
|
||||
/*
|
||||
* there are limits on the max size of input plaintext, for SM2 encryptions,
|
||||
* the length will be equal to the `ECCref_MAX_CIPHER_LEN`
|
||||
*/
|
||||
/*
|
||||
* Symmetric Encryption:
|
||||
* `SDF_Encrypt`
|
||||
* `SDF_Decrypt`
|
||||
*
|
||||
* we will not provide two-step operations for SDF API which means the
|
||||
* caller can not assign the `pucEnData` to be NULL hoping that the API will
|
||||
* return the proper out length through `*puiEncDataLength`. The reason is
|
||||
* that the maximum output length can be easily estimated in almost all the
|
||||
* APIs of SDF. So when `pucEncData` is NULL or `*puiEncDataLength` is not
|
||||
* large enough, the API will just return with an error.
|
||||
*
|
||||
* The implementation will not carefully to estimate the output length, so
|
||||
* always prepare the max output buffer. For exmaple, prepare at least two
|
||||
* extra blocks for symmetric encryption, prepare max digest length of known
|
||||
* hash functions as the MAC buffer size.
|
||||
*
|
||||
* Note: the GM/T 0018-2012 standard requires the implementation MUST NOT do
|
||||
* any padding operatons, and the input data length should be multiple block
|
||||
* length. Thus these two functions can be used for modes such as CBC, the
|
||||
* caller can use a function more than once and do the padding himself.
|
||||
*/
|
||||
|
||||
int SDF_GenerateKeyPair_ECC(
|
||||
void *hSessionHandle,
|
||||
unsigned int uiAlgID,
|
||||
unsigned int uiKeyBits,
|
||||
ECCrefPublicKey *pucPublicKey,
|
||||
ECCrefPrivateKey *pucPrivateKey)
|
||||
{
|
||||
int ret = SDR_UNKNOWERR;
|
||||
EC_KEY *ec_key = NULL;
|
||||
|
||||
/* check arguments */
|
||||
if (!hSessionHandle || !pucPublicKey || !pucPrivateKey) {
|
||||
SDFerr(SDF_F_SDF_GENERATEKEYPAIR_ECC,
|
||||
ERR_R_PASSED_NULL_PARAMETER);
|
||||
return SDR_UNKNOWERR;
|
||||
}
|
||||
if (uiAlgID != SGD_SM2 && uiAlgID != SGD_SM2_1 &&
|
||||
uiAlgID != SGD_SM2_2 && uiAlgID != SGD_SM2_3) {
|
||||
SDFerr(SDF_F_SDF_GENERATEKEYPAIR_ECC,
|
||||
SDF_R_INVALID_ALGOR);
|
||||
return SDR_UNKNOWERR;
|
||||
}
|
||||
if (uiKeyBits != 256) {
|
||||
SDFerr(SDF_F_SDF_GENERATEKEYPAIR_ECC,
|
||||
SDF_R_INVALID_KEY_LENGTH);
|
||||
return SDR_UNKNOWERR;
|
||||
}
|
||||
|
||||
/* generate */
|
||||
if(!(ec_key = EC_KEY_new_by_curve_name(NID_sm2p256v1))) {
|
||||
SDFerr(SDF_F_SDF_GENERATEKEYPAIR_ECC, ERR_R_EC_LIB);
|
||||
goto end;
|
||||
}
|
||||
|
||||
/* convert */
|
||||
if (!EC_KEY_get_ECCrefPublicKey(ec_key, pucPublicKey)) {
|
||||
SDFerr(SDF_F_SDF_GENERATEKEYPAIR_ECC,
|
||||
SDF_R_GET_PUBLIC_KEY_FAILED);
|
||||
goto end;
|
||||
}
|
||||
if (!EC_KEY_get_ECCrefPrivateKey(ec_key, pucPrivateKey)) {
|
||||
SDFerr(SDF_F_SDF_GENERATEKEYPAIR_ECC,
|
||||
SDF_R_GET_PRIVATE_KEY_FAILED);
|
||||
goto end;
|
||||
}
|
||||
|
||||
ret = SAR_OK;
|
||||
end:
|
||||
EC_KEY_free(ec_key);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int SDF_ExportSignPublicKey_ECC(
|
||||
void *hSessionHandle,
|
||||
unsigned int uiKeyIndex,
|
||||
ECCrefPublicKey *pucPublicKey)
|
||||
{
|
||||
int ret = SDR_UNKNOWERR;
|
||||
EVP_PKEY *pkey = NULL;
|
||||
unsigned int uiKeyUsage = SGD_SM2_1;
|
||||
|
||||
/* check arguments */
|
||||
if (!hSessionHandle || !pucPublicKey) {
|
||||
SDFerr(SDF_F_SDF_EXPORTSIGNPUBLICKEY_ECC,
|
||||
ERR_R_PASSED_NULL_PARAMETER);
|
||||
return SDR_UNKNOWERR;
|
||||
}
|
||||
|
||||
/* load key */
|
||||
if (!(pkey = sdf_load_ec_public_key(hSessionHandle,
|
||||
uiKeyIndex, uiKeyUsage))) {
|
||||
SDFerr(SDF_F_SDF_EXPORTSIGNPUBLICKEY_ECC,
|
||||
ERR_R_GMAPI_LIB);
|
||||
goto end;
|
||||
}
|
||||
|
||||
/* set return value */
|
||||
if (!EC_KEY_get_ECCrefPublicKey(EVP_PKEY_get0_EC_KEY(pkey),
|
||||
pucPublicKey)) {
|
||||
SDFerr(SDF_F_SDF_EXPORTSIGNPUBLICKEY_ECC,
|
||||
ERR_R_GMAPI_LIB);
|
||||
goto end;
|
||||
}
|
||||
ret = SDR_OK;
|
||||
|
||||
end:
|
||||
EVP_PKEY_free(pkey);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int SDF_ExportEncPublicKey_ECC(
|
||||
void *hSessionHandle,
|
||||
unsigned int uiKeyIndex,
|
||||
ECCrefPublicKey *pucPublicKey)
|
||||
{
|
||||
int ret = SDR_UNKNOWERR;
|
||||
EVP_PKEY *pkey = NULL;
|
||||
unsigned int uiKeyUsage = 1;
|
||||
|
||||
/* check arguments */
|
||||
if (!hSessionHandle || !pucPublicKey) {
|
||||
SDFerr(SDF_F_SDF_EXPORTENCPUBLICKEY_ECC,
|
||||
ERR_R_PASSED_NULL_PARAMETER);
|
||||
return SDR_UNKNOWERR;
|
||||
}
|
||||
|
||||
/* load key */
|
||||
if (!(pkey = sdf_load_ec_public_key(hSessionHandle,
|
||||
uiKeyIndex, uiKeyUsage))) {
|
||||
SDFerr(SDF_F_SDF_EXPORTENCPUBLICKEY_ECC,
|
||||
ERR_R_GMAPI_LIB);
|
||||
goto end;
|
||||
}
|
||||
|
||||
/* set return value */
|
||||
if (!EC_KEY_get_ECCrefPublicKey(EVP_PKEY_get0_EC_KEY(pkey),
|
||||
pucPublicKey)) {
|
||||
SDFerr(SDF_F_SDF_EXPORTENCPUBLICKEY_ECC,
|
||||
ERR_R_GMAPI_LIB);
|
||||
goto end;
|
||||
}
|
||||
ret = SDR_OK;
|
||||
|
||||
end:
|
||||
EVP_PKEY_free(pkey);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int SDF_GenerateAgreementDataWithECC(
|
||||
void *hSessionHandle,
|
||||
unsigned int uiISKIndex,
|
||||
unsigned int uiKeyBits,
|
||||
unsigned char *pucSponsorID,
|
||||
unsigned int uiSponsorIDLength,
|
||||
ECCrefPublicKey *pucSponsorPublicKey,
|
||||
ECCrefPublicKey *pucSponsorTmpPublicKey,
|
||||
void **phAgreementHandle)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int SDF_GenerateKeyWithECC(
|
||||
void *hSessionHandle,
|
||||
unsigned char *pucResponseID,
|
||||
unsigned int uiResponseIDLength,
|
||||
ECCrefPublicKey *pucResponsePublicKey,
|
||||
ECCrefPublicKey *pucResponseTmpPublicKey,
|
||||
void *hAgreementHandle,
|
||||
void **phKeyHandle)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* generate a session key and encrypt it with internal public key
|
||||
* we can first random a key,
|
||||
* export the public key,
|
||||
* and then use the SDF_GenerateKeyWithEPK_ECC to encrypt the key
|
||||
* the output key handle is only a pointer to the key buffer.
|
||||
*/
|
||||
int SDF_GenerateKeyWithIPK_ECC(
|
||||
void *hSessionHandle,
|
||||
unsigned int uiIPKIndex,
|
||||
unsigned int uiKeyBits, /* output session key length */
|
||||
ECCCipher *pucKey,
|
||||
void **phKeyHandle)
|
||||
{
|
||||
int ret = SDR_UNKNOWERR;
|
||||
SDF_KEY *key = NULL;
|
||||
unsigned int uiAlgID = SGD_SM2_3;
|
||||
|
||||
/* check arguments */
|
||||
if (!hSessionHandle || !pucKey || !phKeyHandle) {
|
||||
SDFerr(SDF_F_SDF_GENERATEKEYWITHIPK_ECC,
|
||||
ERR_R_PASSED_NULL_PARAMETER);
|
||||
return SDR_UNKNOWERR;
|
||||
}
|
||||
if (uiKeyBits <= 0 || uiKeyBits > EVP_MAX_KEY_LENGTH * 8 ||
|
||||
uiKeyBits % 8) {
|
||||
SDFerr(SDF_F_SDF_GENERATEKEYWITHIPK_ECC,
|
||||
SDF_R_INVALID_KEY_LENGTH);
|
||||
return SDR_UNKNOWERR;
|
||||
}
|
||||
|
||||
/* random key */
|
||||
if (!(key = OPENSSL_zalloc(sizeof(*key)))) {
|
||||
SDFerr(SDF_F_SDF_GENERATEKEYWITHIPK_ECC,
|
||||
ERR_R_MALLOC_FAILURE);
|
||||
goto end;
|
||||
}
|
||||
key->keylen = uiKeyBits/8;
|
||||
if ((ret = SDF_GenerateRandom(hSessionHandle, key->keylen,
|
||||
key->key)) != SDR_OK) {
|
||||
SDFerr(SDF_F_SDF_GENERATEKEYWITHIPK_ECC,
|
||||
ERR_R_GMAPI_LIB);
|
||||
goto end;
|
||||
}
|
||||
|
||||
/* encrypt key with external ec public key */
|
||||
if ((ret = SDF_InternalEncrypt_ECC(
|
||||
hSessionHandle,
|
||||
uiIPKIndex,
|
||||
uiAlgID,
|
||||
key->key,
|
||||
key->keylen,
|
||||
pucKey)) != SDR_OK) {
|
||||
SDFerr(SDF_F_SDF_GENERATEKEYWITHIPK_ECC,
|
||||
ERR_R_GMAPI_LIB);
|
||||
goto end;
|
||||
}
|
||||
|
||||
/* set return value */
|
||||
*phKeyHandle = key;
|
||||
key = NULL;
|
||||
ret = SDR_OK;
|
||||
|
||||
end:
|
||||
OPENSSL_clear_free(key, sizeof(*key));
|
||||
return ret;
|
||||
}
|
||||
|
||||
int SDF_GenerateKeyWithEPK_ECC(
|
||||
void *hSessionHandle,
|
||||
unsigned int uiKeyBits,
|
||||
unsigned int uiAlgID, /* must be SGD_SM2_3 */
|
||||
ECCrefPublicKey *pucPublicKey,
|
||||
ECCCipher *pucKey,
|
||||
void **phKeyHandle)
|
||||
{
|
||||
int ret = SDR_UNKNOWERR;
|
||||
SDF_KEY *key = NULL;
|
||||
|
||||
/* check arguments */
|
||||
if (!hSessionHandle || !pucPublicKey || !pucKey || !phKeyHandle) {
|
||||
SDFerr(SDF_F_SDF_GENERATEKEYWITHEPK_ECC,
|
||||
ERR_R_PASSED_NULL_PARAMETER);
|
||||
return SDR_UNKNOWERR;
|
||||
}
|
||||
if (uiKeyBits <= 0 || uiKeyBits >= EVP_MAX_KEY_LENGTH * 8 ||
|
||||
uiKeyBits % 8) {
|
||||
SDFerr(SDF_F_SDF_GENERATEKEYWITHEPK_ECC,
|
||||
SDF_R_INVALID_KEY_LENGTH);
|
||||
return SDR_UNKNOWERR;
|
||||
}
|
||||
if (uiAlgID != SGD_SM2_3) {
|
||||
SDFerr(SDF_F_SDF_GENERATEKEYWITHEPK_ECC,
|
||||
SDF_R_INVALID_ALGOR);
|
||||
return SDR_UNKNOWERR;
|
||||
}
|
||||
|
||||
/* random key */
|
||||
if (!(key = OPENSSL_zalloc(sizeof(*key)))) {
|
||||
SDFerr(SDF_F_SDF_GENERATEKEYWITHEPK_ECC,
|
||||
ERR_R_MALLOC_FAILURE);
|
||||
goto end;
|
||||
}
|
||||
key->keylen = uiKeyBits/8;
|
||||
if ((ret = SDF_GenerateRandom(hSessionHandle, key->keylen,
|
||||
key->key)) != SDR_OK) {
|
||||
SDFerr(SDF_F_SDF_GENERATEKEYWITHEPK_ECC,
|
||||
ERR_R_GMAPI_LIB);
|
||||
goto end;
|
||||
}
|
||||
|
||||
/* encrypt key with external ec public key */
|
||||
if ((ret = SDF_ExternalEncrypt_ECC(
|
||||
hSessionHandle,
|
||||
uiAlgID,
|
||||
pucPublicKey,
|
||||
key->key,
|
||||
key->keylen,
|
||||
pucKey)) != SDR_OK) {
|
||||
SDFerr(SDF_F_SDF_GENERATEKEYWITHEPK_ECC,
|
||||
ERR_R_GMAPI_LIB);
|
||||
goto end;
|
||||
}
|
||||
|
||||
/* set return value */
|
||||
*phKeyHandle = key;
|
||||
key = NULL;
|
||||
ret = SDR_OK;
|
||||
|
||||
end:
|
||||
OPENSSL_clear_free(key, sizeof(*key));
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* import session key
|
||||
* use the engine to decrypt the ECCipher
|
||||
*/
|
||||
int SDF_ImportKeyWithISK_ECC(
|
||||
void *hSessionHandle,
|
||||
unsigned int uiISKIndex,
|
||||
ECCCipher *pucKey,
|
||||
void **phKeyHandle)
|
||||
{
|
||||
int ret = SDR_UNKNOWERR;
|
||||
SDF_KEY *key = NULL;
|
||||
unsigned int uiAlgID = SGD_SM2_3;
|
||||
|
||||
/* check arguments */
|
||||
if (!hSessionHandle || !pucKey || !phKeyHandle) {
|
||||
SDFerr(SDF_F_SDF_IMPORTKEYWITHISK_ECC,
|
||||
ERR_R_PASSED_NULL_PARAMETER);
|
||||
return SDR_UNKNOWERR;
|
||||
}
|
||||
|
||||
/* prepare key */
|
||||
if (!(key = OPENSSL_zalloc(sizeof(*key)))) {
|
||||
SDFerr(SDF_F_SDF_IMPORTKEYWITHISK_ECC,
|
||||
ERR_R_MALLOC_FAILURE);
|
||||
goto end;
|
||||
}
|
||||
key->keylen = EVP_MAX_KEY_LENGTH;
|
||||
|
||||
/* decrypt with internal ec private key */
|
||||
if ((ret = SDF_InternalDecrypt_ECC(
|
||||
hSessionHandle,
|
||||
uiISKIndex,
|
||||
uiAlgID,
|
||||
pucKey,
|
||||
key->key,
|
||||
&key->keylen)) != SDR_OK) {
|
||||
SDFerr(SDF_F_SDF_IMPORTKEYWITHISK_ECC,
|
||||
ERR_R_GMAPI_LIB);
|
||||
goto end;
|
||||
}
|
||||
|
||||
/* set return value */
|
||||
*phKeyHandle = key;
|
||||
key = NULL;
|
||||
ret = SDR_OK;
|
||||
|
||||
end:
|
||||
OPENSSL_clear_free(key, sizeof(*key));
|
||||
return ret;
|
||||
}
|
||||
|
||||
int SDF_ExchangeDigitEnvelopeBaseOnECC(
|
||||
void *hSessionHandle,
|
||||
unsigned int uiKeyIndex,
|
||||
unsigned int uiAlgID,
|
||||
ECCrefPublicKey *pucPublicKey,
|
||||
ECCCipher *pucEncDataIn,
|
||||
ECCCipher *pucEncDataOut)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Implementation of SM2 signing
|
||||
*
|
||||
* Although the digest and signing operations should be the wrapping of the EVP
|
||||
* API, it will be simpler when using the native API of the `sm2` module.
|
||||
* Another consideration is that the usage of SM2 EVP might be changed, and the
|
||||
* operations might also be different from the GM standards, like signing the
|
||||
* H(Z||H(M)) instead of signing H(Z||M). So in the GMAPI we use the SM2 API
|
||||
* directly.
|
||||
*/
|
||||
|
||||
int SDF_ExternalSign_ECC(
|
||||
void *hSessionHandle, /* no use so not checked */
|
||||
unsigned int uiAlgID, /* must be SGD_SM2_1 */
|
||||
ECCrefPrivateKey *pucPrivateKey,
|
||||
unsigned char *pucData, /* digest */
|
||||
unsigned int uiDataLength,
|
||||
ECCSignature *pucSignature)
|
||||
{
|
||||
int ret = SDR_UNKNOWERR;
|
||||
EC_KEY *ec_key = NULL;
|
||||
ECDSA_SIG *sig = NULL;
|
||||
|
||||
/* check arguments */
|
||||
if (!hSessionHandle || !pucData || !pucSignature) {
|
||||
SDFerr(SDF_F_SDF_EXTERNALSIGN_ECC,
|
||||
ERR_R_PASSED_NULL_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
if (uiAlgID != SGD_SM2_1) {
|
||||
SDFerr(SDF_F_SDF_EXTERNALSIGN_ECC,
|
||||
SDF_R_INVALID_ALGOR);
|
||||
return 0;
|
||||
}
|
||||
if (uiDataLength > INT_MAX) {
|
||||
SDFerr(SDF_F_SDF_EXTERNALSIGN_ECC,
|
||||
SDF_R_INVALID_INPUT_LENGTH);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* load ec private key */
|
||||
if (!(ec_key = EC_KEY_new_from_ECCrefPrivateKey(pucPrivateKey))) {
|
||||
SDFerr(SDF_F_SDF_EXTERNALSIGN_ECC,
|
||||
ERR_R_GMAPI_LIB);
|
||||
goto end;
|
||||
}
|
||||
if (!(sig = SM2_do_sign(pucData, uiDataLength, ec_key))) {
|
||||
SDFerr(SDF_F_SDF_EXTERNALSIGN_ECC,
|
||||
ERR_R_EC_LIB);
|
||||
goto end;
|
||||
}
|
||||
|
||||
/* set return value */
|
||||
if (!ECDSA_SIG_get_ECCSignature(sig, pucSignature)) {
|
||||
SDFerr(SDF_F_SDF_EXTERNALSIGN_ECC,
|
||||
ERR_R_GMAPI_LIB);
|
||||
goto end;
|
||||
}
|
||||
ret = SDR_OK;
|
||||
|
||||
end:
|
||||
EC_KEY_free(ec_key);
|
||||
ECDSA_SIG_free(sig);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int SDF_ExternalVerify_ECC(
|
||||
void *hSessionHandle,
|
||||
unsigned int uiAlgID,
|
||||
ECCrefPublicKey *pucPublicKey,
|
||||
unsigned char *pucDataInput,
|
||||
unsigned int uiInputLength,
|
||||
ECCSignature *pucSignature)
|
||||
{
|
||||
int ret = SDR_UNKNOWERR;
|
||||
EC_KEY *ec_key = NULL;
|
||||
ECDSA_SIG *sig = NULL;
|
||||
|
||||
/* check arguments */
|
||||
if (!hSessionHandle || !pucPublicKey || !pucDataInput ||
|
||||
!pucSignature) {
|
||||
SDFerr(SDF_F_SDF_EXTERNALVERIFY_ECC,
|
||||
ERR_R_PASSED_NULL_PARAMETER);
|
||||
return SDR_UNKNOWERR;
|
||||
}
|
||||
if (uiAlgID != SGD_SM2_1) {
|
||||
SDFerr(SDF_F_SDF_EXTERNALVERIFY_ECC,
|
||||
SDF_R_INVALID_ALGOR);
|
||||
return SDR_UNKNOWERR;
|
||||
}
|
||||
if (uiInputLength != SM3_DIGEST_LENGTH) {
|
||||
SDFerr(SDF_F_SDF_EXTERNALVERIFY_ECC,
|
||||
SDF_R_INVALID_INPUT_LENGTH);
|
||||
return SDR_UNKNOWERR;
|
||||
}
|
||||
|
||||
/* parse arguments */
|
||||
if (!(ec_key = EC_KEY_new_from_ECCrefPublicKey(pucPublicKey))) {
|
||||
SDFerr(SDF_F_SDF_EXTERNALVERIFY_ECC,
|
||||
SDF_R_INVALID_EC_PUBLIC_KEY);
|
||||
goto end;
|
||||
}
|
||||
if (!(sig = SM2_do_sign(pucDataInput, uiInputLength, ec_key))) {
|
||||
SDFerr(SDF_F_SDF_EXTERNALVERIFY_ECC, ERR_R_EC_LIB);
|
||||
goto end;
|
||||
}
|
||||
if (!ECDSA_SIG_get_ECCSignature(sig, pucSignature)) {
|
||||
SDFerr(SDF_F_SDF_EXTERNALVERIFY_ECC, ERR_R_GMAPI_LIB);
|
||||
goto end;
|
||||
}
|
||||
|
||||
/* set return value */
|
||||
ret = SDR_OK;
|
||||
|
||||
end:
|
||||
EC_KEY_free(ec_key);
|
||||
ECDSA_SIG_free(sig);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int SDF_ExternalEncrypt_ECC(
|
||||
void *hSessionHandle,
|
||||
unsigned int uiAlgID, /* SGD_SM2_3 */
|
||||
ECCrefPublicKey *pucPublicKey,
|
||||
unsigned char *pucData,
|
||||
unsigned int uiDataLength,
|
||||
ECCCipher *pucEncData)
|
||||
{
|
||||
int ret = SDR_UNKNOWERR;
|
||||
EC_KEY *ec_key = NULL;
|
||||
SM2_CIPHERTEXT_VALUE *cv = NULL;
|
||||
SM2_ENC_PARAMS params;
|
||||
|
||||
/* check arguments */
|
||||
if (!hSessionHandle || !pucPublicKey || !pucData || !pucEncData) {
|
||||
SDFerr(SDF_F_SDF_EXTERNALENCRYPT_ECC,
|
||||
ERR_R_PASSED_NULL_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
if (uiAlgID != SGD_SM2_3) {
|
||||
SDFerr(SDF_F_SDF_EXTERNALENCRYPT_ECC,
|
||||
SDF_R_INVALID_ALGOR);
|
||||
return 0;
|
||||
}
|
||||
/* FIXME
|
||||
if (uiDataLength > ECCref_MAX_CIPHER_LEN) {
|
||||
SDFerr(SDF_F_SDF_EXTERNALENCRYPT_ECC,
|
||||
SDF_R_INVALID_INPUT_LENGTH);
|
||||
return 0;
|
||||
}
|
||||
*/
|
||||
|
||||
/* parse public key */
|
||||
if (!(ec_key = EC_KEY_new_from_ECCrefPublicKey(pucPublicKey))) {
|
||||
SDFerr(SDF_F_SDF_EXTERNALENCRYPT_ECC, ERR_R_GMAPI_LIB);
|
||||
goto end;
|
||||
}
|
||||
|
||||
/* encrypt */
|
||||
(void)SM2_ENC_PARAMS_init_with_recommended(¶ms);
|
||||
if (!(cv = SM2_do_encrypt(¶ms, pucData, (size_t)uiDataLength,
|
||||
ec_key))) {
|
||||
SDFerr(SDF_F_SDF_EXTERNALENCRYPT_ECC, ERR_R_EC_LIB);
|
||||
goto end;
|
||||
}
|
||||
/* encode ciphertext */
|
||||
if (!SM2_CIPHERTEXT_VALUE_get_ECCCipher(cv, pucEncData)) {
|
||||
SDFerr(SDF_F_SDF_EXTERNALENCRYPT_ECC, ERR_R_EC_LIB);
|
||||
goto end;
|
||||
}
|
||||
|
||||
ret = SDR_OK;
|
||||
|
||||
end:
|
||||
EC_KEY_free(ec_key);
|
||||
SM2_CIPHERTEXT_VALUE_free(cv);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int SDF_ExternalDecrypt_ECC(
|
||||
void *hSessionHandle,
|
||||
unsigned int uiAlgID,
|
||||
ECCrefPrivateKey *pucPrivateKey,
|
||||
ECCCipher *pucEncData,
|
||||
unsigned char *pucData,
|
||||
unsigned int *puiDataLength)
|
||||
{
|
||||
int ret = SDR_UNKNOWERR;
|
||||
EC_KEY *ec_key = NULL;
|
||||
SM2_CIPHERTEXT_VALUE *cv = NULL;
|
||||
SM2_ENC_PARAMS params;
|
||||
size_t siz;
|
||||
|
||||
/* check arguments */
|
||||
if (!hSessionHandle || !pucPrivateKey || !pucEncData ||
|
||||
!pucData || !puiDataLength) {
|
||||
SDFerr(SDF_F_SDF_EXTERNALDECRYPT_ECC,
|
||||
ERR_R_PASSED_NULL_PARAMETER);
|
||||
return SDR_UNKNOWERR;
|
||||
}
|
||||
/* FIXME
|
||||
if (*puiDataLength < ECCref_MAX_CIPHER_LEN) {
|
||||
SDFerr(SDF_F_SDF_EXTERNALDECRYPT_ECC,
|
||||
SDF_R_BUFFER_TOO_SMALL);
|
||||
return SDR_UNKNOWERR;
|
||||
}
|
||||
*/
|
||||
|
||||
/* parse arguments */
|
||||
if (!(ec_key = EC_KEY_new_from_ECCrefPrivateKey(pucPrivateKey))) {
|
||||
SDFerr(SDF_F_SDF_EXTERNALDECRYPT_ECC,
|
||||
SDF_R_INVALID_EC_PRIVATE_KEY);
|
||||
goto end;
|
||||
}
|
||||
if (!(cv = SM2_CIPHERTEXT_VALUE_new_from_ECCCipher(pucEncData))) {
|
||||
SDFerr(SDF_F_SDF_EXTERNALDECRYPT_ECC,
|
||||
SDF_R_INVALID_EC_CIPHERTEXT);
|
||||
goto end;
|
||||
}
|
||||
|
||||
/* decrypt */
|
||||
(void)SM2_ENC_PARAMS_init_with_recommended(¶ms);
|
||||
siz = (size_t)*puiDataLength;
|
||||
if (!SM2_do_decrypt(¶ms, cv, pucData, &siz, ec_key)) {
|
||||
SDFerr(SDF_F_SDF_EXTERNALDECRYPT_ECC, ERR_R_EC_LIB);
|
||||
}
|
||||
|
||||
/* set return value */
|
||||
*puiDataLength = (unsigned int)siz;
|
||||
ret = SDR_OK;
|
||||
|
||||
end:
|
||||
EC_KEY_free(ec_key);
|
||||
SM2_CIPHERTEXT_VALUE_free(cv);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* internal private key operation will use ENGINE */
|
||||
int SDF_InternalSign_ECC(
|
||||
void *hSessionHandle,
|
||||
unsigned int uiISKIndex,
|
||||
unsigned char *pucData,
|
||||
unsigned int uiDataLength,
|
||||
ECCSignature *pucSignature)
|
||||
{
|
||||
int ret = 0;
|
||||
SDF_SESSION *session = (SDF_SESSION *)hSessionHandle;
|
||||
EVP_PKEY_CTX *ctx = NULL;
|
||||
EVP_PKEY *pkey = NULL;
|
||||
unsigned char buf[256/4 + 32];
|
||||
size_t siz;
|
||||
|
||||
/* check arguments */
|
||||
if (!hSessionHandle || !pucData || !pucSignature) {
|
||||
SDFerr(SDF_F_SDF_INTERNALSIGN_ECC,
|
||||
ERR_R_PASSED_NULL_PARAMETER);
|
||||
return SDR_UNKNOWERR;
|
||||
}
|
||||
if (uiDataLength > SM3_DIGEST_LENGTH) {
|
||||
SDFerr(SDF_F_SDF_INTERNALSIGN_ECC,
|
||||
SDF_R_INVALID_INPUT_LENGTH);
|
||||
return SDR_UNKNOWERR;
|
||||
}
|
||||
|
||||
/* parse arguments */
|
||||
if (!(pkey = sdf_load_ec_private_key(hSessionHandle, uiISKIndex,
|
||||
SGD_PK_SIGN))) {
|
||||
SDFerr(SDF_F_SDF_INTERNALSIGN_ECC,
|
||||
SDF_R_INVALID_KEY_HANDLE);
|
||||
goto end;
|
||||
}
|
||||
|
||||
/* sign
|
||||
* use the EVP API instead of the native SM2 API to use ENGINE
|
||||
*/
|
||||
if (!(ctx = EVP_PKEY_CTX_new(pkey, session->engine))) {
|
||||
SDFerr(SDF_F_SDF_INTERNALSIGN_ECC, ERR_R_EVP_LIB);
|
||||
goto end;
|
||||
}
|
||||
if (!EVP_PKEY_sign_init(ctx)) {
|
||||
SDFerr(SDF_F_SDF_INTERNALSIGN_ECC, ERR_R_EVP_LIB);
|
||||
goto end;
|
||||
}
|
||||
if (!EVP_PKEY_CTX_set_ec_sign_type(ctx, NID_sm_scheme)) {
|
||||
SDFerr(SDF_F_SDF_INTERNALSIGN_ECC, ERR_R_EVP_LIB);
|
||||
goto end;
|
||||
}
|
||||
siz = sizeof(buf);
|
||||
if (!EVP_PKEY_sign(ctx, buf, &siz, pucData, (size_t)uiDataLength)) {
|
||||
SDFerr(SDF_F_SDF_INTERNALSIGN_ECC, ERR_R_EVP_LIB);
|
||||
goto end;
|
||||
}
|
||||
|
||||
/* convert signature buf to ECCSignature */
|
||||
if (!sdf_decode_ec_signature(pucSignature, buf, siz)) {
|
||||
SDFerr(SDF_F_SDF_INTERNALSIGN_ECC, ERR_R_GMAPI_LIB);
|
||||
goto end;
|
||||
}
|
||||
|
||||
/* set return value */
|
||||
ret = SDR_OK;
|
||||
|
||||
end:
|
||||
EVP_PKEY_CTX_free(ctx);
|
||||
EVP_PKEY_free(pkey);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int SDF_InternalVerify_ECC(
|
||||
void *hSessionHandle,
|
||||
unsigned int uiIPKIndex,
|
||||
unsigned char *pucData,
|
||||
unsigned int uiDataLength,
|
||||
ECCSignature *pucSignature)
|
||||
{
|
||||
int ret = SDR_UNKNOWERR;
|
||||
SDF_SESSION *session = (SDF_SESSION *)hSessionHandle;
|
||||
EVP_PKEY *pkey = NULL;
|
||||
EVP_PKEY_CTX *ctx = NULL;
|
||||
unsigned char buf[521/4 + 32];
|
||||
size_t siz;
|
||||
|
||||
/* check arguments */
|
||||
if (!hSessionHandle || !pucData || !pucSignature) {
|
||||
SDFerr(SDF_F_SDF_INTERNALVERIFY_ECC,
|
||||
ERR_R_PASSED_NULL_PARAMETER);
|
||||
return SDR_UNKNOWERR;
|
||||
}
|
||||
if (uiDataLength != SM3_DIGEST_LENGTH) {
|
||||
SDFerr(SDF_F_SDF_INTERNALVERIFY_ECC,
|
||||
SDF_R_INVALID_INPUT_LENGTH);
|
||||
return SDR_UNKNOWERR;
|
||||
}
|
||||
|
||||
/* parse arguments */
|
||||
if (!(pkey = sdf_load_ec_public_key(hSessionHandle, uiIPKIndex,
|
||||
SGD_PK_SIGN))) {
|
||||
SDFerr(SDF_F_SDF_INTERNALVERIFY_ECC, ERR_R_GMAPI_LIB);
|
||||
goto end;
|
||||
}
|
||||
siz = sizeof(buf);
|
||||
if (!sdf_encode_ec_signature(pucSignature, buf, &siz)) {
|
||||
SDFerr(SDF_F_SDF_INTERNALVERIFY_ECC, ERR_R_GMAPI_LIB);
|
||||
goto end;
|
||||
}
|
||||
|
||||
/* verify with EVP API and ENGINE */
|
||||
if (!(ctx = EVP_PKEY_CTX_new(pkey, session->engine))) {
|
||||
SDFerr(SDF_F_SDF_INTERNALVERIFY_ECC, ERR_R_EVP_LIB);
|
||||
goto end;
|
||||
}
|
||||
if (!EVP_PKEY_verify_init(ctx)) {
|
||||
SDFerr(SDF_F_SDF_INTERNALVERIFY_ECC, ERR_R_EVP_LIB);
|
||||
goto end;
|
||||
}
|
||||
if (!EVP_PKEY_CTX_set_ec_sign_type(ctx, NID_sm_scheme)) {
|
||||
SDFerr(SDF_F_SDF_INTERNALVERIFY_ECC, ERR_R_EVP_LIB);
|
||||
goto end;
|
||||
}
|
||||
if (1 != EVP_PKEY_verify(ctx, buf, siz, pucData,
|
||||
(size_t)uiDataLength)) {
|
||||
SDFerr(SDF_F_SDF_INTERNALVERIFY_ECC, ERR_R_EVP_LIB);
|
||||
goto end;
|
||||
}
|
||||
|
||||
ret = SDR_OK;
|
||||
|
||||
end:
|
||||
EVP_PKEY_CTX_free(ctx);
|
||||
EVP_PKEY_free(pkey);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int SDF_InternalEncrypt_ECC(
|
||||
void *hSessionHandle,
|
||||
unsigned int uiIPKIndex,
|
||||
unsigned int uiAlgID,
|
||||
unsigned char *pucData,
|
||||
unsigned int uiDataLength,
|
||||
ECCCipher *pucEncData)
|
||||
{
|
||||
int ret = 0;
|
||||
EVP_PKEY *pkey = NULL;
|
||||
SM2_CIPHERTEXT_VALUE *cv = NULL;
|
||||
SM2_ENC_PARAMS params;
|
||||
|
||||
/* check arguments */
|
||||
if (!hSessionHandle || !pucData || !pucEncData) {
|
||||
SDFerr(SDF_F_SDF_INTERNALENCRYPT_ECC,
|
||||
ERR_R_PASSED_NULL_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
if (uiDataLength > ECCref_MAX_LEN) {
|
||||
SDFerr(SDF_F_SDF_INTERNALENCRYPT_ECC,
|
||||
SDF_R_INVALID_INPUT_LENGTH);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!(pkey = sdf_load_ec_public_key((SDF_SESSION *)hSessionHandle,
|
||||
uiIPKIndex, uiAlgID))) {
|
||||
SDFerr(SDF_F_SDF_INTERNALENCRYPT_ECC, ERR_R_GMAPI_LIB);
|
||||
goto end;
|
||||
}
|
||||
|
||||
(void)SM2_ENC_PARAMS_init_with_recommended(¶ms);
|
||||
|
||||
/* we need to use the EVP_PKEY interface to use ENGINE ?*/
|
||||
if (!(cv = SM2_do_encrypt(¶ms, pucData, (size_t)uiDataLength,
|
||||
EVP_PKEY_get0_EC_KEY(pkey)))) {
|
||||
SDFerr(SDF_F_SDF_INTERNALENCRYPT_ECC, ERR_R_EC_LIB);
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (!SM2_CIPHERTEXT_VALUE_get_ECCCipher(cv, pucEncData)) {
|
||||
SDFerr(SDF_F_SDF_INTERNALENCRYPT_ECC, ERR_R_EC_LIB);
|
||||
goto end;
|
||||
}
|
||||
|
||||
ret = SDR_OK;
|
||||
|
||||
end:
|
||||
EVP_PKEY_free(pkey);
|
||||
SM2_CIPHERTEXT_VALUE_free(cv);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int SDF_InternalDecrypt_ECC(
|
||||
void *hSessionHandle,
|
||||
unsigned int uiISKIndex,
|
||||
unsigned int uiAlgID,
|
||||
ECCCipher *pucEncData,
|
||||
unsigned char *pucData,
|
||||
unsigned int *puiDataLength)
|
||||
{
|
||||
int ret = 0;
|
||||
EVP_PKEY *pkey = NULL;
|
||||
|
||||
|
||||
/* check arguments */
|
||||
if (!hSessionHandle || !pucEncData || !pucData || !puiDataLength) {
|
||||
SDFerr(SDF_F_SDF_INTERNALDECRYPT_ECC,
|
||||
ERR_R_PASSED_NULL_PARAMETER);
|
||||
return SDR_UNKNOWERR;
|
||||
}
|
||||
|
||||
if (!(pkey = sdf_load_ec_private_key(hSessionHandle,
|
||||
uiISKIndex, uiAlgID))) {
|
||||
SDFerr(SDF_F_SDF_INTERNALDECRYPT_ECC, ERR_R_GMAPI_LIB);
|
||||
goto end;
|
||||
}
|
||||
|
||||
|
||||
end:
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1,215 +0,0 @@
|
||||
/* ====================================================================
|
||||
* Copyright (c) 2016 The GmSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the GmSSL Project.
|
||||
* (http://gmssl.org/)"
|
||||
*
|
||||
* 4. The name "GmSSL Project" must not be used to endorse or promote
|
||||
* products derived from this software without prior written
|
||||
* permission. For written permission, please contact
|
||||
* guanzhi1980@gmail.com.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "GmSSL"
|
||||
* nor may "GmSSL" appear in their names without prior written
|
||||
* permission of the GmSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the GmSSL Project
|
||||
* (http://gmssl.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE GmSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GmSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES
|
||||
* LOSS OF USE, DATA, OR PROFITS OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/rand.h>
|
||||
#include <openssl/gmapi.h>
|
||||
#include <openssl/gmsdf.h>
|
||||
#include "sdf_lcl.h"
|
||||
|
||||
/* TODO: current max input length is INT_MAX
|
||||
* we will return error when the input is longer than INT_MAX.
|
||||
* do not fixed this in GmSSL 2.x, fixed it in the future.
|
||||
* we can seperate the input to multiple of INT_MAX with multiple upadtes.
|
||||
*/
|
||||
/*
|
||||
* Implement with ENGINE
|
||||
* as some of the ciphers such as SM1/SSF33 can not be supported by
|
||||
* software, we can use ENGINEs hoping that such ciphers can be supported.
|
||||
*/
|
||||
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 ret = SDR_UNKNOWERR;
|
||||
SDF_SESSION *session = (SDF_SESSION *)hSessionHandle;
|
||||
SDF_KEY *key = (SDF_KEY *)hKeyHandle;
|
||||
EVP_CIPHER_CTX *ctx = NULL;
|
||||
const EVP_CIPHER *cipher;
|
||||
unsigned char *p;
|
||||
int len;
|
||||
|
||||
/* check arguments */
|
||||
if (!hSessionHandle || !hKeyHandle || !pucIV || !pucData || !pucEncData
|
||||
|| !puiEncDataLength) {
|
||||
SDFerr(SDF_F_SDF_ENCRYPT, ERR_R_PASSED_NULL_PARAMETER);
|
||||
return SDR_UNKNOWERR;
|
||||
}
|
||||
if (uiDataLength <= 0 || uiDataLength > INT_MAX) {
|
||||
SDFerr(SDF_F_SDF_ENCRYPT, SDF_R_INVALID_INPUT_LENGTH);
|
||||
return SDR_UNKNOWERR;
|
||||
}
|
||||
if (*puiEncDataLength < uiDataLength + EVP_MAX_BLOCK_LENGTH * 2) {
|
||||
SDFerr(SDF_F_SDF_ENCRYPT, SDF_R_BUFFER_TOO_SMALL);
|
||||
return SDR_UNKNOWERR;
|
||||
}
|
||||
|
||||
/* parse arguments */
|
||||
if (!(cipher = sdf_get_cipher(hSessionHandle, uiAlgID))) {
|
||||
SDFerr(SDF_F_SDF_ENCRYPT, SDF_R_INVALID_ALGOR);
|
||||
goto end;
|
||||
}
|
||||
if (key->keylen != EVP_CIPHER_key_length(cipher)) {
|
||||
SDFerr(SDF_F_SDF_ENCRYPT, SDF_R_INVALID_KEY_HANDLE);
|
||||
goto end;
|
||||
}
|
||||
|
||||
/* encrypt */
|
||||
if (!(ctx = EVP_CIPHER_CTX_new())) {
|
||||
SDFerr(SDF_F_SDF_ENCRYPT, ERR_R_MALLOC_FAILURE);
|
||||
goto end;
|
||||
}
|
||||
if (!EVP_EncryptInit_ex(ctx, cipher, session->engine, key->key, pucIV)) {
|
||||
SDFerr(SDF_F_SDF_ENCRYPT, ERR_R_EVP_LIB);
|
||||
goto end;
|
||||
}
|
||||
p = pucEncData;
|
||||
if (!EVP_EncryptUpdate(ctx, p, &len, pucData, (int)uiDataLength)) {
|
||||
SDFerr(SDF_F_SDF_ENCRYPT, ERR_R_EVP_LIB);
|
||||
goto end;
|
||||
}
|
||||
p += len;
|
||||
if (!EVP_EncryptFinal_ex(ctx, p, &len)) {
|
||||
SDFerr(SDF_F_SDF_ENCRYPT, ERR_R_EVP_LIB);
|
||||
goto end;
|
||||
}
|
||||
p += len;
|
||||
|
||||
/* set return value */
|
||||
*puiEncDataLength = p - pucEncData;
|
||||
ret = SDR_OK;
|
||||
|
||||
end:
|
||||
EVP_CIPHER_CTX_free(ctx);
|
||||
return 0;
|
||||
}
|
||||
|
||||
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 ret = SDR_UNKNOWERR;
|
||||
SDF_SESSION *session = (SDF_SESSION *)hSessionHandle;
|
||||
SDF_KEY *key = (SDF_KEY *)hKeyHandle;
|
||||
const EVP_CIPHER *cipher;
|
||||
EVP_CIPHER_CTX *ctx = NULL;
|
||||
unsigned char *p;
|
||||
int len;
|
||||
|
||||
/* check arguments */
|
||||
if (!hSessionHandle || !hKeyHandle || !pucIV || !pucEncData ||
|
||||
!pucData || !puiDataLength) {
|
||||
SDFerr(SDF_F_SDF_DECRYPT, ERR_R_PASSED_NULL_PARAMETER);
|
||||
return SDR_UNKNOWERR;
|
||||
}
|
||||
if (uiEncDataLength <= 0 || uiEncDataLength > INT_MAX) {
|
||||
SDFerr(SDF_F_SDF_DECRYPT, SDF_R_INVALID_INPUT_LENGTH);
|
||||
return SDR_UNKNOWERR;
|
||||
}
|
||||
if (*puiDataLength < uiEncDataLength) {
|
||||
SDFerr(SDF_F_SDF_DECRYPT, SDF_R_BUFFER_TOO_SMALL);
|
||||
return SDR_UNKNOWERR;
|
||||
}
|
||||
|
||||
/* parse arguments */
|
||||
if (!(cipher = sdf_get_cipher(hSessionHandle, uiAlgID))) {
|
||||
SDFerr(SDF_F_SDF_DECRYPT, SDF_R_INVALID_ALGOR);
|
||||
goto end;
|
||||
}
|
||||
if (key->keylen != EVP_CIPHER_key_length(cipher)) {
|
||||
SDFerr(SDF_F_SDF_DECRYPT, SDF_R_INVALID_KEY_HANDLE);
|
||||
goto end;
|
||||
}
|
||||
|
||||
/* decrypt */
|
||||
if (!(ctx = EVP_CIPHER_CTX_new())) {
|
||||
SDFerr(SDF_F_SDF_DECRYPT, ERR_R_MALLOC_FAILURE);
|
||||
goto end;
|
||||
}
|
||||
if (!EVP_DecryptInit_ex(ctx, cipher, session->engine, key->key, pucIV)) {
|
||||
SDFerr(SDF_F_SDF_DECRYPT, ERR_R_EVP_LIB);
|
||||
goto end;
|
||||
}
|
||||
p = pucData;
|
||||
if (!EVP_DecryptUpdate(ctx, p, &len, pucEncData,
|
||||
(int)uiEncDataLength)) {
|
||||
SDFerr(SDF_F_SDF_DECRYPT, ERR_R_EVP_LIB);
|
||||
goto end;
|
||||
}
|
||||
p += len;
|
||||
if (!EVP_DecryptFinal_ex(ctx, p, &len)) {
|
||||
SDFerr(SDF_F_SDF_DECRYPT, ERR_R_EVP_LIB);
|
||||
goto end;
|
||||
}
|
||||
p += len;
|
||||
|
||||
/* set return value */
|
||||
*puiDataLength = p - pucEncData;
|
||||
ret =SDR_OK;
|
||||
|
||||
end:
|
||||
EVP_CIPHER_CTX_free(ctx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -1,129 +0,0 @@
|
||||
/*
|
||||
* Generated by util/mkerr.pl DO NOT EDIT
|
||||
* Copyright 1995-2017 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
* this file except in compliance with the License. You can obtain a copy
|
||||
* in the file LICENSE in the source distribution or at
|
||||
* https://www.openssl.org/source/license.html
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/gmsdf.h>
|
||||
|
||||
/* BEGIN ERROR CODES */
|
||||
#ifndef OPENSSL_NO_ERR
|
||||
|
||||
# define ERR_FUNC(func) ERR_PACK(ERR_LIB_SDF,func,0)
|
||||
# define ERR_REASON(reason) ERR_PACK(ERR_LIB_SDF,0,reason)
|
||||
|
||||
static ERR_STRING_DATA SDF_str_functs[] = {
|
||||
{ERR_FUNC(SDF_F_SDF_CALCULATEMAC), "SDF_CalculateMAC"},
|
||||
{ERR_FUNC(SDF_F_SDF_CLOSEDEVICE), "SDF_CloseDevice"},
|
||||
{ERR_FUNC(SDF_F_SDF_CLOSESESSION), "SDF_CloseSession"},
|
||||
{ERR_FUNC(SDF_F_SDF_DECODE_EC_SIGNATURE), "sdf_decode_ec_signature"},
|
||||
{ERR_FUNC(SDF_F_SDF_DECRYPT), "SDF_Decrypt"},
|
||||
{ERR_FUNC(SDF_F_SDF_ENCODE_EC_SIGNATURE), "sdf_encode_ec_signature"},
|
||||
{ERR_FUNC(SDF_F_SDF_ENCRYPT), "SDF_Encrypt"},
|
||||
{ERR_FUNC(SDF_F_SDF_EXPORTENCPUBLICKEY_ECC),
|
||||
"SDF_ExportEncPublicKey_ECC"},
|
||||
{ERR_FUNC(SDF_F_SDF_EXPORTENCPUBLICKEY_RSA),
|
||||
"SDF_ExportEncPublicKey_RSA"},
|
||||
{ERR_FUNC(SDF_F_SDF_EXPORTSIGNPUBLICKEY_ECC),
|
||||
"SDF_ExportSignPublicKey_ECC"},
|
||||
{ERR_FUNC(SDF_F_SDF_EXPORTSIGNPUBLICKEY_RSA),
|
||||
"SDF_ExportSignPublicKey_RSA"},
|
||||
{ERR_FUNC(SDF_F_SDF_EXTERNALDECRYPT_ECC), "SDF_ExternalDecrypt_ECC"},
|
||||
{ERR_FUNC(SDF_F_SDF_EXTERNALENCRYPT_ECC), "SDF_ExternalEncrypt_ECC"},
|
||||
{ERR_FUNC(SDF_F_SDF_EXTERNALPRIVATEKEYOPERATION_RSA),
|
||||
"SDF_ExternalPrivateKeyOperation_RSA"},
|
||||
{ERR_FUNC(SDF_F_SDF_EXTERNALPUBLICKEYOPERATION_RSA),
|
||||
"SDF_ExternalPublicKeyOperation_RSA"},
|
||||
{ERR_FUNC(SDF_F_SDF_EXTERNALSIGN_ECC), "SDF_ExternalSign_ECC"},
|
||||
{ERR_FUNC(SDF_F_SDF_EXTERNALVERIFY_ECC), "SDF_ExternalVerify_ECC"},
|
||||
{ERR_FUNC(SDF_F_SDF_GENERATEKEYPAIR_ECC), "SDF_GenerateKeyPair_ECC"},
|
||||
{ERR_FUNC(SDF_F_SDF_GENERATEKEYPAIR_RSA), "SDF_GenerateKeyPair_RSA"},
|
||||
{ERR_FUNC(SDF_F_SDF_GENERATEKEYWITHEPK_ECC),
|
||||
"SDF_GenerateKeyWithEPK_ECC"},
|
||||
{ERR_FUNC(SDF_F_SDF_GENERATEKEYWITHEPK_RSA),
|
||||
"SDF_GenerateKeyWithEPK_RSA"},
|
||||
{ERR_FUNC(SDF_F_SDF_GENERATEKEYWITHIPK_ECC),
|
||||
"SDF_GenerateKeyWithIPK_ECC"},
|
||||
{ERR_FUNC(SDF_F_SDF_GENERATEKEYWITHIPK_RSA),
|
||||
"SDF_GenerateKeyWithIPK_RSA"},
|
||||
{ERR_FUNC(SDF_F_SDF_GENERATERANDOM), "SDF_GenerateRandom"},
|
||||
{ERR_FUNC(SDF_F_SDF_GETDEVICEINFO), "SDF_GetDeviceInfo"},
|
||||
{ERR_FUNC(SDF_F_SDF_GETPRIVATEKEYACCESSRIGHT),
|
||||
"SDF_GetPrivateKeyAccessRight"},
|
||||
{ERR_FUNC(SDF_F_SDF_GET_CIPHER), "sdf_get_cipher"},
|
||||
{ERR_FUNC(SDF_F_SDF_GET_DIGEST), "sdf_get_digest"},
|
||||
{ERR_FUNC(SDF_F_SDF_HASHFINAL), "SDF_HashFinal"},
|
||||
{ERR_FUNC(SDF_F_SDF_HASHINIT), "SDF_HashInit"},
|
||||
{ERR_FUNC(SDF_F_SDF_HASHUPDATE), "SDF_HashUpdate"},
|
||||
{ERR_FUNC(SDF_F_SDF_IMPORTKEY), "SDF_ImportKey"},
|
||||
{ERR_FUNC(SDF_F_SDF_IMPORTKEYWITHISK_ECC), "SDF_ImportKeyWithISK_ECC"},
|
||||
{ERR_FUNC(SDF_F_SDF_IMPORTKEYWITHISK_RSA), "SDF_ImportKeyWithISK_RSA"},
|
||||
{ERR_FUNC(SDF_F_SDF_INTERNALDECRYPT_ECC), "SDF_InternalDecrypt_ECC"},
|
||||
{ERR_FUNC(SDF_F_SDF_INTERNALENCRYPT_ECC), "SDF_InternalEncrypt_ECC"},
|
||||
{ERR_FUNC(SDF_F_SDF_INTERNALPRIVATEKEYOPERATION_RSA),
|
||||
"SDF_InternalPrivateKeyOperation_RSA"},
|
||||
{ERR_FUNC(SDF_F_SDF_INTERNALPUBLICKEYOPERATION_RSA),
|
||||
"SDF_InternalPublicKeyOperation_RSA"},
|
||||
{ERR_FUNC(SDF_F_SDF_INTERNALSIGN_ECC), "SDF_InternalSign_ECC"},
|
||||
{ERR_FUNC(SDF_F_SDF_INTERNALVERIFY_ECC), "SDF_InternalVerify_ECC"},
|
||||
{ERR_FUNC(SDF_F_SDF_LOAD_EC_PRIVATE_KEY), "sdf_load_ec_private_key"},
|
||||
{ERR_FUNC(SDF_F_SDF_LOAD_EC_PUBLIC_KEY), "sdf_load_ec_public_key"},
|
||||
{ERR_FUNC(SDF_F_SDF_LOAD_RSA_PRIVATE_KEY), "sdf_load_rsa_private_key"},
|
||||
{ERR_FUNC(SDF_F_SDF_LOAD_RSA_PUBLIC_KEY), "sdf_load_rsa_public_key"},
|
||||
{ERR_FUNC(SDF_F_SDF_OPENDEVICE), "SDF_OpenDevice"},
|
||||
{ERR_FUNC(SDF_F_SDF_OPENSESSION), "SDF_OpenSession"},
|
||||
{ERR_FUNC(SDF_F_SDF_RELEASEPRIVATEKEYACCESSRIGHT),
|
||||
"SDF_ReleasePrivateKeyAccessRight"},
|
||||
{0, NULL}
|
||||
};
|
||||
|
||||
static ERR_STRING_DATA SDF_str_reasons[] = {
|
||||
{ERR_REASON(SDF_R_BUFFER_TOO_SMALL), "buffer too small"},
|
||||
{ERR_REASON(SDF_R_BUUTER_TOO_SMALL), "buuter too small"},
|
||||
{ERR_REASON(SDF_R_CBCMAC_FAILURE), "cbcmac failure"},
|
||||
{ERR_REASON(SDF_R_CMAC_FAILURE), "cmac failure"},
|
||||
{ERR_REASON(SDF_R_COMPUTE_SM2_ID_FAILURE), "compute sm2 id failure"},
|
||||
{ERR_REASON(SDF_R_ENGINE_LOAD_KEY_FAILURE), "engine load key failure"},
|
||||
{ERR_REASON(SDF_R_GET_PRIVATE_KEY_FAILED), "get private key failed"},
|
||||
{ERR_REASON(SDF_R_GET_PUBLIC_KEY_FAILED), "get public key failed"},
|
||||
{ERR_REASON(SDF_R_INVALID_ALGOR), "invalid algor"},
|
||||
{ERR_REASON(SDF_R_INVALID_DEVICE_HANDLE), "invalid device handle"},
|
||||
{ERR_REASON(SDF_R_INVALID_EC_CIPHERTEXT), "invalid ec ciphertext"},
|
||||
{ERR_REASON(SDF_R_INVALID_EC_PRIVATE_KEY), "invalid ec private key"},
|
||||
{ERR_REASON(SDF_R_INVALID_EC_PUBLIC_KEY), "invalid ec public key"},
|
||||
{ERR_REASON(SDF_R_INVALID_INPUT_LENGTH), "invalid input length"},
|
||||
{ERR_REASON(SDF_R_INVALID_KEY_HANDLE), "invalid key handle"},
|
||||
{ERR_REASON(SDF_R_INVALID_KEY_INDEX), "invalid key index"},
|
||||
{ERR_REASON(SDF_R_INVALID_KEY_LENGTH), "invalid key length"},
|
||||
{ERR_REASON(SDF_R_INVALID_KEY_USAGE), "invalid key usage"},
|
||||
{ERR_REASON(SDF_R_INVALID_LENGTH), "invalid length"},
|
||||
{ERR_REASON(SDF_R_INVALID_OPERATION_STATE), "invalid operation state"},
|
||||
{ERR_REASON(SDF_R_INVALID_PASSWORD_LENGTH), "invalid password length"},
|
||||
{ERR_REASON(SDF_R_INVALID_SESSION), "invalid session"},
|
||||
{ERR_REASON(SDF_R_INVALID_SESSION_HANDLE), "invalid session handle"},
|
||||
{ERR_REASON(SDF_R_KEY_TYPE_NOT_MATCH), "key type not match"},
|
||||
{ERR_REASON(SDF_R_LOAD_ENGINE_FAILURE), "load engine failure"},
|
||||
{ERR_REASON(SDF_R_RANDOM_FAILURE), "random failure"},
|
||||
{ERR_REASON(SDF_R_SDF_SESSION_NO_ENGINE), "sdf session no engine"},
|
||||
{0, NULL}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
int ERR_load_SDF_strings(void)
|
||||
{
|
||||
#ifndef OPENSSL_NO_ERR
|
||||
|
||||
if (ERR_func_error_string(SDF_str_functs[0].error) == NULL) {
|
||||
ERR_load_strings(0, SDF_str_functs);
|
||||
ERR_load_strings(0, SDF_str_reasons);
|
||||
}
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
@@ -1,99 +0,0 @@
|
||||
/* ====================================================================
|
||||
* Copyright (c) 2016 The GmSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the GmSSL Project.
|
||||
* (http://gmssl.org/)"
|
||||
*
|
||||
* 4. The name "GmSSL Project" must not be used to endorse or promote
|
||||
* products derived from this software without prior written
|
||||
* permission. For written permission, please contact
|
||||
* guanzhi1980@gmail.com.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "GmSSL"
|
||||
* nor may "GmSSL" appear in their names without prior written
|
||||
* permission of the GmSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the GmSSL Project
|
||||
* (http://gmssl.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE GmSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GmSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*/
|
||||
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/sdf.h>
|
||||
#include "../../e_os.h"
|
||||
|
||||
static ERR_STRING_DATA sdf_errstr[] = {
|
||||
{ SDR_OK, "Success" },
|
||||
{ SDR_BASE, "Base" },
|
||||
{ SDR_UNKNOWERR, "Unknown error" },
|
||||
{ SDR_NOTSUPPORT, "Not supported" },
|
||||
{ SDR_COMMFAIL, "Commnunication failure" },
|
||||
{ SDR_HARDFAIL, "Hardware failure" },
|
||||
{ SDR_OPENDEVICE, "Open device" },
|
||||
{ SDR_OPENSESSION, "Open session" },
|
||||
{ SDR_PARDENY, "Private key access denied (for index 0)" },
|
||||
{ SDR_KEYNOTEXIST, "Key not exist" },
|
||||
{ SDR_ALGNOTSUPPOT, "Algorithm not supported" },
|
||||
{ SDR_ALGMODNOTSUPPORT, "Algorithm mode not supported" },
|
||||
{ SDR_PKOPERR, "Public key operation error" },
|
||||
{ SDR_SKOPERR, "Private key operation error" },
|
||||
{ SDR_SIGNERR, "Signature generation error" },
|
||||
{ SDR_VERIFYERR, "Singature verification error" },
|
||||
{ SDR_SYMOPERR, "Symmetric encryption error" },
|
||||
{ SDR_STEPERR, "Multi-step operation error" },
|
||||
{ SDR_FILESIZEERR, "File size error" },
|
||||
{ SDR_FILENOEXIST, "File not exist" },
|
||||
{ SDR_FILEOFSERR, "File offset error" },
|
||||
{ SDR_KEYTYPEERR, "Key type error" },
|
||||
{ SDR_KEYERR, "Key error" },
|
||||
{ SDR_ENCDATAERR, "ECC encrypted data error" },
|
||||
{ SDR_RANDERR, "Random number generator error" },
|
||||
{ SDR_PRKRERR, "Private key privilege error" },
|
||||
{ SDR_MACERR, "MAC computation error" },
|
||||
{ SDR_FILEEXSITS, "File already exist" },
|
||||
{ SDR_FILEWERR, "File write error" },
|
||||
{ SDR_NOBUFFER, "No buffer" },
|
||||
{ SDR_INARGERR, "Input argument error" },
|
||||
{ SDR_OUTARGERR, "Output argument error" },
|
||||
};
|
||||
|
||||
const char *SDF_GetErrorString(int err)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < OSSL_NELEM(sdf_errstr); i++) {
|
||||
if (err == sdf_errstr[i].error) {
|
||||
return sdf_errstr[i].string;
|
||||
}
|
||||
}
|
||||
return "(undef)";
|
||||
}
|
||||
|
||||
@@ -1,238 +0,0 @@
|
||||
/* ====================================================================
|
||||
* Copyright (c) 2016 The GmSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the GmSSL Project.
|
||||
* (http://gmssl.org/)"
|
||||
*
|
||||
* 4. The name "GmSSL Project" must not be used to endorse or promote
|
||||
* products derived from this software without prior written
|
||||
* permission. For written permission, please contact
|
||||
* guanzhi1980@gmail.com.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "GmSSL"
|
||||
* nor may "GmSSL" appear in their names without prior written
|
||||
* permission of the GmSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the GmSSL Project
|
||||
* (http://gmssl.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE GmSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GmSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES
|
||||
* LOSS OF USE, DATA, OR PROFITS OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <openssl/gmsdf.h>
|
||||
#include <openssl/gmapi.h>
|
||||
#include "sdf_lcl.h"
|
||||
|
||||
int SDF_PrintDeviceInfo(FILE *fp, DEVICEINFO *devInfo)
|
||||
{
|
||||
char issuerName[41];
|
||||
char deviceName[17];
|
||||
char deviceSerial[17];
|
||||
|
||||
/* IssuerName */
|
||||
memcpy(issuerName, devInfo->IssuerName, 40);
|
||||
issuerName[40] = 0;
|
||||
fprintf(fp, "IssuerName = %s\n", issuerName);
|
||||
|
||||
/* DeviceName */
|
||||
memcpy(deviceName, devInfo->DeviceName, 16);
|
||||
deviceName[16] = 0;
|
||||
fprintf(fp, "DeviceName = %s\n", deviceName);
|
||||
|
||||
/* DeviceSerial */
|
||||
memcpy(deviceSerial, devInfo->DeviceSerial, 16);
|
||||
deviceSerial[16] = 0;
|
||||
fprintf(fp, "DeviceSerial = %s\n", deviceSerial);
|
||||
|
||||
/* DeviceVersion */
|
||||
fprintf(fp, "DeviceVersion = 0x%08X\n", devInfo->DeviceVersion);
|
||||
|
||||
/* StandardVersion */
|
||||
fprintf(fp, "StandardVersion = 0x%08X\n", devInfo->StandardVersion);
|
||||
|
||||
/* AsymAlgAbility */
|
||||
fputs("AsymAlgAbility[0] =", fp);
|
||||
if (devInfo->AsymAlgAbility[0] & SGD_RSA) {
|
||||
fputs(" RSA", fp);
|
||||
}
|
||||
if (devInfo->AsymAlgAbility[0] & SGD_SM2) {
|
||||
fputs(" SM2", fp);
|
||||
}
|
||||
fputs("\n", fp);
|
||||
fprintf(fp, "AsymAlgAbility[1] = 0x%08X\n", devInfo->AsymAlgAbility[1]);
|
||||
|
||||
/* SymAlgAbility */
|
||||
fputs("SymAlgAbility =", fp);
|
||||
if (devInfo->SymAlgAbility & SGD_SM1)
|
||||
fputs(" SM1", fp);
|
||||
if (devInfo->SymAlgAbility & SGD_SSF33)
|
||||
fputs(" SSF33", fp);
|
||||
if (devInfo->SymAlgAbility & SGD_SM4)
|
||||
fputs(" SM4", fp);
|
||||
if (devInfo->SymAlgAbility & SGD_ZUC)
|
||||
fputs(" ZUC", fp);
|
||||
fputs("\n", fp);
|
||||
|
||||
/* HashAlgAbility */
|
||||
fputs("HashAlgAbility =", fp);
|
||||
if (devInfo->HashAlgAbility & SGD_SM3)
|
||||
fputs(" SM3", fp);
|
||||
if (devInfo->HashAlgAbility & SGD_SHA1)
|
||||
fputs(" SHA1", fp);
|
||||
if (devInfo->HashAlgAbility & SGD_SHA256)
|
||||
fputs(" SHA256", fp);
|
||||
fputs("\n", fp);
|
||||
|
||||
/* BufferSize */
|
||||
fprintf(fp, "BufferSize = %u\n", devInfo->BufferSize);
|
||||
|
||||
return SDR_OK;
|
||||
}
|
||||
|
||||
int SDF_PrintRSAPublicKey(FILE *fp, RSArefPublicKey *pk)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* bits */
|
||||
(void)fprintf(fp, "bits = %u\n", pk->bits);
|
||||
|
||||
/* m */
|
||||
(void)fputs("m = ", fp);
|
||||
for (i = 0; i < RSAref_MAX_LEN; i++) {
|
||||
(void)fprintf(fp, "%02X", pk->m[i]);
|
||||
}
|
||||
(void)fputs("\n", fp);
|
||||
|
||||
/* e */
|
||||
(void)fputs("e = ", fp);
|
||||
for (i = 0; i < RSAref_MAX_LEN; i++) {
|
||||
(void)fprintf(fp, "%02X", pk->e[i]);
|
||||
}
|
||||
(void)fputs("\n", fp);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int SDF_PrintRSAPrivateKey(FILE *fp, RSArefPrivateKey *sk)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int SDF_PrintECCPublicKey(FILE *fp, ECCrefPublicKey *pk)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* bits */
|
||||
(void)fprintf(fp, "bits = %u\n", pk->bits);
|
||||
|
||||
/* x */
|
||||
(void)fputs("x = ", fp);
|
||||
for (i = 0; i < ECCref_MAX_LEN; i++) {
|
||||
(void)fprintf(fp, "%02X", pk->x[i]);
|
||||
}
|
||||
(void)fputs("\n", fp);
|
||||
|
||||
/* y */
|
||||
(void)fputs("y = ", fp);
|
||||
for (i = 0; i < ECCref_MAX_LEN; i++) {
|
||||
(void)fprintf(fp, "%02X", pk->y[i]);
|
||||
}
|
||||
(void)fputs("\n", fp);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int SDF_PrintECCPrivateKey(FILE *fp, ECCrefPrivateKey *pk)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int SDF_PrintECCCipher(FILE *fp, ECCCipher *cipher)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* x */
|
||||
(void)fputs("x = ", fp);
|
||||
for (i = 0; i < ECCref_MAX_LEN; i++) {
|
||||
(void)fprintf(fp, "%02X", cipher->x[i]);
|
||||
}
|
||||
(void)fputs("\n", fp);
|
||||
|
||||
/* y */
|
||||
(void)fputs("y = ", fp);
|
||||
for (i = 0; i < ECCref_MAX_LEN; i++) {
|
||||
(void)fprintf(fp, "%02X", cipher->y[i]);
|
||||
}
|
||||
(void)fputs("\n", fp);
|
||||
|
||||
/* M */
|
||||
(void)fputs("M = ", fp);
|
||||
for (i = 0; i < 32; i++) {
|
||||
(void)fprintf(fp, "%02X", cipher->M[i]);
|
||||
}
|
||||
(void)fputs("\n", fp);
|
||||
|
||||
/* L */
|
||||
(void)fprintf(fp, "L = %u\n", cipher->L);
|
||||
|
||||
/* C */
|
||||
for (i = 0; i < cipher->L; i++) {
|
||||
(void)fprintf(fp, "%02X", cipher->C[i]);
|
||||
}
|
||||
(void)fputs("\n", fp);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int SDF_PrintECCSignature(FILE *fp, ECCSignature *sig)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* r */
|
||||
(void)fputs("r = ", fp);
|
||||
for (i = 0; i < ECCref_MAX_LEN; i++) {
|
||||
(void)fprintf(fp, "%02X", sig->r[i]);
|
||||
}
|
||||
(void)fputs("\n", fp);
|
||||
|
||||
/* s */
|
||||
(void)fputs("s = ", fp);
|
||||
for (i = 0; i < ECCref_MAX_LEN; i++) {
|
||||
(void)fprintf(fp, "%02X", sig->s[i]);
|
||||
}
|
||||
(void)fputs("\n", fp);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -1,89 +0,0 @@
|
||||
/* ====================================================================
|
||||
* Copyright (c) 2016 The GmSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the GmSSL Project.
|
||||
* (http://gmssl.org/)"
|
||||
*
|
||||
* 4. The name "GmSSL Project" must not be used to endorse or promote
|
||||
* products derived from this software without prior written
|
||||
* permission. For written permission, please contact
|
||||
* guanzhi1980@gmail.com.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "GmSSL"
|
||||
* nor may "GmSSL" appear in their names without prior written
|
||||
* permission of the GmSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the GmSSL Project
|
||||
* (http://gmssl.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE GmSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GmSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES
|
||||
* LOSS OF USE, DATA, OR PROFITS OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*/
|
||||
|
||||
#include <openssl/gmsdf.h>
|
||||
|
||||
int SDF_CreateFile(
|
||||
void *hSessionHandle,
|
||||
unsigned char *pucFileName,
|
||||
unsigned int uiNameLen,
|
||||
unsigned int uiFileSize)
|
||||
{
|
||||
return SDR_NOTSUPPORT;
|
||||
}
|
||||
|
||||
int SDF_ReadFile(
|
||||
void *hSessionHandle,
|
||||
unsigned char *pucFileName,
|
||||
unsigned int uiNameLen,
|
||||
unsigned int uiOffset,
|
||||
unsigned int *puiReadLength,
|
||||
unsigned char *pucBuffer)
|
||||
{
|
||||
return SDR_NOTSUPPORT;
|
||||
}
|
||||
|
||||
int SDF_WriteFile(
|
||||
void *hSessionHandle,
|
||||
unsigned char *pucFileName,
|
||||
unsigned int uiNameLen,
|
||||
unsigned int uiOffset,
|
||||
unsigned int uiWriteLength,
|
||||
unsigned char *pucBuffer)
|
||||
{
|
||||
return SDR_NOTSUPPORT;
|
||||
}
|
||||
|
||||
int SDF_DeleteFile(
|
||||
void *hSessionHandle,
|
||||
unsigned char *pucFileName,
|
||||
unsigned int uiNameLen)
|
||||
{
|
||||
return SDR_NOTSUPPORT;
|
||||
}
|
||||
@@ -1,217 +0,0 @@
|
||||
/* ====================================================================
|
||||
* Copyright (c) 2016 The GmSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the GmSSL Project.
|
||||
* (http://gmssl.org/)"
|
||||
*
|
||||
* 4. The name "GmSSL Project" must not be used to endorse or promote
|
||||
* products derived from this software without prior written
|
||||
* permission. For written permission, please contact
|
||||
* guanzhi1980@gmail.com.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "GmSSL"
|
||||
* nor may "GmSSL" appear in their names without prior written
|
||||
* permission of the GmSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the GmSSL Project
|
||||
* (http://gmssl.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE GmSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GmSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES
|
||||
* LOSS OF USE, DATA, OR PROFITS OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/sm2.h>
|
||||
#include <openssl/gmsdf.h>
|
||||
#include "sdf_lcl.h"
|
||||
|
||||
int SDF_HashInit(
|
||||
void *hSessionHandle,
|
||||
unsigned int uiAlgID,
|
||||
ECCrefPublicKey *pucPublicKey,
|
||||
unsigned char *pucID,
|
||||
unsigned int uiIDLength)
|
||||
{
|
||||
int ret = SDR_UNKNOWERR;
|
||||
SDF_SESSION *session = (SDF_SESSION *)hSessionHandle;
|
||||
EVP_MD_CTX *md_ctx = NULL;
|
||||
const EVP_MD *md;
|
||||
|
||||
/* check arguments */
|
||||
if (!hSessionHandle) {
|
||||
SDFerr(SDF_F_SDF_HASHINIT, ERR_R_PASSED_NULL_PARAMETER);
|
||||
return SDR_INARGERR;
|
||||
}
|
||||
if (pucID && (uiIDLength <= 0 || uiIDLength > INT_MAX)) {
|
||||
SDFerr(SDF_F_SDF_HASHINIT, SDF_R_INVALID_LENGTH);
|
||||
return SDR_INARGERR;
|
||||
}
|
||||
if (session->md_ctx) {
|
||||
SDFerr(SDF_F_SDF_HASHINIT, SDF_R_INVALID_OPERATION_STATE);
|
||||
return SDR_INARGERR;
|
||||
}
|
||||
if (!(md = EVP_get_digestbysgd(uiAlgID))) {
|
||||
SDFerr(SDF_F_SDF_HASHINIT, SDF_R_INVALID_ALGOR);
|
||||
return SDR_INARGERR;
|
||||
}
|
||||
|
||||
/* malloc and init */
|
||||
if (!(md_ctx = EVP_MD_CTX_new())) {
|
||||
SDFerr(SDF_F_SDF_HASHINIT, ERR_R_MALLOC_FAILURE);
|
||||
ret = SDR_NOBUFFER;
|
||||
goto end;
|
||||
}
|
||||
if (!EVP_DigestInit_ex(md_ctx, md, session->engine)) {
|
||||
SDFerr(SDF_F_SDF_HASHINIT, ERR_R_EVP_LIB);
|
||||
ret = SDR_UNKNOWERR;
|
||||
goto end;
|
||||
}
|
||||
|
||||
/* compute ZA and update */
|
||||
if (pucPublicKey) {
|
||||
EC_KEY *ec_key = NULL;
|
||||
unsigned char za[EVP_MAX_MD_SIZE];
|
||||
size_t zalen = sizeof(za);
|
||||
char *id;
|
||||
size_t idlen;
|
||||
|
||||
if (pucID) {
|
||||
id = (char *)pucID;
|
||||
idlen = uiIDLength;
|
||||
} else {
|
||||
id = SM2_DEFAULT_ID;
|
||||
idlen = strlen(SM2_DEFAULT_ID);
|
||||
}
|
||||
|
||||
if (!(ec_key = EC_KEY_new_from_ECCrefPublicKey(pucPublicKey))) {
|
||||
SDFerr(SDF_F_SDF_HASHINIT, ERR_R_GMAPI_LIB);
|
||||
ret = SDR_INARGERR;
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (!SM2_compute_id_digest(md, id, idlen, za, &zalen, ec_key)) {
|
||||
SDFerr(SDF_F_SDF_HASHINIT,
|
||||
SDF_R_COMPUTE_SM2_ID_FAILURE);
|
||||
ret = SDR_UNKNOWERR;
|
||||
EC_KEY_free(ec_key);
|
||||
goto end;
|
||||
}
|
||||
|
||||
EC_KEY_free(ec_key);
|
||||
|
||||
if (!EVP_DigestUpdate(md_ctx, za, zalen)) {
|
||||
SDFerr(SDF_F_SDF_HASHINIT, ERR_R_EVP_LIB);
|
||||
ret = SDR_UNKNOWERR;
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
session->md_ctx = md_ctx;
|
||||
md_ctx = NULL;
|
||||
ret = SDR_OK;
|
||||
|
||||
end:
|
||||
EVP_MD_CTX_free(md_ctx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int SDF_HashUpdate(
|
||||
void *hSessionHandle,
|
||||
unsigned char *pucData,
|
||||
unsigned int uiDataLength)
|
||||
{
|
||||
SDF_SESSION *session = (SDF_SESSION *)hSessionHandle;
|
||||
|
||||
/* check arguments */
|
||||
if (!hSessionHandle || !pucData) {
|
||||
SDFerr(SDF_F_SDF_HASHUPDATE, ERR_R_PASSED_NULL_PARAMETER);
|
||||
return SDR_INARGERR;
|
||||
}
|
||||
if (session->magic != SDF_SESSION_MAGIC) {
|
||||
SDFerr(SDF_F_SDF_HASHUPDATE, SDF_R_INVALID_SESSION);
|
||||
return SDR_INARGERR;
|
||||
}
|
||||
if (!session->md_ctx) {
|
||||
SDFerr(SDF_F_SDF_HASHUPDATE, SDF_R_INVALID_OPERATION_STATE);
|
||||
return SDR_INARGERR;
|
||||
}
|
||||
|
||||
/* update */
|
||||
if (!EVP_DigestUpdate(session->md_ctx, pucData, (size_t)uiDataLength)) {
|
||||
SDFerr(SDF_F_SDF_HASHUPDATE, ERR_R_EVP_LIB);
|
||||
return SDR_UNKNOWERR;
|
||||
}
|
||||
|
||||
return SDR_OK;
|
||||
}
|
||||
|
||||
int SDF_HashFinal(
|
||||
void *hSessionHandle,
|
||||
unsigned char *pucHash,
|
||||
unsigned int *puiHashLength)
|
||||
{
|
||||
SDF_SESSION *session = (SDF_SESSION *)hSessionHandle;
|
||||
|
||||
/* check arguments */
|
||||
if (!hSessionHandle || !pucHash || !puiHashLength) {
|
||||
SDFerr(SDF_F_SDF_HASHFINAL, ERR_R_PASSED_NULL_PARAMETER);
|
||||
return SDR_INARGERR;
|
||||
}
|
||||
if (session->magic != SDF_SESSION_MAGIC) {
|
||||
SDFerr(SDF_F_SDF_HASHFINAL, SDF_R_INVALID_SESSION);
|
||||
return SDR_INARGERR;
|
||||
}
|
||||
if (!session->md_ctx) {
|
||||
SDFerr(SDF_F_SDF_HASHFINAL,
|
||||
SDF_R_INVALID_OPERATION_STATE);
|
||||
return SDR_INARGERR;
|
||||
}
|
||||
if (*puiHashLength < EVP_MD_CTX_size(session->md_ctx)) {
|
||||
SDFerr(SDF_F_SDF_HASHFINAL, SDF_R_BUFFER_TOO_SMALL);
|
||||
return SDR_INARGERR;
|
||||
}
|
||||
|
||||
/* digest final */
|
||||
if (!EVP_DigestFinal_ex(session->md_ctx, pucHash, puiHashLength)) {
|
||||
SDFerr(SDF_F_SDF_HASHFINAL, ERR_R_EVP_LIB);
|
||||
return SDR_UNKNOWERR;
|
||||
}
|
||||
|
||||
/* note: only success, the md_ctx can be free-ed */
|
||||
EVP_MD_CTX_free(session->md_ctx);
|
||||
session->md_ctx = NULL;
|
||||
|
||||
return SDR_OK;
|
||||
}
|
||||
|
||||
@@ -1,97 +0,0 @@
|
||||
/* ====================================================================
|
||||
* Copyright (c) 2016 The GmSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the GmSSL Project.
|
||||
* (http://gmssl.org/)"
|
||||
*
|
||||
* 4. The name "GmSSL Project" must not be used to endorse or promote
|
||||
* products derived from this software without prior written
|
||||
* permission. For written permission, please contact
|
||||
* guanzhi1980@gmail.com.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "GmSSL"
|
||||
* nor may "GmSSL" appear in their names without prior written
|
||||
* permission of the GmSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the GmSSL Project
|
||||
* (http://gmssl.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE GmSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GmSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES
|
||||
* LOSS OF USE, DATA, OR PROFITS OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*/
|
||||
/*
|
||||
* In the standard GM/T 0018, the value of `uiKeyIndex` should start from 1,
|
||||
* and the maximum value is defined by the vendor.
|
||||
* The password length should be at least 8-byte.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/rand.h>
|
||||
#include <openssl/gmapi.h>
|
||||
#include <openssl/gmsdf.h>
|
||||
#include "sdf_lcl.h"
|
||||
|
||||
int SDF_GenerateKeyWithKEK(
|
||||
void *hSessionHandle,
|
||||
unsigned int uiKeyBits,
|
||||
unsigned int uiAlgID,
|
||||
unsigned int uiKEKIndex,
|
||||
unsigned char *pucKey,
|
||||
unsigned int *puiKeyLength,
|
||||
void **phKeyHandle)
|
||||
{
|
||||
return SDR_NOTSUPPORT;
|
||||
}
|
||||
|
||||
int SDF_ImportKeyWithKEK(
|
||||
void *hSessionHandle,
|
||||
unsigned int uiAlgID,
|
||||
unsigned int uiKEKIndex,
|
||||
unsigned char *pucKey,
|
||||
unsigned int uiKeyLength,
|
||||
void **phKeyHandle)
|
||||
{
|
||||
/* dont support this in GmSSL 2.x */
|
||||
return SDR_NOTSUPPORT;
|
||||
}
|
||||
|
||||
/* the destroy operation will always success! */
|
||||
int SDF_DestroyKey(
|
||||
void *hSessionHandle,
|
||||
void *hKeyHandle)
|
||||
{
|
||||
SDF_KEY *key = (SDF_KEY *)hKeyHandle;
|
||||
OPENSSL_clear_free(key, sizeof(*key));
|
||||
return SDR_OK;
|
||||
}
|
||||
|
||||
@@ -1,99 +0,0 @@
|
||||
/* ====================================================================
|
||||
* Copyright (c) 2016 The GmSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the GmSSL Project.
|
||||
* (http://gmssl.org/)"
|
||||
*
|
||||
* 4. The name "GmSSL Project" must not be used to endorse or promote
|
||||
* products derived from this software without prior written
|
||||
* permission. For written permission, please contact
|
||||
* guanzhi1980@gmail.com.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "GmSSL"
|
||||
* nor may "GmSSL" appear in their names without prior written
|
||||
* permission of the GmSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the GmSSL Project
|
||||
* (http://gmssl.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE GmSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GmSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES
|
||||
* LOSS OF USE, DATA, OR PROFITS OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/rand.h>
|
||||
#include <openssl/gmapi.h>
|
||||
#include <openssl/gmsdf.h>
|
||||
#include "sdf_lcl.h"
|
||||
|
||||
int SDF_ImportKey(
|
||||
void *hSessionHandle,
|
||||
unsigned char *pucKey,
|
||||
unsigned int uiKeyLength,
|
||||
void **phKeyHandle)
|
||||
{
|
||||
int ret = 0;
|
||||
SDF_KEY *key = NULL;
|
||||
|
||||
/* check arguments */
|
||||
if (!hSessionHandle || !pucKey || !phKeyHandle) {
|
||||
SDFerr(SDF_F_SDF_IMPORTKEY,
|
||||
ERR_R_PASSED_NULL_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
if (uiKeyLength <= 0 || uiKeyLength > EVP_MAX_KEY_LENGTH) {
|
||||
SDFerr(SDF_F_SDF_IMPORTKEY,
|
||||
SDF_R_INVALID_KEY_LENGTH);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* create object */
|
||||
if (!(key = OPENSSL_zalloc(sizeof(*key)))) {
|
||||
SDFerr(SDF_F_SDF_IMPORTKEY, ERR_R_MALLOC_FAILURE);
|
||||
goto end;
|
||||
}
|
||||
|
||||
/* copy key data */
|
||||
memcpy(key->key, pucKey, uiKeyLength);
|
||||
key->keylen = uiKeyLength;
|
||||
|
||||
/* set output */
|
||||
*phKeyHandle = key;
|
||||
key = NULL;
|
||||
ret = SDR_OK;
|
||||
|
||||
end:
|
||||
OPENSSL_clear_free(key, sizeof(*key));
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -1,81 +0,0 @@
|
||||
/* ====================================================================
|
||||
* Copyright (c) 2016 The GmSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the GmSSL Project.
|
||||
* (http://gmssl.org/)"
|
||||
*
|
||||
* 4. The name "GmSSL Project" must not be used to endorse or promote
|
||||
* products derived from this software without prior written
|
||||
* permission. For written permission, please contact
|
||||
* guanzhi1980@gmail.com.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "GmSSL"
|
||||
* nor may "GmSSL" appear in their names without prior written
|
||||
* permission of the GmSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the GmSSL Project
|
||||
* (http://gmssl.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE GmSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GmSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES
|
||||
* LOSS OF USE, DATA, OR PROFITS OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*/
|
||||
|
||||
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/e_os2.h>
|
||||
|
||||
extern char *deviceHandle;
|
||||
|
||||
#define SDF_ENGINE_ID "openssl"
|
||||
#define SDF_SESSION_MAGIC 0x12345678
|
||||
|
||||
typedef struct {
|
||||
uint32_t magic;
|
||||
char *app;
|
||||
ENGINE *engine;
|
||||
char *password[SDF_MAX_KEY_INDEX];
|
||||
EVP_MD_CTX *md_ctx;
|
||||
} SDF_SESSION;
|
||||
|
||||
typedef struct {
|
||||
unsigned char key[EVP_MAX_KEY_LENGTH];
|
||||
unsigned int keylen;
|
||||
} SDF_KEY;
|
||||
|
||||
const EVP_CIPHER *sdf_get_cipher(SDF_SESSION *session, unsigned int uiAlgoID);
|
||||
const EVP_MD *sdf_get_digest(SDF_SESSION *session, unsigned int uiAlgoID);
|
||||
EVP_PKEY *sdf_load_rsa_public_key(SDF_SESSION *session, unsigned int uiKeyIndex, unsigned int uiKeyUsage);
|
||||
EVP_PKEY *sdf_load_rsa_private_key(SDF_SESSION *session, unsigned int uiKeyIndex, unsigned int uiKeyUsage);
|
||||
EVP_PKEY *sdf_load_ec_public_key(SDF_SESSION *session, unsigned int uiKeyIndex, unsigned int uiKeyUsage);
|
||||
EVP_PKEY *sdf_load_ec_private_key(SDF_SESSION *session, unsigned int uiKeyIndex, unsigned int uiKeyUsage);
|
||||
int sdf_encode_ec_signature(ECCSignature *ref, unsigned char *out, size_t *outlen);
|
||||
int sdf_decode_ec_signature(ECCSignature *ref, const unsigned char *in, size_t inlen);
|
||||
|
||||
|
||||
@@ -1,327 +0,0 @@
|
||||
/* ====================================================================
|
||||
* Copyright (c) 2016 The GmSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the GmSSL Project.
|
||||
* (http://gmssl.org/)"
|
||||
*
|
||||
* 4. The name "GmSSL Project" must not be used to endorse or promote
|
||||
* products derived from this software without prior written
|
||||
* permission. For written permission, please contact
|
||||
* guanzhi1980@gmail.com.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "GmSSL"
|
||||
* nor may "GmSSL" appear in their names without prior written
|
||||
* permission of the GmSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the GmSSL Project
|
||||
* (http://gmssl.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE GmSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GmSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES
|
||||
* LOSS OF USE, DATA, OR PROFITS OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*/
|
||||
|
||||
#include <openssl/sgd.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/engine.h>
|
||||
#include <openssl/gmsdf.h>
|
||||
#include <openssl/gmapi.h>
|
||||
#include "sdf_lcl.h"
|
||||
|
||||
/*
|
||||
* We always get these objects from engine, hardware-based engine,
|
||||
* software-based engine with storage, or just ossl default engine.
|
||||
*/
|
||||
|
||||
const EVP_CIPHER *sdf_get_cipher(SDF_SESSION *session,
|
||||
unsigned int uiAlgoID)
|
||||
{
|
||||
int nid;
|
||||
|
||||
if (!session->engine) {
|
||||
SDFerr(SDF_F_SDF_GET_CIPHER,
|
||||
SDF_R_SDF_SESSION_NO_ENGINE);
|
||||
return NULL;
|
||||
}
|
||||
if ((nid = GMAPI_sgd2ciphernid(uiAlgoID)) == NID_undef) {
|
||||
SDFerr(SDF_F_SDF_GET_CIPHER,
|
||||
SDF_R_INVALID_ALGOR);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return ENGINE_get_cipher(session->engine, nid);
|
||||
}
|
||||
|
||||
const EVP_MD *sdf_get_digest(SDF_SESSION *session,
|
||||
unsigned int uiAlgoID)
|
||||
{
|
||||
int nid;
|
||||
|
||||
if (!session->engine) {
|
||||
SDFerr(SDF_F_SDF_GET_DIGEST,
|
||||
SDF_R_SDF_SESSION_NO_ENGINE);
|
||||
return NULL;
|
||||
}
|
||||
if ((nid = GMAPI_sgd2mdnid(uiAlgoID)) == NID_undef) {
|
||||
SDFerr(SDF_F_SDF_GET_DIGEST,
|
||||
SDF_R_INVALID_ALGOR);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return ENGINE_get_digest(session->engine, nid);
|
||||
}
|
||||
|
||||
/* we assume that the SDF ENGINE implementations follow the same design of
|
||||
* the SKF key storage model: app/container/keyusage. And we assume the
|
||||
* session is binded with app, the container is refered by key index, and
|
||||
* the key usage is the same. So the `key_id` string used for ENGINE is as
|
||||
* follows:
|
||||
* "AppName/ContainerNameOrIndex/KeyUsage"
|
||||
*/
|
||||
//FIXME: we should change the following 4 functions into 1 and 4 macros
|
||||
EVP_PKEY *sdf_load_rsa_public_key(SDF_SESSION *session,
|
||||
unsigned int uiKeyIndex, unsigned int uiKeyUsage)
|
||||
{
|
||||
EVP_PKEY *ret = NULL;
|
||||
EVP_PKEY *pkey = NULL;
|
||||
char key_id[256];
|
||||
char *app = "";
|
||||
char *usage;
|
||||
|
||||
if (!session->engine) {
|
||||
SDFerr(SDF_F_SDF_LOAD_RSA_PUBLIC_KEY,
|
||||
SDF_R_SDF_SESSION_NO_ENGINE);
|
||||
return NULL;
|
||||
}
|
||||
if (!(usage = GMAPI_keyusage2str(uiKeyUsage))) {
|
||||
SDFerr(SDF_F_SDF_LOAD_RSA_PUBLIC_KEY,
|
||||
SDF_R_INVALID_KEY_USAGE);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
snprintf(key_id, sizeof(key_id), "%s/%u/%s", app, uiKeyIndex, usage);
|
||||
|
||||
if (!(pkey = ENGINE_load_public_key(session->engine, key_id,
|
||||
NULL, NULL))) {
|
||||
SDFerr(SDF_F_SDF_LOAD_RSA_PUBLIC_KEY,
|
||||
SDF_R_ENGINE_LOAD_KEY_FAILURE);
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (EVP_PKEY_id(pkey) != EVP_PKEY_RSA) {
|
||||
SDFerr(SDF_F_SDF_LOAD_RSA_PUBLIC_KEY,
|
||||
SDF_R_KEY_TYPE_NOT_MATCH);
|
||||
goto end;
|
||||
}
|
||||
|
||||
ret = pkey;
|
||||
pkey = NULL;
|
||||
|
||||
end:
|
||||
EVP_PKEY_free(pkey);
|
||||
return ret;
|
||||
}
|
||||
|
||||
EVP_PKEY *sdf_load_rsa_private_key(SDF_SESSION *session,
|
||||
unsigned int uiKeyIndex, unsigned int uiKeyUsage)
|
||||
{
|
||||
EVP_PKEY *ret = NULL;
|
||||
EVP_PKEY *pkey = NULL;
|
||||
char key_id[256];
|
||||
char *app = "";
|
||||
char *usage;
|
||||
|
||||
if (!session->engine) {
|
||||
SDFerr(SDF_F_SDF_LOAD_RSA_PRIVATE_KEY,
|
||||
SDF_R_SDF_SESSION_NO_ENGINE);
|
||||
return NULL;
|
||||
}
|
||||
if (!(usage = GMAPI_keyusage2str(uiKeyUsage))) {
|
||||
SDFerr(SDF_F_SDF_LOAD_RSA_PRIVATE_KEY,
|
||||
SDF_R_INVALID_KEY_USAGE);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
snprintf(key_id, sizeof(key_id), "%s/%u/%s", app, uiKeyIndex, usage);
|
||||
|
||||
if (!(pkey = ENGINE_load_private_key(session->engine, key_id,
|
||||
NULL, NULL))) {
|
||||
SDFerr(SDF_F_SDF_LOAD_RSA_PRIVATE_KEY,
|
||||
SDF_R_ENGINE_LOAD_KEY_FAILURE);
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (EVP_PKEY_id(pkey) != EVP_PKEY_RSA) {
|
||||
SDFerr(SDF_F_SDF_LOAD_RSA_PRIVATE_KEY,
|
||||
SDF_R_KEY_TYPE_NOT_MATCH);
|
||||
goto end;
|
||||
}
|
||||
|
||||
ret = pkey;
|
||||
pkey = NULL;
|
||||
|
||||
end:
|
||||
EVP_PKEY_free(pkey);
|
||||
return ret;
|
||||
}
|
||||
|
||||
EVP_PKEY *sdf_load_ec_public_key(SDF_SESSION *session,
|
||||
unsigned int uiKeyIndex, unsigned int uiKeyUsage)
|
||||
{
|
||||
EVP_PKEY *ret = NULL;
|
||||
EVP_PKEY *pkey = NULL;
|
||||
char key_id[256];
|
||||
char *app = "";
|
||||
char *usage;
|
||||
|
||||
if (!session->engine) {
|
||||
SDFerr(SDF_F_SDF_LOAD_EC_PUBLIC_KEY,
|
||||
SDF_R_SDF_SESSION_NO_ENGINE);
|
||||
return NULL;
|
||||
}
|
||||
if (!(usage = GMAPI_keyusage2str(uiKeyUsage))) {
|
||||
SDFerr(SDF_F_SDF_LOAD_EC_PUBLIC_KEY,
|
||||
SDF_R_INVALID_KEY_USAGE);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
snprintf(key_id, sizeof(key_id), "%s/%u/%s", app, uiKeyIndex, usage);
|
||||
|
||||
if (!(pkey = ENGINE_load_public_key(session->engine, key_id,
|
||||
NULL, NULL))) {
|
||||
SDFerr(SDF_F_SDF_LOAD_EC_PUBLIC_KEY,
|
||||
SDF_R_ENGINE_LOAD_KEY_FAILURE);
|
||||
goto end;
|
||||
}
|
||||
if (EVP_PKEY_id(pkey) != EVP_PKEY_EC) {
|
||||
SDFerr(SDF_F_SDF_LOAD_EC_PUBLIC_KEY,
|
||||
SDF_R_KEY_TYPE_NOT_MATCH);
|
||||
goto end;
|
||||
}
|
||||
|
||||
ret = pkey;
|
||||
pkey = NULL;
|
||||
|
||||
end:
|
||||
EVP_PKEY_free(pkey);
|
||||
return ret;
|
||||
}
|
||||
|
||||
EVP_PKEY *sdf_load_ec_private_key(SDF_SESSION *session,
|
||||
unsigned int uiKeyIndex, unsigned int uiKeyUsage)
|
||||
{
|
||||
EVP_PKEY *ret = NULL;
|
||||
EVP_PKEY *pkey = NULL;
|
||||
char key_id[256];
|
||||
char *app = "";
|
||||
char *usage;
|
||||
|
||||
if (!session->engine) {
|
||||
SDFerr(SDF_F_SDF_LOAD_EC_PRIVATE_KEY,
|
||||
SDF_R_SDF_SESSION_NO_ENGINE);
|
||||
return NULL;
|
||||
}
|
||||
if (!(usage = GMAPI_keyusage2str(uiKeyUsage))) {
|
||||
SDFerr(SDF_F_SDF_LOAD_EC_PRIVATE_KEY,
|
||||
SDF_R_INVALID_KEY_USAGE);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
snprintf(key_id, sizeof(key_id), "%s/%u/%s", app, uiKeyIndex, usage);
|
||||
|
||||
if (!(pkey = ENGINE_load_private_key(session->engine, key_id,
|
||||
NULL, NULL))) {
|
||||
SDFerr(SDF_F_SDF_LOAD_EC_PRIVATE_KEY,
|
||||
SDF_R_ENGINE_LOAD_KEY_FAILURE);
|
||||
goto end;
|
||||
}
|
||||
if (EVP_PKEY_id(pkey) != EVP_PKEY_EC) {
|
||||
SDFerr(SDF_F_SDF_LOAD_EC_PRIVATE_KEY,
|
||||
SDF_R_KEY_TYPE_NOT_MATCH);
|
||||
goto end;
|
||||
}
|
||||
|
||||
ret = pkey;
|
||||
pkey = NULL;
|
||||
|
||||
end:
|
||||
EVP_PKEY_free(pkey);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int sdf_encode_ec_signature(ECCSignature *ref, unsigned char *out,
|
||||
size_t *outlen)
|
||||
{
|
||||
int ret = 0;
|
||||
ECDSA_SIG *sig = NULL;
|
||||
unsigned char *p;
|
||||
int len;
|
||||
|
||||
if (!(sig = ECDSA_SIG_new_from_ECCSignature(ref))) {
|
||||
SDFerr(SDF_F_SDF_ENCODE_EC_SIGNATURE, ERR_R_GMAPI_LIB);
|
||||
goto end;
|
||||
}
|
||||
|
||||
p = out;
|
||||
if ((len = i2d_ECDSA_SIG(sig, &p)) <= 0) {
|
||||
SDFerr(SDF_F_SDF_ENCODE_EC_SIGNATURE, ERR_R_EC_LIB);
|
||||
goto end;
|
||||
}
|
||||
|
||||
ret = 1;
|
||||
|
||||
end:
|
||||
ECDSA_SIG_free(sig);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int sdf_decode_ec_signature(ECCSignature *ref, const unsigned char *in,
|
||||
size_t inlen)
|
||||
{
|
||||
int ret = 0;
|
||||
ECDSA_SIG *sig = NULL;
|
||||
const unsigned char *p;
|
||||
|
||||
p = in;
|
||||
if (!(sig = d2i_ECDSA_SIG(NULL, &p, inlen))) {
|
||||
SDFerr(SDF_F_SDF_DECODE_EC_SIGNATURE, ERR_R_EC_LIB);
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (!ECDSA_SIG_get_ECCSignature(sig, ref)) {
|
||||
SDFerr(SDF_F_SDF_DECODE_EC_SIGNATURE, ERR_R_GMAPI_LIB);
|
||||
goto end;
|
||||
}
|
||||
|
||||
ret = 1;
|
||||
|
||||
end:
|
||||
ECDSA_SIG_free(sig);
|
||||
return ret;
|
||||
}
|
||||
@@ -1,131 +0,0 @@
|
||||
/* ====================================================================
|
||||
* Copyright (c) 2016 The GmSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the GmSSL Project.
|
||||
* (http://gmssl.org/)"
|
||||
*
|
||||
* 4. The name "GmSSL Project" must not be used to endorse or promote
|
||||
* products derived from this software without prior written
|
||||
* permission. For written permission, please contact
|
||||
* guanzhi1980@gmail.com.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "GmSSL"
|
||||
* nor may "GmSSL" appear in their names without prior written
|
||||
* permission of the GmSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the GmSSL Project
|
||||
* (http://gmssl.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE GmSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GmSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES
|
||||
* LOSS OF USE, DATA, OR PROFITS OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/cmac.h>
|
||||
#include <openssl/gmsdf.h>
|
||||
#include "sdf_lcl.h"
|
||||
|
||||
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 ret = SDR_UNKNOWERR;
|
||||
SDF_SESSION *session = (SDF_SESSION *)hSessionHandle;
|
||||
SDF_KEY *key = (SDF_KEY *)hKeyHandle;
|
||||
CMAC_CTX *ctx = NULL;
|
||||
const EVP_CIPHER *cipher;
|
||||
size_t siz;
|
||||
|
||||
/* check arguments, omit the useless pucIV in CBC-MAC */
|
||||
if (!hSessionHandle || !hKeyHandle || !pucData ||
|
||||
!pucMAC || !puiMACLength) {
|
||||
SDFerr(SDF_F_SDF_CALCULATEMAC,
|
||||
ERR_R_PASSED_NULL_PARAMETER);
|
||||
return SDR_UNKNOWERR;
|
||||
}
|
||||
/* the CBC-MAC API accept size_t input length, but we don't
|
||||
* know whether future MAC implementation will change this */
|
||||
if (uiDataLength <= 0 || uiDataLength > INT_MAX) {
|
||||
SDFerr(SDF_F_SDF_CALCULATEMAC,
|
||||
SDF_R_INVALID_INPUT_LENGTH);
|
||||
return SDR_UNKNOWERR;
|
||||
}
|
||||
|
||||
/* parse arguments */
|
||||
if (!(cipher = sdf_get_cipher(hSessionHandle, uiAlgID))) {
|
||||
SDFerr(SDF_F_SDF_CALCULATEMAC, SDF_R_INVALID_ALGOR);
|
||||
goto end;
|
||||
}
|
||||
if (key->keylen != EVP_CIPHER_key_length(cipher)) {
|
||||
SDFerr(SDF_F_SDF_CALCULATEMAC,
|
||||
SDF_R_INVALID_KEY_HANDLE);
|
||||
goto end;
|
||||
}
|
||||
if (*puiMACLength < EVP_CIPHER_block_size(cipher)) {
|
||||
SDFerr(SDF_F_SDF_CALCULATEMAC, SDF_R_BUUTER_TOO_SMALL);
|
||||
goto end;
|
||||
}
|
||||
|
||||
/* generate mac */
|
||||
if (!(ctx = CMAC_CTX_new())) {
|
||||
SDFerr(SDF_F_SDF_CALCULATEMAC, ERR_R_MALLOC_FAILURE);
|
||||
goto end;
|
||||
}
|
||||
if (!CMAC_Init(ctx, key->key, key->keylen, cipher, session->engine)) {
|
||||
SDFerr(SDF_F_SDF_CALCULATEMAC, SDF_R_CMAC_FAILURE);
|
||||
goto end;
|
||||
}
|
||||
if (!CMAC_Update(ctx, pucData, (size_t)uiDataLength)) {
|
||||
SDFerr(SDF_F_SDF_CALCULATEMAC, SDF_R_CMAC_FAILURE);
|
||||
goto end;
|
||||
}
|
||||
if (!CMAC_Final(ctx, pucMAC, &siz)) {
|
||||
SDFerr(SDF_F_SDF_CALCULATEMAC, SDF_R_CMAC_FAILURE);
|
||||
goto end;
|
||||
}
|
||||
|
||||
*puiMACLength = (unsigned int)siz;
|
||||
ret = SDR_OK;
|
||||
|
||||
end:
|
||||
CMAC_CTX_free(ctx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -1,95 +0,0 @@
|
||||
/* ====================================================================
|
||||
* Copyright (c) 2016 The GmSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the GmSSL Project.
|
||||
* (http://gmssl.org/)"
|
||||
*
|
||||
* 4. The name "GmSSL Project" must not be used to endorse or promote
|
||||
* products derived from this software without prior written
|
||||
* permission. For written permission, please contact
|
||||
* guanzhi1980@gmail.com.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "GmSSL"
|
||||
* nor may "GmSSL" appear in their names without prior written
|
||||
* permission of the GmSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the GmSSL Project
|
||||
* (http://gmssl.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE GmSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GmSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES
|
||||
* LOSS OF USE, DATA, OR PROFITS OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/rand.h>
|
||||
#include <openssl/e_os2.h>
|
||||
#include <openssl/gmsdf.h>
|
||||
#include "sdf_lcl.h"
|
||||
|
||||
int SDF_GenerateRandom(
|
||||
void *hSessionHandle,
|
||||
unsigned int uiLength,
|
||||
unsigned char *pucRandom)
|
||||
{
|
||||
SDF_SESSION *session = (SDF_SESSION *)hSessionHandle;
|
||||
|
||||
if (!hSessionHandle || !pucRandom) {
|
||||
SDFerr(SDF_F_SDF_GENERATERANDOM,
|
||||
ERR_R_PASSED_NULL_PARAMETER);
|
||||
return SDR_INARGERR;
|
||||
}
|
||||
|
||||
if (uiLength > INT_MAX) {
|
||||
SDFerr(SDF_F_SDF_GENERATERANDOM, SDF_R_INVALID_LENGTH);
|
||||
return SDR_INARGERR;
|
||||
}
|
||||
|
||||
#ifndef OPENSSL_NO_ENGINE
|
||||
/* try to use the hardware random generator */
|
||||
if (session->engine) {
|
||||
if (!RAND_set_rand_engine(session->engine)) {
|
||||
//SDFerr(SDF_F_SDF_GENERATERANDOM, ERR_R_RAND_LIB);
|
||||
return SDR_UNKNOWERR;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!RAND_bytes(pucRandom, (int)uiLength)) {
|
||||
SDFerr(SDF_F_SDF_GENERATERANDOM, SDF_R_RANDOM_FAILURE);
|
||||
return SDR_RANDERR;
|
||||
}
|
||||
|
||||
return SDR_OK;
|
||||
}
|
||||
|
||||
@@ -1,570 +0,0 @@
|
||||
/* ====================================================================
|
||||
* Copyright (c) 2016 The GmSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the GmSSL Project.
|
||||
* (http://gmssl.org/)"
|
||||
*
|
||||
* 4. The name "GmSSL Project" must not be used to endorse or promote
|
||||
* products derived from this software without prior written
|
||||
* permission. For written permission, please contact
|
||||
* guanzhi1980@gmail.com.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "GmSSL"
|
||||
* nor may "GmSSL" appear in their names without prior written
|
||||
* permission of the GmSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the GmSSL Project
|
||||
* (http://gmssl.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE GmSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GmSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES
|
||||
* LOSS OF USE, DATA, OR PROFITS OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/rsa.h>
|
||||
#include <openssl/rand.h>
|
||||
#include <openssl/gmsdf.h>
|
||||
#include <openssl/gmapi.h>
|
||||
#include "sdf_lcl.h"
|
||||
|
||||
/* As there are two APIs for export signing key and decryption key, this
|
||||
* means that keys with different usage can be referenced by the same
|
||||
* `uiKeyIndex`, and `uiKeyIndex` is the index of a key container.
|
||||
*/
|
||||
int SDF_ExportSignPublicKey_RSA(
|
||||
void *hSessionHandle,
|
||||
unsigned int uiKeyIndex,
|
||||
RSArefPublicKey *pucPublicKey)
|
||||
{
|
||||
int ret = 0;
|
||||
EVP_PKEY *pkey = NULL;
|
||||
unsigned int uiKeyUsage = 0;
|
||||
|
||||
if (!hSessionHandle || !pucPublicKey) {
|
||||
SDFerr(SDF_F_SDF_EXPORTSIGNPUBLICKEY_RSA,
|
||||
ERR_R_PASSED_NULL_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!(pkey = sdf_load_rsa_public_key((SDF_SESSION *)hSessionHandle,
|
||||
uiKeyIndex, uiKeyUsage))) {
|
||||
SDFerr(SDF_F_SDF_EXPORTSIGNPUBLICKEY_RSA, ERR_R_GMAPI_LIB);
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (!RSA_get_RSArefPublicKey(EVP_PKEY_get0_RSA(pkey), pucPublicKey)) {
|
||||
SDFerr(SDF_F_SDF_EXPORTSIGNPUBLICKEY_RSA, ERR_R_GMAPI_LIB);
|
||||
goto end;
|
||||
}
|
||||
|
||||
ret = SDR_OK;
|
||||
|
||||
end:
|
||||
EVP_PKEY_free(pkey);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int SDF_ExportEncPublicKey_RSA(
|
||||
void *hSessionHandle,
|
||||
unsigned int uiKeyIndex,
|
||||
RSArefPublicKey *pucPublicKey)
|
||||
{
|
||||
int ret = 0;
|
||||
EVP_PKEY *pkey = NULL;
|
||||
unsigned int uiKeyUsage = 1; //FIXME
|
||||
|
||||
if (!hSessionHandle || !pucPublicKey) {
|
||||
SDFerr(SDF_F_SDF_EXPORTENCPUBLICKEY_RSA,
|
||||
ERR_R_PASSED_NULL_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!(pkey = sdf_load_rsa_public_key((SDF_SESSION *)hSessionHandle,
|
||||
uiKeyIndex, uiKeyUsage))) {
|
||||
SDFerr(SDF_F_SDF_EXPORTENCPUBLICKEY_RSA, ERR_R_GMAPI_LIB);
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (!RSA_get_RSArefPublicKey(EVP_PKEY_get0_RSA(pkey), pucPublicKey)) {
|
||||
SDFerr(SDF_F_SDF_EXPORTENCPUBLICKEY_RSA, ERR_R_GMAPI_LIB);
|
||||
goto end;
|
||||
}
|
||||
|
||||
ret = SDR_OK;
|
||||
|
||||
end:
|
||||
EVP_PKEY_free(pkey);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Generate RSA key pair.
|
||||
* The MAX RSA bits is defined as 2048 in GM/T 0018-2012. As 1024 is not very
|
||||
* secure, applications should always use 2048-bit. Use 1024-bit only for
|
||||
* legacy applications.
|
||||
*/
|
||||
int SDF_GenerateKeyPair_RSA(
|
||||
void *hSessionHandle, /* not used */
|
||||
unsigned int uiKeyBits,
|
||||
RSArefPublicKey *pucPublicKey,
|
||||
RSArefPrivateKey *pucPrivateKey)
|
||||
{
|
||||
int ret = 0;
|
||||
RSA *rsa = NULL;
|
||||
|
||||
if (!hSessionHandle || !pucPublicKey || !pucPrivateKey) {
|
||||
SDFerr(SDF_F_SDF_GENERATEKEYPAIR_RSA,
|
||||
ERR_R_PASSED_NULL_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!(rsa = RSA_new())) {
|
||||
SDFerr(SDF_F_SDF_GENERATEKEYPAIR_RSA,
|
||||
ERR_R_MALLOC_FAILURE);
|
||||
goto end;
|
||||
}
|
||||
if (!RSA_generate_key_ex(rsa, uiKeyBits, NULL, NULL)) {
|
||||
SDFerr(SDF_F_SDF_GENERATEKEYPAIR_RSA, ERR_R_RSA_LIB);
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (!RSA_get_RSArefPublicKey(rsa, pucPublicKey)) {
|
||||
SDFerr(SDF_F_SDF_GENERATEKEYPAIR_RSA, ERR_R_GMAPI_LIB);
|
||||
goto end;
|
||||
}
|
||||
if (!RSA_get_RSArefPrivateKey(rsa, pucPrivateKey)) {
|
||||
SDFerr(SDF_F_SDF_GENERATEKEYPAIR_RSA, ERR_R_GMAPI_LIB);
|
||||
goto end;
|
||||
}
|
||||
|
||||
ret = SDR_OK;
|
||||
|
||||
end:
|
||||
RSA_free(rsa);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* In a cryptographic API the symmetric keys (and otehr keys) can be
|
||||
* classified into session keys and storage keys. The storage keys will be
|
||||
* persistantly stored in the secure storage of a cryptograhic hardware
|
||||
* device. While the session keys only exist in the session period, after
|
||||
* the session is finished, it will be destroyed even if the symmetric key
|
||||
* operations are performed inside the hardware.
|
||||
*
|
||||
* The `gmapi` module only support session keys.
|
||||
*/
|
||||
/*
|
||||
* In the current version of GmSSL (2.x), the session keys will be kept in
|
||||
* the host memory intead of the cryptographic hardware's internal memory.
|
||||
* So the key handle will suffer memory attacks.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Generate a symmetric key with bit length `uiKeyBits`, encrypt the key data
|
||||
* with an internal RSA public key with index `uiIPKIndex`, output the
|
||||
* encrypted key data to buffer `pucKey` and length `puiKeyLength`, also return
|
||||
* the handle of the generated key `phKeyHandle`.
|
||||
*/
|
||||
|
||||
/* generate session key and encrypt with internal public key */
|
||||
int SDF_GenerateKeyWithIPK_RSA(
|
||||
void *hSessionHandle,
|
||||
unsigned int uiIPKIndex,
|
||||
unsigned int uiKeyBits, /* generate key length */
|
||||
unsigned char *pucKey,
|
||||
unsigned int *puiKeyLength,
|
||||
void **phKeyHandle)
|
||||
{
|
||||
int ret = 0;
|
||||
SDF_KEY *hkey = NULL;
|
||||
|
||||
if (!hSessionHandle || !pucKey || !puiKeyLength || !phKeyHandle) {
|
||||
SDFerr(SDF_F_SDF_GENERATEKEYWITHIPK_RSA,
|
||||
ERR_R_PASSED_NULL_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
if (uiKeyBits <= 0 || uiKeyBits % 8 || uiKeyBits > EVP_MAX_KEY_LENGTH) {
|
||||
SDFerr(SDF_F_SDF_GENERATEKEYWITHIPK_RSA,
|
||||
SDF_R_INVALID_KEY_LENGTH);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!(hkey = OPENSSL_zalloc(sizeof(*hkey)))) {
|
||||
SDFerr(SDF_F_SDF_GENERATEKEYWITHIPK_RSA,
|
||||
ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((ret = SDF_InternalPublicKeyOperation_RSA(
|
||||
hSessionHandle,
|
||||
uiIPKIndex,
|
||||
hkey->key,
|
||||
hkey->keylen,
|
||||
pucKey,
|
||||
puiKeyLength)) != SDR_OK) {
|
||||
SDFerr(SDF_F_SDF_GENERATEKEYWITHIPK_RSA, ERR_R_GMAPI_LIB);
|
||||
goto end;
|
||||
}
|
||||
|
||||
*phKeyHandle = hkey;
|
||||
hkey = NULL;
|
||||
ret = SDR_OK;
|
||||
|
||||
end:
|
||||
OPENSSL_clear_free(hkey, sizeof(*hkey));
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Generate a symmetric key with bit length `uiKeyBits`, encrypt the key data
|
||||
* with an external RSA public key with data `pucPublicKey` in format
|
||||
* `RSArefPublickey`, output the encrypted key data to buffer `pucKey` and
|
||||
* length `puiKeyLength`, also return the handle `phKeyHandle` of the generated
|
||||
* key.
|
||||
*/
|
||||
int SDF_GenerateKeyWithEPK_RSA(
|
||||
void *hSessionHandle,
|
||||
unsigned int uiKeyBits,
|
||||
RSArefPublicKey *pucPublicKey,
|
||||
unsigned char *pucKey,
|
||||
unsigned int *puiKeyLength,
|
||||
void **phKeyHandle)
|
||||
{
|
||||
int ret = 0;
|
||||
SDF_KEY *key = NULL;
|
||||
|
||||
if (!hSessionHandle || !pucPublicKey || !pucKey || !puiKeyLength ||
|
||||
!phKeyHandle) {
|
||||
SDFerr(SDF_F_SDF_GENERATEKEYWITHEPK_RSA,
|
||||
ERR_R_PASSED_NULL_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
if (uiKeyBits <= 0 || uiKeyBits % 8 || uiKeyBits >
|
||||
EVP_MAX_KEY_LENGTH) {
|
||||
SDFerr(SDF_F_SDF_GENERATEKEYWITHEPK_RSA,
|
||||
SDF_R_INVALID_KEY_LENGTH);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!(key = OPENSSL_zalloc(sizeof(*key)))) {
|
||||
SDFerr(SDF_F_SDF_GENERATEKEYWITHEPK_RSA,
|
||||
ERR_R_MALLOC_FAILURE);
|
||||
goto end;
|
||||
}
|
||||
|
||||
if ((ret = SDF_ExternalPublicKeyOperation_RSA(
|
||||
hSessionHandle,
|
||||
pucPublicKey,
|
||||
key->key,
|
||||
key->keylen,
|
||||
pucKey,
|
||||
puiKeyLength)) != SDR_OK) {
|
||||
SDFerr(SDF_F_SDF_GENERATEKEYWITHEPK_RSA, ERR_R_GMAPI_LIB);
|
||||
goto end;
|
||||
}
|
||||
|
||||
*phKeyHandle = key;
|
||||
key = NULL;
|
||||
ret = SDR_OK;
|
||||
|
||||
end:
|
||||
OPENSSL_clear_free(key, sizeof(*key));
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Import the encrypted key generated from `SDF_GenerateKeyWithIPK_RSA` to the
|
||||
* session context, the internal RSA key index `uiISKIndex` should be the same
|
||||
* index of the parameter `uiIPKIndex` of `SDF_GenerateKeyWithIPK_RSA`.
|
||||
*/
|
||||
|
||||
/* Import session key `pucKey` encrypted by the internal public key indexed
|
||||
* by `uiISKIndex`. As there are no session key in device, we need to
|
||||
* decrypt the `pucKey` with the internal key `uiISKIndex`.
|
||||
*/
|
||||
int SDF_ImportKeyWithISK_RSA(
|
||||
void *hSessionHandle,
|
||||
unsigned int uiISKIndex,
|
||||
unsigned char *pucKey,
|
||||
unsigned int uiKeyLength,
|
||||
void **phKeyHandle)
|
||||
{
|
||||
int ret = 0;
|
||||
SDF_KEY *key = NULL;
|
||||
|
||||
if (!hSessionHandle || !pucKey || !phKeyHandle) {
|
||||
SDFerr(SDF_F_SDF_IMPORTKEYWITHISK_RSA,
|
||||
ERR_R_PASSED_NULL_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!(key = OPENSSL_zalloc(sizeof(*key)))) {
|
||||
SDFerr(SDF_F_SDF_IMPORTKEYWITHISK_RSA,
|
||||
ERR_R_MALLOC_FAILURE);
|
||||
goto end;
|
||||
}
|
||||
|
||||
key->keylen = EVP_MAX_KEY_LENGTH;
|
||||
if ((ret = SDF_InternalPrivateKeyOperation_RSA(
|
||||
hSessionHandle,
|
||||
uiISKIndex,
|
||||
pucKey,
|
||||
uiKeyLength,
|
||||
key->key,
|
||||
&key->keylen)) != SDR_OK) {
|
||||
SDFerr(SDF_F_SDF_IMPORTKEYWITHISK_RSA, ERR_R_GMAPI_LIB);
|
||||
goto end;
|
||||
}
|
||||
|
||||
*phKeyHandle = key;
|
||||
key = NULL;
|
||||
ret = SDR_OK;
|
||||
|
||||
end:
|
||||
OPENSSL_clear_free(key, sizeof(*key));
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert internal public key encrypted symmetric key into ciphertext
|
||||
* encrypted by external public key. The input `pucDEInput` is the symmetric
|
||||
* key encrypted by internal public key `uiKeyIndex`. The output `pucDEOutput`
|
||||
* is encrypted under the external public key `pucPublicKey`.
|
||||
*
|
||||
* Note: This function is very dangerous. It convert a well protected symmetric
|
||||
* key into a state with security unknown. If the external private key is not
|
||||
* well protected, this function is the same as to unwrap of the symmetric key
|
||||
* and output the plaintext.
|
||||
*/
|
||||
|
||||
/*
|
||||
* convert the `pucDEInput` encrypted by internal RSA public key
|
||||
* `uiKeyIndex` to `pucDEOutput` encrypted by the external RSA public key
|
||||
* `pucPublicKey`
|
||||
*/
|
||||
int SDF_ExchangeDigitEnvelopeBaseOnRSA(
|
||||
void *hSessionHandle,
|
||||
unsigned int uiKeyIndex,
|
||||
RSArefPublicKey *pucPublicKey,
|
||||
unsigned char *pucDEInput,
|
||||
unsigned int uiDELength,
|
||||
unsigned char *pucDEOutput,
|
||||
unsigned int *puiDELength)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int SDF_ExternalPublicKeyOperation_RSA(
|
||||
void *hSessionHandle,
|
||||
RSArefPublicKey *pucPublicKey,
|
||||
unsigned char *pucDataInput,
|
||||
unsigned int uiInputLength,
|
||||
unsigned char *pucDataOutput,
|
||||
unsigned int *puiOutputLength)
|
||||
{
|
||||
int ret = 0;
|
||||
RSA *rsa = NULL;
|
||||
int outlen;
|
||||
|
||||
if (!hSessionHandle || !pucPublicKey || !pucDataInput ||
|
||||
!pucDataOutput || !puiOutputLength) {
|
||||
SDFerr(SDF_F_SDF_EXTERNALPUBLICKEYOPERATION_RSA,
|
||||
ERR_R_PASSED_NULL_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!(rsa = RSA_new_from_RSArefPublicKey(pucPublicKey))) {
|
||||
SDFerr(SDF_F_SDF_EXTERNALPUBLICKEYOPERATION_RSA,
|
||||
ERR_R_GMAPI_LIB);
|
||||
goto end;
|
||||
}
|
||||
|
||||
if ((outlen = RSA_public_encrypt((int)uiInputLength, pucDataInput,
|
||||
pucDataOutput, rsa, RSA_NO_PADDING)) < 0) {
|
||||
SDFerr(SDF_F_SDF_EXTERNALPUBLICKEYOPERATION_RSA,
|
||||
ERR_R_RSA_LIB);
|
||||
goto end;
|
||||
}
|
||||
|
||||
*puiOutputLength = (unsigned int)outlen;
|
||||
ret = SDR_OK;
|
||||
|
||||
end:
|
||||
RSA_free(rsa);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* The RSA Operations include
|
||||
* `SDF_ExternalPublicKeyOperation_RSA`
|
||||
* `SDF_InternalPublicKeyOperation_RSA`
|
||||
* `SDF_InternalPrivateKeyOperation_RSA`
|
||||
*
|
||||
* Noramlly RSA operations should be working with some padding methods, such
|
||||
* as PKCS #1 OAEP padding or PSS padding. As the SDF API does not provide any
|
||||
* parameter to set padding method, and it is neither specified in the GM/T
|
||||
* 0018-2012 standard, application developers need to ask the vendor or try
|
||||
* testing. The GmSSL SDF implementation will always try to use the PKCS #1
|
||||
* padding, but the underlying ENGINEs might not support this padding options.
|
||||
*
|
||||
* It should be noted that the SDF API does not support external private key
|
||||
* operations.
|
||||
*/
|
||||
|
||||
int SDF_ExternalPrivateKeyOperation_RSA(
|
||||
void *hSessionHandle,
|
||||
RSArefPrivateKey *pucPrivateKey,
|
||||
unsigned char *pucDataInput,
|
||||
unsigned int uiInputLength,
|
||||
unsigned char *pucDataOutput,
|
||||
unsigned int *puiOutputLength)
|
||||
{
|
||||
int ret = 0;
|
||||
RSA *rsa = NULL;
|
||||
int outlen;
|
||||
|
||||
if (!hSessionHandle || !pucPrivateKey || !pucDataInput ||
|
||||
!pucDataOutput || !puiOutputLength) {
|
||||
SDFerr(SDF_F_SDF_EXTERNALPRIVATEKEYOPERATION_RSA,
|
||||
ERR_R_PASSED_NULL_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!(rsa = RSA_new_from_RSArefPrivateKey(pucPrivateKey))) {
|
||||
SDFerr(SDF_F_SDF_EXTERNALPRIVATEKEYOPERATION_RSA,
|
||||
ERR_R_GMAPI_LIB);
|
||||
goto end;
|
||||
}
|
||||
|
||||
if ((outlen = RSA_private_decrypt((int)uiInputLength, pucDataInput,
|
||||
pucDataOutput, rsa, RSA_NO_PADDING)) < 0) {
|
||||
SDFerr(SDF_F_SDF_EXTERNALPRIVATEKEYOPERATION_RSA,
|
||||
ERR_R_RSA_LIB);
|
||||
goto end;
|
||||
}
|
||||
|
||||
*puiOutputLength = (unsigned int)outlen;
|
||||
ret = SDR_OK;
|
||||
|
||||
end:
|
||||
RSA_free(rsa);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int SDF_InternalPublicKeyOperation_RSA(
|
||||
void *hSessionHandle,
|
||||
unsigned int uiKeyIndex,
|
||||
unsigned char *pucDataInput,
|
||||
unsigned int uiInputLength,
|
||||
unsigned char *pucDataOutput,
|
||||
unsigned int *puiOutputLength)
|
||||
{
|
||||
int ret = 0;
|
||||
EVP_PKEY *pkey = NULL;
|
||||
int outlen;
|
||||
unsigned int uiKeyUsage = -12345; //FIXME: which key should we use?
|
||||
|
||||
if (!hSessionHandle || !pucDataInput || !pucDataOutput ||
|
||||
!puiOutputLength) {
|
||||
SDFerr(SDF_F_SDF_INTERNALPUBLICKEYOPERATION_RSA,
|
||||
ERR_R_PASSED_NULL_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!(pkey = sdf_load_rsa_public_key((SDF_SESSION *)hSessionHandle,
|
||||
uiKeyIndex, uiKeyUsage))) {
|
||||
SDFerr(SDF_F_SDF_INTERNALPUBLICKEYOPERATION_RSA,
|
||||
ERR_R_GMAPI_LIB);
|
||||
goto end;
|
||||
}
|
||||
|
||||
if ((outlen = RSA_public_encrypt((int)uiInputLength, pucDataInput,
|
||||
pucDataOutput, EVP_PKEY_get0_RSA(pkey), RSA_NO_PADDING)) < 0) {
|
||||
SDFerr(SDF_F_SDF_INTERNALPUBLICKEYOPERATION_RSA,
|
||||
ERR_R_RSA_LIB);
|
||||
goto end;
|
||||
}
|
||||
|
||||
*puiOutputLength = (unsigned int)outlen;
|
||||
ret = SDR_OK;
|
||||
|
||||
end:
|
||||
EVP_PKEY_free(pkey);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int SDF_InternalPrivateKeyOperation_RSA(
|
||||
void *hSessionHandle,
|
||||
unsigned int uiKeyIndex,
|
||||
unsigned char *pucDataInput,
|
||||
unsigned int uiInputLength,
|
||||
unsigned char *pucDataOutput,
|
||||
unsigned int *puiOutputLength)
|
||||
{
|
||||
int ret = 0;
|
||||
EVP_PKEY *pkey = NULL;
|
||||
int outlen;
|
||||
unsigned int uiKeyUsage; //FIXME
|
||||
|
||||
if (!hSessionHandle || !pucDataInput || !pucDataOutput ||
|
||||
!puiOutputLength) {
|
||||
SDFerr(SDF_F_SDF_INTERNALPRIVATEKEYOPERATION_RSA,
|
||||
ERR_R_PASSED_NULL_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!(pkey = sdf_load_rsa_private_key((SDF_SESSION *)hSessionHandle,
|
||||
uiKeyIndex, uiKeyUsage))) {
|
||||
SDFerr(SDF_F_SDF_INTERNALPRIVATEKEYOPERATION_RSA,
|
||||
ERR_R_GMAPI_LIB);
|
||||
goto end;
|
||||
}
|
||||
|
||||
if ((outlen = RSA_private_decrypt(uiInputLength, pucDataInput,
|
||||
pucDataOutput, EVP_PKEY_get0_RSA(pkey), RSA_NO_PADDING)) < 0) {
|
||||
SDFerr(SDF_F_SDF_INTERNALPRIVATEKEYOPERATION_RSA,
|
||||
ERR_R_RSA_LIB);
|
||||
goto end;
|
||||
}
|
||||
|
||||
*puiOutputLength = (unsigned int)outlen;
|
||||
ret = SDR_OK;
|
||||
|
||||
end:
|
||||
EVP_PKEY_free(pkey);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -1,237 +0,0 @@
|
||||
/* ====================================================================
|
||||
* Copyright (c) 2016 The GmSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* 3. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the GmSSL Project.
|
||||
* (http://gmssl.org/)"
|
||||
*
|
||||
* 4. The name "GmSSL Project" must not be used to endorse or promote
|
||||
* products derived from this software without prior written
|
||||
* permission. For written permission, please contact
|
||||
* guanzhi1980@gmail.com.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "GmSSL"
|
||||
* nor may "GmSSL" appear in their names without prior written
|
||||
* permission of the GmSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the GmSSL Project
|
||||
* (http://gmssl.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE GmSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GmSSL PROJECT OR
|
||||
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES
|
||||
* LOSS OF USE, DATA, OR PROFITS OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ====================================================================
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/rand.h>
|
||||
#include <openssl/gmsdf.h>
|
||||
#include <openssl/engine.h>
|
||||
#include "sdf_lcl.h"
|
||||
|
||||
/*
|
||||
* Unlike the `SDF_OpenDevice`, we always assume that the `SDF_OpenSession` can
|
||||
* be called multiple times, and the implementation will always return a new
|
||||
* session handle on success. But noramlly the hardware and the software can
|
||||
* only support limited sessions, so this function can also failed.
|
||||
*
|
||||
* For portability, the application should assume that only one cryptographic
|
||||
* operation can be processed over one session. For example, do not mix
|
||||
* symmetric encryption and hash functions over the same session. The
|
||||
* implementation might support multiple operations, check the vendor's manual.
|
||||
*/
|
||||
|
||||
/*
|
||||
* there are two purpose for session:
|
||||
* (1) hold session information
|
||||
* (2) a reference to ENGINE
|
||||
*/
|
||||
/*
|
||||
typedef struct {
|
||||
uint32_t magic;
|
||||
char *app;
|
||||
ENGINE *engine;
|
||||
char *passwords[SDF_MAX_KEY_INDEX];
|
||||
EVP_MD_CTX *md_ctx;
|
||||
} SDF_SESSION;
|
||||
*/
|
||||
|
||||
int SDF_OpenSession(
|
||||
void *hDeviceHandle,
|
||||
void **phSessionHandle)
|
||||
{
|
||||
int ret = SDR_UNKNOWERR;
|
||||
SDF_SESSION *session = NULL;
|
||||
|
||||
if (!hDeviceHandle || !phSessionHandle) {
|
||||
SDFerr(SDF_F_SDF_OPENSESSION, ERR_R_PASSED_NULL_PARAMETER);
|
||||
return SDR_INARGERR;
|
||||
}
|
||||
if (hDeviceHandle != deviceHandle) {
|
||||
SDFerr(SDF_F_SDF_OPENSESSION, SDF_R_INVALID_DEVICE_HANDLE);
|
||||
return SDR_INARGERR;
|
||||
}
|
||||
|
||||
if (!(session = OPENSSL_zalloc(sizeof(*session)))) {
|
||||
SDFerr(SDF_F_SDF_OPENSESSION, ERR_R_MALLOC_FAILURE);
|
||||
ret = SDR_NOBUFFER;
|
||||
goto end;
|
||||
}
|
||||
|
||||
session->magic = SDF_SESSION_MAGIC;
|
||||
|
||||
#ifndef OPENSSL_NO_ENGINE
|
||||
if (!(session->engine = ENGINE_by_id(SDF_ENGINE_ID))) {
|
||||
SDFerr(SDF_F_SDF_OPENSESSION, SDF_R_LOAD_ENGINE_FAILURE);
|
||||
ret = SDR_HARDFAIL;
|
||||
goto end;
|
||||
}
|
||||
#endif
|
||||
|
||||
*phSessionHandle = session;
|
||||
session = NULL;
|
||||
ret = SDR_OK;
|
||||
|
||||
end:
|
||||
OPENSSL_free(session);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int SDF_CloseSession(
|
||||
void *hSessionHandle)
|
||||
{
|
||||
SDF_SESSION *session = (SDF_SESSION *)hSessionHandle;
|
||||
int i;
|
||||
|
||||
if (!hSessionHandle) {
|
||||
return SDR_OK;
|
||||
}
|
||||
|
||||
if (session->magic != SDF_SESSION_MAGIC) {
|
||||
SDFerr(SDF_F_SDF_CLOSESESSION, SDF_R_INVALID_SESSION);
|
||||
return SDR_INARGERR;
|
||||
}
|
||||
|
||||
#ifndef OPENSSL_NO_ENGINE
|
||||
if (session->engine) {
|
||||
ENGINE_finish(session->engine);
|
||||
ENGINE_free(session->engine);
|
||||
session->engine = NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
for (i = 0; i <= SDF_MAX_KEY_INDEX; i++) {
|
||||
OPENSSL_clear_free(session->password[i],
|
||||
strlen(session->password[i]));
|
||||
session->password[i] = NULL;
|
||||
}
|
||||
|
||||
OPENSSL_free(session);
|
||||
return SDR_OK;
|
||||
}
|
||||
|
||||
/* we try that the password is correct by `ENGINE_load_private_key`, then we
|
||||
* destory the returned `EVP_PKEY` and keep the verified password in the
|
||||
* session. We can use `UI_set_result` to pass the password to the ENGINE
|
||||
*/
|
||||
int SDF_GetPrivateKeyAccessRight(
|
||||
void *hSessionHandle,
|
||||
unsigned int uiKeyIndex,
|
||||
unsigned char *pucPassword,
|
||||
unsigned int uiPwdLength)
|
||||
{
|
||||
SDF_SESSION *session = (SDF_SESSION *)hSessionHandle;
|
||||
EVP_PKEY *pkey = NULL;
|
||||
char *key_id = NULL;
|
||||
UI_METHOD *ui_meth = NULL;
|
||||
void *cb_data = NULL;
|
||||
|
||||
if (!hSessionHandle || !pucPassword) {
|
||||
SDFerr(SDF_F_SDF_GETPRIVATEKEYACCESSRIGHT,
|
||||
ERR_R_PASSED_NULL_PARAMETER);
|
||||
return SDR_INARGERR;
|
||||
}
|
||||
if (session->magic != SDF_SESSION_MAGIC) {
|
||||
SDFerr(SDF_F_SDF_GETPRIVATEKEYACCESSRIGHT,
|
||||
SDF_R_INVALID_SESSION_HANDLE);
|
||||
return SDR_INARGERR;
|
||||
}
|
||||
if (uiKeyIndex <= 0 || uiKeyIndex > SDF_MAX_KEY_INDEX) {
|
||||
SDFerr(SDF_F_SDF_GETPRIVATEKEYACCESSRIGHT,
|
||||
SDF_R_INVALID_KEY_INDEX);
|
||||
return -1;
|
||||
}
|
||||
if (uiPwdLength <= 0 || uiPwdLength > INT_MAX) {
|
||||
SDFerr(SDF_F_SDF_GETPRIVATEKEYACCESSRIGHT,
|
||||
SDF_R_INVALID_PASSWORD_LENGTH);
|
||||
return SDR_INARGERR;
|
||||
}
|
||||
|
||||
if (!(pkey = ENGINE_load_private_key(session->engine, key_id,
|
||||
ui_meth, cb_data))) {
|
||||
SDFerr(SDF_F_SDF_GETPRIVATEKEYACCESSRIGHT, ERR_R_ENGINE_LIB);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return SDR_OK;
|
||||
}
|
||||
|
||||
int SDF_ReleasePrivateKeyAccessRight(
|
||||
void *hSessionHandle,
|
||||
unsigned int uiKeyIndex)
|
||||
{
|
||||
SDF_SESSION *session = (SDF_SESSION *)hSessionHandle;
|
||||
|
||||
if (!hSessionHandle) {
|
||||
SDFerr(SDF_F_SDF_RELEASEPRIVATEKEYACCESSRIGHT,
|
||||
ERR_R_PASSED_NULL_PARAMETER);
|
||||
return SDR_INARGERR;
|
||||
}
|
||||
if (session->magic != SDF_SESSION_MAGIC) {
|
||||
SDFerr(SDF_F_SDF_RELEASEPRIVATEKEYACCESSRIGHT,
|
||||
SDF_R_INVALID_SESSION_HANDLE);
|
||||
return SDR_INARGERR;
|
||||
}
|
||||
if (uiKeyIndex <= 0 || uiKeyIndex > SDF_MAX_KEY_INDEX) {
|
||||
SDFerr(SDF_F_SDF_RELEASEPRIVATEKEYACCESSRIGHT,
|
||||
SDF_R_INVALID_KEY_INDEX);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (session->password[uiKeyIndex]) {
|
||||
OPENSSL_clear_free(session->password[uiKeyIndex],
|
||||
strlen(session->password[uiKeyIndex]));
|
||||
session->password[uiKeyIndex] = NULL;
|
||||
}
|
||||
|
||||
return SDR_OK;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user