From e62b8fa722e2d33eb038848ea6ac05e6bbcf34fb Mon Sep 17 00:00:00 2001 From: Zhi Guan Date: Tue, 10 May 2022 11:38:22 +0800 Subject: [PATCH] Add SKF support --- CMakeLists.txt | 10 + include/gmssl/sdf.h | 2 +- include/gmssl/skf.h | 34 +- src/sdf.c | 142 --- src/sdf/sdf.c | 24 +- src/skf/skf.c | 759 +++++++++++- src/skf/skf.h | 748 ++++++++++++ src/skf/skf_dummy.c | 946 +++++++++++++++ src/skf/skf_ext.c | 607 ++++++++++ src/skf/skf_ext.h | 133 +++ src/skf/skf_int.h | 617 ++++++++++ src/skf/skf_lib.c | 2777 +++++++++++++++++++++++++++++++++++++++++++ src/skf/skf_meth.c | 176 +++ src/skf/skf_prn.c | 325 +++++ src/skf/skf_wisec.c | 185 +++ src/skf/skf_wisec.h | 156 +++ tools/gmssl.c | 6 +- tools/sdfutil.c | 8 +- tools/skfutil.c | 271 +++++ tools/sm4.c | 2 +- tools/zuc.c | 2 +- 21 files changed, 7736 insertions(+), 194 deletions(-) delete mode 100644 src/sdf.c create mode 100644 src/skf/skf.h create mode 100644 src/skf/skf_dummy.c create mode 100644 src/skf/skf_ext.c create mode 100644 src/skf/skf_ext.h create mode 100644 src/skf/skf_int.h create mode 100644 src/skf/skf_lib.c create mode 100644 src/skf/skf_meth.c create mode 100644 src/skf/skf_prn.c create mode 100644 src/skf/skf_wisec.c create mode 100644 src/skf/skf_wisec.h create mode 100644 tools/skfutil.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 18c26f85..10530029 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -72,6 +72,12 @@ add_library( src/sdf/sdf_meth.c src/sdf/sdf_ext.c src/sdf/sdf_sansec.c + src/skf/skf.c + src/skf/skf_lib.c + src/skf/skf_meth.c + src/skf/skf_ext.c + src/skf/skf_prn.c + src/skf/skf_wisec.c ) target_link_libraries(gmssl dl) SET_TARGET_PROPERTIES(gmssl PROPERTIES VERSION 3.0 SOVERSION 3) @@ -79,6 +85,9 @@ SET_TARGET_PROPERTIES(gmssl PROPERTIES VERSION 3.0 SOVERSION 3) add_library(sdf_dummy SHARED src/sdf/sdf_dummy.c) SET_TARGET_PROPERTIES(sdf_dummy PROPERTIES VERSION 3.0 SOVERSION 3) +add_library(skf_dummy SHARED src/skf/skf_dummy.c) +SET_TARGET_PROPERTIES(skf_dummy PROPERTIES VERSION 3.0 SOVERSION 3) + # tools add_executable( @@ -116,6 +125,7 @@ add_executable( tools/tls13_client.c tools/tls13_server.c tools/sdfutil.c + tools/skfutil.c ) target_link_libraries (gmssl-bin LINK_PUBLIC gmssl) set_target_properties (gmssl-bin PROPERTIES RUNTIME_OUTPUT_NAME gmssl) diff --git a/include/gmssl/sdf.h b/include/gmssl/sdf.h index 374e79f3..d98c5760 100644 --- a/include/gmssl/sdf.h +++ b/include/gmssl/sdf.h @@ -77,7 +77,7 @@ int sdf_load_library(const char *so_path, const char *vendor); int sdf_open_device(SDF_DEVICE *dev); int sdf_print_device_info(FILE *fp, int fmt, int ind, const char *lable, SDF_DEVICE *dev); int sdf_rand_bytes(SDF_DEVICE *dev, uint8_t *buf, size_t len); -int sdf_load_key(SDF_DEVICE *dev, SDF_KEY *key, int index, const char *pass); +int sdf_load_sign_key(SDF_DEVICE *dev, SDF_KEY *key, int index, const char *pass); int sdf_sign(SDF_KEY *key, const uint8_t dgst[32], uint8_t *sig, size_t *siglen); int sdf_release_key(SDF_KEY *key); int sdf_close_device(SDF_DEVICE *dev); diff --git a/include/gmssl/skf.h b/include/gmssl/skf.h index dc2ead19..d571bf9f 100644 --- a/include/gmssl/skf.h +++ b/include/gmssl/skf.h @@ -71,21 +71,45 @@ typedef struct { } SKF_DEVICE; typedef struct { + SM2_KEY public_key; void *app_handle; char app_name[65]; void *container_handle; char container_name[65]; - SM2_KEY public_key; } SKF_KEY; +int skf_load_library(const char *so_path, const char *vendor); +void skf_unload_library(void); + +int skf_list_devices(FILE *fp, int fmt, int ind, const char *label); +int skf_print_device_info(FILE *fp, int fmt, int ind, const char *devname); +int skf_open_device(SKF_DEVICE *dev, const char *devname, const uint8_t authkey[16]); +int skf_set_label(SKF_DEVICE *dev, const char *label); +int skf_change_authkey(SKF_DEVICE *dev, const uint8_t authkey[16]); +int skf_close_deivce(SKF_DEVICE *dev);; + +int skf_list_apps(SKF_DEVICE *dev, int fmt, int ind, const char *label, FILE *fp); +int skf_create_app(SKF_DEVICE *dev, const char *appname, const char *admin_pin, const char *user_pin); +int skf_delete_app(SKF_DEVICE *dev, const char *appname); +int skf_change_app_admin_pin(SKF_DEVICE *dev, const char *appname, const char *oid_pin, const char *new_pin); +int skf_change_app_user_pin(SKF_DEVICE *dev, const char *appname, const char *oid_pin, const char *new_pin); +int skf_unblock_user_pin(SKF_DEVICE *dev, const char *appname, const char *admin_pin, const char *new_user_pin); + +int skf_list_objects(FILE *fp, int fmt, int ind, const char *label, SKF_DEVICE *dev, const char *appname, const char *pin); +int skf_import_object(SKF_DEVICE *dev, const char *appname, const char *pin, const char *objname, const uint8_t *data, size_t datalen); +int skf_export_object(SKF_DEVICE *dev, const char *appname, const char *pin, const char *objname, uint8_t *out, size_t *outlen); +int skf_delete_object(SKF_DEVICE *dev, const char *appname, const char *pin, const char *objname); + +int skf_list_containers(FILE *fp, int fmt, int ind, const char *label, SKF_DEVICE *dev, const char *appname, const char *pin); +int skf_create_container(SKF_DEVICE *dev, const char *appname, const char *pin, const char *container_name); +int skf_delete_container(SKF_DEVICE *dev, const char *appname, const char *pin, const char *container_name); +int skf_import_sign_cert(SKF_DEVICE *dev, const char *appname, const char *pin, const char *container_name, const uint8_t *cert, size_t certlen); +int skf_export_sign_cert(SKF_DEVICE *dev, const char *appname, const char *pin, const char *container_name, uint8_t *cert, size_t *certlen); -int skf_open_device(SKF_DEVICE *dev, const char *devname, const uint8_t *authkey, size_t authkeylen); -int skf_print_device_info(FILE *fp, int fmt, int ind, const char *lable, SKF_DEVICE *dev); int skf_rand_bytes(SKF_DEVICE *dev, uint8_t *buf, size_t len); -int sdf_load_key(SKF_DEVICE *dev, const char *appname, const char *pass, const char *container_name, SKF_KEY *key); +int skf_load_sign_key(SKF_DEVICE *dev, const char *appname, const char *pin, const char *container_name, SKF_KEY *key); int skf_sign(SKF_KEY *key, const uint8_t dgst[32], uint8_t *sig, size_t *siglen); int skf_release_key(SKF_KEY *key); -int skf_close_deivce(SKF_DEVICE *dev); #ifdef __cplusplus diff --git a/src/sdf.c b/src/sdf.c deleted file mode 100644 index 80ee75d4..00000000 --- a/src/sdf.c +++ /dev/null @@ -1,142 +0,0 @@ -/* - * Copyright (c) 2014 - 2021 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 -#include -#include -#include -#include - - -/* -typedef struct { - void *device_handle; - char device_issuer[41]; - char device_name[17]; - char device_serial[17]; -} SDF_DEVICE; - -typedef struct { - void *session_handle; - int key_index; - SM2_KEY public_key; -} SDF_KEY; - -*/ -int sdf_open_device(SDF_DEVICE *dev) -{ - int ret = 0; - void *hDevice = NULL; - void *hSession = NULL; - DEVICEINFO devInfo = {{0}}; - - if (SDF_OpenDevice(&hDevice) != SDR_OK) { - error_print(); - goto end; - } - if (SDF_OpenSession(hDevice, &hSession) != SDR_OK) { - error_print(); - goto end; - } - if (SDF_GetDeviceInfo(hSession, &devInfo) != SDR_OK) { - error_print(); - goto end; - } - SDF_PrintDeviceInfo(stdout, &devInfo); - - sdf_session = hSession; - hSession = NULL; - sdf_dev = hDevice; - hDevice = NULL; - ret = 1; - -end: - if (hSession && SDF_CloseSession(hSession) != SDR_OK) { - ret = 0; - } - if (hDevice && SDF_CloseDevice(hDevice) != SDR_OK) { - ret = 0; - } - return ret; -} - -int sdf_print_device_info(FILE *fp, int fmt, int ind, const char *lable, SDF_DEVICE *dev) -{ - error_print(); - return -1; -} - -int sdf_rand_bytes(SDF_DEVICE *dev, uint8_t *buf, size_t len) -{ - error_print(); - return -1; -} - -int sdf_load_key(SDF_DEVICE *dev, SDF_KEY *key, int index, const char *pass) -{ - error_print(); - return -1; -} - -int sdf_sign(SDF_KEY *key, const uint8_t dgst[32], uint8_t *sig, size_t *siglen) -{ - error_print(); - return -1; -} - -int sdf_release_key(SDF_KEY *key) -{ - error_print(); - return -1; -} - -int sdf_close_device(SDF_DEVICE *dev) -{ - error_print(); - return -1; -} diff --git a/src/sdf/sdf.c b/src/sdf/sdf.c index 77461b4b..a978b482 100644 --- a/src/sdf/sdf.c +++ b/src/sdf/sdf.c @@ -173,29 +173,7 @@ end: return ret; } -int sdf_export_public_key(SDF_DEVICE *dev, SM2_KEY *public_key, int index) -{ - int ret = -1; - void *hSession = NULL; - ECCrefPublicKey eccPublicKey; - - if (!dev || !public_key) { - error_print(); - return -1; - } - if (SDF_OpenSession(dev->handle, &hSession) != SDR_OK - || SDF_ExportSignPublicKey_ECC(hSession, index, &eccPublicKey) != SDR_OK - || SDF_ECCrefPublicKey_to_SM2_KEY(&eccPublicKey, public_key) != SDR_OK) { - error_print(); - goto end; - } - ret = 1; -end: - if (hSession) SDF_CloseSession(hSession); - return ret; -} - -int sdf_load_key(SDF_DEVICE *dev, SDF_KEY *key, int index, const char *pass) +int sdf_load_sign_key(SDF_DEVICE *dev, SDF_KEY *key, int index, const char *pass) { int ret = -1; void *hSession = NULL; diff --git a/src/skf/skf.c b/src/skf/skf.c index e184c8c5..69ae7dd3 100644 --- a/src/skf/skf.c +++ b/src/skf/skf.c @@ -1,4 +1,4 @@ -/* +/* * Copyright (c) 2014 - 2021 The GmSSL Project. All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -51,47 +51,770 @@ #include #include #include +#include "../sgd.h" +#include "skf.h" +#include "skf_ext.h" +#include "skf_int.h" -int skf_open_device(SKF_DEVICE *dev, const char *devname, const uint8_t *authkey, size_t authkeylen) +int skf_load_library(const char *so_path, const char *vendor) { - error_print(); - return -1; + if (SKF_LoadLibrary((LPSTR)so_path, (LPSTR)vendor) != SAR_OK) { + error_print(); + return -1; + } + return 1; } -int skf_print_device_info(FILE *fp, int fmt, int ind, const char *lable, SKF_DEVICE *dev) +void skf_unload_library(void) { - error_print(); - return -1; + SKF_UnloadLibrary(); +} + + +static int skf_open_app(SKF_DEVICE *dev, const char *appname, const char *pin, HAPPLICATION *phApp) +{ + int ret = 0; + HAPPLICATION hApp = NULL; + ULONG ulPINType = USER_TYPE; + ULONG numRetry; + + if (SKF_OpenApplication(dev->handle, (LPSTR)appname, &hApp) != SAR_OK) { + error_print(); + return -1; + } + if (SKF_VerifyPIN(hApp, ulPINType, (CHAR *)pin, &numRetry) != SAR_OK) { + fprintf(stderr, "Invalid user PIN, retry count = %u\n", numRetry); + error_print(); + goto end; + } + *phApp = hApp; + hApp = NULL; + ret = 1; +end: + if (hApp) SKF_CloseApplication(hApp); + return ret; +} + +static const uint8_t zeros[ECC_MAX_XCOORDINATE_BITS_LEN/8 - 32] = {0}; + +static int SKF_ECCPUBLICKEYBLOB_to_SM2_KEY(const ECCPUBLICKEYBLOB *blob, SM2_KEY *sm2_key) +{ + SM2_POINT point; + + if (blob->BitLen != 256) { + error_print(); + return -1; + } + if (memcmp(blob->XCoordinate, zeros, sizeof(zeros)) != 0 + || memcmp(blob->YCoordinate, zeros, sizeof(zeros)) != 0) { + error_print(); + return -1; + } + if (sm2_point_from_xy(&point, + blob->XCoordinate + ECC_MAX_XCOORDINATE_BITS_LEN/8 - 32, + blob->YCoordinate + ECC_MAX_YCOORDINATE_BITS_LEN/8 - 32) != 1 + || sm2_key_set_public_key(sm2_key, &point) != 1) { + error_print(); + return -1; + } + return SAR_OK; +} + +static int SKF_ECCSIGNATUREBLOB_to_SM2_SIGNATURE(const ECCSIGNATUREBLOB *blob, SM2_SIGNATURE *sig) +{ + if (memcmp(blob->r, zeros, sizeof(zeros)) != 0 + || memcmp(blob->s, zeros, sizeof(zeros)) != 0) { + error_print(); + return -1; + } + memset(sig, 0, sizeof(SM2_SIGNATURE)); + memcpy(sig->r, blob->r + ECC_MAX_XCOORDINATE_BITS_LEN/8 - 32, 32); + memcpy(sig->s, blob->s + ECC_MAX_XCOORDINATE_BITS_LEN/8 - 32, 32); + return SAR_OK; } int skf_rand_bytes(SKF_DEVICE *dev, uint8_t *buf, size_t len) { - error_print(); - return -1; + if (SKF_GenRandom(dev->handle, buf, (ULONG)len) != SAR_OK) { + error_print(); + return -1; + } + return 1; } -int sdf_load_key(SKF_DEVICE *dev, const char *appname, const char *pass, const char *container_name, SKF_KEY *key) +int skf_load_sign_key(SKF_DEVICE *dev, const char *appname, const char *pin, const char *container_name, SKF_KEY *key) { - error_print(); - return -1; + int ret = -1; + HAPPLICATION hApp = NULL; + HCONTAINER hContainer = NULL; + ULONG containerType = 0; + BOOL bSign = SGD_TRUE; + ECCPUBLICKEYBLOB publicKeyBlob; + ULONG ulBlobLen = sizeof(ECCPUBLICKEYBLOB); + SM2_KEY public_key; + + if (skf_open_app(dev, appname, pin, &hApp) != 1) { + error_print(); + return -1; + } + if (SKF_OpenContainer(hApp, (LPSTR)container_name, &hContainer) != SAR_OK + || SKF_GetContainerType(hContainer, &containerType) != SAR_OK) { + error_print(); + goto end; + } + if (containerType != SKF_CONTAINER_TYPE_ECC) { + error_print(); + goto end; + } + if (SKF_ExportPublicKey(hContainer, bSign, (BYTE *)&publicKeyBlob, &ulBlobLen) != SAR_OK) { + error_print(); + goto end; + } + if (ulBlobLen != sizeof(ECCPUBLICKEYBLOB)) { + error_print(); + goto end; + } + if (SKF_ECCPUBLICKEYBLOB_to_SM2_KEY(&publicKeyBlob, &public_key) != SAR_OK) { + error_print(); + goto end; + } + memset(key, 0, sizeof(SKF_KEY)); + key->public_key = public_key; + key->app_handle = hApp; + hApp = NULL; + strncpy(key->app_name, appname, 64); + key->container_handle = hContainer; + hContainer = NULL; + strncpy(key->container_name, container_name, 64); + ret = 1; +end: + if (hApp) SKF_CloseApplication(hApp); + if (hContainer) SKF_CloseContainer(hContainer); + return ret; } int skf_sign(SKF_KEY *key, const uint8_t dgst[32], uint8_t *sig, size_t *siglen) { - error_print(); - return -1; + ECCSIGNATUREBLOB sigBlob; + SM2_SIGNATURE sm2_sig; + + if (SKF_ECCSignData(key->container_handle, (BYTE *)dgst, 32, &sigBlob) != SAR_OK) { + error_print(); + return -1; + } + if (SKF_ECCSIGNATUREBLOB_to_SM2_SIGNATURE(&sigBlob, &sm2_sig) != SAR_OK) { + error_print(); + return -1; + } + *siglen = 0; + if (sm2_signature_to_der(&sm2_sig, &sig, siglen) != 1) { + error_print(); + return -1; + } + return 1; } int skf_release_key(SKF_KEY *key) { - error_print(); - return -1; + if (key->app_handle) { + if (SKF_ClearSecureState(key->app_handle) != SAR_OK + || SKF_CloseApplication(key->app_handle) != SAR_OK) { + error_print(); + return -1; + } + key->app_handle = NULL; + } + if (key->container_handle) { + if (SKF_CloseContainer(key->container_handle) != SAR_OK) { + error_print(); + return -1; + } + } + memset(key, 0, sizeof(SKF_KEY)); + return 1; } int skf_close_deivce(SKF_DEVICE *dev) { - error_print(); - return -1; + if (SKF_UnlockDev(dev->handle) != SAR_OK + || SKF_DisConnectDev(dev->handle) != SAR_OK) { + error_print(); + return -1; + } + memset(dev, 0, sizeof(SKF_DEVICE)); + return 1; } + + + + + + +int skf_list_devices(FILE *fp, int fmt, int ind, const char *label) +{ + int ret = -1; + BOOL bPresent = TRUE; + char *nameList = NULL; + ULONG nameListLen = 0; + const char *name; + int i; + + format_print(fp, fmt, ind, "%s\n", label); + ind += 4; + + if (SKF_EnumDev(bPresent, NULL, &nameListLen) != SAR_OK) { + error_print(); + return -1; + } + if (nameListLen == 0) { + return 0; + } + if (!(nameList = malloc(nameListLen))) { + error_print(); + return -1; + } + if (SKF_EnumDev(bPresent, (LPSTR)nameList, &nameListLen) != SAR_OK) { + error_print(); + goto end; + } + for (name = nameList, i = 0; *name; name += strlen(name) + 1, i++) { + (void)format_print(fp, fmt, ind, "%s\n", name); + } + ret = 1; +end: + free(nameList); + return ret; +} + +int skf_print_device_info(FILE *fp, int fmt, int ind, const char *devname) +{ + int ret = 0; + DEVHANDLE hDev = NULL; + ULONG devState = 0; + LPSTR devStateName = NULL; + DEVINFO devInfo = {{0,0}}; + + format_print(fp, fmt, ind, "%s\n", devname); + ind += 4; + + if (SKF_GetDevState((LPSTR)devname, &devState) != SAR_OK + || SKF_GetDevStateName(devState, &devStateName) != SAR_OK + || SKF_ConnectDev((LPSTR)devname, &hDev) != SAR_OK + || SKF_GetDevInfo(hDev, &devInfo) != SAR_OK) { + error_print(); + goto end; + } + + (void)format_print(fp, fmt, ind, "DeviceState: %s\n", (char *)devStateName); + //(void)SKF_PrintDevInfo(fp, fmt, ind, "DeviceInfo", &devInfo); + ret = 1; +end: + if (hDev) SKF_DisConnectDev(hDev); + return ret; +} + +int skf_set_label(SKF_DEVICE *dev, const char *label) +{ + if (SKF_SetLabel(dev->handle, (LPSTR)label) != SAR_OK) { + error_print(); + return -1; + } + return 1; +} + +int skf_open_device(SKF_DEVICE *dev, const char *devname, const uint8_t authkey[16]) +{ + DEVHANDLE hDev = NULL; + DEVINFO devInfo = {{0,0}}; + ULONG ulTimeOut = 0xffffffff; + BYTE authRand[16] = {0}; + BYTE authData[16] = {0}; + ULONG authRandLen = SKF_AUTHRAND_LENGTH; + ULONG authDataLen = sizeof(authData); + BLOCKCIPHERPARAM encParam = {{0}, 0, 0, 0}; + + if (SKF_OpenDevice((LPSTR)devname, (BYTE *)authkey, &devInfo, &hDev) != SAR_OK + || SKF_LockDev(hDev, ulTimeOut) != SAR_OK) { + error_print(); + return -1; + } + memset(dev, 0, sizeof(SKF_DEVICE)); + dev->handle = hDev; + hDev = NULL; + + return 1; +} + +int skf_change_authkey(SKF_DEVICE *dev, const uint8_t authkey[16]) +{ + if (SKF_ChangeDevAuthKey(dev->handle, (BYTE *)authkey, 16) != SAR_OK) { + error_print(); + return -1; + } + return 1; +} + +int skf_list_apps(SKF_DEVICE *dev, int fmt, int ind, const char *label, FILE *fp) +{ + int ret = 0; + HAPPLICATION hApp = NULL; + char *nameList = NULL; + ULONG nameListLen = 0; + const char *name; + int i; + + format_print(fp, fmt, ind, "%s\n", label); + ind += 4; + + if (SKF_EnumApplication(dev->handle, NULL, &nameListLen) != SAR_OK) { + error_print(); + return -1; + } + if (nameListLen <= 1) { + return 0; + } + if (!(nameList = malloc(nameListLen))) { + error_print(); + return -1; + } + if (SKF_EnumApplication(dev->handle, (LPSTR)nameList, &nameListLen) != SAR_OK) { + error_print(); + goto end; + } + for (name = nameList, i = 0; *name; name += strlen(name) + 1, i++) { + ULONG adminMaxRetry; + ULONG adminMinRetry; + ULONG userMaxRetry; + ULONG userMinRetry; + BOOL adminDefaultPin; + BOOL userDefaultPin; + + if (SKF_OpenApplication(dev->handle, (LPSTR)name, &hApp) != SAR_OK + || SKF_GetPINInfo(hApp, ADMIN_TYPE, &adminMaxRetry, &adminMinRetry, &adminDefaultPin) != SAR_OK + || SKF_GetPINInfo(hApp, USER_TYPE, &userMaxRetry, &userMinRetry, &userDefaultPin) != SAR_OK + || SKF_CloseApplication(hApp) != SAR_OK) { + error_print(); + goto end; + } + hApp = NULL; + + (void)format_print(fp, fmt, ind, "Application %d:\n", i); + (void)format_print(fp, fmt, ind + 4, "ApplicationName", name); + (void)format_print(fp, fmt, ind + 4, "AdminPinMaxRetry: %s\n", adminMaxRetry); + (void)format_print(fp, fmt, ind + 4, "AdminPinMinRetry: %u\n", adminMinRetry); + (void)format_print(fp, fmt, ind + 4, "AdminDefaultPin: %s\n", adminDefaultPin ? "True" : "False"); + (void)format_print(fp, fmt, ind + 4, "UserPinMaxRetry: %u\n", userMaxRetry); + (void)format_print(fp, fmt, ind + 4, "UserPinMinRetry: %u\n", userMinRetry); + (void)format_print(fp, fmt, ind + 4, "UserDefaultPin: %s\n", userDefaultPin ? "True" : "False"); + } + ret = 1; +end: + if (hApp) SKF_CloseApplication(hApp); + return ret; +} + +int skf_create_app(SKF_DEVICE *dev, const char *appname, const char *admin_pin, const char *user_pin) +{ + int ret = 0; + HAPPLICATION hApp = NULL; + ULONG appRights = SECURE_ANYONE_ACCOUNT; + + if (SKF_CreateApplication(dev->handle, (LPSTR)appname, + (CHAR *)admin_pin, SKF_DEFAULT_ADMIN_PIN_RETRY_COUNT, + (CHAR *)user_pin, SKF_DEFAULT_USER_PIN_RETRY_COUNT, + appRights, &hApp) != SAR_OK) { + error_print(); + return -1; + } + if (SKF_CloseApplication(hApp) != SAR_OK) { + error_print(); + return -1; + } + return 1; +} + +int skf_delete_app(SKF_DEVICE *dev, const char *appname) +{ + if (SKF_DeleteApplication(dev->handle, (LPSTR)appname) != SAR_OK) { + error_print(); + return -1; + } + return 1; +} + +int skf_change_app_admin_pin(SKF_DEVICE *dev, const char *appname, const char *oid_pin, const char *new_pin) +{ + int ret = -1; + HAPPLICATION hApp = NULL; + ULONG ulPINType = ADMIN_TYPE; + ULONG ulRetryCount = 0; + + if (SKF_OpenApplication(dev->handle, (LPSTR)appname, &hApp) != SAR_OK + || SKF_ChangePIN(hApp, ulPINType, (CHAR *)oid_pin, (CHAR *)new_pin, &ulRetryCount) != SAR_OK) { + fprintf(stderr, "Retry Count = %u\n", ulRetryCount); + error_print(); + goto end; + } + ret = 1; +end: + if (hApp) SKF_CloseApplication(hApp); + return ret; +} + +int skf_change_app_user_pin(SKF_DEVICE *dev, const char *appname, const char *oid_pin, const char *new_pin) +{ + int ret = -1; + HAPPLICATION hApp = NULL; + ULONG ulPINType = USER_TYPE; + ULONG ulRetryCount = 0; + + if (SKF_OpenApplication(dev->handle, (LPSTR)appname, &hApp) != SAR_OK + || SKF_ChangePIN(hApp, ulPINType, (CHAR *)oid_pin, (CHAR *)new_pin, &ulRetryCount) != SAR_OK) { + fprintf(stderr, "Retry Count = %u\n", ulRetryCount); + goto end; + } + ret = 1; +end: + if (hApp) SKF_CloseApplication(hApp); + return ret; +} + +int skf_unblock_user_pin(SKF_DEVICE *dev, const char *appname, const char *admin_pin, const char *new_user_pin) +{ + int ret = -1; + HAPPLICATION hApp = NULL; + ULONG ulRetryCount = 0; + + if (SKF_OpenApplication(dev->handle, (LPSTR)appname, &hApp) != SAR_OK + || SKF_UnblockPIN(hApp, (CHAR *)admin_pin, (CHAR *)new_user_pin, &ulRetryCount) != SAR_OK) { + fprintf(stderr, "Invalid admin PIN, retry count = %u\n", ulRetryCount); + error_print(); + goto end; + } + ret = 1; +end: + if (hApp) SKF_CloseApplication(hApp); + return ret; +} + +int skf_list_objects(FILE *fp, int fmt, int ind, const char *label, + SKF_DEVICE *dev, const char *appname, const char *pin) +{ + int ret = -1; + HAPPLICATION hApp = NULL; + char *nameList = NULL; + ULONG nameListLen = 0; + const char *name; + int i; + + format_print(fp, fmt, ind, "%s\n", label); + ind += 4; + + if (skf_open_app(dev, appname, pin, &hApp) != 1) { + error_print(); + return -1; + } + if (SKF_EnumFiles(hApp, NULL, &nameListLen) != SAR_OK) { + error_print(); + goto end; + } + if (nameListLen <= 1) { + ret = 0; + goto end; + } + if (!(nameList = malloc(nameListLen))) { + error_print(); + goto end; + } + if (SKF_EnumFiles(hApp, (LPSTR)nameList, &nameListLen) != SAR_OK) { + error_print(); + goto end; + } + for (name = nameList, i = 0; *name; name += strlen(name) + 1, i++) { + FILEATTRIBUTE fileInfo; + + if (SKF_GetFileInfo(hApp, (LPSTR)name, &fileInfo) != SAR_OK) { + error_print(); + goto end; + } + format_print(fp, fmt, ind, "Object:\n"); + format_print(fp, fmt, ind + 4, "Name: %s\n", (char *)&(fileInfo.FileName)); + format_print(fp, fmt, ind + 4, "Size: %u\n", fileInfo.FileSize); + format_print(fp, fmt, ind + 4, "ReadRights: %08X\n", fileInfo.ReadRights); + format_print(fp, fmt, ind + 4, "WriteRights: %08X\n", fileInfo.WriteRights); + } + + ret = 1; + +end: + if (hApp) SKF_CloseApplication(hApp); + if (nameList) free(nameList); + return ret; +} + +int skf_import_object(SKF_DEVICE *dev, const char *appname, const char *pin, + const char *objname, const uint8_t *data, size_t datalen) +{ + int ret = -1; + HAPPLICATION hApp = NULL; + ULONG ulReadRights = SECURE_ANYONE_ACCOUNT; + ULONG ulWriteRights = SECURE_USER_ACCOUNT; + + if (!dev || !appname || !pin || !objname || !data || !datalen) { + error_print(); + return -1; + } + if (datalen > SKF_MAX_FILE_SIZE) { + error_print(); + return -1; + } + if (skf_open_app(dev, appname, pin, &hApp) != 1) { + error_print(); + return -1; + } + if (SKF_CreateFile(hApp, (LPSTR)objname, datalen, ulReadRights, ulWriteRights) != SAR_OK + || SKF_WriteFile(hApp, (LPSTR)objname, 0, (BYTE *)data, datalen) != SAR_OK) { + error_print(); + goto end; + } + ret = 1; +end: + if (hApp) SKF_CloseApplication(hApp); + return ret; +} + +int skf_export_object(SKF_DEVICE *dev, const char *appname, const char *pin, + const char *objname, uint8_t *out, size_t *outlen) +{ + int ret = -1; + HAPPLICATION hApp = NULL; + FILEATTRIBUTE fileInfo; + ULONG ulen; + int len; + + if (!dev || !appname || !pin || !objname || !outlen) { + error_print(); + return -1; + } + if (skf_open_app(dev, appname, pin, &hApp) != 1) { + error_print(); + return -1; + } + if (SKF_GetFileInfo(hApp, (LPSTR)objname, &fileInfo) != SAR_OK) { + error_print(); + goto end; + } + if (fileInfo.FileSize > SKF_MAX_FILE_SIZE) { + error_print(); + goto end; + } + if (!out) { + *outlen = (size_t)fileInfo.FileSize; + ret = 1; + goto end; + } + ulen = fileInfo.FileSize; + if (SKF_ReadFile(hApp, (LPSTR)objname, 0, fileInfo.FileSize, out, &ulen) != SAR_OK) { + goto end; + } + if (ulen != fileInfo.FileSize) { + error_print(); + goto end; + } + *outlen = ulen; + ret = 1; +end: + if (hApp) SKF_CloseApplication(hApp); + return ret; +} + +int skf_delete_object(SKF_DEVICE *dev, const char *appname, const char *pin, const char *objname) +{ + int ret = -1; + HAPPLICATION hApp = NULL; + + if (skf_open_app(dev, appname, pin, &hApp) != 1) { + error_print(); + return -1; + } + if (SKF_DeleteFile(hApp, (LPSTR)objname) != SAR_OK) { + error_print(); + goto end; + } + ret = 1; +end: + if (hApp) SKF_CloseApplication(hApp); + return ret; +} + +int skf_list_containers(FILE *fp, int fmt, int ind, const char *label, + SKF_DEVICE *dev, const char *appname, const char *pin) +{ + int ret = -1; + HAPPLICATION hApp = NULL; + HCONTAINER hContainer = NULL; + char *nameList = NULL; + ULONG nameListLen = 0; + const char *name; + int i; + + format_print(fp, fmt, ind, "%s\n", label); + ind += 4; + + if (skf_open_app(dev, appname, pin, &hApp) != 1) { + error_print(); + return -1; + } + if (SKF_EnumContainer(hApp, NULL, &nameListLen) != SAR_OK) { + error_print(); + goto end; + } + if (nameListLen <= 1) { + ret = 0; + goto end; + } + if (!(nameList = malloc(nameListLen))) { + error_print(); + goto end; + } + if (SKF_EnumContainer(hApp, (LPSTR)nameList, &nameListLen) != SAR_OK) { + error_print(); + goto end; + } + for (name = nameList, i = 0; *name; name += strlen(name) + 1, i++) { + ULONG containerType; + LPSTR containerTypeName; + + if (SKF_OpenContainer(hApp, (LPSTR)name, &hContainer) != SAR_OK + || SKF_GetContainerType(hContainer, &containerType) != SAR_OK + || SKF_GetContainerTypeName(containerType, &containerTypeName) != SAR_OK + || SKF_CloseContainer(hContainer) != SAR_OK) { + error_print(); + goto end; + } + hContainer = NULL; + (void)format_print(fp, fmt, ind, "Container:\n"); + (void)format_print(fp, fmt, ind + 4, "Name: %s\n", name); + (void)format_print(fp, fmt, ind + 4, "Type: %s\n", (char *)containerTypeName); + } + ret = 1; + +end: + if (hContainer) SKF_CloseContainer(hContainer); + if (hApp) SKF_CloseApplication(hApp); + return ret; +} + +int skf_create_container(SKF_DEVICE *dev, const char *appname, const char *pin, const char *container_name) +{ + int ret = -1; + HAPPLICATION hApp = NULL; + HCONTAINER hContainer = NULL; + ECCPUBLICKEYBLOB publicKey = {0, {0}, {0}}; + + if (skf_open_app(dev, appname, pin, &hApp) != 1) { + error_print(); + return -1; + } + if (SKF_CreateContainer(hApp, (LPSTR)container_name, &hContainer) != SAR_OK + || SKF_GenECCKeyPair(hContainer, SGD_SM2_1, &publicKey) != SAR_OK) { + error_print(); + goto end; + } + ret = 1; +end: + if (hContainer) SKF_CloseContainer(hContainer); + if (hApp) SKF_CloseApplication(hApp); + return ret; +} + +int skf_delete_container(SKF_DEVICE *dev, const char *appname, const char *pin, const char *container_name) +{ + int ret = -1; + HAPPLICATION hApp = NULL; + + if (skf_open_app(dev, appname, pin, &hApp) != 1) { + error_print(); + return -1; + } + if (SKF_DeleteContainer(hApp, (LPSTR)container_name) != SAR_OK) { + error_print(); + goto end; + } + ret = 1; +end: + if (hApp) SKF_CloseApplication(hApp); + return 1; +} + +int skf_import_sign_cert(SKF_DEVICE *dev, const char *appname, const char *pin, + const char *container_name, const uint8_t *cert, size_t certlen) +{ + int ret = 0; + HAPPLICATION hApp = NULL; + HCONTAINER hContainer = NULL; + ULONG containerType; + BOOL bSign = SGD_TRUE; + + if (skf_open_app(dev, appname, pin, &hApp) != 1) { + error_print(); + return -1; + } + if (SKF_GetContainerType(hContainer, &containerType) != SAR_OK) { + error_print(); + goto end; + } + if (containerType == SKF_CONTAINER_TYPE_UNDEF) { + error_print(); + goto end; + } + if (containerType != SKF_CONTAINER_TYPE_ECC) { + error_print(); + goto end; + } + // FIXME: 判断导入证书的类型是否为签名证书 + if (SKF_ImportCertificate(hContainer, bSign, (BYTE *)cert, (ULONG)certlen) != SAR_OK) { + error_print(); + goto end; + } + ret = 1; +end: + if (hContainer) SKF_CloseContainer(hContainer); + if (hApp) SKF_CloseApplication(hApp); + return ret; +} + +int skf_export_sign_cert(SKF_DEVICE *dev, const char *appname, const char *pin, + const char *container_name, uint8_t *cert, size_t *certlen) +{ + int ret = -1; + HAPPLICATION hApp = NULL; + HCONTAINER hContainer = NULL; + ULONG containerType; + BOOL bSign = SGD_TRUE; + ULONG ulCertLen = 0; + + if (skf_open_app(dev, appname, pin, &hApp) != 1) { + error_print(); + return -1; + } + if (SKF_GetContainerType(hContainer, &containerType) != SAR_OK) { + error_print(); + goto end; + } + if (containerType != SKF_CONTAINER_TYPE_ECC) { + error_print(); + goto end; + } + if (SKF_ExportCertificate(hContainer, bSign, (BYTE *)cert, &ulCertLen) != SAR_OK) { + error_print(); + goto end; + } + ret = 1; +end: + if (hContainer) SKF_CloseContainer(hContainer); + if (hApp) SKF_CloseApplication(hApp); + return ret; +} diff --git a/src/skf/skf.h b/src/skf/skf.h new file mode 100644 index 00000000..90706074 --- /dev/null +++ b/src/skf/skf.h @@ -0,0 +1,748 @@ +/* ==================================================================== + * Copyright (c) 2015 - 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. + * ==================================================================== + */ +/* This header file is from the official specification with minor + * modification. + */ + +#ifndef SKFUTIL_SKF_H +#define SKFUTIL_SKF_H + + +#include "../sgd.h" + + +#ifdef __cplusplus +extern "C" { +#endif + +#pragma pack(1) +typedef struct Struct_Version{ + BYTE major; + BYTE minor; +} VERSION; + +typedef struct Struct_DEVINFO { + VERSION Version; + CHAR Manufacturer[64]; + CHAR Issuer[64]; + CHAR Label[32]; + CHAR SerialNumber[32]; + VERSION HWVersion; + VERSION FirmwareVersion; + ULONG AlgSymCap; + ULONG AlgAsymCap; + ULONG AlgHashCap; + ULONG DevAuthAlgId; + ULONG TotalSpace; + ULONG FreeSpace; + ULONG MaxECCBufferSize; + ULONG MaxBufferSize; + BYTE Reserved[64]; +} DEVINFO, *PDEVINFO; + +typedef struct Struct_RSAPUBLICKEYBLOB { + ULONG AlgID; + ULONG BitLen; + BYTE Modulus[MAX_RSA_MODULUS_LEN]; + BYTE PublicExponent[MAX_RSA_EXPONENT_LEN]; +} RSAPUBLICKEYBLOB, *PRSAPUBLICKEYBLOB; + +typedef struct Struct_RSAPRIVATEKEYBLOB { + ULONG AlgID; + ULONG BitLen; + BYTE Modulus[MAX_RSA_MODULUS_LEN]; + BYTE PublicExponent[MAX_RSA_EXPONENT_LEN]; + BYTE PrivateExponent[MAX_RSA_MODULUS_LEN]; + BYTE Prime1[MAX_RSA_MODULUS_LEN/2]; + BYTE Prime2[MAX_RSA_MODULUS_LEN/2]; + BYTE Prime1Exponent[MAX_RSA_MODULUS_LEN/2]; + BYTE Prime2Exponent[MAX_RSA_MODULUS_LEN/2]; + BYTE Coefficient[MAX_RSA_MODULUS_LEN/2]; +} RSAPRIVATEKEYBLOB, *PRSAPRIVATEKEYBLOB; + +typedef struct Struct_ECCPUBLICKEYBLOB { + ULONG BitLen; + BYTE XCoordinate[ECC_MAX_XCOORDINATE_BITS_LEN/8]; + BYTE YCoordinate[ECC_MAX_YCOORDINATE_BITS_LEN/8]; +} ECCPUBLICKEYBLOB, *PECCPUBLICKEYBLOB; + +typedef struct Struct_ECCPRIVATEKEYBLOB { + ULONG BitLen; + BYTE PrivateKey[ECC_MAX_MODULUS_BITS_LEN/8]; +} ECCPRIVATEKEYBLOB, *PECCPRIVATEKEYBLOB; + +typedef struct Struct_ECCCIPHERBLOB { + BYTE XCoordinate[ECC_MAX_XCOORDINATE_BITS_LEN/8]; + BYTE YCoordinate[ECC_MAX_XCOORDINATE_BITS_LEN/8]; + BYTE HASH[32]; + ULONG CipherLen; + BYTE Cipher[1]; +} ECCCIPHERBLOB, *PECCCIPHERBLOB; + +typedef struct Struct_ECCSIGNATUREBLOB { + BYTE r[ECC_MAX_XCOORDINATE_BITS_LEN/8]; + BYTE s[ECC_MAX_XCOORDINATE_BITS_LEN/8]; +} ECCSIGNATUREBLOB, *PECCSIGNATUREBLOB; + +typedef struct Struct_BLOCKCIPHERPARAM { + BYTE IV[MAX_IV_LEN]; + ULONG IVLen; + ULONG PaddingType; + ULONG FeedBitLen; +} BLOCKCIPHERPARAM, *PBLOCKCIPHERPARAM; + +typedef struct SKF_ENVELOPEDKEYBLOB { + ULONG Version; + ULONG ulSymmAlgID; + ULONG ulBits; + BYTE cbEncryptedPriKey[64]; + ECCPUBLICKEYBLOB PubKey; + ECCCIPHERBLOB ECCCipherBlob; +} ENVELOPEDKEYBLOB, *PENVELOPEDKEYBLOB; + +typedef struct Struct_FILEATTRIBUTE { + CHAR FileName[MAX_FILE_NAME_SIZE]; + ULONG FileSize; + ULONG ReadRights; + ULONG WriteRights; +} FILEATTRIBUTE, *PFILEATTRIBUTE; +#pragma pack() + +/* 7.1.2 */ +ULONG DEVAPI SKF_WaitForDevEvent( + LPSTR szDevName, + ULONG *pulDevNameLen, + ULONG *pulEvent); + +/* 7.1.3 */ +ULONG DEVAPI SKF_CancelWaitForDevEvent( + void); + +/* 7.1.4 */ +ULONG DEVAPI SKF_EnumDev( + BOOL bPresent, + LPSTR szNameList, + ULONG *pulSize); + +/* 7.1.5 */ +ULONG DEVAPI SKF_ConnectDev( + LPSTR szName, + DEVHANDLE *phDev); + +/* 7.1.6 */ +ULONG DEVAPI SKF_DisConnectDev( + DEVHANDLE hDev); + +/* 7.1.7 */ +ULONG DEVAPI SKF_GetDevState( + LPSTR szDevName, + ULONG *pulDevState); + +/* 7.1.8 */ +ULONG DEVAPI SKF_SetLabel( + DEVHANDLE hDev, + LPSTR szLabel); + +/* 7.1.9 */ +ULONG DEVAPI SKF_GetDevInfo( + DEVHANDLE hDev, + DEVINFO *pDevInfo); + +/* 7.1.10 */ +ULONG DEVAPI SKF_LockDev( + DEVHANDLE hDev, + ULONG ulTimeOut); + +/* 7.1.11 */ +ULONG DEVAPI SKF_UnlockDev( + DEVHANDLE hDev); + +/* 7.1.12 */ +ULONG DEVAPI SKF_Transmit( + DEVHANDLE hDev, + BYTE *pbCommand, + ULONG ulCommandLen, + BYTE *pbData, + ULONG *pulDataLen); + +/* 7.2.2 */ +ULONG DEVAPI SKF_ChangeDevAuthKey( + DEVHANDLE hDev, + BYTE *pbKeyValue, + ULONG ulKeyLen); + +/* 7.2.3 */ +ULONG DEVAPI SKF_DevAuth( + DEVHANDLE hDev, + BYTE *pbAuthData, + ULONG ulLen); + +/* 7.2.4 */ +ULONG DEVAPI SKF_ChangePIN( + HAPPLICATION hApplication, + ULONG ulPINType, + LPSTR szOldPin, + LPSTR szNewPin, + ULONG *pulRetryCount); + +/* 7.2.5 */ +LONG DEVAPI SKF_GetPINInfo( + HAPPLICATION hApplication, + ULONG ulPINType, + ULONG *pulMaxRetryCount, + ULONG *pulRemainRetryCount, + BOOL *pbDefaultPin); + +/* 7.2.6 */ +ULONG DEVAPI SKF_VerifyPIN( + HAPPLICATION hApplication, + ULONG ulPINType, + LPSTR szPIN, + ULONG *pulRetryCount); + +/* 7.2.7 */ +ULONG DEVAPI SKF_UnblockPIN( + HAPPLICATION hApplication, + LPSTR szAdminPIN, + LPSTR szNewUserPIN, + ULONG *pulRetryCount); + +/* 7.2.8 */ +ULONG DEVAPI SKF_ClearSecureState( + HAPPLICATION hApplication); + +/* 7.3.2 */ +ULONG DEVAPI SKF_CreateApplication( + DEVHANDLE hDev, + LPSTR szAppName, + LPSTR szAdminPin, + DWORD dwAdminPinRetryCount, + LPSTR szUserPin, + DWORD dwUserPinRetryCount, + DWORD dwCreateFileRights, + HAPPLICATION *phApplication); + +/* 7.3.3 */ +ULONG DEVAPI SKF_EnumApplication( + DEVHANDLE hDev, + LPSTR szAppName, + ULONG *pulSize); + +/* 7.3.4 */ +ULONG DEVAPI SKF_DeleteApplication( + DEVHANDLE hDev, + LPSTR szAppName); + +/* 7.3.5 */ +ULONG DEVAPI SKF_OpenApplication( + DEVHANDLE hDev, + LPSTR szAppName, + HAPPLICATION *phApplication); + +/* 7.3.6 */ +ULONG DEVAPI SKF_CloseApplication( + HAPPLICATION hApplication); + +/* 7.4.2 */ +ULONG DEVAPI SKF_CreateFile( + HAPPLICATION hApplication, + LPSTR szFileName, + ULONG ulFileSize, + ULONG ulReadRights, + ULONG ulWriteRights); + +/* 7.4.3 */ +ULONG DEVAPI SKF_DeleteFile( + HAPPLICATION hApplication, + LPSTR szFileName); + +/* 7.4.4 */ +ULONG DEVAPI SKF_EnumFiles( + HAPPLICATION hApplication, + LPSTR szFileList, + ULONG *pulSize); + +/* 7.4.5 */ +ULONG DEVAPI SKF_GetFileInfo( + HAPPLICATION hApplication, + LPSTR szFileName, + FILEATTRIBUTE *pFileInfo); + +/* 7.4.6 */ +ULONG DEVAPI SKF_ReadFile( + HAPPLICATION hApplication, + LPSTR szFileName, + ULONG ulOffset, + ULONG ulSize, + BYTE *pbOutData, + ULONG *pulOutLen); + +/* 7.4.7 */ +ULONG DEVAPI SKF_WriteFile( + HAPPLICATION hApplication, + LPSTR szFileName, + ULONG ulOffset, + BYTE *pbData, + ULONG ulSize); + +/* 7.5.2 */ +ULONG DEVAPI SKF_CreateContainer( + HAPPLICATION hApplication, + LPSTR szContainerName, + HCONTAINER *phContainer); + +/* 7.5.3 */ +ULONG DEVAPI SKF_DeleteContainer( + HAPPLICATION hApplication, + LPSTR szContainerName); + +/* 7.5.4 */ +ULONG DEVAPI SKF_OpenContainer( + HAPPLICATION hApplication, + LPSTR szContainerName, + HCONTAINER *phContainer); + +/* 7.5.5 */ +ULONG DEVAPI SKF_CloseContainer( + HCONTAINER hContainer); + +/* 7.5.6 */ +ULONG DEVAPI SKF_EnumContainer( + HAPPLICATION hApplication, + LPSTR szContainerName, + ULONG *pulSize); + +/* 7.5.7 */ +ULONG DEVAPI SKF_GetContainerType( + HCONTAINER hContainer, + ULONG *pulContainerType); + +/* 7.5.8 */ +ULONG DEVAPI SKF_ImportCertificate( + HCONTAINER hContainer, + BOOL bExportSignKey, + BYTE *pbCert, + ULONG ulCertLen); + +/* 7.5.9 */ +ULONG DEVAPI SKF_ExportCertificate( + HCONTAINER hContainer, + BOOL bSignFlag, + BYTE *pbCert, + ULONG *pulCertLen); + +/* 7.6.2 */ +ULONG DEVAPI SKF_GenRandom( + DEVHANDLE hDev, + BYTE *pbRandom, + ULONG ulRandomLen); + +/* 7.6.3 */ +ULONG DEVAPI SKF_GenExtRSAKey( + DEVHANDLE hDev, + ULONG ulBitsLen, + RSAPRIVATEKEYBLOB *pBlob); + +/* 7.6.4 */ +ULONG DEVAPI SKF_GenRSAKeyPair( + HCONTAINER hContainer, + ULONG ulBitsLen, + RSAPUBLICKEYBLOB *pBlob); + +/* 7.6.5 */ +ULONG DEVAPI SKF_ImportRSAKeyPair( + HCONTAINER hContainer, + ULONG ulSymAlgId, + BYTE *pbWrappedKey, + ULONG ulWrappedKeyLen, + BYTE *pbEncryptedData, + ULONG ulEncryptedDataLen); + +/* 7.6.6 */ +ULONG DEVAPI SKF_RSASignData( + HCONTAINER hContainer, + BYTE *pbData, + ULONG ulDataLen, + BYTE *pbSignature, + ULONG *pulSignLen); + +/* 7.6.7 */ +ULONG DEVAPI SKF_RSAVerify( + DEVHANDLE hDev, + RSAPUBLICKEYBLOB *pRSAPubKeyBlob, + BYTE *pbData, + ULONG ulDataLen, + BYTE *pbSignature, + ULONG ulSignLen); + +/* 7.6.8 */ +ULONG DEVAPI SKF_RSAExportSessionKey( + HCONTAINER hContainer, + ULONG ulAlgId, + RSAPUBLICKEYBLOB *pPubKey, + BYTE *pbData, + ULONG *pulDataLen, + HANDLE *phSessionKey); + +/* 7.6.9 */ +ULONG DEVAPI SKF_ExtRSAPubKeyOperation( + DEVHANDLE hDev, + RSAPUBLICKEYBLOB *pRSAPubKeyBlob, + BYTE *pbInput, + ULONG ulInputLen, + BYTE *pbOutput, + ULONG *pulOutputLen); + +/* 7.6.10 */ +ULONG DEVAPI SKF_ExtRSAPriKeyOperation( + DEVHANDLE hDev, + RSAPRIVATEKEYBLOB *pRSAPriKeyBlob, + BYTE *pbInput, + ULONG ulInputLen, + BYTE *pbOutput, + ULONG *pulOutputLen); + +/* 7.6.11 */ +ULONG DEVAPI SKF_GenECCKeyPair( + HCONTAINER hContainer, + ULONG ulAlgId, + ECCPUBLICKEYBLOB *pBlob); + +/* 7.6.12 */ +ULONG DEVAPI SKF_ImportECCKeyPair( + HCONTAINER hContainer, + ENVELOPEDKEYBLOB *pEnvelopedKeyBlob); + +/* 7.6.13 */ +ULONG DEVAPI SKF_ECCSignData( + HCONTAINER hContainer, + BYTE *pbDigest, + ULONG ulDigestLen, + ECCSIGNATUREBLOB *pSignature); + +#ifdef SKF_HAS_ECCDECRYPT +ULONG DEVAPI SKF_ECCDecrypt( + HCONTAINER hContainer, + ECCCIPHERBLOB *pCipherBlob, + BYTE *pbPlainText, + ULONG *pulPlainTextLen); +#endif + +/* 7.6.14 */ +ULONG DEVAPI SKF_ECCVerify( + DEVHANDLE hDev, + ECCPUBLICKEYBLOB *pECCPubKeyBlob, + BYTE *pbData, + ULONG ulDataLen, + ECCSIGNATUREBLOB *pSignature); + +/* 7.6.15 */ +ULONG DEVAPI SKF_ECCExportSessionKey( + HCONTAINER hContainer, + ULONG ulAlgId, + ECCPUBLICKEYBLOB *pPubKey, + ECCCIPHERBLOB *pData, + HANDLE *phSessionKey); + +/* 7.6.16 */ +ULONG DEVAPI SKF_ExtECCEncrypt( + DEVHANDLE hDev, + ECCPUBLICKEYBLOB *pECCPubKeyBlob, + BYTE *pbPlainText, + ULONG ulPlainTextLen, + ECCCIPHERBLOB *pCipherText); + +/* 7.6.17 */ +ULONG DEVAPI SKF_ExtECCDecrypt( + DEVHANDLE hDev, + ECCPRIVATEKEYBLOB *pECCPriKeyBlob, + ECCCIPHERBLOB *pCipherText, + BYTE *pbPlainText, + ULONG *pulPlainTextLen); + +/* 7.6.18 */ +ULONG DEVAPI SKF_ExtECCSign( + DEVHANDLE hDev, + ECCPRIVATEKEYBLOB *pECCPriKeyBlob, + BYTE *pbData, + ULONG ulDataLen, + ECCSIGNATUREBLOB *pSignature); + +/* 7.6.19 */ +ULONG DEVAPI SKF_ExtECCVerify( + DEVHANDLE hDev, + ECCPUBLICKEYBLOB *pECCPubKeyBlob, + BYTE *pbData, + ULONG ulDataLen, + ECCSIGNATUREBLOB *pSignature); + +/* 7.6.20 */ +ULONG DEVAPI SKF_GenerateAgreementDataWithECC( + HCONTAINER hContainer, + ULONG ulAlgId, + ECCPUBLICKEYBLOB *pTempECCPubKeyBlob, + BYTE *pbID, + ULONG ulIDLen, + HANDLE *phAgreementHandle); + +/* 7.6.21 */ +ULONG DEVAPI SKF_GenerateAgreementDataAndKeyWithECC( + HANDLE hContainer, + ULONG ulAlgId, + ECCPUBLICKEYBLOB *pSponsorECCPubKeyBlob, + ECCPUBLICKEYBLOB *pSponsorTempECCPubKeyBlob, + ECCPUBLICKEYBLOB *pTempECCPubKeyBlob, + BYTE *pbID, + ULONG ulIDLen, + BYTE *pbSponsorID, + ULONG ulSponsorIDLen, + HANDLE *phKeyHandle); + +/* 7.6.22 */ +ULONG DEVAPI SKF_GenerateKeyWithECC( + HANDLE hAgreementHandle, + ECCPUBLICKEYBLOB *pECCPubKeyBlob, + ECCPUBLICKEYBLOB *pTempECCPubKeyBlob, + BYTE *pbID, + ULONG ulIDLen, + HANDLE *phKeyHandle); + +/* 7.6.23 */ +ULONG DEVAPI SKF_ExportPublicKey( + HCONTAINER hContainer, + BOOL bSignFlag, + BYTE *pbBlob, + ULONG *pulBlobLen); + +/* 7.6.24 */ +ULONG DEVAPI SKF_ImportSessionKey( + HCONTAINER hContainer, + ULONG ulAlgId, + BYTE *pbWrapedData, + ULONG ulWrapedLen, + HANDLE *phKey); + +/* 7.6.25 */ +ULONG DEVAPI SKF_SetSymmKey( + DEVHANDLE hDev, + BYTE *pbKey, + ULONG ulAlgID, + HANDLE *phKey); + +/* 7.6.26 */ +ULONG DEVAPI SKF_EncryptInit( + HANDLE hKey, + BLOCKCIPHERPARAM EncryptParam); + +/* 7.6.27 */ +ULONG DEVAPI SKF_Encrypt( + HANDLE hKey, + BYTE *pbData, + ULONG ulDataLen, + BYTE *pbEncryptedData, + ULONG *pulEncryptedLen); + +/* 7.6.28 */ +ULONG DEVAPI SKF_EncryptUpdate( + HANDLE hKey, + BYTE *pbData, + ULONG ulDataLen, + BYTE *pbEncryptedData, + ULONG *pulEncryptedLen); + +/* 7.6.29 */ +ULONG DEVAPI SKF_EncryptFinal( + HANDLE hKey, + BYTE *pbEncryptedData, + ULONG *pulEncryptedDataLen); + +/* 7.6.30 */ +ULONG DEVAPI SKF_DecryptInit( + HANDLE hKey, + BLOCKCIPHERPARAM DecryptParam); + +/* 7.6.31 */ +ULONG DEVAPI SKF_Decrypt( + HANDLE hKey, + BYTE *pbEncryptedData, + ULONG ulEncryptedLen, + BYTE *pbData, + ULONG *pulDataLen); + +/* 7.6.32 */ +ULONG DEVAPI SKF_DecryptUpdate( + HANDLE hKey, + BYTE *pbEncryptedData, + ULONG ulEncryptedLen, + BYTE *pbData, + ULONG *pulDataLen); + +/* 7.6.33 */ +ULONG DEVAPI SKF_DecryptFinal( + HANDLE hKey, + BYTE *pbDecryptedData, + ULONG *pulDecryptedDataLen); + +/* 7.6.34 */ +ULONG DEVAPI SKF_DigestInit( + DEVHANDLE hDev, + ULONG ulAlgID, + ECCPUBLICKEYBLOB *pPubKey, + BYTE *pbID, + ULONG ulIDLen, + HANDLE *phHash); + +/* 7.6.35 */ +ULONG DEVAPI SKF_Digest( + HANDLE hHash, + BYTE *pbData, + ULONG ulDataLen, + BYTE *pbHashData, + ULONG *pulHashLen); + +/* 7.6.36 */ +ULONG DEVAPI SKF_DigestUpdate( + HANDLE hHash, + BYTE *pbData, + ULONG ulDataLen); + +/* 7.6.37 */ +ULONG DEVAPI SKF_DigestFinal( + HANDLE hHash, + BYTE *pHashData, + ULONG *pulHashLen); + +/* 7.6.38 */ +ULONG DEVAPI SKF_MacInit( + HANDLE hKey, + BLOCKCIPHERPARAM *pMacParam, + HANDLE *phMac); + +/* 7.6.39 */ +ULONG DEVAPI SKF_Mac( + HANDLE hMac, + BYTE *pbData, + ULONG ulDataLen, + BYTE *pbMacData, + ULONG *pulMacLen); + +/* 7.6.40 */ +ULONG DEVAPI SKF_MacUpdate( + HANDLE hMac, + BYTE *pbData, + ULONG ulDataLen); + +/* 7.6.41 */ +ULONG DEVAPI SKF_MacFinal( + HANDLE hMac, + BYTE *pbMacData, + ULONG *pulMacDataLen); + +/* 7.6.42 */ +ULONG DEVAPI SKF_CloseHandle( + HANDLE hHandle); + + +#define SAR_OK 0x00000000 +#define SAR_FAIL 0x0A000001 +#define SAR_UNKNOWNERR 0x0A000002 +#define SAR_NOTSUPPORTYETERR 0x0A000003 +#define SAR_FILEERR 0x0A000004 +#define SAR_INVALIDHANDLEERR 0x0A000005 +#define SAR_INVALIDPARAMERR 0x0A000006 +#define SAR_READFILEERR 0x0A000007 +#define SAR_WRITEFILEERR 0x0A000008 +#define SAR_NAMELENERR 0x0A000009 +#define SAR_KEYUSAGEERR 0x0A00000A +#define SAR_MODULUSLENERR 0x0A00000B +#define SAR_NOTINITIALIZEERR 0x0A00000C +#define SAR_OBJERR 0x0A00000D +#define SAR_MEMORYERR 0x0A00000E +#define SAR_TIMEOUTERR 0x0A00000F +#define SAR_INDATALENERR 0x0A000010 +#define SAR_INDATAERR 0x0A000011 +#define SAR_GENRANDERR 0x0A000012 +#define SAR_HASHOBJERR 0x0A000013 +#define SAR_HASHERR 0x0A000014 +#define SAR_GENRSAKEYERR 0x0A000015 +#define SAR_RSAMODULUSLENERR 0x0A000016 +#define SAR_CSPIMPRTPUBKEYERR 0x0A000017 +#define SAR_RSAENCERR 0x0A000018 +#define SAR_RSADECERR 0x0A000019 +#define SAR_HASHNOTEQUALERR 0x0A00001A +#define SAR_KEYNOTFOUNTERR 0x0A00001B +#define SAR_CERTNOTFOUNTERR 0x0A00001C +#define SAR_NOTEXPORTERR 0x0A00001D +#define SAR_DECRYPTPADERR 0x0A00001E +#define SAR_MACLENERR 0x0A00001F +#define SAR_BUFFER_TOO_SMALL 0x0A000020 +#define SAR_KEYINFOTYPEERR 0x0A000021 +#define SAR_NOT_EVENTERR 0x0A000022 +#define SAR_DEVICE_REMOVED 0x0A000023 +#define SAR_PIN_INCORRECT 0x0A000024 +#define SAR_PIN_LOCKED 0x0A000025 +#define SAR_PIN_INVALID 0x0A000026 +#define SAR_PIN_LEN_RANGE 0x0A000027 +#define SAR_USER_ALREADY_LOGGED_IN 0x0A000028 +#define SAR_USER_PIN_NOT_INITIALIZED 0x0A000029 +#define SAR_USER_TYPE_INVALID 0x0A00002A +#define SAR_APPLICATION_NAME_INVALID 0x0A00002B +#define SAR_APPLICATION_EXISTS 0x0A00002C +#define SAR_USER_NOT_LOGGED_IN 0x0A00002D +#define SAR_APPLICATION_NOT_EXISTS 0x0A00002E +#define SAR_FILE_ALREADY_EXIST 0x0A00002F +#define SAR_NO_ROOM 0x0A000030 +#define SAR_FILE_NOT_EXIST 0x0A000031 +#define SAR_REACH_MAX_CONTAINER_COUNT 0x0A000032 + + +#ifdef __cplusplus +} +#endif +#endif diff --git a/src/skf/skf_dummy.c b/src/skf/skf_dummy.c new file mode 100644 index 00000000..4f6babb9 --- /dev/null +++ b/src/skf/skf_dummy.c @@ -0,0 +1,946 @@ +/* ==================================================================== + * Copyright (c) 2014 - 2017 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 +#include +#include +#include "skf.h" +#include "skf_ext.h" + +static char *hDeviceHandle = "hDeviceHandle"; +static char *hApplication = "hApplication"; +static char *hContainer = "hContainer"; +static char *hAgreementHandle = "AgreementHandle"; +static char *hKeyHandle = "KeyHandle"; +static char *hHashHandle = "HashHandle"; +static char *hMacHandle = "MacHandle"; + +static char *sm2cert_pemstr = "-----BEGIN CERTIFICATE-----\n" +"MIICHDCCAcOgAwIBAgIBIzAKBggqgRzPVQGDdTBRMQswCQYDVQQGEwJDTjELMAkG\n" +"A1UECAwCQkoxCzAJBgNVBAcMAkJKMQwwCgYDVQQKDANQS1UxCzAJBgNVBAsMAkNT\n" +"MQ0wCwYDVQQDDARHTUNBMB4XDTE3MDYxODA4NDMyN1oXDTE4MDYxODA4NDMyN1ow\n" +"UzELMAkGA1UEBhMCQ04xCzAJBgNVBAgMAkJKMQwwCgYDVQQKDANQS1UxDTALBgNV\n" +"BAsMBFNpZ24xGjAYBgNVBAMMEWNsaWVudEBwa3UuZWR1LmNuMFkwEwYHKoZIzj0C\n" +"AQYIKoEcz1UBgi0DQgAEzsZMPwnZFCD75xb8IT02XJCyOShTaEL8o/iQ6ksmG2Ce\n" +"MKSPGUcRtlSAU/1hQcFv4j59Csdr03lXiDRfdD72AKOBiTCBhjAJBgNVHRMEAjAA\n" +"MAsGA1UdDwQEAwIHgDAsBglghkgBhvhCAQ0EHxYdT3BlblNTTCBHZW5lcmF0ZWQg\n" +"Q2VydGlmaWNhdGUwHQYDVR0OBBYEFHbwURtb+xQrmxma7NnHe300//yuMB8GA1Ud\n" +"IwQYMBaAFMJhPpIHIHmrPQdEsiK3SaZ60qiPMAoGCCqBHM9VAYN1A0cAMEQCIBhO\n" +"uu7R3uMpVcy2r+t/OGYRs7JpQMnNwhGy9dwTm+h8AiA9y4o0fkRLQfuT3RPClX2o\n" +"B5vw09GcQVzsjKxhGgHLZw==\n" +"-----END CERTIFICATE-----\n"; + +static char *sm2key_pemstr = "-----BEGIN EC PRIVATE KEY-----\n" +"MHcCAQEEIAMbqE0bEEoGoicBgR0VISmbbuInWUBMQBtZBFVPD0+aoAoGCCqBHM9V\n" +"AYItoUQDQgAEzsZMPwnZFCD75xb8IT02XJCyOShTaEL8o/iQ6ksmG2CeMKSPGUcR\n" +"tlSAU/1hQcFv4j59Csdr03lXiDRfdD72AA==\n" +"-----END EC PRIVATE KEY-----\n"; + +#define devNameList "DummyDev1\0DummyDev2\0" +#define appNameList "App1\0App2\0" +#define fileNameList "File1\0File2\0" +#define containerNameList "Container1\0Container2\0" + + +ULONG DEVAPI SKF_WaitForDevEvent( + LPSTR szDevName, + ULONG *pulDevNameLen, + ULONG *pulEvent) +{ + return SAR_OK; +} + +ULONG DEVAPI SKF_CancelWaitForDevEvent( + void) +{ + return SAR_OK; +} + +ULONG DEVAPI SKF_EnumDev(BOOL bPresent, + LPSTR szNameList, + ULONG *pulSize) +{ + if (!pulSize) + return SAR_INVALIDPARAMERR; + *pulSize = sizeof(devNameList); + if (szNameList) + memcpy(szNameList, devNameList, sizeof(devNameList)); + return SAR_OK; +} + +ULONG DEVAPI SKF_ConnectDev( + LPSTR szName, + DEVHANDLE *phDev) +{ + if (!phDev) + return SAR_INVALIDPARAMERR; + *phDev = hDeviceHandle; + return SAR_OK; +} + +ULONG DEVAPI SKF_DisConnectDev( + DEVHANDLE hDev) +{ + return SAR_OK; +} + +ULONG DEVAPI SKF_GetDevState( + LPSTR szDevName, + ULONG *pulDevState) +{ + if (!pulDevState) + return SAR_INVALIDPARAMERR; + *pulDevState = SKF_DEV_STATE_PRESENT; + return SAR_OK; +} + +ULONG DEVAPI SKF_SetLabel( + DEVHANDLE hDev, + LPSTR szLabel) +{ + return SAR_OK; +} + +ULONG DEVAPI SKF_GetDevInfo(DEVHANDLE hDev, + DEVINFO *pDevInfo) +{ + DEVINFO devInfo; + + if (!pDevInfo) { + return SAR_INVALIDPARAMERR; + } + + memset(&devInfo, 0, sizeof(devInfo)); + devInfo.Version.major = 1; + devInfo.Version.minor = 0; + strcpy((char *)&devInfo.Manufacturer, "GmSSL Project (http://gmssl.org)"); + strcpy((char *)&devInfo.Issuer, "GmSSL Project (http://gmssl.org)"); + strcpy((char *)&devInfo.Label, "SKF Dummy Token"); + strcpy((char *)&devInfo.SerialNumber, "1"); + devInfo.HWVersion.major = 1; + devInfo.HWVersion.minor = 0; + devInfo.FirmwareVersion.major = 1; + devInfo.FirmwareVersion.minor = 0; + devInfo.AlgSymCap = SGD_SM1|SGD_SSF33|SGD_SM4|SGD_ECB|SGD_CBC|SGD_CFB|SGD_OFB; + devInfo.AlgAsymCap = SGD_RSA|SGD_SM2|SGD_PK_SIGN|SGD_PK_ENC; + devInfo.AlgHashCap = SGD_SM3|SGD_SHA1|SGD_SHA256; + devInfo.DevAuthAlgId = SGD_SM4_ECB; + devInfo.TotalSpace = 64*1024; + devInfo.FreeSpace = 32*1024; + devInfo.MaxECCBufferSize = 100; + devInfo.MaxBufferSize = 128; + + memcpy(pDevInfo, &devInfo, sizeof(DEVINFO)); + return SAR_OK; +} + +ULONG DEVAPI SKF_LockDev( + DEVHANDLE hDev, + ULONG ulTimeOut) +{ + return SAR_OK; +} + +ULONG DEVAPI SKF_UnlockDev( + DEVHANDLE hDev) +{ + return SAR_OK; +} + +ULONG DEVAPI SKF_Transmit( + DEVHANDLE hDev, + BYTE *pbCommand, + ULONG ulCommandLen, + BYTE *pbData, + ULONG *pulDataLen) +{ + if (!pulDataLen) + return SAR_INVALIDPARAMERR; + *pulDataLen = ulCommandLen; + return SAR_OK; +} + +ULONG DEVAPI SKF_ChangeDevAuthKey( + DEVHANDLE hDev, + BYTE *pbKeyValue, + ULONG ulKeyLen) +{ + return SAR_OK; +} + +ULONG DEVAPI SKF_DevAuth( + DEVHANDLE hDev, + BYTE *pbAuthData, + ULONG ulLen) +{ + return SAR_OK; +} + +ULONG DEVAPI SKF_ChangePIN( + HAPPLICATION hApplication, + ULONG ulPINType, + LPSTR szOldPin, + LPSTR szNewPin, + ULONG *pulRetryCount) +{ + if (!pulRetryCount) + return SAR_INVALIDPARAMERR; + *pulRetryCount = 100; + return SAR_OK; +} + +LONG DEVAPI SKF_GetPINInfo( + HAPPLICATION hApplication, + ULONG ulPINType, + ULONG *pulMaxRetryCount, + ULONG *pulRemainRetryCount, + BOOL *pbDefaultPin) +{ + if (!pulMaxRetryCount || !pulRemainRetryCount || !pbDefaultPin) + return SAR_INVALIDPARAMERR; + *pulMaxRetryCount = 100; + *pulRemainRetryCount = 100; + *pbDefaultPin = TRUE; + return SAR_OK; +} + +ULONG DEVAPI SKF_VerifyPIN( + HAPPLICATION hApplication, + ULONG ulPINType, + LPSTR szPIN, + ULONG *pulRetryCount) +{ + if (!pulRetryCount) + return SAR_INVALIDPARAMERR; + *pulRetryCount = 100; + return SAR_OK; +} + +ULONG DEVAPI SKF_UnblockPIN( + HAPPLICATION hApplication, + LPSTR szAdminPIN, + LPSTR szNewUserPIN, + ULONG *pulRetryCount) +{ + if (!pulRetryCount) + return SAR_INVALIDPARAMERR; + *pulRetryCount = 100; + return SAR_OK; +} + +ULONG DEVAPI SKF_ClearSecureState( + HAPPLICATION hApplication) +{ + return SAR_OK; +} + +ULONG DEVAPI SKF_CreateApplication( + DEVHANDLE hDev, + LPSTR szAppName, + LPSTR szAdminPin, + DWORD dwAdminPinRetryCount, + LPSTR szUserPin, + DWORD dwUserPinRetryCount, + DWORD dwCreateFileRights, + HAPPLICATION *phApplication) +{ + if (!phApplication) + return SAR_INVALIDPARAMERR; + *phApplication = hApplication; + return SAR_OK; +} + +ULONG DEVAPI SKF_EnumApplication(DEVHANDLE hDev, + LPSTR szAppName, + ULONG *pulSize) +{ + if (!pulSize) + return SAR_INVALIDPARAMERR; + *pulSize = sizeof(appNameList); + if (szAppName) + memcpy(szAppName, appNameList, sizeof(appNameList)); + return SAR_OK; +} + +ULONG DEVAPI SKF_DeleteApplication( + DEVHANDLE hDev, + LPSTR szAppName) +{ + return SAR_OK; +} + +ULONG DEVAPI SKF_OpenApplication( + DEVHANDLE hDev, + LPSTR szAppName, + HAPPLICATION *phApplication) +{ + if (!phApplication) + return SAR_INVALIDPARAMERR; + *phApplication = hApplication; + return SAR_OK; +} + +ULONG DEVAPI SKF_CloseApplication( + HAPPLICATION hApplication) +{ + return SAR_OK; +} + +ULONG DEVAPI SKF_CreateFile( + HAPPLICATION hApplication, + LPSTR szFileName, + ULONG ulFileSize, + ULONG ulReadRights, + ULONG ulWriteRights) +{ + return SAR_OK; +} + +ULONG DEVAPI SKF_DeleteFile( + HAPPLICATION hApplication, + LPSTR szFileName) +{ + return SAR_OK; +} + +ULONG DEVAPI SKF_EnumFiles( + HAPPLICATION hApplication, + LPSTR szFileList, + ULONG *pulSize) +{ + if (!pulSize) + return SAR_INVALIDPARAMERR; + *pulSize = sizeof(fileNameList); + if (szFileList) + memcpy(szFileList, fileNameList, sizeof(fileNameList)); + return SAR_OK; +} + +ULONG DEVAPI SKF_GetFileInfo( + HAPPLICATION hApplication, + LPSTR szFileName, + FILEATTRIBUTE *pFileInfo) +{ + if (!pFileInfo) + return SAR_INVALIDPARAMERR; + strcpy((char *)pFileInfo->FileName, "FileName"); + pFileInfo->FileSize = 1024; + pFileInfo->ReadRights = SECURE_ANYONE_ACCOUNT; + return SAR_OK; +} + +ULONG DEVAPI SKF_ReadFile( + HAPPLICATION hApplication, + LPSTR szFileName, + ULONG ulOffset, + ULONG ulSize, + BYTE *pbOutData, + ULONG *pulOutLen) +{ + if (!pbOutData || !pulOutLen) + return SAR_INVALIDPARAMERR; + memset(pbOutData, 'x', ulSize); + *pulOutLen = ulSize; + return SAR_OK; +} + +ULONG DEVAPI SKF_WriteFile( + HAPPLICATION hApplication, + LPSTR szFileName, + ULONG ulOffset, + BYTE *pbData, + ULONG ulSize) +{ + return SAR_OK; +} + +ULONG DEVAPI SKF_CreateContainer( + HAPPLICATION hApplication, + LPSTR szContainerName, + HCONTAINER *phContainer) +{ + if (!phContainer) + return SAR_INVALIDPARAMERR; + *phContainer = hContainer; + return SAR_OK; +} + +ULONG DEVAPI SKF_DeleteContainer( + HAPPLICATION hApplication, + LPSTR szContainerName) +{ + return SAR_OK; +} + +ULONG DEVAPI SKF_EnumContainer( + HAPPLICATION hApplication, + LPSTR szContainerName, + ULONG *pulSize) +{ + if (!pulSize) + return SAR_INVALIDPARAMERR; + *pulSize = sizeof(containerNameList); + if (szContainerName) + memcpy(szContainerName, containerNameList, sizeof(containerNameList)); + return SAR_OK; +} + +ULONG DEVAPI SKF_OpenContainer( + HAPPLICATION hApplication, + LPSTR szContainerName, + HCONTAINER *phContainer) +{ + if (!phContainer) + return SAR_INVALIDPARAMERR; + *phContainer = hContainer; + return SAR_OK; +} + +ULONG DEVAPI SKF_CloseContainer( + HCONTAINER hContainer) +{ + return SAR_OK; +} + +ULONG DEVAPI SKF_GetContainerType( + HCONTAINER hContainer, + ULONG *pulContainerType) +{ + if (!pulContainerType) + return SAR_INVALIDPARAMERR; + *pulContainerType = SKF_CONTAINER_TYPE_ECC; + return SAR_OK; +} + +ULONG DEVAPI SKF_ImportCertificate( + HCONTAINER hContainer, + BOOL bExportSignKey, + BYTE *pbCert, + ULONG ulCertLen) +{ + return SAR_OK; +} + +ULONG DEVAPI SKF_ExportCertificate( + HCONTAINER hContainer, + BOOL bSignFlag, + BYTE *pbCert, + ULONG *pulCertLen) +{ + *pulCertLen = strlen(sm2cert_pemstr); + memcpy(pbCert, sm2cert_pemstr, *pulCertLen); + + return SAR_OK; +} + +ULONG DEVAPI SKF_ExportPublicKey( + HCONTAINER hContainer, + BOOL bSignFlag, + BYTE *pbBlob, + ULONG *pulBlobLen) +{ + if (!pulBlobLen) + return SAR_INVALIDPARAMERR; + *pulBlobLen = 2048/8; + return SAR_OK; +} + +ULONG DEVAPI SKF_GenRandom( + DEVHANDLE hDev, + BYTE *pbRandom, + ULONG ulRandomLen) +{ + return SAR_OK; +} + +ULONG DEVAPI SKF_GenExtRSAKey( + DEVHANDLE hDev, + ULONG ulBitsLen, + RSAPRIVATEKEYBLOB *pBlob) +{ + if (!pBlob) + return SAR_INVALIDPARAMERR; + return SAR_OK; +} + +ULONG DEVAPI SKF_GenRSAKeyPair( + HCONTAINER hContainer, + ULONG ulBitsLen, + RSAPUBLICKEYBLOB *pBlob) +{ + if (!pBlob) + return SAR_INVALIDPARAMERR; + return SAR_OK; +} + +ULONG DEVAPI SKF_ImportRSAKeyPair( + HCONTAINER hContainer, + ULONG ulSymAlgId, + BYTE *pbWrappedKey, + ULONG ulWrappedKeyLen, + BYTE *pbEncryptedData, + ULONG ulEncryptedDataLen) +{ + return SAR_OK; +} + +ULONG DEVAPI SKF_RSASignData( + HCONTAINER hContainer, + BYTE *pbData, + ULONG ulDataLen, + BYTE *pbSignature, + ULONG *pulSignLen) +{ + if (!pulSignLen) + return SAR_INVALIDPARAMERR; + *pulSignLen = 2048/8; + return SAR_OK; +} + +ULONG DEVAPI SKF_RSAVerify( + DEVHANDLE hDev, + RSAPUBLICKEYBLOB *pRSAPubKeyBlob, + BYTE *pbData, + ULONG ulDataLen, + BYTE *pbSignature, + ULONG ulSignLen) +{ + return SAR_OK; +} + +ULONG DEVAPI SKF_RSAExportSessionKey( + HCONTAINER hContainer, + ULONG ulAlgId, + RSAPUBLICKEYBLOB *pPubKey, + BYTE *pbData, + ULONG *pulDataLen, + HANDLE *phSessionKey) +{ + if (!pulDataLen || !phSessionKey) + return SAR_INVALIDPARAMERR; + *pulDataLen = 2048/8; + *phSessionKey = hKeyHandle; + return SAR_OK; +} + +ULONG DEVAPI SKF_ExtRSAPubKeyOperation( + DEVHANDLE hDev, + RSAPUBLICKEYBLOB *pRSAPubKeyBlob, + BYTE *pbInput, + ULONG ulInputLen, + BYTE *pbOutput, + ULONG *pulOutputLen) +{ + if (!pulOutputLen) + return SAR_INVALIDPARAMERR; + *pulOutputLen = 2048/8; + return SAR_OK; +} + +ULONG DEVAPI SKF_ExtRSAPriKeyOperation( + DEVHANDLE hDev, + RSAPRIVATEKEYBLOB *pRSAPriKeyBlob, + BYTE *pbInput, + ULONG ulInputLen, + BYTE *pbOutput, + ULONG *pulOutputLen) +{ + if (!pulOutputLen) + return SAR_INVALIDPARAMERR; + *pulOutputLen = 2048/8; + return SAR_OK; +} + +ULONG DEVAPI SKF_GenECCKeyPair( + HCONTAINER hContainer, + ULONG ulAlgId, + ECCPUBLICKEYBLOB *pBlob) +{ + if (!pBlob) + return SAR_INVALIDPARAMERR; + return SAR_OK; +} + +ULONG DEVAPI SKF_ImportECCKeyPair( + HCONTAINER hContainer, + ENVELOPEDKEYBLOB *pEnvelopedKeyBlob) +{ + return SAR_OK; +} + +ULONG DEVAPI SKF_ECCSignData( + HCONTAINER hContainer, + BYTE *pbDigest, + ULONG ulDigestLen, + ECCSIGNATUREBLOB *pSignature) +{ + return SAR_OK; +} + +ULONG DEVAPI SKF_ECCVerify( + DEVHANDLE hDev, + ECCPUBLICKEYBLOB *pECCPubKeyBlob, + BYTE *pbData, + ULONG ulDataLen, + ECCSIGNATUREBLOB *pSignature) +{ + return SAR_OK; +} + +ULONG DEVAPI SKF_ECCExportSessionKey( + HCONTAINER hContainer, + ULONG ulAlgId, + ECCPUBLICKEYBLOB *pPubKey, + ECCCIPHERBLOB *pData, + HANDLE *phSessionKey) +{ + if (!phSessionKey) + return SAR_INVALIDPARAMERR; + *phSessionKey = hKeyHandle; + return SAR_OK; +} + +ULONG DEVAPI SKF_ExtECCEncrypt( + DEVHANDLE hDev, + ECCPUBLICKEYBLOB *pECCPubKeyBlob, + BYTE *pbPlainText, + ULONG ulPlainTextLen, + ECCCIPHERBLOB *pCipherText) +{ + return SAR_OK; +} + +ULONG DEVAPI SKF_ExtECCDecrypt( + DEVHANDLE hDev, + ECCPRIVATEKEYBLOB *pECCPriKeyBlob, + ECCCIPHERBLOB *pCipherText, + BYTE *pbPlainText, + ULONG *pulPlainTextLen) +{ + if (!pulPlainTextLen) + return SAR_INVALIDPARAMERR; + *pulPlainTextLen = 1; + return SAR_OK; +} + +ULONG DEVAPI SKF_ExtECCSign( + DEVHANDLE hDev, + ECCPRIVATEKEYBLOB *pECCPriKeyBlob, + BYTE *pbData, + ULONG ulDataLen, + ECCSIGNATUREBLOB *pSignature) +{ + if (!pSignature) + return SAR_INVALIDPARAMERR; + return SAR_OK; +} + +ULONG DEVAPI SKF_ExtECCVerify( + DEVHANDLE hDev, + ECCPUBLICKEYBLOB *pECCPubKeyBlob, + BYTE *pbData, + ULONG ulDataLen, + ECCSIGNATUREBLOB *pSignature) +{ + return SAR_OK; +} + +ULONG DEVAPI SKF_GenerateAgreementDataWithECC( + HCONTAINER hContainer, + ULONG ulAlgId, + ECCPUBLICKEYBLOB *pTempECCPubKeyBlob, + BYTE *pbID, + ULONG ulIDLen, + HANDLE *phAgreementHandle) +{ + if (!phAgreementHandle) + return SAR_INVALIDPARAMERR; + *phAgreementHandle = hAgreementHandle; + return SAR_OK; +} + +ULONG DEVAPI SKF_GenerateAgreementDataAndKeyWithECC( + HANDLE hContainer, + ULONG ulAlgId, + ECCPUBLICKEYBLOB *pSponsorECCPubKeyBlob, + ECCPUBLICKEYBLOB *pSponsorTempECCPubKeyBlob, + ECCPUBLICKEYBLOB *pTempECCPubKeyBlob, + BYTE *pbID, + ULONG ulIDLen, + BYTE *pbSponsorID, + ULONG ulSponsorIDLen, + HANDLE *phKeyHandle) +{ + if (!phKeyHandle) + return SAR_INVALIDPARAMERR; + *phKeyHandle = hKeyHandle; + return SAR_OK; +} + +ULONG DEVAPI SKF_GenerateKeyWithECC( + HANDLE hAgreementHandle, + ECCPUBLICKEYBLOB *pECCPubKeyBlob, + ECCPUBLICKEYBLOB *pTempECCPubKeyBlob, + BYTE *pbID, + ULONG ulIDLen, + HANDLE *phKeyHandle) +{ + if (!phKeyHandle) + return SAR_INVALIDPARAMERR; + *phKeyHandle = hKeyHandle; + return SAR_OK; +} + +ULONG DEVAPI SKF_ImportSessionKey( + HCONTAINER hContainer, + ULONG ulAlgId, + BYTE *pbWrapedData, + ULONG ulWrapedLen, + HANDLE *phKey) +{ + if (!phKey) + return SAR_INVALIDPARAMERR; + *phKey = hKeyHandle; + return SAR_OK; +} + +ULONG DEVAPI SKF_SetSymmKey( + DEVHANDLE hDev, + BYTE *pbKey, + ULONG ulAlgID, + HANDLE *phKey) +{ + if (!phKey) + return SAR_INVALIDPARAMERR; + *phKey = hKeyHandle; + return SAR_OK; +} + +ULONG DEVAPI SKF_EncryptInit( + HANDLE hKey, + BLOCKCIPHERPARAM EncryptParam) +{ + return SAR_OK; +} + +ULONG DEVAPI SKF_Encrypt( + HANDLE hKey, + BYTE *pbData, + ULONG ulDataLen, + BYTE *pbEncryptedData, + ULONG *pulEncryptedLen) +{ + if (!pulEncryptedLen) + return SAR_INVALIDPARAMERR; + *pulEncryptedLen = ulDataLen; + return SAR_OK; +} + +ULONG DEVAPI SKF_EncryptUpdate( + HANDLE hKey, + BYTE *pbData, + ULONG ulDataLen, + BYTE *pbEncryptedData, + ULONG *pulEncryptedLen) +{ + if (!pulEncryptedLen) + return SAR_INVALIDPARAMERR; + *pulEncryptedLen = ulDataLen; + return SAR_OK; +} + +ULONG DEVAPI SKF_EncryptFinal( + HANDLE hKey, + BYTE *pbEncryptedData, + ULONG *pulEncryptedDataLen) +{ + if (!pulEncryptedDataLen) + return SAR_INVALIDPARAMERR; + *pulEncryptedDataLen = 0; + return SAR_OK; +} + +ULONG DEVAPI SKF_DecryptInit( + HANDLE hKey, + BLOCKCIPHERPARAM DecryptParam) +{ + return SAR_OK; +} + +ULONG DEVAPI SKF_Decrypt( + HANDLE hKey, + BYTE *pbEncryptedData, + ULONG ulEncryptedLen, + BYTE *pbData, + ULONG *pulDataLen) +{ + if (!pulDataLen) + return SAR_INVALIDPARAMERR; + *pulDataLen = ulEncryptedLen; + return SAR_OK; +} + +ULONG DEVAPI SKF_DecryptUpdate( + HANDLE hKey, + BYTE *pbEncryptedData, + ULONG ulEncryptedLen, + BYTE *pbData, + ULONG *pulDataLen) +{ + if (!pulDataLen) + return SAR_INVALIDPARAMERR; + *pulDataLen = ulEncryptedLen; + return SAR_OK; +} + +ULONG DEVAPI SKF_DecryptFinal( + HANDLE hKey, + BYTE *pbDecryptedData, + ULONG *pulDecryptedDataLen) +{ + if (!pulDecryptedDataLen) + return SAR_INVALIDPARAMERR; + *pulDecryptedDataLen = 0; + return SAR_OK; +} + +ULONG DEVAPI SKF_DigestInit( + DEVHANDLE hDev, + ULONG ulAlgID, + ECCPUBLICKEYBLOB *pPubKey, + BYTE *pbID, + ULONG ulIDLen, + HANDLE *phHash) +{ + if (!phHash) + return SAR_INVALIDPARAMERR; + *phHash = hHashHandle; + return SAR_OK; +} + +ULONG DEVAPI SKF_Digest( + HANDLE hHash, + BYTE *pbData, + ULONG ulDataLen, + BYTE *pbHashData, + ULONG *pulHashLen) +{ + if (!pulHashLen) + return SAR_INVALIDPARAMERR; + *pulHashLen = 32; + return SAR_OK; +} + +ULONG DEVAPI SKF_DigestUpdate( + HANDLE hHash, + BYTE *pbData, + ULONG ulDataLen) +{ + return SAR_OK; +} + +ULONG DEVAPI SKF_DigestFinal( + HANDLE hHash, + BYTE *pbHashData, + ULONG *pulHashLen) +{ + if (!pulHashLen) + return SAR_INVALIDPARAMERR; + *pulHashLen = 32; + return SAR_OK; +} + +ULONG DEVAPI SKF_MacInit( + HANDLE hKey, + BLOCKCIPHERPARAM *pMacParam, + HANDLE *phMac) +{ + if (!phMac) + return SAR_INVALIDPARAMERR; + *phMac = hMacHandle; + return SAR_OK; +} + +ULONG DEVAPI SKF_Mac( + HANDLE hMac, + BYTE *pbData, + ULONG ulDataLen, + BYTE *pbMacData, + ULONG *pulMacLen) +{ + if (!pulMacLen) + return SAR_INVALIDPARAMERR; + *pulMacLen = 16; + return SAR_OK; +} + +ULONG DEVAPI SKF_MacUpdate( + HANDLE hMac, + BYTE *pbData, + ULONG ulDataLen) +{ + return SAR_OK; +} + +ULONG DEVAPI SKF_MacFinal( + HANDLE hMac, + BYTE *pbMacData, + ULONG *pulMacDataLen) +{ + if (!pulMacDataLen) + return SAR_INVALIDPARAMERR; + *pulMacDataLen = 16; + return SAR_OK; +} + +ULONG DEVAPI SKF_CloseHandle( + HANDLE hHandle) +{ + return SAR_OK; +} diff --git a/src/skf/skf_ext.c b/src/skf/skf_ext.c new file mode 100644 index 00000000..ad42e380 --- /dev/null +++ b/src/skf/skf_ext.c @@ -0,0 +1,607 @@ +/* ==================================================================== + * Copyright (c) 2014 - 2019 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 +#include +#include +#include +#include "skf_int.h" +#include "skf_ext.h" +#include "skf.h" + + +#define SKFerr(f,e) + +ULONG DEVAPI SKF_NewECCCipher(ULONG ulCipherLen, ECCCIPHERBLOB **cipherBlob) +{ + ECCCIPHERBLOB *ret = NULL; + + if (!(ret = malloc(sizeof(ECCCIPHERBLOB) - 1 + ulCipherLen))) { + SKFerr(SKF_F_SKF_NEWECCCIPHER, ERR_R_MALLOC_FAILURE); + return SAR_MEMORYERR; + } + + ret->CipherLen = ulCipherLen; + *cipherBlob = ret; + return SAR_OK; +} + +ULONG DEVAPI SKF_NewEnvelopedKey(ULONG ulCipherLen, ENVELOPEDKEYBLOB **envelopedKeyBlob) +{ + ENVELOPEDKEYBLOB *ret = NULL; + + if (!(ret = malloc(sizeof(ENVELOPEDKEYBLOB) - 1 + ulCipherLen))) { + SKFerr(SKF_F_SKF_NEWENVELOPEDKEY, ERR_R_MALLOC_FAILURE); + return SAR_MEMORYERR; + } + + ret->ECCCipherBlob.CipherLen = ulCipherLen; + *envelopedKeyBlob = ret; + return SAR_OK; +} + +ULONG DEVAPI SKF_OpenDevice(LPSTR devName, BYTE authKey[16], DEVINFO *devInfo, DEVHANDLE *phDev) +{ + ULONG rv; + DEVHANDLE hDev = NULL; + HANDLE hKey = NULL; + ULONG ulTimeOut = 0xffffffff; + BYTE authRand[16] = {0}; + BYTE authData[16] = {0}; + ULONG authRandLen = SKF_AUTHRAND_LENGTH; + ULONG authDataLen = sizeof(authData); + BLOCKCIPHERPARAM encParam = {{0}, 0, 0, 0}; + + if ((rv = SKF_ConnectDev((LPSTR)devName, &hDev)) != SAR_OK + || (rv = SKF_GetDevInfo(hDev, devInfo)) != SAR_OK + || (rv = SKF_LockDev(hDev, ulTimeOut)) != SAR_OK + || (rv = SKF_GenRandom(hDev, authRand, authRandLen)) != SAR_OK + || (rv = SKF_SetSymmKey(hDev, authKey, devInfo->DevAuthAlgId, &hKey)) != SAR_OK + || (rv = SKF_EncryptInit(hKey, encParam)) != SAR_OK + || (rv = SKF_Encrypt(hKey, authRand, sizeof(authRand), authData, &authDataLen)) != SAR_OK + || (rv =SKF_DevAuth(hDev, authData, authDataLen)) != SAR_OK) { + SKFerr(SKF_F_SKF_OPENDEVICE, ERR_R_SKF_LIB); + goto end; + } + *phDev = hDev; + hDev = NULL; + +end: + //OPENSSL_cleanse(authRand, sizeof(authRand)); + //OPENSSL_cleanse(authData, sizeof(authData)); + if (hKey && (rv = SKF_CloseHandle(hKey)) != SAR_OK) { + SKFerr(SKF_F_SKF_OPENDEVICE, ERR_R_SKF_LIB); + } + if (hDev && (rv = SKF_DisConnectDev(hDev)) != SAR_OK) { + SKFerr(SKF_F_SKF_OPENDEVICE, ERR_R_SKF_LIB); + } + return rv; +} + +ULONG DEVAPI SKF_CloseDevice(DEVHANDLE hDev) +{ + ULONG rv; + if ((rv = SKF_UnlockDev(hDev)) != SAR_OK) { + SKFerr(SKF_F_SKF_CLOSEDEVICE, ERR_R_SKF_LIB); + } + if ((rv = SKF_DisConnectDev(hDev)) != SAR_OK) { + SKFerr(SKF_F_SKF_CLOSEDEVICE, ERR_R_SKF_LIB); + } + return rv; +} + +#if 0 +ULONG DEVAPI SKF_ImportECCPrivateKey(DEVHANDLE hDev, HCONTAINER hContainer, + EC_KEY *ec_key, ULONG symmAlgId) +{ + int ret = 0; + ULONG rv; + ULONG containerType; + ECCPRIVATEKEYBLOB eccPriKeyBlob; + BYTE symmKey[16]; + HANDLE hSymmKey = NULL; + BLOCKCIPHERPARAM encParam; + ULONG encedPriKeyLen; + SKF_PUBLICKEYBLOB signPubKeyBlob; + ULONG signPubKeyLen = sizeof(signPubKeyBlob); + ENVELOPEDKEYBLOB envelopedKeyBlob; + + /* check container type */ + if ((rv = SKF_GetContainerType(hContainer, &containerType)) != SAR_OK) { + SKFerr(SKF_F_SKF_IMPORTECCPRIVATEKEY, ERR_R_SKF_LIB); + return rv; + } + if (containerType != SKF_CONTAINER_TYPE_ECC) { + SKFerr(SKF_F_SKF_IMPORTECCPRIVATEKEY, SKF_R_CONTAINER_TYPE_NOT_MATCH); + return SAR_FAIL; + } + + /* get private key and public key */ + if (!EC_KEY_get_ECCPRIVATEKEYBLOB(ec_key, &eccPriKeyBlob) + || !EC_KEY_get_ECCPUBLICKEYBLOB(ec_key, &(envelopedKeyBlob.PubKey))) { + SKFerr(SKF_F_SKF_IMPORTECCPRIVATEKEY, ERR_R_GMAPI_LIB); + rv = SAR_FAIL; + goto end; + } + + /* set Version, ulSymmAlgID, ulBits */ + envelopedKeyBlob.Version = SKF_ENVELOPEDKEYBLOB_VERSION; + envelopedKeyBlob.ulSymmAlgID = symmAlgId; + envelopedKeyBlob.ulBits = eccPriKeyBlob.BitLen; + + /* encrypt private key with random generated symmkey */ + if (!rand_bytes(symmKey, sizeof(symmKey))) { + SKFerr(SKF_F_SKF_IMPORTECCPRIVATEKEY, ERR_R_SKF_LIB); + rv = SAR_FAIL; + goto end; + } + if ((rv = SKF_SetSymmKey(hDev, symmKey, symmAlgId, &hSymmKey)) != SAR_OK) { + SKFerr(SKF_F_SKF_IMPORTECCPRIVATEKEY, ERR_R_SKF_LIB); + goto end; + } + encParam.IVLen = 0; + encParam.PaddingType = SKF_NO_PADDING; + if ((rv = SKF_EncryptInit(hSymmKey, encParam)) != SAR_OK) { + SKFerr(SKF_F_SKF_IMPORTECCPRIVATEKEY, ERR_R_SKF_LIB); + goto end; + } + encedPriKeyLen = sizeof(envelopedKeyBlob.cbEncryptedPriKey); + if ((rv = SKF_Encrypt(hSymmKey, + eccPriKeyBlob.PrivateKey, sizeof(eccPriKeyBlob.PrivateKey), + (BYTE *)&(envelopedKeyBlob.cbEncryptedPriKey), &encedPriKeyLen)) != SAR_OK) { + SKFerr(SKF_F_SKF_IMPORTECCPRIVATEKEY, ERR_R_SKF_LIB); + goto end; + } + if (encedPriKeyLen != sizeof(eccPriKeyBlob.PrivateKey)) { + SKFerr(SKF_F_SKF_IMPORTECCPRIVATEKEY, ERR_R_SKF_LIB); + rv = SAR_FAIL; + goto end; + } + + /* encrypt symmKey */ + if ((rv = SKF_ExportPublicKey(hContainer, TRUE, + (BYTE *)&signPubKeyBlob, &signPubKeyLen)) != SAR_OK) { + SKFerr(SKF_F_SKF_IMPORTECCPRIVATEKEY, ERR_R_SKF_LIB); + goto end; + } + if (signPubKeyLen != sizeof(ECCPUBLICKEYBLOB)) { + SKFerr(SKF_F_SKF_IMPORTECCPRIVATEKEY, ERR_R_SKF_LIB); + rv = SAR_FAIL; + goto end; + } + if ((rv = SKF_ExtECCEncrypt(hDev, (ECCPUBLICKEYBLOB *)&signPubKeyBlob, + symmKey, sizeof(symmKey), &(envelopedKeyBlob.ECCCipherBlob))) != SAR_OK) { + SKFerr(SKF_F_SKF_IMPORTECCPRIVATEKEY, ERR_R_SKF_LIB); + goto end; + } + + ret = 1; +end: + OPENSSL_cleanse(&eccPriKeyBlob, sizeof(eccPriKeyBlob)); + OPENSSL_cleanse(symmKey, sizeof(symmKey)); + if (hSymmKey && SKF_CloseHandle(hSymmKey) != SAR_OK) { + SKFerr(SKF_F_SKF_IMPORTECCPRIVATEKEY, ERR_R_SKF_LIB); + ret = 0; + } + return ret; +} + +ULONG DEVAPI SKF_ImportRSAPrivateKey(DEVHANDLE hDev, HCONTAINER hContainer, + RSA *rsa, ULONG symmAlgId) +{ + ULONG rv; + ULONG containerType; + RSAPRIVATEKEYBLOB rsaPriKeyBlob; + unsigned char symmKey[16]; + RSAPUBLICKEYBLOB rsaPubKeyBlob; + ULONG rsaPubKeyLen = sizeof(rsaPubKeyBlob); + BYTE wrappedKey[MAX_RSA_MODULUS_LEN]; + ULONG wrappedKeyLen = sizeof(wrappedKey); + EVP_CIPHER_CTX *cctx = NULL; + unsigned char *p; + int len; + BYTE encedPriKey[sizeof(RSAPRIVATEKEYBLOB) + 16*2]; + ULONG encedPriKeyLen = sizeof(encedPriKey); + + + if ((rv = SKF_GetContainerType(hContainer, &containerType)) != SAR_OK) { + SKFerr(SKF_F_SKF_IMPORTRSAPRIVATEKEY, ERR_R_SKF_LIB); + return rv; + } + if (containerType != SKF_CONTAINER_TYPE_RSA) { + SKFerr(SKF_F_SKF_IMPORTRSAPRIVATEKEY, ERR_R_SKF_LIB); + return SAR_FAIL; + } + + if (!RSA_get_RSAPRIVATEKEYBLOB(rsa, &rsaPriKeyBlob)) { + SKFerr(SKF_F_SKF_IMPORTRSAPRIVATEKEY, ERR_R_SKF_LIB); + goto end; + } + + /* generate symmkey */ + /* wrap symmkey with signing public key */ + if (!rand_bytes(symmKey, sizeof(symmKey))) { + SKFerr(SKF_F_SKF_IMPORTRSAPRIVATEKEY, ERR_R_SKF_LIB); + goto end; + } + if ((rv = SKF_ExportPublicKey(hContainer, SGD_TRUE, + (BYTE *)&rsaPubKeyBlob, &rsaPubKeyLen)) != SAR_OK) { + SKFerr(SKF_F_SKF_IMPORTRSAPRIVATEKEY, ERR_R_SKF_LIB); + goto end; + } + if (!(rsa = RSA_new_from_RSAPUBLICKEYBLOB(&rsaPubKeyBlob))) { + SKFerr(SKF_F_SKF_IMPORTRSAPRIVATEKEY, ERR_R_SKF_LIB); + goto end; + } + if ((len = RSA_public_encrypt(sizeof(symmKey), symmKey, wrappedKey, + rsa, RSA_PKCS1_PADDING)) != rsaPriKeyBlob.BitLen / 8) { + goto end; + } + wrappedKeyLen = (ULONG)len; + + /* encrypt private key with symmkey in ECB mode */ + if (!(cctx = EVP_CIPHER_CTX_new())) { + SKFerr(SKF_F_SKF_IMPORTRSAPRIVATEKEY, ERR_R_MALLOC_FAILURE); + goto end; + } + if (!EVP_EncryptInit_ex(cctx, EVP_sms4_ecb(), NULL, symmKey, NULL)) { + SKFerr(SKF_F_SKF_IMPORTRSAPRIVATEKEY, ERR_R_EVP_LIB); + goto end; + } + p = encedPriKey; + if (!EVP_EncryptUpdate(cctx, p, &len, (unsigned char *)&rsaPriKeyBlob, + sizeof(RSAPRIVATEKEYBLOB))) { + SKFerr(SKF_F_SKF_IMPORTRSAPRIVATEKEY, ERR_R_EVP_LIB); + goto end; + } + p += len; + if (!EVP_EncryptFinal_ex(cctx, p, &len)) { + SKFerr(SKF_F_SKF_IMPORTRSAPRIVATEKEY, ERR_R_EVP_LIB); + goto end; + } + p += len; + encedPriKeyLen = p - encedPriKey; + + /* import */ + if ((rv = SKF_ImportRSAKeyPair(hContainer, symmAlgId, wrappedKey, wrappedKeyLen, + encedPriKey, encedPriKeyLen)) != SAR_OK) { + SKFerr(SKF_F_SKF_IMPORTRSAPRIVATEKEY, ERR_R_SKF_LIB); + goto end; + } + +end: + OPENSSL_cleanse(&rsaPriKeyBlob, sizeof(rsaPriKeyBlob)); + OPENSSL_cleanse(symmKey, sizeof(symmKey)); + OPENSSL_cleanse(wrappedKey, sizeof(wrappedKey)); + EVP_CIPHER_CTX_free(cctx); + return rv; +} + +ULONG DEVAPI SKF_ImportPrivateKey(DEVHANDLE hDev, HCONTAINER hContainer, + EVP_PKEY *pkey, ULONG symmAlgId) +{ + ULONG rv; + switch (EVP_PKEY_id(pkey)) { + case EVP_PKEY_EC: + if ((rv = SKF_ImportECCPrivateKey(hDev, hContainer, + EVP_PKEY_get0_EC_KEY(pkey), symmAlgId)) != SAR_OK) { + SKFerr(SKF_F_SKF_IMPORTPRIVATEKEY, ERR_R_SKF_LIB); + return rv; + } + break; + case EVP_PKEY_RSA: + if ((rv = SKF_ImportRSAPrivateKey(hDev, hContainer, + EVP_PKEY_get0_RSA(pkey), symmAlgId)) != SAR_OK) { + SKFerr(SKF_F_SKF_IMPORTPRIVATEKEY, ERR_R_SKF_LIB); + return rv; + } + break; + default: + SKFerr(SKF_F_SKF_IMPORTPRIVATEKEY, + SKF_R_UNSUPPORTED_PRIVATE_KEY_TYPE); + return SAR_FAIL; + } + return SAR_OK; +} + +ULONG DEVAPI SKF_ExportECCPublicKey(HCONTAINER hContainer, BOOL bSign, EC_KEY **ec_key) +{ + ULONG rv; + ULONG containerType; + BYTE pubKeyBlob[sizeof(SKF_PUBLICKEYBLOB)]; + ECCPUBLICKEYBLOB *pubKey = (ECCPUBLICKEYBLOB *)pubKeyBlob; + ULONG pubKeyLen = sizeof(SKF_PUBLICKEYBLOB); + + if ((rv = SKF_GetContainerType(hContainer, &containerType)) != SAR_OK) { + SKFerr(SKF_F_SKF_EXPORTECCPUBLICKEY, ERR_R_SKF_LIB); + return rv; + } + if (containerType != SKF_CONTAINER_TYPE_ECC) { + SKFerr(SKF_F_SKF_EXPORTECCPUBLICKEY, SKF_R_CONTAINER_TYPE_NOT_MATCH); + return SAR_FAIL; + } + + if ((rv = SKF_ExportPublicKey(hContainer, bSign, + pubKeyBlob, &pubKeyLen)) != SAR_OK) { + SKFerr(SKF_F_SKF_EXPORTECCPUBLICKEY, ERR_R_SKF_LIB); + return rv; + } + if (pubKeyLen != sizeof(ECCPUBLICKEYBLOB)) { + SKFerr(SKF_F_SKF_EXPORTECCPUBLICKEY, ERR_R_SKF_LIB); + return SAR_FAIL; + } + + if (!(*ec_key = EC_KEY_new_from_ECCPUBLICKEYBLOB(pubKey))) { + SKFerr(SKF_F_SKF_EXPORTECCPUBLICKEY, SKF_R_INVALID_ECC_PUBLIC_KEY); + return SAR_FAIL; + } + return SAR_OK; +} + +ULONG DEVAPI SKF_ExportRSAPublicKey(HCONTAINER hContainer, BOOL bSign, RSA **rsa) +{ + ULONG rv; + ULONG containerType; + BYTE pubKeyBlob[sizeof(SKF_PUBLICKEYBLOB)]; + RSAPUBLICKEYBLOB *pubKey = (RSAPUBLICKEYBLOB *)pubKeyBlob; + ULONG pubKeyLen = sizeof(SKF_PUBLICKEYBLOB); + + if ((rv = SKF_GetContainerType(hContainer, &containerType)) != SAR_OK) { + SKFerr(SKF_F_SKF_EXPORTRSAPUBLICKEY, ERR_R_SKF_LIB); + return rv; + } + if (containerType != SKF_CONTAINER_TYPE_RSA) { + SKFerr(SKF_F_SKF_EXPORTRSAPUBLICKEY, SKF_R_CONTAINER_TYPE_NOT_MATCH); + return SAR_FAIL; + } + + if ((rv = SKF_ExportPublicKey(hContainer, bSign, + pubKeyBlob, &pubKeyLen)) != SAR_OK) { + SKFerr(SKF_F_SKF_EXPORTRSAPUBLICKEY, ERR_R_SKF_LIB); + return rv; + } + if (pubKeyLen != sizeof(RSAPUBLICKEYBLOB)) { + SKFerr(SKF_F_SKF_EXPORTRSAPUBLICKEY, ERR_R_SKF_LIB); + return SAR_FAIL; + } + + if (!(*rsa = RSA_new_from_RSAPUBLICKEYBLOB(pubKey))) { + SKFerr(SKF_F_SKF_EXPORTRSAPUBLICKEY, SKF_R_INVALID_RSA_PUBLIC_KEY); + return SAR_FAIL; + } + return SAR_OK; +} + +ULONG DEVAPI SKF_ExportEVPPublicKey(HCONTAINER hContainer, BOOL bSign, EVP_PKEY **pp) +{ + ULONG rv; + ULONG containerType; + EVP_PKEY *pkey = NULL; + + if ((rv = SKF_GetContainerType(hContainer, &containerType)) != SAR_OK) { + SKFerr(SKF_F_SKF_EXPORTEVPPUBLICKEY, ERR_R_SKF_LIB); + return rv; + } + + if (!(pkey = EVP_PKEY_new())) { + SKFerr(SKF_F_SKF_EXPORTEVPPUBLICKEY, ERR_R_MALLOC_FAILURE); + return SAR_MEMORYERR; + } + + if (containerType == SKF_CONTAINER_TYPE_ECC) { + EC_KEY *ec_key = NULL; + if ((rv = SKF_ExportECCPublicKey(hContainer, bSign, + &ec_key)) != SAR_OK) { + SKFerr(SKF_F_SKF_EXPORTEVPPUBLICKEY, ERR_R_SKF_LIB); + goto end; + } + if (!EVP_PKEY_assign_EC_KEY(pkey, ec_key)) { + EC_KEY_free(ec_key); + rv = SAR_FAIL; + goto end; + } + + } else if (containerType == SKF_CONTAINER_TYPE_RSA) { + RSA *rsa = NULL; + if ((rv = SKF_ExportRSAPublicKey(hContainer, bSign, + &rsa)) != SAR_OK) { + SKFerr(SKF_F_SKF_EXPORTEVPPUBLICKEY, ERR_R_SKF_LIB); + goto end; + } + if (!EVP_PKEY_assign_RSA(pkey, rsa)) { + RSA_free(rsa); + rv = SAR_FAIL; + goto end; + } + + } else { + SKFerr(SKF_F_SKF_EXPORTEVPPUBLICKEY, SKF_R_INVALID_CONTAINER_TYPE); + rv = SAR_FAIL; + goto end; + } + + *pp = pkey; + pkey = NULL; + rv = SAR_OK; + +end: + EVP_PKEY_free(pkey); + return rv; +} +#endif + +/* +ULONG DEVAPI SKF_ImportX509Certificate(HCONTAINER hContainer, BOOL bSign, X509 *x509) +{ + int ret = 0; + ULONG containerType; + unsigned char *cert = NULL; + unsigned char *p; + int len; + + if (SKF_GetContainerType(hContainer, &containerType) != SAR_OK) { + return 0; + } + if (containerType == SKF_CONTAINER_TYPE_UNDEF) { + return 0; + } + + switch (EVP_PKEY_id(X509_get0_pubkey(x509))) { + case EVP_PKEY_EC: + if (containerType != SKF_CONTAINER_TYPE_ECC) { + goto end; + } + if (!EC_KEY_is_sm2p256v1(EVP_PKEY_get0_EC_KEY(X509_get0_pubkey(x509)))) { + goto end; + } + break; + + case EVP_PKEY_RSA: + if (containerType != SKF_CONTAINER_TYPE_RSA) { + goto end; + } + break; + default: + goto end; + } + + if (X509_get_key_usage(x509) & (KU_DIGITAL_SIGNATURE| + KU_NON_REPUDIATION|KU_KEY_CERT_SIGN|KU_CRL_SIGN)) { + bSign = SGD_TRUE; + } else if (X509_get_key_usage(x509) & (KU_KEY_ENCIPHERMENT| + KU_DATA_ENCIPHERMENT|KU_KEY_AGREEMENT|KU_ENCIPHER_ONLY)) { + bSign = SGD_FALSE; + } else { + goto end; + } + + if ((len = i2d_X509(x509, NULL)) <= 0 + || !(p = cert = malloc(len)) + || (len = i2d_X509(x509, &p)) <= 0) { + goto end; + } + + if (SKF_ImportCertificate(hContainer, bSign, cert, (ULONG)len) != SAR_OK) { + goto end; + } + + ret = 1; +end: + X509_free(x509); + OPENSSL_free(cert); + return ret; +} + +ULONG DEVAPI SKF_ImportX509CertificateByKeyUsage(HCONTAINER hContainer, X509 *x509) +{ + ULONG rv; + BOOL bSign; + + if (X509_get_key_usage(x509) & (KU_DIGITAL_SIGNATURE| + KU_NON_REPUDIATION|KU_KEY_CERT_SIGN|KU_CRL_SIGN)) { + bSign = SGD_TRUE; + } else if (X509_get_key_usage(x509) & (KU_KEY_ENCIPHERMENT| + KU_DATA_ENCIPHERMENT|KU_KEY_AGREEMENT|KU_ENCIPHER_ONLY)) { + bSign = SGD_FALSE; + } else { + SKFerr(SKF_F_SKF_IMPORTX509CERTIFICATEBYKEYUSAGE, + SKF_R_UNKNOWN_CERTIFICATE_KEYUSAGE); + return SAR_FAIL; + } + + if ((rv = SKF_ImportX509Certificate(hContainer, bSign, x509)) != SAR_OK) { + SKFerr(SKF_F_SKF_IMPORTX509CERTIFICATEBYKEYUSAGE, ERR_R_SKF_LIB); + return rv; + } + + return SAR_OK; +} + +ULONG DEVAPI SKF_ExportX509Certificate(HCONTAINER hContainer, BOOL bSign, X509 **px509) +{ + ULONG rv = SAR_FAIL; + BYTE *pbCert = NULL; + ULONG ulCertLen; + const unsigned char *p; + X509 *x509 = NULL; + + ulCertLen = SKF_MAX_CERTIFICATE_SIZE; + if (!(pbCert = malloc(ulCertLen))) { + SKFerr(SKF_F_SKF_EXPORTX509CERTIFICATE, ERR_R_MALLOC_FAILURE); + rv = SAR_MEMORYERR; + goto end; + } + if ((rv = SKF_ExportCertificate(hContainer, bSign, + pbCert, &ulCertLen)) != SAR_OK) { + SKFerr(SKF_F_SKF_EXPORTX509CERTIFICATE, ERR_R_SKF_LIB); + goto end; + } + + p = pbCert; + if (!(x509 = d2i_X509(NULL, &p, (long)ulCertLen))) { + SKFerr(SKF_F_SKF_EXPORTX509CERTIFICATE, + SKF_R_PARSE_CERTIFICATE_FAILURE); + goto end; + } + if (p - pbCert != ulCertLen) { + SKFerr(SKF_F_SKF_EXPORTX509CERTIFICATE, + SKF_R_PARSE_CERTIFICATE_FAILURE); + goto end; + } + + *px509 = x509; + x509 = NULL; + rv = SAR_OK; + +end: + OPENSSL_free(pbCert); + X509_free(x509); + return rv; +} +*/ diff --git a/src/skf/skf_ext.h b/src/skf/skf_ext.h new file mode 100644 index 00000000..6d22d0f8 --- /dev/null +++ b/src/skf/skf_ext.h @@ -0,0 +1,133 @@ +/* ==================================================================== + * Copyright (c) 2015 - 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. + * ==================================================================== + */ + +#ifndef SKFUTIL_SKF_EXT_H +#define SKFUTIL_SKF_EXT_H + + +#include +#include "skf.h" + + +#define SKF_NO_PADDING 0 +#define SKF_PKCS5_PADDING 1 + +#define SKF_DEV_STATE_ABSENT 0x00000000 +#define SKF_DEV_STATE_PRESENT 0x00000001 +#define SKF_DEV_STATE_UNKNOW 0x00000010 + +#define SKF_CONTAINER_TYPE_UNDEF 0 +#define SKF_CONTAINER_TYPE_RSA 1 +#define SKF_CONTAINER_TYPE_ECC 2 + +#define SKF_ENVELOPEDKEYBLOB_VERSION 1 +#define SKF_AUTHKEY_LENGTH 16 +#define SKF_AUTHRAND_LENGTH 16 +#define SKF_MAX_FILE_SIZE (256*1024) +#define SKF_MAX_CERTIFICATE_SIZE (8*1024) + + +#define SKF_DEFAULT_ADMIN_PIN_RETRY_COUNT 6 +#define SKF_DEFAULT_USER_PIN_RETRY_COUNT 6 + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + union { + ECCPUBLICKEYBLOB ecc; + RSAPUBLICKEYBLOB rsa; + } u; +} SKF_PUBLICKEYBLOB; +#define SKF_MAX_PUBLICKEYBOLB_LENGTH sizeof(SKF_PUBLICKEYBLOB) + +typedef struct { + char *name; + unsigned char *buf; + int offset; + int length; +} SKF_FILE_OP_PARAMS; + + +ULONG DEVAPI SKF_LoadLibrary(LPSTR so_path, LPSTR vendor); +ULONG DEVAPI SKF_UnloadLibrary(void); +ULONG DEVAPI SKF_OpenDevice(LPSTR devName, BYTE authKey[16], DEVINFO *devInfo, DEVHANDLE *phDev); +ULONG DEVAPI SKF_CloseDevice(DEVHANDLE hDev); +ULONG DEVAPI SKF_GetDevStateName(ULONG ulDevState, LPSTR *szName); +ULONG DEVAPI SKF_GetContainerTypeName(ULONG ulContainerType, LPSTR *szName); +ULONG DEVAPI SKF_GetAlgorName(ULONG ulAlgID, LPSTR *szName); +ULONG DEVAPI SKF_PrintDevInfo(FILE *fp, const DEVINFO *devInfo); +ULONG DEVAPI SKF_PrintRSAPublicKey(FILE *fp, const RSAPUBLICKEYBLOB *blob); +ULONG DEVAPI SKF_PrintRSAPrivateKey(FILE *fp, const RSAPRIVATEKEYBLOB *blob); +ULONG DEVAPI SKF_PrintECCPublicKey(FILE *fp, const ECCPUBLICKEYBLOB *blob); +ULONG DEVAPI SKF_PrintECCPrivateKey(FILE *fp, const ECCPRIVATEKEYBLOB *blob); +ULONG DEVAPI SKF_PrintECCCipher(FILE *fp, const ECCCIPHERBLOB *blob); +ULONG DEVAPI SKF_PrintECCSignature(FILE *fp, const ECCSIGNATUREBLOB *blob); +ULONG DEVAPI SKF_GetErrorString(ULONG ulError, LPSTR *szErrorStr); +ULONG DEVAPI SKF_NewECCCipher(ULONG ulCipherLen, ECCCIPHERBLOB **cipherBlob); +ULONG DEVAPI SKF_NewEnvelopedKey(ULONG ulCipherLen, ENVELOPEDKEYBLOB **envelopedKeyBlob); + +/* +ULONG DEVAPI SKF_ImportECCPrivateKey(DEVHANDLE hDev, HCONTAINER hContainer, EC_KEY *ec_key, ULONG symmAlgId); +ULONG DEVAPI SKF_ImportRSAPrivateKey(DEVHANDLE hDev, HCONTAINER hContainer, RSA *rsa, ULONG symmAlgId); +ULONG DEVAPI SKF_ImportPrivateKey(DEVHANDLE hDev, HCONTAINER hContainer, EVP_PKEY *pkey, ULONG symmAlgId); +ULONG DEVAPI SKF_ExportECCPublicKey(HCONTAINER hContainer, BOOL bSign, EC_KEY **pp); +ULONG DEVAPI SKF_ExportRSAPublicKey(HCONTAINER hContainer, BOOL bSign, RSA **pp); +ULONG DEVAPI SKF_ExportEVPPublicKey(HCONTAINER hContainer, BOOL bSign, EVP_PKEY **pp); +ULONG DEVAPI SKF_ImportX509CertificateByKeyUsage(HCONTAINER hContainer, X509 *x509); +ULONG DEVAPI SKF_ImportX509Certificate(HCONTAINER hContainer, BOOL bSign, X509 *x509); +ULONG DEVAPI SKF_ExportX509Certificate(HCONTAINER hContainer, BOOL bSign, X509 **px509); +*/ + + +#ifdef __cplusplus +} +#endif +#endif diff --git a/src/skf/skf_int.h b/src/skf/skf_int.h new file mode 100644 index 00000000..224d13d0 --- /dev/null +++ b/src/skf/skf_int.h @@ -0,0 +1,617 @@ +/* ==================================================================== + * Copyright (c) 2014 - 2017 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. + * ==================================================================== + */ + +#ifndef SKFUTIL_SKF_INT_H +#define SKFUTIL_SKF_INT_H + +#include "../sgd.h" +#include "skf.h" + + +typedef ULONG (DEVAPI *SKF_WaitForDevEvent_FuncPtr)( + LPSTR szDevName, + ULONG *pulDevNameLen, + ULONG *pulEvent); + +typedef ULONG (DEVAPI *SKF_CancelWaitForDevEvent_FuncPtr)( + void); + +typedef ULONG (DEVAPI *SKF_EnumDev_FuncPtr)( + BOOL bPresent, + LPSTR szNameList, + ULONG *pulSize); + +typedef ULONG (DEVAPI *SKF_ConnectDev_FuncPtr)( + LPSTR szName, + DEVHANDLE *phDev); + +typedef ULONG (DEVAPI *SKF_DisConnectDev_FuncPtr)( + DEVHANDLE hDev); + +typedef ULONG (DEVAPI *SKF_GetDevState_FuncPtr)( + LPSTR szDevName, + ULONG *pulDevState); + +typedef ULONG (DEVAPI *SKF_SetLabel_FuncPtr)( + DEVHANDLE hDev, + LPSTR szLabel); + +typedef ULONG (DEVAPI *SKF_GetDevInfo_FuncPtr)( + DEVHANDLE hDev, + DEVINFO *pDevInfo); + +typedef ULONG (DEVAPI *SKF_LockDev_FuncPtr)( + DEVHANDLE hDev, + ULONG ulTimeOut); + +typedef ULONG (DEVAPI *SKF_UnlockDev_FuncPtr)( + DEVHANDLE hDev); + +typedef ULONG (DEVAPI *SKF_Transmit_FuncPtr)( + DEVHANDLE hDev, + BYTE *pbCommand, + ULONG ulCommandLen, + BYTE *pbData, + ULONG *pulDataLen); + +typedef ULONG (DEVAPI *SKF_ChangeDevAuthKey_FuncPtr)( + DEVHANDLE hDev, + BYTE *pbKeyValue, + ULONG ulKeyLen); + +typedef ULONG (DEVAPI *SKF_DevAuth_FuncPtr)( + DEVHANDLE hDev, + BYTE *pbAuthData, + ULONG ulLen); + +typedef ULONG (DEVAPI *SKF_ChangePIN_FuncPtr)( + HAPPLICATION hApplication, + ULONG ulPINType, + LPSTR szOldPin, + LPSTR szNewPin, + ULONG *pulRetryCount); + +typedef LONG (DEVAPI *SKF_GetPINInfo_FuncPtr)( + HAPPLICATION hApplication, + ULONG ulPINType, + ULONG *pulMaxRetryCount, + ULONG *pulRemainRetryCount, + BOOL *pbDefaultPin); + +typedef ULONG (DEVAPI *SKF_VerifyPIN_FuncPtr)( + HAPPLICATION hApplication, + ULONG ulPINType, + LPSTR szPIN, + ULONG *pulRetryCount); + +typedef ULONG (DEVAPI *SKF_UnblockPIN_FuncPtr)( + HAPPLICATION hApplication, + LPSTR szAdminPIN, + LPSTR szNewUserPIN, + ULONG *pulRetryCount); + +typedef ULONG (DEVAPI *SKF_ClearSecureState_FuncPtr)( + HAPPLICATION hApplication); + +typedef ULONG (DEVAPI *SKF_CreateApplication_FuncPtr)( + DEVHANDLE hDev, + LPSTR szAppName, + LPSTR szAdminPin, + DWORD dwAdminPinRetryCount, + LPSTR szUserPin, + DWORD dwUserPinRetryCount, + DWORD dwCreateFileRights, + HAPPLICATION *phApplication); + +typedef ULONG (DEVAPI *SKF_EnumApplication_FuncPtr)( + DEVHANDLE hDev, + LPSTR szAppName, + ULONG *pulSize); + +typedef ULONG (DEVAPI *SKF_DeleteApplication_FuncPtr)( + DEVHANDLE hDev, + LPSTR szAppName); + +typedef ULONG (DEVAPI *SKF_OpenApplication_FuncPtr)( + DEVHANDLE hDev, + LPSTR szAppName, + HAPPLICATION *phApplication); + +typedef ULONG (DEVAPI *SKF_CloseApplication_FuncPtr)( + HAPPLICATION hApplication); + +typedef ULONG (DEVAPI *SKF_CreateObject_FuncPtr)( + HAPPLICATION hApplication, + LPSTR szFileName, + ULONG ulFileSize, + ULONG ulReadRights, + ULONG ulWriteRights); + +typedef ULONG (DEVAPI *SKF_DeleteObject_FuncPtr)( + HAPPLICATION hApplication, + LPSTR szFileName); + +typedef ULONG (DEVAPI *SKF_EnumObjects_FuncPtr)( + HAPPLICATION hApplication, + LPSTR szFileList, + ULONG *pulSize); + +typedef ULONG (DEVAPI *SKF_GetObjectInfo_FuncPtr)( + HAPPLICATION hApplication, + LPSTR szFileName, + FILEATTRIBUTE *pFileInfo); + +typedef ULONG (DEVAPI *SKF_ReadObject_FuncPtr)( + HAPPLICATION hApplication, + LPSTR szFileName, + ULONG ulOffset, + ULONG ulSize, + BYTE *pbOutData, + ULONG *pulOutLen); + +typedef ULONG (DEVAPI *SKF_WriteObject_FuncPtr)( + HAPPLICATION hApplication, + LPSTR szFileName, + ULONG ulOffset, + BYTE *pbData, + ULONG ulSize); + +typedef ULONG (DEVAPI *SKF_CreateContainer_FuncPtr)( + HAPPLICATION hApplication, + LPSTR szContainerName, + HCONTAINER *phContainer); + +typedef ULONG (DEVAPI *SKF_DeleteContainer_FuncPtr)( + HAPPLICATION hApplication, + LPSTR szContainerName); + +typedef ULONG (DEVAPI *SKF_EnumContainer_FuncPtr)( + HAPPLICATION hApplication, + LPSTR szContainerName, + ULONG *pulSize); + +typedef ULONG (DEVAPI *SKF_OpenContainer_FuncPtr)( + HAPPLICATION hApplication, + LPSTR szContainerName, + HCONTAINER *phContainer); + +typedef ULONG (DEVAPI *SKF_CloseContainer_FuncPtr)( + HCONTAINER hContainer); + +typedef ULONG (DEVAPI *SKF_GetContainerType_FuncPtr)( + HCONTAINER hContainer, + ULONG *pulContainerType); + +typedef ULONG (DEVAPI *SKF_ImportCertificate_FuncPtr)( + HCONTAINER hContainer, + BOOL bExportSignKey, + BYTE *pbCert, + ULONG ulCertLen); + +typedef ULONG (DEVAPI *SKF_ExportCertificate_FuncPtr)( + HCONTAINER hContainer, + BOOL bSignFlag, + BYTE *pbCert, + ULONG *pulCertLen); + +typedef ULONG (DEVAPI *SKF_ExportPublicKey_FuncPtr)( + HCONTAINER hContainer, + BOOL bSignFlag, + BYTE *pbBlob, + ULONG *pulBlobLen); + +typedef ULONG (DEVAPI *SKF_GenRandom_FuncPtr)( + DEVHANDLE hDev, + BYTE *pbRandom, + ULONG ulRandomLen); + +typedef ULONG (DEVAPI *SKF_GenExtRSAKey_FuncPtr)( + DEVHANDLE hDev, + ULONG ulBitsLen, + RSAPRIVATEKEYBLOB *pBlob); + +typedef ULONG (DEVAPI *SKF_GenRSAKeyPair_FuncPtr)( + HCONTAINER hContainer, + ULONG ulBitsLen, + RSAPUBLICKEYBLOB *pBlob); + +typedef ULONG (DEVAPI *SKF_ImportRSAKeyPair_FuncPtr)( + HCONTAINER hContainer, + ULONG ulSymAlgId, + BYTE *pbWrappedKey, + ULONG ulWrappedKeyLen, + BYTE *pbEncryptedData, + ULONG ulEncryptedDataLen); + +typedef ULONG (DEVAPI *SKF_RSASignData_FuncPtr)( + HCONTAINER hContainer, + BYTE *pbData, + ULONG ulDataLen, + BYTE *pbSignature, + ULONG *pulSignLen); + +typedef ULONG (DEVAPI *SKF_RSAVerify_FuncPtr)( + DEVHANDLE hDev, + RSAPUBLICKEYBLOB *pRSAPubKeyBlob, + BYTE *pbData, + ULONG ulDataLen, + BYTE *pbSignature, + ULONG ulSignLen); + +typedef ULONG (DEVAPI *SKF_RSAExportSessionKey_FuncPtr)( + HCONTAINER hContainer, + ULONG ulAlgId, + RSAPUBLICKEYBLOB *pPubKey, + BYTE *pbData, + ULONG *pulDataLen, + HANDLE *phSessionKey); + +typedef ULONG (DEVAPI *SKF_ExtRSAPubKeyOperation_FuncPtr)( + DEVHANDLE hDev, + RSAPUBLICKEYBLOB *pRSAPubKeyBlob, + BYTE *pbInput, + ULONG ulInputLen, + BYTE *pbOutput, + ULONG *pulOutputLen); + +typedef ULONG (DEVAPI *SKF_ExtRSAPriKeyOperation_FuncPtr)( + DEVHANDLE hDev, + RSAPRIVATEKEYBLOB *pRSAPriKeyBlob, + BYTE *pbInput, + ULONG ulInputLen, + BYTE *pbOutput, + ULONG *pulOutputLen); + +typedef ULONG (DEVAPI *SKF_GenECCKeyPair_FuncPtr)( + HCONTAINER hContainer, + ULONG ulAlgId, + ECCPUBLICKEYBLOB *pBlob); + +typedef ULONG (DEVAPI *SKF_ImportECCKeyPair_FuncPtr)( + HCONTAINER hContainer, + ENVELOPEDKEYBLOB *pEnvelopedKeyBlob); + +typedef ULONG (DEVAPI *SKF_ECCSignData_FuncPtr)( + HCONTAINER hContainer, + BYTE *pbDigest, + ULONG ulDigestLen, + ECCSIGNATUREBLOB *pSignature); + +typedef ULONG (DEVAPI *SKF_ECCVerify_FuncPtr)( + DEVHANDLE hDev, + ECCPUBLICKEYBLOB *pECCPubKeyBlob, + BYTE *pbData, + ULONG ulDataLen, + ECCSIGNATUREBLOB *pSignature); + +typedef ULONG (DEVAPI *SKF_ECCExportSessionKey_FuncPtr)( + HCONTAINER hContainer, + ULONG ulAlgId, + ECCPUBLICKEYBLOB *pPubKey, + ECCCIPHERBLOB *pData, + HANDLE *phSessionKey); + +typedef ULONG (DEVAPI *SKF_ExtECCEncrypt_FuncPtr)( + DEVHANDLE hDev, + ECCPUBLICKEYBLOB *pECCPubKeyBlob, + BYTE *pbPlainText, + ULONG ulPlainTextLen, + ECCCIPHERBLOB *pCipherText); + +typedef ULONG (DEVAPI *SKF_ECCDecrypt_FuncPtr)( + HCONTAINER hContainer, + ECCCIPHERBLOB *pCipherText, + BYTE *pbPlainText, + ULONG *pulPlainTextLen); + +typedef ULONG (DEVAPI *SKF_ExtECCDecrypt_FuncPtr)( + DEVHANDLE hDev, + ECCPRIVATEKEYBLOB *pECCPriKeyBlob, + ECCCIPHERBLOB *pCipherText, + BYTE *pbPlainText, + ULONG *pulPlainTextLen); + +typedef ULONG (DEVAPI *SKF_ExtECCSign_FuncPtr)( + DEVHANDLE hDev, + ECCPRIVATEKEYBLOB *pECCPriKeyBlob, + BYTE *pbData, + ULONG ulDataLen, + ECCSIGNATUREBLOB *pSignature); + +typedef ULONG (DEVAPI *SKF_ExtECCVerify_FuncPtr)( + DEVHANDLE hDev, + ECCPUBLICKEYBLOB *pECCPubKeyBlob, + BYTE *pbData, + ULONG ulDataLen, + ECCSIGNATUREBLOB *pSignature); + +typedef ULONG (DEVAPI *SKF_GenerateAgreementDataWithECC_FuncPtr)( + HCONTAINER hContainer, + ULONG ulAlgId, + ECCPUBLICKEYBLOB *pTempECCPubKeyBlob, + BYTE *pbID, + ULONG ulIDLen, + HANDLE *phAgreementHandle); + +typedef ULONG (DEVAPI *SKF_GenerateAgreementDataAndKeyWithECC_FuncPtr)( + HANDLE hContainer, + ULONG ulAlgId, + ECCPUBLICKEYBLOB *pSponsorECCPubKeyBlob, + ECCPUBLICKEYBLOB *pSponsorTempECCPubKeyBlob, + ECCPUBLICKEYBLOB *pTempECCPubKeyBlob, + BYTE *pbID, + ULONG ulIDLen, + BYTE *pbSponsorID, + ULONG ulSponsorIDLen, + HANDLE *phKeyHandle); + +typedef ULONG (DEVAPI *SKF_GenerateKeyWithECC_FuncPtr)( + HANDLE hAgreementHandle, + ECCPUBLICKEYBLOB *pECCPubKeyBlob, + ECCPUBLICKEYBLOB *pTempECCPubKeyBlob, + BYTE *pbID, + ULONG ulIDLen, + HANDLE *phKeyHandle); + +typedef ULONG (DEVAPI *SKF_ImportSessionKey_FuncPtr)( + HCONTAINER hContainer, + ULONG ulAlgId, + BYTE *pbWrapedData, + ULONG ulWrapedLen, + HANDLE *phKey); + +typedef ULONG (DEVAPI *SKF_SetSymmKey_FuncPtr)( + DEVHANDLE hDev, + BYTE *pbKey, + ULONG ulAlgID, + HANDLE *phKey); + +typedef ULONG (DEVAPI *SKF_EncryptInit_FuncPtr)( + HANDLE hKey, + BLOCKCIPHERPARAM EncryptParam); + +typedef ULONG (DEVAPI *SKF_Encrypt_FuncPtr)( + HANDLE hKey, + BYTE *pbData, + ULONG ulDataLen, + BYTE *pbEncryptedData, + ULONG *pulEncryptedLen); + +typedef ULONG (DEVAPI *SKF_EncryptUpdate_FuncPtr)( + HANDLE hKey, + BYTE *pbData, + ULONG ulDataLen, + BYTE *pbEncryptedData, + ULONG *pulEncryptedLen); + +typedef ULONG (DEVAPI *SKF_EncryptFinal_FuncPtr)( + HANDLE hKey, + BYTE *pbEncryptedData, + ULONG *pulEncryptedDataLen); + +typedef ULONG (DEVAPI *SKF_DecryptInit_FuncPtr)( + HANDLE hKey, + BLOCKCIPHERPARAM DecryptParam); + +typedef ULONG (DEVAPI *SKF_Decrypt_FuncPtr)( + HANDLE hKey, + BYTE *pbEncryptedData, + ULONG ulEncryptedLen, + BYTE *pbData, + ULONG *pulDataLen); + +typedef ULONG (DEVAPI *SKF_DecryptUpdate_FuncPtr)( + HANDLE hKey, + BYTE *pbEncryptedData, + ULONG ulEncryptedLen, + BYTE *pbData, + ULONG *pulDataLen); + +typedef ULONG (DEVAPI *SKF_DecryptFinal_FuncPtr)( + HANDLE hKey, + BYTE *pbDecryptedData, + ULONG *pulDecryptedDataLen); + +typedef ULONG (DEVAPI *SKF_DigestInit_FuncPtr)( + DEVHANDLE hDev, + ULONG ulAlgID, + ECCPUBLICKEYBLOB *pPubKey, + BYTE *pbID, + ULONG ulIDLen, + HANDLE *phHash); + +typedef ULONG (DEVAPI *SKF_Digest_FuncPtr)( + HANDLE hHash, + BYTE *pbData, + ULONG ulDataLen, + BYTE *pbHashData, + ULONG *pulHashLen); + +typedef ULONG (DEVAPI *SKF_DigestUpdate_FuncPtr)( + HANDLE hHash, + BYTE *pbData, + ULONG ulDataLen); + +typedef ULONG (DEVAPI *SKF_DigestFinal_FuncPtr)( + HANDLE hHash, + BYTE *pHashData, + ULONG *pulHashLen); + +typedef ULONG (DEVAPI *SKF_MacInit_FuncPtr)( + HANDLE hKey, + BLOCKCIPHERPARAM *pMacParam, + HANDLE *phMac); + +typedef ULONG (DEVAPI *SKF_Mac_FuncPtr)( + HANDLE hMac, + BYTE *pbData, + ULONG ulDataLen, + BYTE *pbMacData, + ULONG *pulMacLen); + +typedef ULONG (DEVAPI *SKF_MacUpdate_FuncPtr)( + HANDLE hMac, + BYTE *pbData, + ULONG ulDataLen); + +typedef ULONG (DEVAPI *SKF_MacFinal_FuncPtr)( + HANDLE hMac, + BYTE *pbMacData, + ULONG *pulMacDataLen); + +typedef ULONG (DEVAPI *SKF_CloseHandle_FuncPtr)( + HANDLE hHandle); + + +typedef struct skf_method_st { + char *name; + void *dso; + SKF_WaitForDevEvent_FuncPtr WaitForDevEvent; + SKF_CancelWaitForDevEvent_FuncPtr CancelWaitForDevEvent; + SKF_EnumDev_FuncPtr EnumDev; + SKF_ConnectDev_FuncPtr ConnectDev; + SKF_DisConnectDev_FuncPtr DisConnectDev; + SKF_GetDevState_FuncPtr GetDevState; + SKF_SetLabel_FuncPtr SetLabel; + SKF_GetDevInfo_FuncPtr GetDevInfo; + SKF_LockDev_FuncPtr LockDev; + SKF_UnlockDev_FuncPtr UnlockDev; + SKF_Transmit_FuncPtr Transmit; + SKF_ChangeDevAuthKey_FuncPtr ChangeDevAuthKey; + SKF_DevAuth_FuncPtr DevAuth; + SKF_ChangePIN_FuncPtr ChangePIN; + SKF_GetPINInfo_FuncPtr GetPINInfo; + SKF_VerifyPIN_FuncPtr VerifyPIN; + SKF_UnblockPIN_FuncPtr UnblockPIN; + SKF_ClearSecureState_FuncPtr ClearSecureState; + SKF_CreateApplication_FuncPtr CreateApplication; + SKF_EnumApplication_FuncPtr EnumApplication; + SKF_DeleteApplication_FuncPtr DeleteApplication; + SKF_OpenApplication_FuncPtr OpenApplication; + SKF_CloseApplication_FuncPtr CloseApplication; + SKF_CreateObject_FuncPtr CreateObject; + SKF_DeleteObject_FuncPtr DeleteObject; + SKF_EnumObjects_FuncPtr EnumObjects; + SKF_GetObjectInfo_FuncPtr GetObjectInfo; + SKF_ReadObject_FuncPtr ReadObject; + SKF_WriteObject_FuncPtr WriteObject; + SKF_CreateContainer_FuncPtr CreateContainer; + SKF_DeleteContainer_FuncPtr DeleteContainer; + SKF_EnumContainer_FuncPtr EnumContainer; + SKF_OpenContainer_FuncPtr OpenContainer; + SKF_CloseContainer_FuncPtr CloseContainer; + SKF_GetContainerType_FuncPtr GetContainerType; + SKF_ImportCertificate_FuncPtr ImportCertificate; + SKF_ExportCertificate_FuncPtr ExportCertificate; + SKF_ExportPublicKey_FuncPtr ExportPublicKey; + SKF_GenRandom_FuncPtr GenRandom; + SKF_GenExtRSAKey_FuncPtr GenExtRSAKey; + SKF_GenRSAKeyPair_FuncPtr GenRSAKeyPair; + SKF_ImportRSAKeyPair_FuncPtr ImportRSAKeyPair; + SKF_RSASignData_FuncPtr RSASignData; + SKF_RSAVerify_FuncPtr RSAVerify; + SKF_RSAExportSessionKey_FuncPtr RSAExportSessionKey; + SKF_ExtRSAPubKeyOperation_FuncPtr ExtRSAPubKeyOperation; + SKF_ExtRSAPriKeyOperation_FuncPtr ExtRSAPriKeyOperation; + SKF_GenECCKeyPair_FuncPtr GenECCKeyPair; + SKF_ImportECCKeyPair_FuncPtr ImportECCKeyPair; + SKF_ECCSignData_FuncPtr ECCSignData; + SKF_ECCVerify_FuncPtr ECCVerify; + SKF_ECCExportSessionKey_FuncPtr ECCExportSessionKey; + SKF_ExtECCEncrypt_FuncPtr ExtECCEncrypt; + SKF_ExtECCDecrypt_FuncPtr ExtECCDecrypt; + SKF_ECCDecrypt_FuncPtr ECCDecrypt; + SKF_ExtECCSign_FuncPtr ExtECCSign; + SKF_ExtECCVerify_FuncPtr ExtECCVerify; + SKF_GenerateAgreementDataWithECC_FuncPtr GenerateAgreementDataWithECC; + SKF_GenerateAgreementDataAndKeyWithECC_FuncPtr GenerateAgreementDataAndKeyWithECC; + SKF_GenerateKeyWithECC_FuncPtr GenerateKeyWithECC; + SKF_ImportSessionKey_FuncPtr ImportSessionKey; + SKF_SetSymmKey_FuncPtr SetSymmKey; + SKF_EncryptInit_FuncPtr EncryptInit; + SKF_Encrypt_FuncPtr Encrypt; + SKF_EncryptUpdate_FuncPtr EncryptUpdate; + SKF_EncryptFinal_FuncPtr EncryptFinal; + SKF_DecryptInit_FuncPtr DecryptInit; + SKF_Decrypt_FuncPtr Decrypt; + SKF_DecryptUpdate_FuncPtr DecryptUpdate; + SKF_DecryptFinal_FuncPtr DecryptFinal; + SKF_DigestInit_FuncPtr DigestInit; + SKF_Digest_FuncPtr Digest; + SKF_DigestUpdate_FuncPtr DigestUpdate; + SKF_DigestFinal_FuncPtr DigestFinal; + SKF_MacInit_FuncPtr MacInit; + SKF_Mac_FuncPtr Mac; + SKF_MacUpdate_FuncPtr MacUpdate; + SKF_MacFinal_FuncPtr MacFinal; + SKF_CloseHandle_FuncPtr CloseHandle; +} SKF_METHOD; + +SKF_METHOD *SKF_METHOD_load_library(const char *so_path); +void SKF_METHOD_free(SKF_METHOD *meth); + + +typedef struct skf_vendor_st { + char *name; + unsigned int authrand_length; + ULONG (*get_cipher_algor)(ULONG vendor_id); + ULONG (*get_cipher_cap)(ULONG vendor_cap); + ULONG (*get_digest_algor)(ULONG vendor_id); + ULONG (*get_digest_cap)(ULONG vendor_cap); + ULONG (*get_pkey_algor)(ULONG vendor_id); + ULONG (*get_pkey_cap)(ULONG vendor_cap); + unsigned long (*get_error_reason)(ULONG err); +} SKF_VENDOR; + +typedef struct { + ULONG err; + unsigned long reason; +} SKF_ERR_REASON; + +#endif diff --git a/src/skf/skf_lib.c b/src/skf/skf_lib.c new file mode 100644 index 00000000..11efac43 --- /dev/null +++ b/src/skf/skf_lib.c @@ -0,0 +1,2777 @@ +/* ==================================================================== + * Copyright (c) 2014 - 2017 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 +#include +#include +#include "skf_int.h" + + + +SKF_METHOD *skf_method = NULL; +SKF_VENDOR *skf_vendor = NULL; +extern SKF_VENDOR skf_wisec; + + +#define SKFerr(f,e) + + +ULONG SKF_LoadLibrary(LPSTR so_path, LPSTR vendor) +{ + if (skf_method) { + SKF_METHOD_free(skf_method); + skf_method = NULL; + } + + if (!(skf_method = SKF_METHOD_load_library((char *)so_path))) { + SKFerr(SKF_F_SKF_LOADLIBRARY, SKF_R_LOAD_LIBRARY_FAILURE); + return SAR_FAIL; + } + + if (vendor) { + if (strcmp((char *)vendor, skf_wisec.name) == 0) { + skf_vendor = &skf_wisec; + } else { + SKFerr(SKF_F_SKF_LOADLIBRARY, SKF_R_UNKNOWN_VENDOR); + return SAR_FAIL; + } + } + + return SAR_OK; +} + +ULONG SKF_UnloadLibrary(void) +{ + SKF_METHOD_free(skf_method); + skf_method = NULL; + skf_vendor = NULL; + return SAR_OK; +} + +/* +static SKF_ERR_REASON skf_errors[] = { + { SAR_OK, SKF_R_SUCCESS }, + { SAR_FAIL, SKF_R_FAILURE }, + { SAR_UNKNOWNERR, SKF_R_UNKNOWN_ERROR }, + { SAR_NOTSUPPORTYETERR, SKF_R_OPERATION_NOT_SUPPORTED }, + { SAR_FILEERR, SKF_R_FILE_ERROR }, + { SAR_INVALIDHANDLEERR, SKF_R_INVALID_HANDLE }, + { SAR_INVALIDPARAMERR, SKF_R_INVALID_PARAMETER }, + { SAR_READFILEERR, SKF_R_READ_FILE_FAILURE }, + { SAR_WRITEFILEERR, SKF_R_WRITE_FILE_FAILURE }, + { SAR_NAMELENERR, SKF_R_INVALID_NAME_LENGTH }, + { SAR_KEYUSAGEERR, SKF_R_INVALID_KEY_USAGE }, + { SAR_MODULUSLENERR, SKF_R_INVALID_MODULUS_LENGTH }, + { SAR_NOTINITIALIZEERR, SKF_R_NOT_INITIALIZED }, + { SAR_OBJERR, SKF_R_INVALID_OBJECT }, + { SAR_MEMORYERR, SKF_R_MEMORY_ERROR }, + { SAR_TIMEOUTERR, SKF_R_TIMEOUT }, + { SAR_INDATALENERR, SKF_R_INVALID_INPUT_LENGTH }, + { SAR_INDATAERR, SKF_R_INVALID_INPUT_VALUE }, + { SAR_GENRANDERR, SKF_R_RANDOM_GENERATION_FAILED }, + { SAR_HASHOBJERR, SKF_R_INVALID_DIGEST_HANDLE }, + { SAR_HASHERR, SKF_R_DIGEST_ERROR }, + { SAR_GENRSAKEYERR, SKF_R_RSA_KEY_GENERATION_FAILURE }, + { SAR_RSAMODULUSLENERR, SKF_R_INVALID_RSA_MODULUS_LENGTH }, + { SAR_CSPIMPRTPUBKEYERR, SKF_R_CSP_IMPORT_PUBLIC_KEY_ERROR }, + { SAR_RSAENCERR, SKF_R_RSA_ENCRYPTION_FAILURE }, + { SAR_RSADECERR, SKF_R_RSA_DECRYPTION_FAILURE }, + { SAR_HASHNOTEQUALERR, SKF_R_HASH_NOT_EQUAL }, + { SAR_KEYNOTFOUNTERR, SKF_R_KEY_NOT_FOUND }, + { SAR_CERTNOTFOUNTERR, SKF_R_CERTIFICATE_NOT_FOUND }, + { SAR_NOTEXPORTERR, SKF_R_EXPORT_FAILED }, + { SAR_DECRYPTPADERR, SKF_R_DECRYPT_INVALID_PADDING }, + { SAR_MACLENERR, SKF_R_INVALID_MAC_LENGTH }, + { SAR_BUFFER_TOO_SMALL, SKF_R_BUFFER_TOO_SMALL }, + { SAR_KEYINFOTYPEERR, SKF_R_INVALID_KEY_INFO_TYPE }, + { SAR_NOT_EVENTERR, SKF_R_NO_EVENT }, + { SAR_DEVICE_REMOVED, SKF_R_DEVICE_REMOVED }, + { SAR_PIN_INCORRECT, SKF_R_PIN_INCORRECT }, + { SAR_PIN_LOCKED, SKF_R_PIN_LOCKED }, + { SAR_PIN_INVALID, SKF_R_INVALID_PIN }, + { SAR_PIN_LEN_RANGE, SKF_R_INVALID_PIN_LENGTH }, + { SAR_USER_ALREADY_LOGGED_IN, SKF_R_USER_ALREADY_LOGGED_IN }, + { SAR_USER_PIN_NOT_INITIALIZED, SKF_R_USER_PIN_NOT_INITIALIZED }, + { SAR_USER_TYPE_INVALID, SKF_R_INVALID_USER_TYPE }, + { SAR_APPLICATION_NAME_INVALID, SKF_R_INVALID_APPLICATION_NAME }, + { SAR_APPLICATION_EXISTS, SKF_R_APPLICATION_ALREADY_EXIST }, + { SAR_USER_NOT_LOGGED_IN, SKF_R_USER_NOT_LOGGED_IN }, + { SAR_APPLICATION_NOT_EXISTS, SKF_R_APPLICATION_NOT_EXIST }, + { SAR_FILE_ALREADY_EXIST, SKF_R_FILE_ALREADY_EXIST }, + { SAR_NO_ROOM, SKF_R_NO_SPACE }, + { SAR_FILE_NOT_EXIST, SKF_R_FILE_NOT_EXIST }, +}; +*/ + +static unsigned long skf_get_error_reason(ULONG ulError) +{ +/* + int i; + for (i = 0; i < OSSL_NELEM(skf_errors); i++) { + if (ulError == skf_errors[i].err) { + return skf_errors[i].reason; + } + } + if (skf_vendor) { + return skf_vendor->get_error_reason(ulError); + } +*/ + return 0; +} + +ULONG SKF_GetErrorString(ULONG ulError, LPSTR *szErrorStr) +{ + unsigned long reason; + + if ((reason = skf_get_error_reason(ulError)) != 0) { + //*szErrorStr = (LPSTR)ERR_reason_error_string(reason); + } else { + *szErrorStr = (LPSTR)"(unknown)"; + } + + return SAR_OK; +} + +ULONG DEVAPI SKF_WaitForDevEvent( + LPSTR szDevName, + ULONG *pulDevNameLen, + ULONG *pulEvent) +{ + ULONG rv; + + if (!skf_method) { + SKFerr(SKF_F_SKF_WAITFORDEVEVENT, + SKF_R_SKF_METHOD_NOT_INITIALIZED); + return SAR_NOTINITIALIZEERR; + } + + if (!skf_method->WaitForDevEvent) { + SKFerr(SKF_F_SKF_WAITFORDEVEVENT, + SKF_R_FUNCTION_NOT_SUPPORTED); + return SAR_NOTSUPPORTYETERR; + } + + if ((rv = skf_method->WaitForDevEvent( + szDevName, + pulDevNameLen, + pulEvent)) != SAR_OK) { + SKFerr(SKF_F_SKF_WAITFORDEVEVENT, skf_get_error_reason(rv)); + return rv; + } + + return SAR_OK; +} + +ULONG DEVAPI SKF_CancelWaitForDevEvent( + void) +{ + ULONG rv; + + if (!skf_method) { + SKFerr(SKF_F_SKF_CANCELWAITFORDEVEVENT, + SKF_R_SKF_METHOD_NOT_INITIALIZED); + return SAR_NOTINITIALIZEERR; + } + + if (!skf_method->CancelWaitForDevEvent) { + SKFerr(SKF_F_SKF_CANCELWAITFORDEVEVENT, + SKF_R_FUNCTION_NOT_SUPPORTED); + return SAR_NOTSUPPORTYETERR; + } + + if (skf_method->CancelWaitForDevEvent) { + return skf_method->CancelWaitForDevEvent(); + } + + if ((rv = skf_method->CancelWaitForDevEvent()) != SAR_OK) { + SKFerr(SKF_F_SKF_CANCELWAITFORDEVEVENT, skf_get_error_reason(rv)); + return rv; + } + + return SAR_OK; +} + +ULONG DEVAPI SKF_EnumDev( + BOOL bPresent, + LPSTR szNameList, + ULONG *pulSize) +{ + ULONG rv; + + + // check output of all enum functions !!!! + + if (!skf_method) { + SKFerr(SKF_F_SKF_ENUMDEV, + SKF_R_SKF_METHOD_NOT_INITIALIZED); + return SAR_NOTINITIALIZEERR; + } + + if (!skf_method->EnumDev) { + SKFerr(SKF_F_SKF_ENUMDEV, + SKF_R_FUNCTION_NOT_SUPPORTED); + return SAR_NOTSUPPORTYETERR; + } + + if (szNameList) { + memset(szNameList, 0, *pulSize); + } + + if ((rv = skf_method->EnumDev( + bPresent, + szNameList, + pulSize)) != SAR_OK) { + SKFerr(SKF_F_SKF_ENUMDEV, skf_get_error_reason(rv)); + return rv; + } + + return SAR_OK; +} + +ULONG DEVAPI SKF_ConnectDev( + LPSTR szName, + DEVHANDLE *phDev) +{ + ULONG rv; + + if (!skf_method) { + SKFerr(SKF_F_SKF_CONNECTDEV, + SKF_R_SKF_METHOD_NOT_INITIALIZED); + return SAR_NOTINITIALIZEERR; + } + + if (!skf_method->ConnectDev) { + SKFerr(SKF_F_SKF_CONNECTDEV, + SKF_R_FUNCTION_NOT_SUPPORTED); + return SAR_NOTSUPPORTYETERR; + } + + if ((rv = skf_method->ConnectDev( + szName, + phDev)) != SAR_OK) { + SKFerr(SKF_F_SKF_CONNECTDEV, skf_get_error_reason(rv)); + return rv; + } + + return SAR_OK; +} + +ULONG DEVAPI SKF_DisConnectDev( + DEVHANDLE hDev) +{ + ULONG rv; + + if (!skf_method) { + SKFerr(SKF_F_SKF_DISCONNECTDEV, + SKF_R_SKF_METHOD_NOT_INITIALIZED); + return SAR_NOTINITIALIZEERR; + } + + if (!skf_method->DisConnectDev) { + SKFerr(SKF_F_SKF_DISCONNECTDEV, + SKF_R_FUNCTION_NOT_SUPPORTED); + return SAR_NOTSUPPORTYETERR; + } + + if ((rv = skf_method->DisConnectDev( + hDev)) != SAR_OK) { + SKFerr(SKF_F_SKF_DISCONNECTDEV, skf_get_error_reason(rv)); + return rv; + } + + return SAR_OK; +} + +ULONG DEVAPI SKF_GetDevState( + LPSTR szDevName, + ULONG *pulDevState) +{ + ULONG rv; + + if (!skf_method) { + SKFerr(SKF_F_SKF_GETDEVSTATE, + SKF_R_SKF_METHOD_NOT_INITIALIZED); + return SAR_NOTINITIALIZEERR; + } + + if (!skf_method->GetDevState) { + SKFerr(SKF_F_SKF_GETDEVSTATE, + SKF_R_FUNCTION_NOT_SUPPORTED); + return SAR_NOTSUPPORTYETERR; + } + + if ((rv = skf_method->GetDevState( + szDevName, + pulDevState)) != SAR_OK) { + SKFerr(SKF_F_SKF_GETDEVSTATE, skf_get_error_reason(rv)); + return rv; + } + + return SAR_OK; +} + +ULONG DEVAPI SKF_SetLabel( + DEVHANDLE hDev, + LPSTR szLabel) +{ + ULONG rv; + + if (!skf_method) { + SKFerr(SKF_F_SKF_SETLABEL, + SKF_R_SKF_METHOD_NOT_INITIALIZED); + return SAR_NOTINITIALIZEERR; + } + + if (!skf_method->SetLabel) { + SKFerr(SKF_F_SKF_SETLABEL, + SKF_R_FUNCTION_NOT_SUPPORTED); + return SAR_NOTSUPPORTYETERR; + } + + if ((rv = skf_method->SetLabel( + hDev, + szLabel)) != SAR_OK) { + SKFerr(SKF_F_SKF_SETLABEL, skf_get_error_reason(rv)); + return rv; + } + + return SAR_OK; +} + +ULONG DEVAPI SKF_GetDevInfo( + DEVHANDLE hDev, + DEVINFO *pDevInfo) +{ + ULONG rv; + + if (!skf_method) { + SKFerr(SKF_F_SKF_GETDEVINFO, + SKF_R_SKF_METHOD_NOT_INITIALIZED); + return SAR_NOTINITIALIZEERR; + } + + if (!skf_method->GetDevInfo) { + SKFerr(SKF_F_SKF_GETDEVINFO, + SKF_R_FUNCTION_NOT_SUPPORTED); + return SAR_NOTSUPPORTYETERR; + } + + memset(pDevInfo, 0, sizeof(DEVINFO)); + + if ((rv = skf_method->GetDevInfo( + hDev, + pDevInfo)) != SAR_OK) { + SKFerr(SKF_F_SKF_GETDEVINFO, skf_get_error_reason(rv)); + printf("rv = %8x\n", rv); + return rv; + } + + if (skf_vendor) { + pDevInfo->AlgSymCap = skf_vendor->get_cipher_cap(pDevInfo->AlgSymCap); + pDevInfo->AlgAsymCap = skf_vendor->get_pkey_cap(pDevInfo->AlgAsymCap); + pDevInfo->AlgHashCap = skf_vendor->get_digest_cap(pDevInfo->AlgHashCap); + pDevInfo->DevAuthAlgId = skf_vendor->get_cipher_cap(pDevInfo->DevAuthAlgId); + } + + return SAR_OK; +} + +ULONG DEVAPI SKF_LockDev( + DEVHANDLE hDev, + ULONG ulTimeOut) +{ + ULONG rv; + + if (!skf_method) { + SKFerr(SKF_F_SKF_LOCKDEV, + SKF_R_SKF_METHOD_NOT_INITIALIZED); + return SAR_NOTINITIALIZEERR; + } + + if (!skf_method->LockDev) { + SKFerr(SKF_F_SKF_LOCKDEV, + SKF_R_FUNCTION_NOT_SUPPORTED); + return SAR_NOTSUPPORTYETERR; + } + + if ((rv = skf_method->LockDev( + hDev, + ulTimeOut)) != SAR_OK) { + SKFerr(SKF_F_SKF_LOCKDEV, skf_get_error_reason(rv)); + return rv; + } + + return SAR_OK; +} + +ULONG DEVAPI SKF_UnlockDev( + DEVHANDLE hDev) +{ + ULONG rv; + + if (!skf_method) { + SKFerr(SKF_F_SKF_UNLOCKDEV, + SKF_R_SKF_METHOD_NOT_INITIALIZED); + return SAR_NOTINITIALIZEERR; + } + + if (!skf_method->UnlockDev) { + SKFerr(SKF_F_SKF_UNLOCKDEV, + SKF_R_FUNCTION_NOT_SUPPORTED); + return SAR_NOTSUPPORTYETERR; + } + + if ((rv = skf_method->UnlockDev( + hDev)) != SAR_OK) { + SKFerr(SKF_F_SKF_UNLOCKDEV, skf_get_error_reason(rv)); + return rv; + } + + return SAR_OK; +} + +ULONG DEVAPI SKF_Transmit( + DEVHANDLE hDev, + BYTE *pbCommand, + ULONG ulCommandLen, + BYTE *pbData, + ULONG *pulDataLen) +{ + ULONG rv; + + if (!skf_method) { + SKFerr(SKF_F_SKF_TRANSMIT, + SKF_R_SKF_METHOD_NOT_INITIALIZED); + return SAR_NOTINITIALIZEERR; + } + + if (!skf_method->Transmit) { + SKFerr(SKF_F_SKF_TRANSMIT, + SKF_R_FUNCTION_NOT_SUPPORTED); + return SAR_NOTSUPPORTYETERR; + } + + if ((rv = skf_method->Transmit( + hDev, + pbCommand, + ulCommandLen, + pbData, + pulDataLen)) != SAR_OK) { + SKFerr(SKF_F_SKF_TRANSMIT, skf_get_error_reason(rv)); + return rv; + } + + return SAR_OK; +} + +ULONG DEVAPI SKF_ChangeDevAuthKey( + DEVHANDLE hDev, + BYTE *pbKeyValue, + ULONG ulKeyLen) +{ + ULONG rv; + + if (!skf_method) { + SKFerr(SKF_F_SKF_CHANGEDEVAUTHKEY, + SKF_R_SKF_METHOD_NOT_INITIALIZED); + return SAR_NOTINITIALIZEERR; + } + + if (!skf_method->ChangeDevAuthKey) { + SKFerr(SKF_F_SKF_CHANGEDEVAUTHKEY, + SKF_R_FUNCTION_NOT_SUPPORTED); + return SAR_NOTSUPPORTYETERR; + } + + if ((rv = skf_method->ChangeDevAuthKey( + hDev, + pbKeyValue, + ulKeyLen)) != SAR_OK) { + SKFerr(SKF_F_SKF_CHANGEDEVAUTHKEY, skf_get_error_reason(rv)); + return rv; + } + + return SAR_OK; +} + +ULONG DEVAPI SKF_DevAuth( + DEVHANDLE hDev, + BYTE *pbAuthData, + ULONG ulLen) +{ + ULONG rv; + + if (!skf_method) { + SKFerr(SKF_F_SKF_DEVAUTH, + SKF_R_SKF_METHOD_NOT_INITIALIZED); + return SAR_NOTINITIALIZEERR; + } + + if (!skf_method->DevAuth) { + SKFerr(SKF_F_SKF_DEVAUTH, + SKF_R_FUNCTION_NOT_SUPPORTED); + return SAR_NOTSUPPORTYETERR; + } + + if ((rv = skf_method->DevAuth( + hDev, + pbAuthData, + ulLen)) != SAR_OK) { + SKFerr(SKF_F_SKF_DEVAUTH, skf_get_error_reason(rv)); + return rv; + } + + return SAR_OK; +} + +ULONG DEVAPI SKF_ChangePIN( + HAPPLICATION hApplication, + ULONG ulPINType, + LPSTR szOldPin, + LPSTR szNewPin, + ULONG *pulRetryCount) +{ + ULONG rv; + + if (!skf_method) { + SKFerr(SKF_F_SKF_CHANGEPIN, + SKF_R_SKF_METHOD_NOT_INITIALIZED); + return SAR_NOTINITIALIZEERR; + } + + if (!skf_method->ChangePIN) { + SKFerr(SKF_F_SKF_CHANGEPIN, + SKF_R_FUNCTION_NOT_SUPPORTED); + return SAR_NOTSUPPORTYETERR; + } + + if ((rv = skf_method->ChangePIN( + hApplication, + ulPINType, + szOldPin, + szNewPin, + pulRetryCount)) != SAR_OK) { + SKFerr(SKF_F_SKF_CHANGEPIN, skf_get_error_reason(rv)); + return rv; + } + + return SAR_OK; +} + +LONG DEVAPI SKF_GetPINInfo( + HAPPLICATION hApplication, + ULONG ulPINType, + ULONG *pulMaxRetryCount, + ULONG *pulRemainRetryCount, + BOOL *pbDefaultPin) +{ + ULONG rv; + + if (!skf_method) { + SKFerr(SKF_F_SKF_GETPININFO, + SKF_R_SKF_METHOD_NOT_INITIALIZED); + return SAR_NOTINITIALIZEERR; + } + + if (!skf_method->GetPINInfo) { + SKFerr(SKF_F_SKF_GETPININFO, + SKF_R_FUNCTION_NOT_SUPPORTED); + return SAR_NOTSUPPORTYETERR; + } + + if ((rv = skf_method->GetPINInfo( + hApplication, + ulPINType, + pulMaxRetryCount, + pulRemainRetryCount, + pbDefaultPin)) != SAR_OK) { + SKFerr(SKF_F_SKF_GETPININFO, skf_get_error_reason(rv)); + return rv; + } + + return SAR_OK; +} + +ULONG DEVAPI SKF_VerifyPIN( + HAPPLICATION hApplication, + ULONG ulPINType, + LPSTR szPIN, + ULONG *pulRetryCount) +{ + ULONG rv; + + if (!skf_method) { + SKFerr(SKF_F_SKF_VERIFYPIN, + SKF_R_SKF_METHOD_NOT_INITIALIZED); + return SAR_NOTINITIALIZEERR; + } + + if (!skf_method->VerifyPIN) { + SKFerr(SKF_F_SKF_VERIFYPIN, + SKF_R_FUNCTION_NOT_SUPPORTED); + return SAR_NOTSUPPORTYETERR; + } + + if ((rv = skf_method->VerifyPIN( + hApplication, + ulPINType, + szPIN, + pulRetryCount)) != SAR_OK) { + SKFerr(SKF_F_SKF_VERIFYPIN, skf_get_error_reason(rv)); + return rv; + } + + return SAR_OK; +} + +ULONG DEVAPI SKF_UnblockPIN( + HAPPLICATION hApplication, + LPSTR szAdminPIN, + LPSTR szNewUserPIN, + ULONG *pulRetryCount) +{ + ULONG rv; + + if (!skf_method) { + SKFerr(SKF_F_SKF_UNBLOCKPIN, + SKF_R_SKF_METHOD_NOT_INITIALIZED); + return SAR_NOTINITIALIZEERR; + } + + if (!skf_method->UnblockPIN) { + SKFerr(SKF_F_SKF_UNBLOCKPIN, + SKF_R_FUNCTION_NOT_SUPPORTED); + return SAR_NOTSUPPORTYETERR; + } + + if ((rv = skf_method->UnblockPIN( + hApplication, + szAdminPIN, + szNewUserPIN, + pulRetryCount)) != SAR_OK) { + SKFerr(SKF_F_SKF_UNBLOCKPIN, skf_get_error_reason(rv)); + return rv; + } + + return SAR_OK; +} + +ULONG DEVAPI SKF_ClearSecureState( + HAPPLICATION hApplication) +{ + ULONG rv; + + if (!skf_method) { + SKFerr(SKF_F_SKF_CLEARSECURESTATE, + SKF_R_SKF_METHOD_NOT_INITIALIZED); + return SAR_NOTINITIALIZEERR; + } + + if (!skf_method->ClearSecureState) { + SKFerr(SKF_F_SKF_CLEARSECURESTATE, + SKF_R_FUNCTION_NOT_SUPPORTED); + return SAR_NOTSUPPORTYETERR; + } + + if ((rv = skf_method->ClearSecureState( + hApplication)) != SAR_OK) { + SKFerr(SKF_F_SKF_CLEARSECURESTATE, skf_get_error_reason(rv)); + return rv; + } + + return SAR_OK; +} + +ULONG DEVAPI SKF_CreateApplication( + DEVHANDLE hDev, + LPSTR szAppName, + LPSTR szAdminPin, + DWORD dwAdminPinRetryCount, + LPSTR szUserPin, + DWORD dwUserPinRetryCount, + DWORD dwCreateFileRights, + HAPPLICATION *phApplication) +{ + ULONG rv; + + if (!skf_method) { + SKFerr(SKF_F_SKF_CREATEAPPLICATION, + SKF_R_SKF_METHOD_NOT_INITIALIZED); + return SAR_NOTINITIALIZEERR; + } + + if (!skf_method->CreateApplication) { + SKFerr(SKF_F_SKF_CREATEAPPLICATION, + SKF_R_FUNCTION_NOT_SUPPORTED); + return SAR_NOTSUPPORTYETERR; + } + + if ((rv = skf_method->CreateApplication( + hDev, + szAppName, + szAdminPin, + dwAdminPinRetryCount, + szUserPin, + dwUserPinRetryCount, + dwCreateFileRights, + phApplication)) != SAR_OK) { + SKFerr(SKF_F_SKF_CREATEAPPLICATION, skf_get_error_reason(rv)); + return rv; + } + + return SAR_OK; +} + +ULONG DEVAPI SKF_EnumApplication( + DEVHANDLE hDev, + LPSTR szAppName, + ULONG *pulSize) +{ + ULONG rv; + + if (!skf_method) { + SKFerr(SKF_F_SKF_ENUMAPPLICATION, + SKF_R_SKF_METHOD_NOT_INITIALIZED); + return SAR_NOTINITIALIZEERR; + } + + if (!skf_method->EnumApplication) { + SKFerr(SKF_F_SKF_ENUMAPPLICATION, + SKF_R_FUNCTION_NOT_SUPPORTED); + return SAR_NOTSUPPORTYETERR; + } + + if ((rv = skf_method->EnumApplication( + hDev, + szAppName, + pulSize)) != SAR_OK) { + SKFerr(SKF_F_SKF_ENUMAPPLICATION, skf_get_error_reason(rv)); + return rv; + } + + return SAR_OK; +} + +ULONG DEVAPI SKF_DeleteApplication( + DEVHANDLE hDev, + LPSTR szAppName) +{ + ULONG rv; + + if (!skf_method) { + SKFerr(SKF_F_SKF_DELETEAPPLICATION, + SKF_R_SKF_METHOD_NOT_INITIALIZED); + return SAR_NOTINITIALIZEERR; + } + + if (!skf_method->DeleteApplication) { + SKFerr(SKF_F_SKF_DELETEAPPLICATION, + SKF_R_FUNCTION_NOT_SUPPORTED); + return SAR_NOTSUPPORTYETERR; + } + + if ((rv = skf_method->DeleteApplication( + hDev, + szAppName)) != SAR_OK) { + SKFerr(SKF_F_SKF_DELETEAPPLICATION, skf_get_error_reason(rv)); + return rv; + } + + return SAR_OK; +} + +ULONG DEVAPI SKF_OpenApplication( + DEVHANDLE hDev, + LPSTR szAppName, + HAPPLICATION *phApplication) +{ + ULONG rv; + + if (!skf_method) { + SKFerr(SKF_F_SKF_OPENAPPLICATION, + SKF_R_SKF_METHOD_NOT_INITIALIZED); + return SAR_NOTINITIALIZEERR; + } + + if (!skf_method->OpenApplication) { + SKFerr(SKF_F_SKF_OPENAPPLICATION, + SKF_R_FUNCTION_NOT_SUPPORTED); + return SAR_NOTSUPPORTYETERR; + } + + if ((rv = skf_method->OpenApplication( + hDev, + szAppName, + phApplication)) != SAR_OK) { + SKFerr(SKF_F_SKF_OPENAPPLICATION, skf_get_error_reason(rv)); + return rv; + } + + return SAR_OK; +} + +ULONG DEVAPI SKF_CloseApplication( + HAPPLICATION hApplication) +{ + ULONG rv; + + if (!skf_method) { + SKFerr(SKF_F_SKF_CLOSEAPPLICATION, + SKF_R_SKF_METHOD_NOT_INITIALIZED); + return SAR_NOTINITIALIZEERR; + } + + if (!skf_method->CloseApplication) { + SKFerr(SKF_F_SKF_CLOSEAPPLICATION, + SKF_R_FUNCTION_NOT_SUPPORTED); + return SAR_NOTSUPPORTYETERR; + } + + if ((rv = skf_method->CloseApplication( + hApplication)) != SAR_OK) { + SKFerr(SKF_F_SKF_CLOSEAPPLICATION, skf_get_error_reason(rv)); + return rv; + } + + return SAR_OK; +} + +ULONG DEVAPI SKF_CreateFile( + HAPPLICATION hApplication, + LPSTR szFileName, + ULONG ulFileSize, + ULONG ulReadRights, + ULONG ulWriteRights) +{ + ULONG rv; + + if (!skf_method) { + SKFerr(SKF_F_SKF_CREATEFILE, + SKF_R_SKF_METHOD_NOT_INITIALIZED); + return SAR_NOTINITIALIZEERR; + } + + if (!skf_method->CreateObject) { + SKFerr(SKF_F_SKF_CREATEFILE, + SKF_R_FUNCTION_NOT_SUPPORTED); + return SAR_NOTSUPPORTYETERR; + } + + if ((rv = skf_method->CreateObject( + hApplication, + szFileName, + ulFileSize, + ulReadRights, + ulWriteRights)) != SAR_OK) { + SKFerr(SKF_F_SKF_CREATEFILE, skf_get_error_reason(rv)); + + //LPSTR str = NULL; + //printf("error = %08X\n", rv); + //SKF_GetErrorString(rv, &str); + //printf("error = %s\n", (char *)str); + + return rv; + } + + return SAR_OK; +} + +ULONG DEVAPI SKF_DeleteFile( + HAPPLICATION hApplication, + LPSTR szFileName) +{ + ULONG rv; + + if (!skf_method) { + SKFerr(SKF_F_SKF_DELETEFILE, + SKF_R_SKF_METHOD_NOT_INITIALIZED); + return SAR_NOTINITIALIZEERR; + } + + if (!skf_method->DeleteObject) { + SKFerr(SKF_F_SKF_DELETEFILE, + SKF_R_FUNCTION_NOT_SUPPORTED); + return SAR_NOTSUPPORTYETERR; + } + + if ((rv = skf_method->DeleteObject( + hApplication, + szFileName)) != SAR_OK) { + SKFerr(SKF_F_SKF_DELETEFILE, skf_get_error_reason(rv)); + return rv; + } + + return SAR_OK; +} + +ULONG DEVAPI SKF_EnumFiles( + HAPPLICATION hApplication, + LPSTR szFileList, + ULONG *pulSize) +{ + ULONG rv; + + if (!skf_method) { + SKFerr(SKF_F_SKF_ENUMFILES, + SKF_R_SKF_METHOD_NOT_INITIALIZED); + return SAR_NOTINITIALIZEERR; + } + + if (!skf_method->EnumObjects) { + SKFerr(SKF_F_SKF_ENUMFILES, + SKF_R_FUNCTION_NOT_SUPPORTED); + return SAR_NOTSUPPORTYETERR; + } + + if ((rv = skf_method->EnumObjects( + hApplication, + szFileList, + pulSize)) != SAR_OK) { + SKFerr(SKF_F_SKF_ENUMFILES, skf_get_error_reason(rv)); + return rv; + } + + return SAR_OK; +} + +ULONG DEVAPI SKF_GetFileInfo( + HAPPLICATION hApplication, + LPSTR szFileName, + FILEATTRIBUTE *pFileInfo) +{ + ULONG rv; + + if (!skf_method) { + SKFerr(SKF_F_SKF_GETFILEINFO, + SKF_R_SKF_METHOD_NOT_INITIALIZED); + return SAR_NOTINITIALIZEERR; + } + + if (!skf_method->GetObjectInfo) { + SKFerr(SKF_F_SKF_GETFILEINFO, + SKF_R_FUNCTION_NOT_SUPPORTED); + return SAR_NOTSUPPORTYETERR; + } + + memset(pFileInfo, 0, sizeof(FILEATTRIBUTE)); + + if ((rv = skf_method->GetObjectInfo( + hApplication, + szFileName, + pFileInfo)) != SAR_OK) { + SKFerr(SKF_F_SKF_GETFILEINFO, skf_get_error_reason(rv)); + return rv; + } + + return SAR_OK; +} + +ULONG DEVAPI SKF_ReadFile( + HAPPLICATION hApplication, + LPSTR szFileName, + ULONG ulOffset, + ULONG ulSize, + BYTE *pbOutData, + ULONG *pulOutLen) +{ + ULONG rv; + + if (!skf_method) { + SKFerr(SKF_F_SKF_READFILE, + SKF_R_SKF_METHOD_NOT_INITIALIZED); + return SAR_NOTINITIALIZEERR; + } + + if (!skf_method->ReadObject) { + SKFerr(SKF_F_SKF_READFILE, + SKF_R_FUNCTION_NOT_SUPPORTED); + return SAR_NOTSUPPORTYETERR; + } + + if ((rv = skf_method->ReadObject( + hApplication, + szFileName, + ulOffset, + ulSize, + pbOutData, + pulOutLen)) != SAR_OK) { + SKFerr(SKF_F_SKF_READFILE, skf_get_error_reason(rv)); + return rv; + } + + return SAR_OK; +} + +ULONG DEVAPI SKF_WriteFile( + HAPPLICATION hApplication, + LPSTR szFileName, + ULONG ulOffset, + BYTE *pbData, + ULONG ulSize) +{ + ULONG rv; + + if (!skf_method) { + SKFerr(SKF_F_SKF_WRITEFILE, + SKF_R_SKF_METHOD_NOT_INITIALIZED); + return SAR_NOTINITIALIZEERR; + } + + if (!skf_method->WriteObject) { + SKFerr(SKF_F_SKF_WRITEFILE, + SKF_R_FUNCTION_NOT_SUPPORTED); + return SAR_NOTSUPPORTYETERR; + } + + if ((rv = skf_method->WriteObject( + hApplication, + szFileName, + ulOffset, + pbData, + ulSize)) != SAR_OK) { + SKFerr(SKF_F_SKF_WRITEFILE, skf_get_error_reason(rv)); + + printf("error = %08X\n", rv); + + return rv; + } + + return SAR_OK; +} + +ULONG DEVAPI SKF_CreateContainer( + HAPPLICATION hApplication, + LPSTR szContainerName, + HCONTAINER *phContainer) +{ + ULONG rv; + + if (!skf_method) { + SKFerr(SKF_F_SKF_CREATECONTAINER, + SKF_R_SKF_METHOD_NOT_INITIALIZED); + return SAR_NOTINITIALIZEERR; + } + + if (!skf_method->CreateContainer) { + SKFerr(SKF_F_SKF_CREATECONTAINER, + SKF_R_FUNCTION_NOT_SUPPORTED); + return SAR_NOTSUPPORTYETERR; + } + + if ((rv = skf_method->CreateContainer( + hApplication, + szContainerName, + phContainer)) != SAR_OK) { + SKFerr(SKF_F_SKF_CREATECONTAINER, skf_get_error_reason(rv)); + return rv; + } + + return SAR_OK; +} + +ULONG DEVAPI SKF_DeleteContainer( + HAPPLICATION hApplication, + LPSTR szContainerName) +{ + ULONG rv; + + if (!skf_method) { + SKFerr(SKF_F_SKF_DELETECONTAINER, + SKF_R_SKF_METHOD_NOT_INITIALIZED); + return SAR_NOTINITIALIZEERR; + } + + if (!skf_method->DeleteContainer) { + SKFerr(SKF_F_SKF_DELETECONTAINER, + SKF_R_FUNCTION_NOT_SUPPORTED); + return SAR_NOTSUPPORTYETERR; + } + + if ((rv = skf_method->DeleteContainer( + hApplication, + szContainerName)) != SAR_OK) { + SKFerr(SKF_F_SKF_DELETECONTAINER, skf_get_error_reason(rv)); + return rv; + } + + return SAR_OK; +} + +ULONG DEVAPI SKF_EnumContainer( + HAPPLICATION hApplication, + LPSTR szContainerName, + ULONG *pulSize) +{ + ULONG rv; + + if (!skf_method) { + SKFerr(SKF_F_SKF_ENUMCONTAINER, + SKF_R_SKF_METHOD_NOT_INITIALIZED); + return SAR_NOTINITIALIZEERR; + } + + if (!skf_method->EnumContainer) { + SKFerr(SKF_F_SKF_ENUMCONTAINER, + SKF_R_FUNCTION_NOT_SUPPORTED); + return SAR_NOTSUPPORTYETERR; + } + + if ((rv = skf_method->EnumContainer( + hApplication, + szContainerName, + pulSize)) != SAR_OK) { + SKFerr(SKF_F_SKF_ENUMCONTAINER, skf_get_error_reason(rv)); + return rv; + } + + return SAR_OK; +} + +ULONG DEVAPI SKF_OpenContainer( + HAPPLICATION hApplication, + LPSTR szContainerName, + HCONTAINER *phContainer) +{ + ULONG rv; + + if (!skf_method) { + SKFerr(SKF_F_SKF_OPENCONTAINER, + SKF_R_SKF_METHOD_NOT_INITIALIZED); + return SAR_NOTINITIALIZEERR; + } + + if (!skf_method->OpenContainer) { + SKFerr(SKF_F_SKF_OPENCONTAINER, + SKF_R_FUNCTION_NOT_SUPPORTED); + return SAR_NOTSUPPORTYETERR; + } + + if ((rv = skf_method->OpenContainer( + hApplication, + szContainerName, + phContainer)) != SAR_OK) { + SKFerr(SKF_F_SKF_OPENCONTAINER, skf_get_error_reason(rv)); + return rv; + } + + return SAR_OK; +} + +ULONG DEVAPI SKF_CloseContainer( + HCONTAINER hContainer) +{ + ULONG rv; + + if (!skf_method) { + SKFerr(SKF_F_SKF_CLOSECONTAINER, + SKF_R_SKF_METHOD_NOT_INITIALIZED); + return SAR_NOTINITIALIZEERR; + } + + if (!skf_method->CloseContainer) { + SKFerr(SKF_F_SKF_CLOSECONTAINER, + SKF_R_FUNCTION_NOT_SUPPORTED); + return SAR_NOTSUPPORTYETERR; + } + + if ((rv = skf_method->CloseContainer( + hContainer)) != SAR_OK) { + SKFerr(SKF_F_SKF_CLOSECONTAINER, skf_get_error_reason(rv)); + return rv; + } + + return SAR_OK; +} + +ULONG DEVAPI SKF_GetContainerType( + HCONTAINER hContainer, + ULONG *pulContainerType) +{ + ULONG rv; + + if (!skf_method) { + SKFerr(SKF_F_SKF_GETCONTAINERTYPE, + SKF_R_SKF_METHOD_NOT_INITIALIZED); + return SAR_NOTINITIALIZEERR; + } + + if (!skf_method->GetContainerType) { + SKFerr(SKF_F_SKF_GETCONTAINERTYPE, + SKF_R_FUNCTION_NOT_SUPPORTED); + return SAR_NOTSUPPORTYETERR; + } + + if ((rv = skf_method->GetContainerType( + hContainer, + pulContainerType)) != SAR_OK) { + SKFerr(SKF_F_SKF_GETCONTAINERTYPE, skf_get_error_reason(rv)); + return rv; + } + + return SAR_OK; +} + +ULONG DEVAPI SKF_ImportCertificate( + HCONTAINER hContainer, + BOOL bExportSignKey, + BYTE *pbCert, + ULONG ulCertLen) +{ + ULONG rv; + + if (!skf_method) { + SKFerr(SKF_F_SKF_IMPORTCERTIFICATE, + SKF_R_SKF_METHOD_NOT_INITIALIZED); + return SAR_NOTINITIALIZEERR; + } + + if (!skf_method->ImportCertificate) { + SKFerr(SKF_F_SKF_IMPORTCERTIFICATE, + SKF_R_FUNCTION_NOT_SUPPORTED); + return SAR_NOTSUPPORTYETERR; + } + + if ((rv = skf_method->ImportCertificate( + hContainer, + bExportSignKey, + pbCert, + ulCertLen)) != SAR_OK) { + SKFerr(SKF_F_SKF_IMPORTCERTIFICATE, skf_get_error_reason(rv)); + return rv; + } + + return SAR_OK; +} + +ULONG DEVAPI SKF_ExportCertificate( + HCONTAINER hContainer, + BOOL bSignFlag, + BYTE *pbCert, + ULONG *pulCertLen) +{ + ULONG rv; + + if (!skf_method) { + SKFerr(SKF_F_SKF_EXPORTCERTIFICATE, + SKF_R_SKF_METHOD_NOT_INITIALIZED); + return SAR_NOTINITIALIZEERR; + } + + if (!skf_method->ExportCertificate) { + SKFerr(SKF_F_SKF_EXPORTCERTIFICATE, + SKF_R_FUNCTION_NOT_SUPPORTED); + return SAR_NOTSUPPORTYETERR; + } + + if ((rv = skf_method->ExportCertificate( + hContainer, + bSignFlag, + pbCert, + pulCertLen)) != SAR_OK) { + SKFerr(SKF_F_SKF_EXPORTCERTIFICATE, skf_get_error_reason(rv)); + return rv; + } + + return SAR_OK; +} + +ULONG DEVAPI SKF_ExportPublicKey( + HCONTAINER hContainer, + BOOL bSignFlag, + BYTE *pbBlob, + ULONG *pulBlobLen) +{ + ULONG rv; + + // TODO: check the output length, clear the memmory. + // if pbBlob is NULL, return the length + + if (!skf_method) { + SKFerr(SKF_F_SKF_EXPORTPUBLICKEY, + SKF_R_SKF_METHOD_NOT_INITIALIZED); + return SAR_NOTINITIALIZEERR; + } + + if (!skf_method->ExportPublicKey) { + SKFerr(SKF_F_SKF_EXPORTPUBLICKEY, + SKF_R_FUNCTION_NOT_SUPPORTED); + return SAR_NOTSUPPORTYETERR; + } + + if ((rv = skf_method->ExportPublicKey( + hContainer, + bSignFlag, + pbBlob, + pulBlobLen)) != SAR_OK) { + SKFerr(SKF_F_SKF_EXPORTPUBLICKEY, skf_get_error_reason(rv)); + return rv; + } + + return SAR_OK; +} + +ULONG DEVAPI SKF_GenRandom( + DEVHANDLE hDev, + BYTE *pbRandom, + ULONG ulRandomLen) +{ + ULONG rv; + + if (!skf_method) { + SKFerr(SKF_F_SKF_GENRANDOM, + SKF_R_SKF_METHOD_NOT_INITIALIZED); + return SAR_NOTINITIALIZEERR; + } + + if (!skf_method->GenRandom) { + SKFerr(SKF_F_SKF_GENRANDOM, + SKF_R_FUNCTION_NOT_SUPPORTED); + return SAR_NOTSUPPORTYETERR; + } + + if ((rv = skf_method->GenRandom( + hDev, + pbRandom, + ulRandomLen)) != SAR_OK) { + SKFerr(SKF_F_SKF_GENRANDOM, skf_get_error_reason(rv)); + return rv; + } + + return SAR_OK; +} + +ULONG DEVAPI SKF_GenExtRSAKey( + DEVHANDLE hDev, + ULONG ulBitsLen, + RSAPRIVATEKEYBLOB *pBlob) +{ + ULONG rv; + + if (!skf_method) { + SKFerr(SKF_F_SKF_GENEXTRSAKEY, + SKF_R_SKF_METHOD_NOT_INITIALIZED); + return SAR_NOTINITIALIZEERR; + } + + if (!skf_method->GenExtRSAKey) { + SKFerr(SKF_F_SKF_GENEXTRSAKEY, + SKF_R_FUNCTION_NOT_SUPPORTED); + return SAR_NOTSUPPORTYETERR; + } + + if ((rv = skf_method->GenExtRSAKey( + hDev, + ulBitsLen, + pBlob)) != SAR_OK) { + SKFerr(SKF_F_SKF_GENEXTRSAKEY, skf_get_error_reason(rv)); + return rv; + } + + return SAR_OK; +} + +ULONG DEVAPI SKF_GenRSAKeyPair( + HCONTAINER hContainer, + ULONG ulBitsLen, + RSAPUBLICKEYBLOB *pBlob) +{ + ULONG rv; + + if (!skf_method) { + SKFerr(SKF_F_SKF_GENRSAKEYPAIR, + SKF_R_SKF_METHOD_NOT_INITIALIZED); + return SAR_NOTINITIALIZEERR; + } + + if (!skf_method->GenRSAKeyPair) { + SKFerr(SKF_F_SKF_GENRSAKEYPAIR, + SKF_R_FUNCTION_NOT_SUPPORTED); + return SAR_NOTSUPPORTYETERR; + } + + memset(pBlob, 0, sizeof(RSAPUBLICKEYBLOB)); + if ((rv = skf_method->GenRSAKeyPair( + hContainer, + ulBitsLen, + pBlob)) != SAR_OK) { + SKFerr(SKF_F_SKF_GENRSAKEYPAIR, skf_get_error_reason(rv)); + return rv; + } + + return SAR_OK; +} + +ULONG DEVAPI SKF_ImportRSAKeyPair( + HCONTAINER hContainer, + ULONG ulSymAlgId, + BYTE *pbWrappedKey, + ULONG ulWrappedKeyLen, + BYTE *pbEncryptedData, + ULONG ulEncryptedDataLen) +{ + ULONG rv; + + if (!skf_method) { + SKFerr(SKF_F_SKF_IMPORTRSAKEYPAIR, + SKF_R_SKF_METHOD_NOT_INITIALIZED); + return SAR_NOTINITIALIZEERR; + } + + if (!skf_method->ImportRSAKeyPair) { + SKFerr(SKF_F_SKF_IMPORTRSAKEYPAIR, + SKF_R_FUNCTION_NOT_SUPPORTED); + return SAR_NOTSUPPORTYETERR; + } + + if (skf_vendor) { + if (!(ulSymAlgId = skf_vendor->get_cipher_algor(ulSymAlgId))) { + SKFerr(SKF_F_SKF_IMPORTRSAKEYPAIR, + SKF_R_NOT_SUPPORTED_CIPHER_ALGOR); + return SAR_NOTSUPPORTYETERR; + } + } + + if ((rv = skf_method->ImportRSAKeyPair( + hContainer, + ulSymAlgId, + pbWrappedKey, + ulWrappedKeyLen, + pbEncryptedData, + ulEncryptedDataLen)) != SAR_OK) { + SKFerr(SKF_F_SKF_IMPORTRSAKEYPAIR, skf_get_error_reason(rv)); + return rv; + } + + return SAR_OK; +} + +ULONG DEVAPI SKF_RSASignData( + HCONTAINER hContainer, + BYTE *pbData, + ULONG ulDataLen, + BYTE *pbSignature, + ULONG *pulSignLen) +{ + ULONG rv; + + if (!skf_method) { + SKFerr(SKF_F_SKF_RSASIGNDATA, + SKF_R_SKF_METHOD_NOT_INITIALIZED); + return SAR_NOTINITIALIZEERR; + } + + if (!skf_method->RSASignData) { + SKFerr(SKF_F_SKF_RSASIGNDATA, + SKF_R_FUNCTION_NOT_SUPPORTED); + return SAR_NOTSUPPORTYETERR; + } + + if ((rv = skf_method->RSASignData( + hContainer, + pbData, + ulDataLen, + pbSignature, + pulSignLen)) != SAR_OK) { + SKFerr(SKF_F_SKF_RSASIGNDATA, skf_get_error_reason(rv)); + return rv; + } + + return SAR_OK; +} + +ULONG DEVAPI SKF_RSAVerify( + DEVHANDLE hDev, + RSAPUBLICKEYBLOB *pRSAPubKeyBlob, + BYTE *pbData, + ULONG ulDataLen, + BYTE *pbSignature, + ULONG ulSignLen) +{ + ULONG rv; + + if (!skf_method) { + SKFerr(SKF_F_SKF_RSAVERIFY, + SKF_R_SKF_METHOD_NOT_INITIALIZED); + return SAR_NOTINITIALIZEERR; + } + + if (!skf_method->RSAVerify) { + SKFerr(SKF_F_SKF_RSAVERIFY, + SKF_R_FUNCTION_NOT_SUPPORTED); + return SAR_NOTSUPPORTYETERR; + } + + if ((rv = skf_method->RSAVerify( + hDev, + pRSAPubKeyBlob, + pbData, + ulDataLen, + pbSignature, + ulSignLen)) != SAR_OK) { + SKFerr(SKF_F_SKF_RSAVERIFY, skf_get_error_reason(rv)); + return rv; + } + + return SAR_OK; +} + +ULONG DEVAPI SKF_RSAExportSessionKey( + HCONTAINER hContainer, + ULONG ulAlgId, + RSAPUBLICKEYBLOB *pPubKey, + BYTE *pbData, + ULONG *pulDataLen, + HANDLE *phSessionKey) +{ + ULONG rv; + + if (!skf_method) { + SKFerr(SKF_F_SKF_RSAEXPORTSESSIONKEY, + SKF_R_SKF_METHOD_NOT_INITIALIZED); + return SAR_NOTINITIALIZEERR; + } + + if (!skf_method->RSAExportSessionKey) { + SKFerr(SKF_F_SKF_RSAEXPORTSESSIONKEY, + SKF_R_FUNCTION_NOT_SUPPORTED); + return SAR_NOTSUPPORTYETERR; + } + + if (skf_vendor) { + if (!(ulAlgId = skf_vendor->get_cipher_algor(ulAlgId))) { + SKFerr(SKF_F_SKF_RSAEXPORTSESSIONKEY, + SKF_R_NOT_SUPPORTED_CIPHER_ALGOR); + return SAR_NOTSUPPORTYETERR; + } + } + + if ((rv = skf_method->RSAExportSessionKey( + hContainer, + ulAlgId, + pPubKey, + pbData, + pulDataLen, + phSessionKey)) != SAR_OK) { + SKFerr(SKF_F_SKF_RSAEXPORTSESSIONKEY, skf_get_error_reason(rv)); + return rv; + } + + return SAR_OK; +} + +ULONG DEVAPI SKF_ExtRSAPubKeyOperation( + DEVHANDLE hDev, + RSAPUBLICKEYBLOB *pRSAPubKeyBlob, + BYTE *pbInput, + ULONG ulInputLen, + BYTE *pbOutput, + ULONG *pulOutputLen) +{ + ULONG rv; + + if (!skf_method) { + SKFerr(SKF_F_SKF_EXTRSAPUBKEYOPERATION, + SKF_R_SKF_METHOD_NOT_INITIALIZED); + return SAR_NOTINITIALIZEERR; + } + + if (!skf_method->ExtRSAPubKeyOperation) { + SKFerr(SKF_F_SKF_EXTRSAPUBKEYOPERATION, + SKF_R_FUNCTION_NOT_SUPPORTED); + return SAR_NOTSUPPORTYETERR; + } + + if ((rv = skf_method->ExtRSAPubKeyOperation( + hDev, + pRSAPubKeyBlob, + pbInput, + ulInputLen, + pbOutput, + pulOutputLen)) != SAR_OK) { + SKFerr(SKF_F_SKF_EXTRSAPUBKEYOPERATION, skf_get_error_reason(rv)); + return rv; + } + + return SAR_OK; +} + +ULONG DEVAPI SKF_ExtRSAPriKeyOperation( + DEVHANDLE hDev, + RSAPRIVATEKEYBLOB *pRSAPriKeyBlob, + BYTE *pbInput, + ULONG ulInputLen, + BYTE *pbOutput, + ULONG *pulOutputLen) +{ + ULONG rv; + + if (!skf_method) { + SKFerr(SKF_F_SKF_EXTRSAPRIKEYOPERATION, + SKF_R_SKF_METHOD_NOT_INITIALIZED); + return SAR_NOTINITIALIZEERR; + } + + if (!skf_method->ExtRSAPriKeyOperation) { + SKFerr(SKF_F_SKF_EXTRSAPRIKEYOPERATION, + SKF_R_FUNCTION_NOT_SUPPORTED); + return SAR_NOTSUPPORTYETERR; + } + + if ((rv = skf_method->ExtRSAPriKeyOperation( + hDev, + pRSAPriKeyBlob, + pbInput, + ulInputLen, + pbOutput, + pulOutputLen)) != SAR_OK) { + SKFerr(SKF_F_SKF_EXTRSAPRIKEYOPERATION, skf_get_error_reason(rv)); + return rv; + } + + return SAR_OK; +} + +ULONG DEVAPI SKF_GenECCKeyPair( + HCONTAINER hContainer, + ULONG ulAlgId, + ECCPUBLICKEYBLOB *pBlob) +{ + ULONG rv; + + if (!skf_method) { + SKFerr(SKF_F_SKF_GENECCKEYPAIR, + SKF_R_SKF_METHOD_NOT_INITIALIZED); + return SAR_NOTINITIALIZEERR; + } + + if (!skf_method->GenECCKeyPair) { + SKFerr(SKF_F_SKF_GENECCKEYPAIR, + SKF_R_FUNCTION_NOT_SUPPORTED); + return SAR_NOTSUPPORTYETERR; + } + + if (skf_vendor) { + if (!(ulAlgId = skf_vendor->get_pkey_algor(ulAlgId))) { + SKFerr(SKF_F_SKF_GENECCKEYPAIR, + SKF_R_NOT_SUPPORTED_PKEY_ALGOR); + return SAR_NOTSUPPORTYETERR; + } + } + + memset(pBlob, 0, sizeof(ECCPUBLICKEYBLOB)); + if ((rv = skf_method->GenECCKeyPair( + hContainer, + ulAlgId, + pBlob)) != SAR_OK) { + SKFerr(SKF_F_SKF_GENECCKEYPAIR, skf_get_error_reason(rv)); + return rv; + } + + return SAR_OK; +} + +ULONG DEVAPI SKF_ImportECCKeyPair( + HCONTAINER hContainer, + ENVELOPEDKEYBLOB *pEnvelopedKeyBlob) +{ + ULONG rv; + + if (!skf_method) { + SKFerr(SKF_F_SKF_IMPORTECCKEYPAIR, + SKF_R_SKF_METHOD_NOT_INITIALIZED); + return SAR_NOTINITIALIZEERR; + } + + if (!skf_method->ImportECCKeyPair) { + SKFerr(SKF_F_SKF_IMPORTECCKEYPAIR, + SKF_R_FUNCTION_NOT_SUPPORTED); + return SAR_NOTSUPPORTYETERR; + } + + if ((rv = skf_method->ImportECCKeyPair( + hContainer, + pEnvelopedKeyBlob)) != SAR_OK) { + SKFerr(SKF_F_SKF_IMPORTECCKEYPAIR, skf_get_error_reason(rv)); + printf("%s %d: error = %08X\n", __FILE__, __LINE__, rv); + return rv; + } + + return SAR_OK; +} + +ULONG DEVAPI SKF_ECCSignData( + HCONTAINER hContainer, + BYTE *pbDigest, + ULONG ulDigestLen, + ECCSIGNATUREBLOB *pSignature) +{ + ULONG rv; + + if (!skf_method) { + SKFerr(SKF_F_SKF_ECCSIGNDATA, + SKF_R_SKF_METHOD_NOT_INITIALIZED); + return SAR_NOTINITIALIZEERR; + } + + if (!skf_method->ECCSignData) { + SKFerr(SKF_F_SKF_ECCSIGNDATA, + SKF_R_FUNCTION_NOT_SUPPORTED); + return SAR_NOTSUPPORTYETERR; + } + + if ((rv = skf_method->ECCSignData( + hContainer, + pbDigest, + ulDigestLen, + pSignature)) != SAR_OK) { + SKFerr(SKF_F_SKF_ECCSIGNDATA, skf_get_error_reason(rv)); + return rv; + } + + return SAR_OK; +} + +ULONG DEVAPI SKF_ECCVerify( + DEVHANDLE hDev, + ECCPUBLICKEYBLOB *pECCPubKeyBlob, + BYTE *pbData, + ULONG ulDataLen, + ECCSIGNATUREBLOB *pSignature) +{ + ULONG rv; + + if (!skf_method) { + SKFerr(SKF_F_SKF_ECCVERIFY, + SKF_R_SKF_METHOD_NOT_INITIALIZED); + return SAR_NOTINITIALIZEERR; + } + + if (!skf_method->ECCVerify) { + SKFerr(SKF_F_SKF_ECCVERIFY, + SKF_R_FUNCTION_NOT_SUPPORTED); + return SAR_NOTSUPPORTYETERR; + } + + if ((rv = skf_method->ECCVerify( + hDev, + pECCPubKeyBlob, + pbData, + ulDataLen, + pSignature)) != SAR_OK) { + SKFerr(SKF_F_SKF_ECCVERIFY, skf_get_error_reason(rv)); + return rv; + } + + return SAR_OK; +} + +ULONG DEVAPI SKF_ECCExportSessionKey( + HCONTAINER hContainer, + ULONG ulAlgId, + ECCPUBLICKEYBLOB *pPubKey, + ECCCIPHERBLOB *pData, + HANDLE *phSessionKey) +{ + ULONG rv; + + if (!skf_method) { + SKFerr(SKF_F_SKF_ECCEXPORTSESSIONKEY, + SKF_R_SKF_METHOD_NOT_INITIALIZED); + return SAR_NOTINITIALIZEERR; + } + + if (!skf_method->ECCExportSessionKey) { + SKFerr(SKF_F_SKF_ECCEXPORTSESSIONKEY, + SKF_R_FUNCTION_NOT_SUPPORTED); + return SAR_NOTSUPPORTYETERR; + } + + if (skf_vendor) { + if (!(ulAlgId = skf_vendor->get_cipher_algor(ulAlgId))) { + SKFerr(SKF_F_SKF_ECCEXPORTSESSIONKEY, + SKF_R_NOT_SUPPORTED_CIPHER_ALGOR); + return SAR_NOTSUPPORTYETERR; + } + } + + if ((rv = skf_method->ECCExportSessionKey( + hContainer, + ulAlgId, + pPubKey, + pData, + phSessionKey)) != SAR_OK) { + SKFerr(SKF_F_SKF_ECCEXPORTSESSIONKEY, skf_get_error_reason(rv)); + return rv; + } + + return SAR_OK; +} + +ULONG DEVAPI SKF_ECCDecrypt( + HCONTAINER hContainer, + ECCCIPHERBLOB *pCipherText, + BYTE *pbPlainText, + ULONG *pulPlainTextLen) +{ + ULONG rv; + + if (!skf_method) { + SKFerr(SKF_F_SKF_ECCDECRYPT, + SKF_R_SKF_METHOD_NOT_INITIALIZED); + return SAR_NOTINITIALIZEERR; + } + + if (!skf_method->ECCDecrypt) { + SKFerr(SKF_F_SKF_ECCDECRYPT, + SKF_R_FUNCTION_NOT_SUPPORTED); + return SAR_NOTSUPPORTYETERR; + } + + if ((rv = skf_method->ECCDecrypt( + hContainer, + pCipherText, + pbPlainText, + pulPlainTextLen)) != SAR_OK) { + SKFerr(SKF_F_SKF_ECCDECRYPT, skf_get_error_reason(rv)); + return rv; + } + + return SAR_OK; +} + +ULONG DEVAPI SKF_ExtECCEncrypt( + DEVHANDLE hDev, + ECCPUBLICKEYBLOB *pECCPubKeyBlob, + BYTE *pbPlainText, + ULONG ulPlainTextLen, + ECCCIPHERBLOB *pCipherText) +{ + ULONG rv; + + if (!skf_method) { + SKFerr(SKF_F_SKF_EXTECCENCRYPT, + SKF_R_SKF_METHOD_NOT_INITIALIZED); + return SAR_NOTINITIALIZEERR; + } + + if (!skf_method->ExtECCEncrypt) { + SKFerr(SKF_F_SKF_EXTECCENCRYPT, + SKF_R_FUNCTION_NOT_SUPPORTED); + return SAR_NOTSUPPORTYETERR; + } + + if ((rv = skf_method->ExtECCEncrypt( + hDev, + pECCPubKeyBlob, + pbPlainText, + ulPlainTextLen, + pCipherText)) != SAR_OK) { + SKFerr(SKF_F_SKF_EXTECCENCRYPT, skf_get_error_reason(rv)); + return rv; + } + + return SAR_OK; +} + +ULONG DEVAPI SKF_ExtECCDecrypt( + DEVHANDLE hDev, + ECCPRIVATEKEYBLOB *pECCPriKeyBlob, + ECCCIPHERBLOB *pCipherText, + BYTE *pbPlainText, + ULONG *pulPlainTextLen) +{ + ULONG rv; + + if (!skf_method) { + SKFerr(SKF_F_SKF_EXTECCDECRYPT, + SKF_R_SKF_METHOD_NOT_INITIALIZED); + return SAR_NOTINITIALIZEERR; + } + + if (!skf_method->ExtECCDecrypt) { + SKFerr(SKF_F_SKF_EXTECCDECRYPT, + SKF_R_FUNCTION_NOT_SUPPORTED); + return SAR_NOTSUPPORTYETERR; + } + + if ((rv = skf_method->ExtECCDecrypt( + hDev, + pECCPriKeyBlob, + pCipherText, + pbPlainText, + pulPlainTextLen)) != SAR_OK) { + SKFerr(SKF_F_SKF_EXTECCDECRYPT, skf_get_error_reason(rv)); + return rv; + } + + return SAR_OK; +} + +ULONG DEVAPI SKF_ExtECCSign( + DEVHANDLE hDev, + ECCPRIVATEKEYBLOB *pECCPriKeyBlob, + BYTE *pbData, + ULONG ulDataLen, + ECCSIGNATUREBLOB *pSignature) +{ + ULONG rv; + + if (!skf_method) { + SKFerr(SKF_F_SKF_EXTECCSIGN, + SKF_R_SKF_METHOD_NOT_INITIALIZED); + return SAR_NOTINITIALIZEERR; + } + + if (!skf_method->ExtECCSign) { + SKFerr(SKF_F_SKF_EXTECCSIGN, + SKF_R_FUNCTION_NOT_SUPPORTED); + return SAR_NOTSUPPORTYETERR; + } + + if ((rv = skf_method->ExtECCSign( + hDev, + pECCPriKeyBlob, + pbData, + ulDataLen, + pSignature)) != SAR_OK) { + SKFerr(SKF_F_SKF_EXTECCSIGN, skf_get_error_reason(rv)); + return rv; + } + + return SAR_OK; +} + +ULONG DEVAPI SKF_ExtECCVerify( + DEVHANDLE hDev, + ECCPUBLICKEYBLOB *pECCPubKeyBlob, + BYTE *pbData, + ULONG ulDataLen, + ECCSIGNATUREBLOB *pSignature) +{ + ULONG rv; + + if (!skf_method) { + SKFerr(SKF_F_SKF_EXTECCVERIFY, + SKF_R_SKF_METHOD_NOT_INITIALIZED); + return SAR_NOTINITIALIZEERR; + } + + if (!skf_method->ExtECCVerify) { + SKFerr(SKF_F_SKF_EXTECCVERIFY, + SKF_R_FUNCTION_NOT_SUPPORTED); + return SAR_NOTSUPPORTYETERR; + } + + if ((rv = skf_method->ExtECCVerify( + hDev, + pECCPubKeyBlob, + pbData, + ulDataLen, + pSignature)) != SAR_OK) { + SKFerr(SKF_F_SKF_EXTECCVERIFY, skf_get_error_reason(rv)); + return rv; + } + + return SAR_OK; +} + +ULONG DEVAPI SKF_GenerateAgreementDataWithECC( + HCONTAINER hContainer, + ULONG ulAlgId, + ECCPUBLICKEYBLOB *pTempECCPubKeyBlob, + BYTE *pbID, + ULONG ulIDLen, + HANDLE *phAgreementHandle) +{ + ULONG rv; + + if (!skf_method) { + SKFerr(SKF_F_SKF_GENERATEAGREEMENTDATAWITHECC, + SKF_R_SKF_METHOD_NOT_INITIALIZED); + return SAR_NOTINITIALIZEERR; + } + + if (!skf_method->GenerateAgreementDataWithECC) { + SKFerr(SKF_F_SKF_GENERATEAGREEMENTDATAWITHECC, + SKF_R_FUNCTION_NOT_SUPPORTED); + return SAR_NOTSUPPORTYETERR; + } + + if (skf_vendor) { + if (!(ulAlgId = skf_vendor->get_cipher_algor(ulAlgId))) { + SKFerr(SKF_F_SKF_GENERATEAGREEMENTDATAWITHECC, + SKF_R_NOT_SUPPORTED_CIPHER_ALGOR); + return SAR_NOTSUPPORTYETERR; + } + } + + if ((rv = skf_method->GenerateAgreementDataWithECC( + hContainer, + ulAlgId, + pTempECCPubKeyBlob, + pbID, + ulIDLen, + phAgreementHandle)) != SAR_OK) { + SKFerr(SKF_F_SKF_GENERATEAGREEMENTDATAWITHECC, skf_get_error_reason(rv)); + return rv; + } + + return SAR_OK; +} + +ULONG DEVAPI SKF_GenerateAgreementDataAndKeyWithECC( + HANDLE hContainer, + ULONG ulAlgId, + ECCPUBLICKEYBLOB *pSponsorECCPubKeyBlob, + ECCPUBLICKEYBLOB *pSponsorTempECCPubKeyBlob, + ECCPUBLICKEYBLOB *pTempECCPubKeyBlob, + BYTE *pbID, + ULONG ulIDLen, + BYTE *pbSponsorID, + ULONG ulSponsorIDLen, + HANDLE *phKeyHandle) +{ + ULONG rv; + + if (!skf_method) { + SKFerr(SKF_F_SKF_GENERATEAGREEMENTDATAANDKEYWITHECC, + SKF_R_SKF_METHOD_NOT_INITIALIZED); + return SAR_NOTINITIALIZEERR; + } + + if (!skf_method->GenerateAgreementDataAndKeyWithECC) { + SKFerr(SKF_F_SKF_GENERATEAGREEMENTDATAANDKEYWITHECC, + SKF_R_FUNCTION_NOT_SUPPORTED); + return SAR_NOTSUPPORTYETERR; + } + + if (skf_vendor) { + if (!(ulAlgId = skf_vendor->get_cipher_algor(ulAlgId))) { + SKFerr(SKF_F_SKF_GENERATEAGREEMENTDATAANDKEYWITHECC, + SKF_R_NOT_SUPPORTED_CIPHER_ALGOR); + return SAR_NOTSUPPORTYETERR; + } + } + + if ((rv = skf_method->GenerateAgreementDataAndKeyWithECC( + hContainer, + ulAlgId, + pSponsorECCPubKeyBlob, + pSponsorTempECCPubKeyBlob, + pTempECCPubKeyBlob, + pbID, + ulIDLen, + pbSponsorID, + ulSponsorIDLen, + phKeyHandle)) != SAR_OK) { + SKFerr(SKF_F_SKF_GENERATEAGREEMENTDATAANDKEYWITHECC, skf_get_error_reason(rv)); + return rv; + } + + return SAR_OK; +} + +ULONG DEVAPI SKF_GenerateKeyWithECC( + HANDLE hAgreementHandle, + ECCPUBLICKEYBLOB *pECCPubKeyBlob, + ECCPUBLICKEYBLOB *pTempECCPubKeyBlob, + BYTE *pbID, + ULONG ulIDLen, + HANDLE *phKeyHandle) +{ + ULONG rv; + + if (!skf_method) { + SKFerr(SKF_F_SKF_GENERATEKEYWITHECC, + SKF_R_SKF_METHOD_NOT_INITIALIZED); + return SAR_NOTINITIALIZEERR; + } + + if (!skf_method->GenerateKeyWithECC) { + SKFerr(SKF_F_SKF_GENERATEKEYWITHECC, + SKF_R_FUNCTION_NOT_SUPPORTED); + return SAR_NOTSUPPORTYETERR; + } + + if ((rv = skf_method->GenerateKeyWithECC( + hAgreementHandle, + pECCPubKeyBlob, + pTempECCPubKeyBlob, + pbID, + ulIDLen, + phKeyHandle)) != SAR_OK) { + SKFerr(SKF_F_SKF_GENERATEKEYWITHECC, skf_get_error_reason(rv)); + return rv; + } + + return SAR_OK; +} + +ULONG DEVAPI SKF_ImportSessionKey( + HCONTAINER hContainer, + ULONG ulAlgId, + BYTE *pbWrapedData, + ULONG ulWrapedLen, + HANDLE *phKey) +{ + ULONG rv; + + if (!skf_method) { + SKFerr(SKF_F_SKF_IMPORTSESSIONKEY, + SKF_R_SKF_METHOD_NOT_INITIALIZED); + return SAR_NOTINITIALIZEERR; + } + + if (!skf_method->ImportSessionKey) { + SKFerr(SKF_F_SKF_IMPORTSESSIONKEY, + SKF_R_FUNCTION_NOT_SUPPORTED); + return SAR_NOTSUPPORTYETERR; + } + + if (skf_vendor) { + if (!(ulAlgId = skf_vendor->get_cipher_algor(ulAlgId))) { + SKFerr(SKF_F_SKF_IMPORTSESSIONKEY, + SKF_R_NOT_SUPPORTED_CIPHER_ALGOR); + return SAR_NOTSUPPORTYETERR; + } + } + + if ((rv = skf_method->ImportSessionKey( + hContainer, + ulAlgId, + pbWrapedData, + ulWrapedLen, + phKey)) != SAR_OK) { + SKFerr(SKF_F_SKF_IMPORTSESSIONKEY, skf_get_error_reason(rv)); + return rv; + } + + return SAR_OK; +} + +ULONG DEVAPI SKF_SetSymmKey( + DEVHANDLE hDev, + BYTE *pbKey, + ULONG ulAlgID, + HANDLE *phKey) +{ + ULONG rv; + + if (!skf_method) { + SKFerr(SKF_F_SKF_SETSYMMKEY, + SKF_R_SKF_METHOD_NOT_INITIALIZED); + return SAR_NOTINITIALIZEERR; + } + + if (!skf_method->SetSymmKey) { + SKFerr(SKF_F_SKF_SETSYMMKEY, + SKF_R_FUNCTION_NOT_SUPPORTED); + return SAR_NOTSUPPORTYETERR; + } + + if (skf_vendor) { + if (!(ulAlgID = skf_vendor->get_cipher_algor(ulAlgID))) { + SKFerr(SKF_F_SKF_SETSYMMKEY, + SKF_R_NOT_SUPPORTED_CIPHER_ALGOR); + return SAR_NOTSUPPORTYETERR; + } + } + + if ((rv = skf_method->SetSymmKey( + hDev, + pbKey, + ulAlgID, + phKey)) != SAR_OK) { + SKFerr(SKF_F_SKF_SETSYMMKEY, skf_get_error_reason(rv)); + return rv; + } + + return SAR_OK; +} + +ULONG DEVAPI SKF_EncryptInit( + HANDLE hKey, + BLOCKCIPHERPARAM EncryptParam) +{ + ULONG rv; + + if (!skf_method) { + SKFerr(SKF_F_SKF_ENCRYPTINIT, + SKF_R_SKF_METHOD_NOT_INITIALIZED); + return SAR_NOTINITIALIZEERR; + } + + if (!skf_method->EncryptInit) { + SKFerr(SKF_F_SKF_ENCRYPTINIT, + SKF_R_FUNCTION_NOT_SUPPORTED); + return SAR_NOTSUPPORTYETERR; + } + + if ((rv = skf_method->EncryptInit( + hKey, + EncryptParam)) != SAR_OK) { + SKFerr(SKF_F_SKF_ENCRYPTINIT, skf_get_error_reason(rv)); + return rv; + } + + return SAR_OK; +} + +ULONG DEVAPI SKF_Encrypt( + HANDLE hKey, + BYTE *pbData, + ULONG ulDataLen, + BYTE *pbEncryptedData, + ULONG *pulEncryptedLen) +{ + ULONG rv; + + if (!skf_method) { + SKFerr(SKF_F_SKF_ENCRYPT, + SKF_R_SKF_METHOD_NOT_INITIALIZED); + return SAR_NOTINITIALIZEERR; + } + + if (!skf_method->Encrypt) { + SKFerr(SKF_F_SKF_ENCRYPT, + SKF_R_FUNCTION_NOT_SUPPORTED); + return SAR_NOTSUPPORTYETERR; + } + + if ((rv = skf_method->Encrypt( + hKey, + pbData, + ulDataLen, + pbEncryptedData, + pulEncryptedLen)) != SAR_OK) { + SKFerr(SKF_F_SKF_ENCRYPT, skf_get_error_reason(rv)); + return rv; + } + + return SAR_OK; +} + +ULONG DEVAPI SKF_EncryptUpdate( + HANDLE hKey, + BYTE *pbData, + ULONG ulDataLen, + BYTE *pbEncryptedData, + ULONG *pulEncryptedLen) +{ + ULONG rv; + + if (!skf_method) { + SKFerr(SKF_F_SKF_ENCRYPTUPDATE, + SKF_R_SKF_METHOD_NOT_INITIALIZED); + return SAR_NOTINITIALIZEERR; + } + + if (!skf_method->EncryptUpdate) { + SKFerr(SKF_F_SKF_ENCRYPTUPDATE, + SKF_R_FUNCTION_NOT_SUPPORTED); + return SAR_NOTSUPPORTYETERR; + } + + if ((rv = skf_method->EncryptUpdate( + hKey, + pbData, + ulDataLen, + pbEncryptedData, + pulEncryptedLen)) != SAR_OK) { + SKFerr(SKF_F_SKF_ENCRYPTUPDATE, skf_get_error_reason(rv)); + return rv; + } + + return SAR_OK; +} + +ULONG DEVAPI SKF_EncryptFinal( + HANDLE hKey, + BYTE *pbEncryptedData, + ULONG *pulEncryptedDataLen) +{ + ULONG rv; + + if (!skf_method) { + SKFerr(SKF_F_SKF_ENCRYPTFINAL, + SKF_R_SKF_METHOD_NOT_INITIALIZED); + return SAR_NOTINITIALIZEERR; + } + + if (!skf_method->EncryptFinal) { + SKFerr(SKF_F_SKF_ENCRYPTFINAL, + SKF_R_FUNCTION_NOT_SUPPORTED); + return SAR_NOTSUPPORTYETERR; + } + + if ((rv = skf_method->EncryptFinal( + hKey, + pbEncryptedData, + pulEncryptedDataLen)) != SAR_OK) { + SKFerr(SKF_F_SKF_ENCRYPTFINAL, skf_get_error_reason(rv)); + return rv; + } + + return SAR_OK; +} + +ULONG DEVAPI SKF_DecryptInit( + HANDLE hKey, + BLOCKCIPHERPARAM DecryptParam) +{ + ULONG rv; + + if (!skf_method) { + SKFerr(SKF_F_SKF_DECRYPTINIT, + SKF_R_SKF_METHOD_NOT_INITIALIZED); + return SAR_NOTINITIALIZEERR; + } + + if (!skf_method->DecryptInit) { + SKFerr(SKF_F_SKF_DECRYPTINIT, + SKF_R_FUNCTION_NOT_SUPPORTED); + return SAR_NOTSUPPORTYETERR; + } + + if ((rv = skf_method->DecryptInit( + hKey, + DecryptParam)) != SAR_OK) { + SKFerr(SKF_F_SKF_DECRYPTINIT, skf_get_error_reason(rv)); + return rv; + } + + return SAR_OK; +} + +ULONG DEVAPI SKF_Decrypt( + HANDLE hKey, + BYTE *pbEncryptedData, + ULONG ulEncryptedLen, + BYTE *pbData, + ULONG *pulDataLen) +{ + ULONG rv; + + if (!skf_method) { + SKFerr(SKF_F_SKF_DECRYPT, + SKF_R_SKF_METHOD_NOT_INITIALIZED); + return SAR_NOTINITIALIZEERR; + } + + if (!skf_method->Decrypt) { + SKFerr(SKF_F_SKF_DECRYPT, + SKF_R_FUNCTION_NOT_SUPPORTED); + return SAR_NOTSUPPORTYETERR; + } + + if ((rv = skf_method->Decrypt( + hKey, + pbEncryptedData, + ulEncryptedLen, + pbData, + pulDataLen)) != SAR_OK) { + SKFerr(SKF_F_SKF_DECRYPT, skf_get_error_reason(rv)); + return rv; + } + + return SAR_OK; +} + +ULONG DEVAPI SKF_DecryptUpdate( + HANDLE hKey, + BYTE *pbEncryptedData, + ULONG ulEncryptedLen, + BYTE *pbData, + ULONG *pulDataLen) +{ + ULONG rv; + + if (!skf_method) { + SKFerr(SKF_F_SKF_DECRYPTUPDATE, + SKF_R_SKF_METHOD_NOT_INITIALIZED); + return SAR_NOTINITIALIZEERR; + } + + if (!skf_method->DecryptUpdate) { + SKFerr(SKF_F_SKF_DECRYPTUPDATE, + SKF_R_FUNCTION_NOT_SUPPORTED); + return SAR_NOTSUPPORTYETERR; + } + + if ((rv = skf_method->DecryptUpdate( + hKey, + pbEncryptedData, + ulEncryptedLen, + pbData, + pulDataLen)) != SAR_OK) { + SKFerr(SKF_F_SKF_DECRYPTUPDATE, skf_get_error_reason(rv)); + return rv; + } + + return SAR_OK; +} + +ULONG DEVAPI SKF_DecryptFinal( + HANDLE hKey, + BYTE *pbDecryptedData, + ULONG *pulDecryptedDataLen) +{ + ULONG rv; + + if (!skf_method) { + SKFerr(SKF_F_SKF_DECRYPTFINAL, + SKF_R_SKF_METHOD_NOT_INITIALIZED); + return SAR_NOTINITIALIZEERR; + } + + if (!skf_method->DecryptFinal) { + SKFerr(SKF_F_SKF_DECRYPTFINAL, + SKF_R_FUNCTION_NOT_SUPPORTED); + return SAR_NOTSUPPORTYETERR; + } + + if ((rv = skf_method->DecryptFinal( + hKey, + pbDecryptedData, + pulDecryptedDataLen)) != SAR_OK) { + SKFerr(SKF_F_SKF_DECRYPTFINAL, skf_get_error_reason(rv)); + return rv; + } + + return SAR_OK; +} + +ULONG DEVAPI SKF_DigestInit( + DEVHANDLE hDev, + ULONG ulAlgID, + ECCPUBLICKEYBLOB *pPubKey, + BYTE *pbID, + ULONG ulIDLen, + HANDLE *phHash) +{ + ULONG rv; + + if (!skf_method) { + SKFerr(SKF_F_SKF_DIGESTINIT, + SKF_R_SKF_METHOD_NOT_INITIALIZED); + return SAR_NOTINITIALIZEERR; + } + + if (!skf_method->DigestInit) { + SKFerr(SKF_F_SKF_DIGESTINIT, + SKF_R_FUNCTION_NOT_SUPPORTED); + return SAR_NOTSUPPORTYETERR; + } + + if (skf_vendor) { + if (!(ulAlgID = skf_vendor->get_digest_algor(ulAlgID))) { + SKFerr(SKF_F_SKF_DIGESTINIT, + SKF_R_NOT_SUPPORTED_DIGEST_ALGOR); + return SAR_NOTSUPPORTYETERR; + } + } + + if ((rv = skf_method->DigestInit( + hDev, + ulAlgID, + pPubKey, + pbID, + ulIDLen, + phHash)) != SAR_OK) { + SKFerr(SKF_F_SKF_DIGESTINIT, skf_get_error_reason(rv)); + return rv; + } + + return SAR_OK; +} + +ULONG DEVAPI SKF_Digest( + HANDLE hHash, + BYTE *pbData, + ULONG ulDataLen, + BYTE *pbHashData, + ULONG *pulHashLen) +{ + ULONG rv; + + if (!skf_method) { + SKFerr(SKF_F_SKF_DIGEST, + SKF_R_SKF_METHOD_NOT_INITIALIZED); + return SAR_NOTINITIALIZEERR; + } + + if (!skf_method->Digest) { + SKFerr(SKF_F_SKF_DIGEST, + SKF_R_FUNCTION_NOT_SUPPORTED); + return SAR_NOTSUPPORTYETERR; + } + + if ((rv = skf_method->Digest( + hHash, + pbData, + ulDataLen, + pbHashData, + pulHashLen)) != SAR_OK) { + SKFerr(SKF_F_SKF_DIGEST, skf_get_error_reason(rv)); + return rv; + } + + return SAR_OK; +} + +ULONG DEVAPI SKF_DigestUpdate( + HANDLE hHash, + BYTE *pbData, + ULONG ulDataLen) +{ + ULONG rv; + + if (!skf_method) { + SKFerr(SKF_F_SKF_DIGESTUPDATE, + SKF_R_SKF_METHOD_NOT_INITIALIZED); + return SAR_NOTINITIALIZEERR; + } + + if (!skf_method->DigestUpdate) { + SKFerr(SKF_F_SKF_DIGESTUPDATE, + SKF_R_FUNCTION_NOT_SUPPORTED); + return SAR_NOTSUPPORTYETERR; + } + + if ((rv = skf_method->DigestUpdate( + hHash, + pbData, + ulDataLen)) != SAR_OK) { + SKFerr(SKF_F_SKF_DIGESTUPDATE, skf_get_error_reason(rv)); + return rv; + } + + return SAR_OK; +} + +ULONG DEVAPI SKF_DigestFinal( + HANDLE hHash, + BYTE *pHashData, + ULONG *pulHashLen) +{ + ULONG rv; + + if (!skf_method) { + SKFerr(SKF_F_SKF_DIGESTFINAL, + SKF_R_SKF_METHOD_NOT_INITIALIZED); + return SAR_NOTINITIALIZEERR; + } + + if (!skf_method->DigestFinal) { + SKFerr(SKF_F_SKF_DIGESTFINAL, + SKF_R_FUNCTION_NOT_SUPPORTED); + return SAR_NOTSUPPORTYETERR; + } + + if ((rv = skf_method->DigestFinal( + hHash, + pHashData, + pulHashLen)) != SAR_OK) { + SKFerr(SKF_F_SKF_DIGESTFINAL, skf_get_error_reason(rv)); + return rv; + } + + return SAR_OK; +} + +ULONG DEVAPI SKF_MacInit( + HANDLE hKey, + BLOCKCIPHERPARAM *pMacParam, + HANDLE *phMac) +{ + ULONG rv; + + if (!skf_method) { + SKFerr(SKF_F_SKF_MACINIT, + SKF_R_SKF_METHOD_NOT_INITIALIZED); + return SAR_NOTINITIALIZEERR; + } + + if (!skf_method->MacInit) { + SKFerr(SKF_F_SKF_MACINIT, + SKF_R_FUNCTION_NOT_SUPPORTED); + return SAR_NOTSUPPORTYETERR; + } + + if ((rv = skf_method->MacInit( + hKey, + pMacParam, + phMac)) != SAR_OK) { + SKFerr(SKF_F_SKF_MACINIT, skf_get_error_reason(rv)); + return rv; + } + + return SAR_OK; +} + +ULONG DEVAPI SKF_Mac( + HANDLE hMac, + BYTE *pbData, + ULONG ulDataLen, + BYTE *pbMacData, + ULONG *pulMacLen) +{ + ULONG rv; + + if (!skf_method) { + SKFerr(SKF_F_SKF_MAC, + SKF_R_SKF_METHOD_NOT_INITIALIZED); + return SAR_NOTINITIALIZEERR; + } + + if (!skf_method->Mac) { + SKFerr(SKF_F_SKF_MAC, + SKF_R_FUNCTION_NOT_SUPPORTED); + return SAR_NOTSUPPORTYETERR; + } + + if ((rv = skf_method->Mac( + hMac, + pbData, + ulDataLen, + pbMacData, + pulMacLen)) != SAR_OK) { + SKFerr(SKF_F_SKF_MAC, skf_get_error_reason(rv)); + return rv; + } + + return SAR_OK; +} + +ULONG DEVAPI SKF_MacUpdate( + HANDLE hMac, + BYTE *pbData, + ULONG ulDataLen) +{ + ULONG rv; + + if (!skf_method) { + SKFerr(SKF_F_SKF_MACUPDATE, + SKF_R_SKF_METHOD_NOT_INITIALIZED); + return SAR_NOTINITIALIZEERR; + } + + if (!skf_method->MacUpdate) { + SKFerr(SKF_F_SKF_MACUPDATE, + SKF_R_FUNCTION_NOT_SUPPORTED); + return SAR_NOTSUPPORTYETERR; + } + + if ((rv = skf_method->MacUpdate( + hMac, + pbData, + ulDataLen)) != SAR_OK) { + SKFerr(SKF_F_SKF_MACUPDATE, skf_get_error_reason(rv)); + return rv; + } + + return SAR_OK; +} + +ULONG DEVAPI SKF_MacFinal( + HANDLE hMac, + BYTE *pbMacData, + ULONG *pulMacDataLen) +{ + ULONG rv; + + if (!skf_method) { + SKFerr(SKF_F_SKF_MACFINAL, + SKF_R_SKF_METHOD_NOT_INITIALIZED); + return SAR_NOTINITIALIZEERR; + } + + if (!skf_method->MacFinal) { + SKFerr(SKF_F_SKF_MACFINAL, + SKF_R_FUNCTION_NOT_SUPPORTED); + return SAR_NOTSUPPORTYETERR; + } + + if ((rv = skf_method->MacFinal( + hMac, + pbMacData, + pulMacDataLen)) != SAR_OK) { + SKFerr(SKF_F_SKF_MACFINAL, skf_get_error_reason(rv)); + return rv; + } + + return SAR_OK; +} + +ULONG DEVAPI SKF_CloseHandle( + HANDLE hHandle) +{ + ULONG rv; + + if (!skf_method) { + SKFerr(SKF_F_SKF_CLOSEHANDLE, + SKF_R_SKF_METHOD_NOT_INITIALIZED); + return SAR_NOTINITIALIZEERR; + } + + if (!skf_method->CloseHandle) { + SKFerr(SKF_F_SKF_CLOSEHANDLE, + SKF_R_FUNCTION_NOT_SUPPORTED); + return SAR_NOTSUPPORTYETERR; + } + + if ((rv = skf_method->CloseHandle( + hHandle)) != SAR_OK) { + SKFerr(SKF_F_SKF_CLOSEHANDLE, skf_get_error_reason(rv)); + return rv; + } + + return SAR_OK; +} + diff --git a/src/skf/skf_meth.c b/src/skf/skf_meth.c new file mode 100644 index 00000000..5bd7739a --- /dev/null +++ b/src/skf/skf_meth.c @@ -0,0 +1,176 @@ +/* ==================================================================== + * Copyright (c) 2014 - 2017 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 +#include +#include +#include +#include "skf.h" +#include "skf_ext.h" +#include "skf_int.h" + +#define SKFerr(e,r) + +#define SKF_METHOD_BIND_FUNCTION_EX(func,name) \ + skf->func = (SKF_##func##_FuncPtr)dlsym(skf->dso, "SKF_"#name) + +#define SKF_METHOD_BIND_FUNCTION(func) \ + SKF_METHOD_BIND_FUNCTION_EX(func,func) + + +SKF_METHOD *SKF_METHOD_load_library(const char *so_path) +{ + SKF_METHOD *ret = NULL; + SKF_METHOD *skf = NULL; + + if (!(skf = malloc(sizeof(*skf)))) { + SKFerr(SKF_F_SKF_METHOD_LOAD_LIBRARY, ERR_R_MALLOC_FAILURE); + goto end; + } + if (!(skf->dso = dlopen(so_path, RTLD_LAZY))) { + SKFerr(SKF_F_SKF_METHOD_LOAD_LIBRARY, SKF_R_DSO_LOAD_FAILURE); + goto end; + } + + SKF_METHOD_BIND_FUNCTION(WaitForDevEvent); + SKF_METHOD_BIND_FUNCTION(CancelWaitForDevEvent); + SKF_METHOD_BIND_FUNCTION(EnumDev); + SKF_METHOD_BIND_FUNCTION(ConnectDev); + SKF_METHOD_BIND_FUNCTION(DisConnectDev); + SKF_METHOD_BIND_FUNCTION(GetDevState); + SKF_METHOD_BIND_FUNCTION(SetLabel); + SKF_METHOD_BIND_FUNCTION(GetDevInfo); + SKF_METHOD_BIND_FUNCTION(LockDev); + SKF_METHOD_BIND_FUNCTION(UnlockDev); + SKF_METHOD_BIND_FUNCTION(Transmit); + SKF_METHOD_BIND_FUNCTION(ChangeDevAuthKey); + SKF_METHOD_BIND_FUNCTION(DevAuth); + SKF_METHOD_BIND_FUNCTION(ChangePIN); + SKF_METHOD_BIND_FUNCTION(GetPINInfo); + SKF_METHOD_BIND_FUNCTION(VerifyPIN); + SKF_METHOD_BIND_FUNCTION(UnblockPIN); + SKF_METHOD_BIND_FUNCTION(ClearSecureState); + SKF_METHOD_BIND_FUNCTION(CreateApplication); + SKF_METHOD_BIND_FUNCTION(EnumApplication); + SKF_METHOD_BIND_FUNCTION(DeleteApplication); + SKF_METHOD_BIND_FUNCTION(OpenApplication); + SKF_METHOD_BIND_FUNCTION(CloseApplication); + SKF_METHOD_BIND_FUNCTION_EX(CreateObject,CreateFile); + SKF_METHOD_BIND_FUNCTION_EX(DeleteObject,DeleteFile); + SKF_METHOD_BIND_FUNCTION_EX(EnumObjects,EnumFiles); + SKF_METHOD_BIND_FUNCTION_EX(GetObjectInfo,GetFileInfo); + SKF_METHOD_BIND_FUNCTION_EX(ReadObject,ReadFile); + SKF_METHOD_BIND_FUNCTION_EX(WriteObject,WriteFile); + SKF_METHOD_BIND_FUNCTION(CreateContainer); + SKF_METHOD_BIND_FUNCTION(DeleteContainer); + SKF_METHOD_BIND_FUNCTION(EnumContainer); + SKF_METHOD_BIND_FUNCTION(OpenContainer); + SKF_METHOD_BIND_FUNCTION(CloseContainer); + SKF_METHOD_BIND_FUNCTION(GetContainerType); + SKF_METHOD_BIND_FUNCTION(ImportCertificate); + SKF_METHOD_BIND_FUNCTION(ExportCertificate); + SKF_METHOD_BIND_FUNCTION(ExportPublicKey); + SKF_METHOD_BIND_FUNCTION(GenRandom); + SKF_METHOD_BIND_FUNCTION(GenExtRSAKey); + SKF_METHOD_BIND_FUNCTION(GenRSAKeyPair); + SKF_METHOD_BIND_FUNCTION(ImportRSAKeyPair); + SKF_METHOD_BIND_FUNCTION(RSASignData); + SKF_METHOD_BIND_FUNCTION(RSAVerify); + SKF_METHOD_BIND_FUNCTION(RSAExportSessionKey); + SKF_METHOD_BIND_FUNCTION(ExtRSAPubKeyOperation); + SKF_METHOD_BIND_FUNCTION(ExtRSAPriKeyOperation); + SKF_METHOD_BIND_FUNCTION(GenECCKeyPair); + SKF_METHOD_BIND_FUNCTION(ImportECCKeyPair); + SKF_METHOD_BIND_FUNCTION(ECCSignData); + SKF_METHOD_BIND_FUNCTION(ECCVerify); + SKF_METHOD_BIND_FUNCTION(ECCExportSessionKey); + SKF_METHOD_BIND_FUNCTION(ExtECCEncrypt); + SKF_METHOD_BIND_FUNCTION(ExtECCDecrypt); + SKF_METHOD_BIND_FUNCTION(ExtECCSign); + SKF_METHOD_BIND_FUNCTION(ExtECCVerify); + SKF_METHOD_BIND_FUNCTION(GenerateAgreementDataWithECC); + SKF_METHOD_BIND_FUNCTION(GenerateAgreementDataAndKeyWithECC); + SKF_METHOD_BIND_FUNCTION(GenerateKeyWithECC); + SKF_METHOD_BIND_FUNCTION(ImportSessionKey); + SKF_METHOD_BIND_FUNCTION(SetSymmKey); + SKF_METHOD_BIND_FUNCTION(EncryptInit); + SKF_METHOD_BIND_FUNCTION(Encrypt); + SKF_METHOD_BIND_FUNCTION(EncryptUpdate); + SKF_METHOD_BIND_FUNCTION(EncryptFinal); + SKF_METHOD_BIND_FUNCTION(DecryptInit); + SKF_METHOD_BIND_FUNCTION(Decrypt); + SKF_METHOD_BIND_FUNCTION(DecryptUpdate); + SKF_METHOD_BIND_FUNCTION(DecryptFinal); + SKF_METHOD_BIND_FUNCTION(DigestInit); + SKF_METHOD_BIND_FUNCTION(Digest); + SKF_METHOD_BIND_FUNCTION(DigestUpdate); + SKF_METHOD_BIND_FUNCTION(DigestFinal); + SKF_METHOD_BIND_FUNCTION(MacInit); + SKF_METHOD_BIND_FUNCTION(Mac); + SKF_METHOD_BIND_FUNCTION(MacUpdate); + SKF_METHOD_BIND_FUNCTION(MacFinal); + SKF_METHOD_BIND_FUNCTION(CloseHandle); +#ifdef SKF_HAS_ECCDECRYPT + SKF_METHOD_BIND_FUNCTION(ECCDecrypt); +#endif + + ret = skf; + skf = NULL; + +end: + SKF_METHOD_free(skf); + return ret; +} + +void SKF_METHOD_free(SKF_METHOD *meth) +{ + if (meth) + free(meth->dso); + free(meth); +} diff --git a/src/skf/skf_prn.c b/src/skf/skf_prn.c new file mode 100644 index 00000000..9c5a9211 --- /dev/null +++ b/src/skf/skf_prn.c @@ -0,0 +1,325 @@ +/* ==================================================================== + * Copyright (c) 2014 - 2019 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 +#include +#include +#include +#include +#include "skf.h" +#include "skf_int.h" +#include "skf_ext.h" + + + +static char *skf_algor_name(ULONG ulAlgID) +{ + switch (ulAlgID) { + case SGD_SM1_ECB: return "sm1-ecb"; + case SGD_SM1_CBC: return "sm1-cbc"; + case SGD_SM1_CFB: return "sm1-cfb"; + case SGD_SM1_OFB: return "sm1-ofb128"; + case SGD_SM1_MAC: return "sm1-mac"; + case SGD_SM4_ECB: return "sms4-ecb"; + case SGD_SM4_CBC: return "sms4-cbc"; + case SGD_SM4_CFB: return "sms4-cfb"; + case SGD_SM4_OFB: return "sms4-ofb128"; + case SGD_SM4_MAC: return "sms4-mac"; + case SGD_SSF33_ECB: return "ssf33-ecb"; + case SGD_SSF33_CBC: return "ssf33-cbc"; + case SGD_SSF33_CFB: return "ssf33-cfb"; + case SGD_SSF33_OFB: return "ssf33-ofb128"; + case SGD_SSF33_MAC: return "ssf33-mac"; + case SGD_RSA: return "rsa"; + case SGD_SM2_1: return "sm2sign"; + case SGD_SM2_2: return "sm2encrypt"; + case SGD_SM2_3: return "sm2keyagreement"; + case SGD_SM3: return "sm3"; + case SGD_SHA1: return "sha1"; + case SGD_SHA256: return "sha256"; + } + return NULL; +} + +ULONG SKF_GetDevStateName(ULONG ulDevState, LPSTR *szDevStateName) +{ + if (!szDevStateName) { + return SAR_INDATALENERR; + } + + switch (ulDevState) { + case SKF_DEV_STATE_ABSENT: + *szDevStateName = (LPSTR)"Absent"; + break; + case SKF_DEV_STATE_PRESENT: + *szDevStateName = (LPSTR)"Present"; + break; + case SKF_DEV_STATE_UNKNOW: + *szDevStateName = (LPSTR)"Unknown"; + break; + default: + *szDevStateName = (LPSTR)"(Error)"; + return SAR_INDATALENERR; + } + + return SAR_OK; +} + +ULONG SKF_GetContainerTypeName(ULONG ulContainerType, LPSTR *szName) +{ + switch (ulContainerType) { + case SKF_CONTAINER_TYPE_UNDEF: + *szName = (LPSTR)"(undef)"; + break; + case SKF_CONTAINER_TYPE_RSA: + *szName = (LPSTR)"RSA"; + break; + case SKF_CONTAINER_TYPE_ECC: + *szName = (LPSTR)"EC"; + break; + default: + *szName = (LPSTR)"(unknown)"; + } + /* always success for help functions */ + return SAR_OK; +} + +typedef struct { + ULONG id; + char *name; +} table_item_t; + +static table_item_t skf_cipher_caps[] = { + { SGD_SM1_ECB, "sm1-ecb" }, + { SGD_SM1_CBC, "sm1-cbc" }, + { SGD_SM1_CFB, "sm1-cfb" }, + { SGD_SM1_OFB, "sm1-ofb128" }, + { SGD_SM1_MAC, "cbcmac-sm1" }, + { SGD_SSF33_ECB, "ssf33-ecb" }, + { SGD_SSF33_CBC, "ssf33-cbc" }, + { SGD_SSF33_CFB, "ssf33-cfb" }, + { SGD_SSF33_OFB, "ssf33-ofb128" }, + { SGD_SSF33_MAC, "cbcmac-ssf33" }, + { SGD_SM4_ECB, "sms4-ecb" }, + { SGD_SM4_CBC, "sms4-cbc" }, + { SGD_SM4_CFB, "sms4-cfb" }, + { SGD_SM4_OFB, "sms4-ofb128" }, + { SGD_SM4_MAC, "cbcmac-sms4" }, + { SGD_ZUC_EEA3, "zuc_128eea3" }, + { SGD_ZUC_EIA3, "zuc_128eia3" } +}; + +static table_item_t skf_digest_caps[] = { + { SGD_SM3, "sm3" }, + { SGD_SHA1, "sha1" }, + { SGD_SHA256, "sha256" }, +}; + +static table_item_t skf_pkey_caps[] = { + { SGD_RSA_SIGN, "rsa" }, + { SGD_RSA_ENC, "rsaEncryption" }, + { SGD_SM2_1, "sm2sign" }, + { SGD_SM2_2, "sm2exchange" }, + { SGD_SM2_3, "sm2encrypt" } +}; + +ULONG SKF_PrintDevInfo(FILE *fp, const DEVINFO *devInfo) +{ + size_t i, n; + int fmt = 0, ind = 4; + + format_print(fp, fmt, ind, "Version: %d.%d\n", devInfo->Version.major, devInfo->Version.minor); + format_print(fp, fmt, ind, "Manufacturer: %s\n", devInfo->Manufacturer); + format_print(fp, fmt, ind, "Issuer: %s\n", devInfo->Issuer); + format_print(fp, fmt, ind, "Label: %s\n", devInfo->Label); + format_bytes(fp, fmt, ind, "SerialNumber", devInfo->SerialNumber, strlen((char *)devInfo->SerialNumber)); + format_print(fp, fmt, ind, "FirmwareVersion: %d.%d\n", devInfo->HWVersion.major, devInfo->HWVersion.minor); + + format_print(fp, fmt, ind, "Ciphers: "); + for (i = n = 0; i < sizeof(skf_cipher_caps)/sizeof(skf_cipher_caps[0]); i++) { + if ((devInfo->AlgSymCap & skf_cipher_caps[i].id) == + skf_cipher_caps[i].id) { + format_print(fp, fmt, 0, "%s%s", n ? "," : "", skf_cipher_caps[i].name); + n++; + } + } + format_print(fp, fmt, 0, "\n"); + + format_print(fp, fmt, ind, "Public Keys: "); + for (i = n = 0; i < sizeof(skf_pkey_caps)/sizeof(skf_pkey_caps[0]); i++) { + if ((devInfo->AlgAsymCap & skf_pkey_caps[i].id) == + skf_pkey_caps[i].id) { + format_print(fp, fmt, 0, "%s%s", n ? "," : "", skf_pkey_caps[i].name); + n++; + } + } + format_print(fp, fmt, 0, "\n"); + + format_print(fp, fmt, ind, "Digests: "); + for (i = n = 0; i < sizeof(skf_digest_caps)/sizeof(skf_digest_caps[0]); i++) { + if ((devInfo->AlgHashCap & skf_digest_caps[i].id) == + skf_digest_caps[i].id) { + format_print(fp, fmt, 0, "%s%s", n ? "," : "", skf_digest_caps[i].name); + n++; + } + } + format_print(fp, fmt, 0, "\n"); + + format_print(fp, fmt, ind, "AuthCipher"); + for (i = 0; i < sizeof(skf_cipher_caps)/sizeof(skf_cipher_caps[0]); i++) { + if (devInfo->DevAuthAlgId == skf_cipher_caps[i].id) { + format_print(fp, fmt, 0, "%s\n", skf_cipher_caps[i].name); + break; + } + } + if (i == sizeof(skf_cipher_caps)/sizeof(skf_cipher_caps[0])) { + format_print(fp, fmt, 0, "(unknown)\n"); + } + format_print(fp, fmt, 0, "\n"); + + + + if (devInfo->TotalSpace == UINT_MAX) + format_print(fp, fmt, ind, "Total Sapce: %s\n", "(unlimited)"); + else format_print(fp, fmt, ind, "Total Sapce: %u\n", devInfo->TotalSpace); + + if (devInfo->FreeSpace == UINT_MAX) + format_print(fp, fmt, ind, "Free Space: %s\n", "(unlimited)"); + else format_print(fp, fmt, ind, "Free Space: %u\n", devInfo->FreeSpace); + + if (devInfo->MaxECCBufferSize == UINT_MAX) + format_print(fp, fmt, ind, "MAX ECC Input: %s\n", "(unlimited)"); + else format_print(fp, fmt, ind, "MAX ECC Input: %u\n", devInfo->MaxECCBufferSize); + + if (devInfo->MaxBufferSize == UINT_MAX) + format_print(fp, fmt, ind, "MAX Cipher Input: %s\n", "(unlimited)"); + else format_print(fp, fmt, ind, "MAX Cipher Input: %u\n", devInfo->MaxBufferSize); + + return SAR_OK; +} + +ULONG SKF_PrintRSAPublicKey(FILE *fp, const RSAPUBLICKEYBLOB *blob) +{ + int fmt = 0, ind = 4; + format_print(fp, fmt, ind, "AlgID: %s\n", skf_algor_name(blob->AlgID)); + format_print(fp, fmt, ind, "BitLen: %u\n", blob->BitLen); + format_bytes(fp, fmt, ind, "Modulus", blob->Modulus, MAX_RSA_MODULUS_LEN); + format_bytes(fp, fmt, ind, "PublicExponent", blob->PublicExponent, MAX_RSA_EXPONENT_LEN); + return SAR_OK; +} + +ULONG SKF_PrintRSAPrivateKey(FILE *fp, const RSAPRIVATEKEYBLOB *blob) +{ + int fmt = 0, ind = 4; + format_print(fp, fmt, ind, "AlgID: %s\n", skf_algor_name(blob->AlgID)); + format_print(fp, fmt, ind, "BitLen: %u\n", blob->BitLen); + format_bytes(fp, fmt, ind, "Modulus", blob->Modulus, MAX_RSA_MODULUS_LEN); + format_bytes(fp, fmt, ind, "PublicExponent", blob->PublicExponent, MAX_RSA_EXPONENT_LEN); + format_bytes(fp, fmt, ind, "PrivateExponent", blob->PrivateExponent, MAX_RSA_MODULUS_LEN); + format_bytes(fp, fmt, ind, "Prime1", blob->Prime1, MAX_RSA_MODULUS_LEN/2); + format_bytes(fp, fmt, ind, "Prime2", blob->Prime2, MAX_RSA_MODULUS_LEN/2); + format_bytes(fp, fmt, ind, "Prime1Exponent", blob->Prime1Exponent, MAX_RSA_MODULUS_LEN/2); + format_bytes(fp, fmt, ind, "Prime2Exponent", blob->Prime2Exponent, MAX_RSA_MODULUS_LEN/2); + format_bytes(fp, fmt, ind, "Coefficient", blob->Coefficient, MAX_RSA_MODULUS_LEN/2); + return SAR_OK; +} + +ULONG SKF_PrintECCPublicKey(FILE *fp, const ECCPUBLICKEYBLOB *blob) +{ + int fmt = 0, ind = 4; + format_print(fp, fmt, ind, "BitLen: %u\n", blob->BitLen); + format_bytes(fp, fmt, ind, "XCoordinate", blob->XCoordinate, ECC_MAX_XCOORDINATE_BITS_LEN/8); + format_bytes(fp, fmt, ind, "YCoordinate", blob->YCoordinate, ECC_MAX_XCOORDINATE_BITS_LEN/8); + return SAR_OK; +} + +ULONG SKF_PrintECCPrivateKey(FILE *fp, const ECCPRIVATEKEYBLOB *blob) +{ + int fmt = 0, ind = 4; + format_print(fp, fmt, ind, "BitLen: %u\n", blob->BitLen); + format_bytes(fp, fmt, ind, "PrivateKey", blob->PrivateKey, ECC_MAX_MODULUS_BITS_LEN/8); + return SAR_OK; +} + +ULONG SKF_PrintECCCipher(FILE *fp, const ECCCIPHERBLOB *blob) +{ + int fmt = 0, ind = 4; + format_bytes(fp, fmt, ind, "XCoordinate", blob->XCoordinate, ECC_MAX_XCOORDINATE_BITS_LEN/8); + format_bytes(fp, fmt, ind, "YCoordinate", blob->YCoordinate, ECC_MAX_XCOORDINATE_BITS_LEN/8); + format_bytes(fp, fmt, ind, "HASH", blob->HASH, 32); + format_print(fp, fmt, ind, "CipherLen: %u\n", blob->CipherLen); + format_bytes(fp, fmt, ind, "Cipher", blob->Cipher, blob->CipherLen); + return SAR_OK; +} + +ULONG SKF_PrintECCSignature(FILE *fp, const ECCSIGNATUREBLOB *blob) +{ + int fmt = 0, ind = 4; + format_bytes(fp, fmt, ind, "r", blob->r, ECC_MAX_XCOORDINATE_BITS_LEN/8); + format_bytes(fp, fmt, ind, "s", blob->s, ECC_MAX_XCOORDINATE_BITS_LEN/8); + return SAR_OK; +} + +ULONG DEVAPI SKF_GetAlgorName(ULONG ulAlgID, LPSTR *szName) +{ + char *name; + if ((name = skf_algor_name(ulAlgID)) != NULL) { + *szName = (LPSTR)&name; + return SAR_OK; + } + return SAR_FAIL; +} + +ULONG DEVAPI SKF_PrintErrorString(FILE *fp, ULONG ulError) +{ + LPSTR str = NULL; + SKF_GetErrorString(ulError, &str); + fprintf(fp, "SKF Error: %s\n", (char *)str); + return SAR_OK; +} diff --git a/src/skf/skf_wisec.c b/src/skf/skf_wisec.c new file mode 100644 index 00000000..29a77ab3 --- /dev/null +++ b/src/skf/skf_wisec.c @@ -0,0 +1,185 @@ +/* ==================================================================== + * Copyright (c) 2016 - 2017 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 +#include +#include +#include +#include "skf_int.h" +#include "skf_wisec.h" + + +typedef struct { + ULONG std_id; + ULONG vendor_id; +} SKF_ALGOR_PAIR; + +static SKF_ALGOR_PAIR wisec_ciphers[] = { + { SGD_SM1, WISEC_SM1 }, + { SGD_SM1_ECB, WISEC_SM1_ECB }, + { SGD_SM1_CBC, WISEC_SM1_CBC }, + { SGD_SM1_CFB, WISEC_SM1_CFB }, + { SGD_SM1_OFB, WISEC_SM1_OFB }, + { SGD_SM1_MAC, WISEC_SM1_MAC }, + { SGD_SM4, WISEC_SM4 }, + { SGD_SM4_ECB, WISEC_SM4_ECB }, + { SGD_SM4_CBC, WISEC_SM4_CBC }, + { SGD_SM4_CFB, WISEC_SM4_CFB }, + { SGD_SM4_OFB, WISEC_SM4_OFB }, + { SGD_SM4_MAC, WISEC_SM4_MAC }, + { SGD_SSF33, WISEC_SSF33 }, + { SGD_SSF33_ECB, WISEC_SSF33_ECB }, + { SGD_SSF33_CBC, WISEC_SSF33_CBC }, + { SGD_SSF33_CFB, WISEC_SSF33_CFB }, + { SGD_SSF33_OFB, WISEC_SSF33_OFB }, + { SGD_SSF33_MAC, WISEC_SSF33_MAC }, +}; + +static ULONG wisec_get_cipher_algor(ULONG vendor_id) +{ + size_t i; + for (i = 0; i < sizeof(wisec_ciphers)/sizeof(wisec_ciphers[0]); i++) { + if (vendor_id == wisec_ciphers[i].vendor_id) { + return wisec_ciphers[i].std_id; + } + } + return 0; +} + +static ULONG wisec_get_cipher_cap(ULONG vendor_cap) +{ + ULONG std_cap = 0; + size_t i; + for (i = 0; i < sizeof(wisec_ciphers)/sizeof(wisec_ciphers[0]); i++) { + if (vendor_cap & wisec_ciphers[i].vendor_id) { + std_cap |= wisec_ciphers[i].std_id; + } + } + return std_cap; +} + +static SKF_ALGOR_PAIR wisec_digests[] = { + { SGD_SM3, WISEC_SM3 }, + { SGD_SHA1, WISEC_SHA1 }, + { SGD_SHA256, WISEC_SHA256 }, +}; + +static ULONG wisec_get_digest_algor(ULONG vendor_id) +{ + size_t i; + for (i = 0; i < sizeof(wisec_digests)/sizeof(wisec_digests[0]); i++) { + if (vendor_id == wisec_digests[i].vendor_id) { + return wisec_digests[i].std_id; + } + } + return 0; +} + +static ULONG wisec_get_digest_cap(ULONG vendor_cap) +{ + ULONG std_cap = 0; + size_t i; + for (i = 0; i < sizeof(wisec_digests)/sizeof(wisec_digests[0]); i++) { + if (vendor_cap & wisec_digests[i].vendor_id) { + std_cap |= wisec_digests[i].std_id; + } + } + return std_cap; +} + +static SKF_ALGOR_PAIR wisec_pkeys[] = { + { SGD_RSA, WISEC_RSA }, + { SGD_RSA_SIGN, WISEC_RSA_SIGN }, + { SGD_RSA_ENC, WISEC_RSA_ENC }, + { SGD_SM2, WISEC_SM2 }, + { SGD_SM2_1, WISEC_SM2_1 }, + { SGD_SM2_2, WISEC_SM2_2 }, + { SGD_SM2_3, WISEC_SM2_3 }, +}; + +static ULONG wisec_get_pkey_algor(ULONG vendor_id) +{ + size_t i; + for (i = 0; i < sizeof(wisec_pkeys)/sizeof(wisec_pkeys[0]); i++) { + if (vendor_id == wisec_pkeys[i].vendor_id) { + return wisec_pkeys[i].std_id; + } + } + return 0; +} + +static ULONG wisec_get_pkey_cap(ULONG vendor_cap) +{ + ULONG std_cap = 0; + size_t i; + for (i = 0; i < sizeof(wisec_pkeys)/sizeof(wisec_pkeys[0]); i++) { + if (vendor_cap & wisec_pkeys[i].vendor_id) { + std_cap |= wisec_pkeys[i].std_id; + } + } + return std_cap; +} + +static unsigned long wisec_get_error_reason(ULONG err) +{ + return 0; +} + +SKF_VENDOR skf_wisec = { + "wisec", + 16, + wisec_get_cipher_algor, + wisec_get_cipher_cap, + wisec_get_digest_algor, + wisec_get_digest_cap, + wisec_get_pkey_algor, + wisec_get_pkey_cap, + wisec_get_error_reason, +}; diff --git a/src/skf/skf_wisec.h b/src/skf/skf_wisec.h new file mode 100644 index 00000000..02e143eb --- /dev/null +++ b/src/skf/skf_wisec.h @@ -0,0 +1,156 @@ +/* ==================================================================== + * Copyright (c) 2016 - 2017 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. + * ==================================================================== + */ + +#ifndef HEADER_SKF_WISEC_H +#define HEADER_SKF_WISEC_H + +#include "skf.h" + + +#define WISEC_SM1 (SGD_SM1) +#define WISEC_SM1_ECB (SGD_SM1_ECB) +#define WISEC_SM1_CBC (SGD_SM1_CBC) +#define WISEC_SM1_CFB (SGD_SM1_CFB) +#define WISEC_SM1_OFB (SGD_SM1_OFB) +#define WISEC_SM1_MAC (SGD_SM1_MAC) + +#define WISEC_SSF33 (SGD_SSF33) +#define WISEC_SSF33_ECB (SGD_SSF33_ECB) +#define WISEC_SSF33_CBC (SGD_SSF33_CBC) +#define WISEC_SSF33_CFB (SGD_SSF33_CFB) +#define WISEC_SSF33_OFB (SGD_SSF33_OFB) +#define WISEC_SSF33_MAC (SGD_SSF33_MAC) + +#define WISEC_SM4 (SGD_SM4) +#define WISEC_SM4_ECB (WISEC_SM4|SGD_ECB) +#define WISEC_SM4_CBC (WISEC_SM4|SGD_CBC) +#define WISEC_SM4_CFB (WISEC_SM4|SGD_CFB) +#define WISEC_SM4_OFB (WISEC_SM4|SGD_OFB) +#define WISEC_SM4_MAC (WISEC_SM4|SGD_MAC) + +#define WISEC_AES 0x00000800 +#define WISEC_128 0x00000000 +#define WISEC_192 0x00000010 +#define WISEC_256 0x00000020 +#define WISEC_AES128 (WISEC_AES|WISEC_128) +#define WISEC_AES192 (WISEC_AES|WISEC_192) +#define WISEC_AES256 (WISEC_AES|WISEC_256) +#define WISEC_AES128_ECB (WISEC_AES128|SGD_ECB) +#define WISEC_AES128_CBC (WISEC_AES128|SGD_CBC) +#define WISEC_AES128_CFB (WISEC_AES128|SGD_CFB) +#define WISEC_AES128_OFB (WISEC_AES128|SGD_OFB) +#define WISEC_AES128_MAC (WISEC_AES128|SGD_MAC) +#define WISEC_AES192_ECB (WISEC_AES192|SGD_ECB) +#define WISEC_AES192_CBC (WISEC_AES192|SGD_CBC) +#define WISEC_AES192_CFB (WISEC_AES192|SGD_CFB) +#define WISEC_AES192_OFB (WISEC_AES192|SGD_OFB) +#define WISEC_AES192_MAC (WISEC_AES192|SGD_MAC) +#define WISEC_AES256_ECB (WISEC_AES256|SGD_ECB) +#define WISEC_AES256_CBC (WISEC_AES256|SGD_CBC) +#define WISEC_AES256_CFB (WISEC_AES256|SGD_CFB) +#define WISEC_AES256_OFB (WISEC_AES256|SGD_OFB) +#define WISEC_AES256_MAC (WISEC_AES256|SGD_MAC) + +#define WISEC_DES 0x00001000 +#define WISEC_DES_ECB (WISEC_DES|SGD_ECB) +#define WISEC_DES_CBC (WISEC_DES|SGD_CBC) +#define WISEC_DES_CFB (WISEC_DES|SGD_CFB) +#define WISEC_DES_OFB (WISEC_DES|SGD_OFB) +#define WISEC_DES_MAC (WISEC_DES|SGD_MAC) + +#define WISEC_D3DES 0x00001010 +#define WISEC_D3DES_ECB (WISEC_D3DES|SGD_ECB) +#define WISEC_D3DES_CBC (WISEC_D3DES|SGD_CBC) +#define WISEC_D3DES_CFB (WISEC_D3DES|SGD_CFB) +#define WISEC_D3DES_OFB (WISEC_D3DES|SGD_OFB) +#define WISEC_D3DES_MAC (WISEC_D3DES|SGD_MAC) + +#define WISEC_T3DES 0x00001020 +#define WISEC_T3DES_ECB (WISEC_T3DES|SGD_ECB) +#define WISEC_T3DES_CBC (WISEC_T3DES|SGD_CBC) +#define WISEC_T3DES_CFB (WISEC_T3DES|SGD_CFB) +#define WISEC_T3DES_OFB (WISEC_T3DES|SGD_OFB) +#define WISEC_T3DES_MAC (WISEC_T3DES|SGD_MAC) + +#define WISEC_SM3 (SGD_SM3) +#define WISEC_SHA1 (SGD_SHA1) +#define WISEC_SHA256 (SGD_SHA256) + +#define WISEC_RSA (SGD_RSA) +#define WISEC_RSA_SIGN (SGD_RSA_SIGN) +#define WISEC_RSA_ENC (SGD_RSA_ENC) +#define WISEC_SM2 (SGD_SM2) +#define WISEC_SM2_1 (SGD_SM2_1) +#define WISEC_SM2_2 (SGD_SM2_2) +#define WISEC_SM2_3 (SGD_SM2_3) + + +#define WISEC_AUTH_BLOCKED 0x0A000033 +#define WISEC_CERTNOUSAGEERR 0x0A000034 +#define WISEC_INVALIDCONTAINERERR 0x0A000035 +#define WISEC_CONTAINER_NOT_EXISTS 0x0A000036 +#define WISEC_CONTAINER_EXISTS 0x0A000037 +#define WISEC_CERTUSAGEERR 0x0A000038 +#define WISEC_KEYNOUSAGEERR 0x0A000039 +#define WISEC_FILEATTRIBUTEERR 0x0A00003A +#define WISEC_DEVNOAUTH 0x0A00003B + +/* +ULONG DEVAPI SKFE_SetSN(DEVHANDLE hDev, CHAR *SN, UINT SNLen); +ULONG DEVAPI SKFE_GenExtECCKey(DEVHANDLE hDev, PECCPRIVATEKEYBLOB pPriBlob, PECCPUBLICKEYBLOB pPubBlob); +ULONG DEVAPI SKF_ECCDecrypt(HCONTAINER hContainer, PECCCIPHERBLOB pCipherText, BYTE *pbPlainText,ULONG *pulPlainTextLen); +ULONG DEVAPI SKF_GenerateKey(HCONTAINER hContainer, ULONG ulAlgId, HANDLE *phSessionKey) ; +ULONG DEVAPI SKF_ECCExportSessionKeyByHandle(HANDLE phSessionKey, ECCPUBLICKEYBLOB *pPubKey,PECCCIPHERBLOB pData); +ULONG DEVAPI SKF_RSAExportSessionKeyByHandle(HANDLE phSessionKey, RSAPUBLICKEYBLOB*pPubKey,BYTE *pbData, ULONG *pulDataLen); +ULONG DEVAPI SKF_PrvKeyDecrypt(HCONTAINER hContainer, PECCCIPHERBLOB pCipherText, BYTE *pbData, ULONG *pbDataLen); +ULONG DEVAPI SKF_PrvKeyDecrypt(HCONTAINER hContainer, ULONG ulType, PECCCIPHERBLOB pCipherText, BYTE *pbData, ULONG *pbDataLen); +ULONG DEVAPI SKF_RSAPrvKeyDecrypt(HCONTAINER hContainer, BYTE *pCipherData, ULONG pCipherDataLen, BYTE *pbData, ULONG *pbDataLen); +*/ + +#endif diff --git a/tools/gmssl.c b/tools/gmssl.c index 11a6a72c..b6750f3b 100644 --- a/tools/gmssl.c +++ b/tools/gmssl.c @@ -83,6 +83,7 @@ extern int tls12_server_main(int argc, char **argv); extern int tls13_client_main(int argc, char **argv); extern int tls13_server_main(int argc, char **argv); extern int sdfutil_main(int argc, char **argv); +extern int skfutil_main(int argc, char **argv); static const char *options = @@ -121,7 +122,8 @@ static const char *options = " tls12_server TLS 1.2 server\n" " tls13_client TLS 1.3 client\n" " tls13_server TLS 1.3 server\n" - " sdfutil SDF crypto device utility\n"; + " sdfutil SDF crypto device utility\n" + " skfutil SKF crypto device utility\n"; @@ -204,6 +206,8 @@ int main(int argc, char **argv) return tls13_server_main(argc, argv); } else if (!strcmp(*argv, "sdfutil")) { return sdfutil_main(argc, argv); + } else if (!strcmp(*argv, "skfutil")) { + return skfutil_main(argc, argv); } else { fprintf(stderr, "%s: illegal option '%s'\n", prog, *argv); fprintf(stderr, "usage: %s %s\n", prog, options); diff --git a/tools/sdfutil.c b/tools/sdfutil.c index 8c817da4..3236c94e 100644 --- a/tools/sdfutil.c +++ b/tools/sdfutil.c @@ -182,7 +182,11 @@ bad: break; case OP_EXPORTPUBKEY: - sdf_load_key(&dev, &key, keyindex, pass); + if (keyindex < 0) { + error_print(); + goto end; + } + sdf_load_sign_key(&dev, &key, keyindex, pass); sm2_public_key_info_to_pem(&(key.public_key), outfp); break; @@ -193,7 +197,7 @@ bad: uint8_t sig[SM2_MAX_SIGNATURE_SIZE]; size_t siglen; - sdf_load_key(&dev, &key, keyindex, pass); + sdf_load_sign_key(&dev, &key, keyindex, pass); sm3_init(&sm3_ctx); sm2_compute_z(dgst, &(key.public_key.public_key), id, strlen(id)); diff --git a/tools/skfutil.c b/tools/skfutil.c new file mode 100644 index 00000000..3c302e84 --- /dev/null +++ b/tools/skfutil.c @@ -0,0 +1,271 @@ +/* + * Copyright (c) 2014 - 2021 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 +#include +#include +#include +#include +#include +#include +#include + + +#define OP_NONE 0 +#define OP_DEVINFO 1 +#define OP_EXPORTPUBKEY 2 +#define OP_SIGN 3 +#define OP_RAND 4 + + + +static void print_usage(FILE *fp, const char *prog) +{ + fprintf(fp, "usage:\n"); + fprintf(fp, " %s -lib so_path -dev str -devinfo\n", prog); + fprintf(fp, " %s -lib so_path -dev str -app str [-pass str] -container str -exportpubkey [-out file]\n", prog); + fprintf(fp, " %s -lib so_path -dev str -app str [-pass str] -container str -sign [-in file] [-out file]\n", prog); + fprintf(fp, " %s -lib so_path -dev str -rand num [-out file]\n", prog); +} + +int skfutil_main(int argc, char **argv) +{ + int ret = 1; + char *prog = argv[0]; + char *lib = NULL; + int op = 0; + char *devname = NULL; + char *authkeystr = NULL; + char *appname = NULL; + char *container_name = NULL; + char *pass = NULL; + char *id = SM2_DEFAULT_ID; + int num = 0; + char *infile = NULL; + char *outfile = NULL; + FILE *infp = stdin; + FILE *outfp = stdout; + unsigned char buf[4096]; + unsigned int ulen; + int len; + + uint8_t authkey[16]; + size_t authkeylen; + SKF_DEVICE dev; + SKF_KEY key; + + + argc--; + argv++; + if (argc < 1) { +bad: + print_usage(stderr, prog); + return 1; + } + + while (argc > 0) { + if (!strcmp(*argv, "-help")) { + print_usage(stdout, prog); + goto end; + } else if (!strcmp(*argv, "-lib")) { + if (--argc < 1) goto bad; + lib = *(++argv); + } else if (!strcmp(*argv, "-lib")) { + if (--argc < 1) goto bad; + devname = *(++argv); + } else if (!strcmp(*argv, "-devinfo")) { + op = OP_DEVINFO; + } else if (!strcmp(*argv, "-dev")) { + if (--argc < 1) goto bad; + devname = *(++argv); + } else if (!strcmp(*argv, "-authkey")) { + if (--argc < 1) goto bad; + authkeystr = *(++argv); + if (strlen(authkeystr) != 32) { + error_print(); + return -1; + } + hex_to_bytes(authkeystr, strlen(authkeystr), authkey, &authkeylen); + } else if (!strcmp(*argv, "-exportpubkey")) { + op = OP_EXPORTPUBKEY; + } else if (!strcmp(*argv, "-sign")) { + op = OP_SIGN; + } else if (!strcmp(*argv, "-app")) { + if (--argc < 1) goto bad; + appname = *(++argv); + } else if (!strcmp(*argv, "-container")) { + if (--argc < 1) goto bad; + container_name = *(++argv); + } else if (!strcmp(*argv, "-pass")) { + if (--argc < 1) goto bad; + pass = *(++argv); + } else if (!strcmp(*argv, "-id")) { + if (--argc < 1) goto bad; + id = *(++argv); + } else if (!strcmp(*argv, "-rand")) { + if (--argc < 1) goto bad; + len = atoi(*(++argv)); + } else if (!strcmp(*argv, "-in")) { + if (--argc < 1) goto bad; + infile = *(++argv); + } else if (!strcmp(*argv, "-out")) { + if (--argc < 1) goto bad; + outfile = *(++argv); + + } else { + break; + } + + argc--; + argv++; + } + + if (argc) { + fprintf(stderr, "%s: invalid option '%s'\n", prog, *argv); + return 1; + } + + if (!lib) { + fprintf(stderr, "Option '-lib' required\n"); + goto bad; + } + if (skf_load_library(lib, NULL) != 1) { + error_print(); + goto end; + } + + if (infile) { + if (!(infp = fopen(infile, "rb"))) { + error_print(); + return -1; + } + } + + if (outfile) { + if (!(outfp = fopen(outfile, "wb"))) { + error_print(); + return -1; + } + } + + if (!op) { + error_print(); + goto bad; + } + + + if (!devname) { + error_print(); + goto bad; + } + if (op == OP_DEVINFO) { + skf_print_device_info(stdout, 0, 0, devname); + ret = 0; + goto end; + } + + if (skf_open_device(&dev, devname, authkey) != 1) { + error_print(); + return -1; + } + + if (op == OP_RAND) { + skf_rand_bytes(&dev, buf, len); + fwrite(buf, 1, len, outfp); + ret = 0; + goto end; + } + + if (!appname) { + error_print(); + goto bad; + } + if (!container_name) { + error_print(); + goto bad; + } + if (!pass) { + error_print(); + goto bad; + } + + if (op == OP_EXPORTPUBKEY) { + skf_load_sign_key(&dev, appname, pass, container_name, &key); + sm2_public_key_info_to_pem(&(key.public_key), outfp); + ret = 0; + goto end; + } + + if (op == OP_SIGN) { + SM3_CTX sm3_ctx; + uint8_t dgst[32]; + uint8_t sig[SM2_MAX_SIGNATURE_SIZE]; + size_t siglen; + + skf_load_sign_key(&dev, appname, pass, container_name, &key); + + sm3_init(&sm3_ctx); + sm2_compute_z(dgst, &(key.public_key.public_key), id, strlen(id)); + sm3_update(&sm3_ctx, dgst, sizeof(dgst)); + + while ((len = fread(buf, 1, sizeof(buf), infp)) > 0) { + sm3_update(&sm3_ctx, buf, len); + } + sm3_finish(&sm3_ctx, dgst); + + if ((ret = skf_sign(&key, dgst, sig, &siglen)) != 1) { + error_print(); + return -1; + } + ret = 0; + } + +end: + return ret; +} diff --git a/tools/sm4.c b/tools/sm4.c index 5189aecc..553a4f82 100644 --- a/tools/sm4.c +++ b/tools/sm4.c @@ -138,7 +138,7 @@ bad: return -1; } if (strlen(keystr) != 32) { - printf("keystr len = %d\n", strlen(keystr)); + printf("keystr len = %zu\n", strlen(keystr)); error_print(); return -1; } diff --git a/tools/zuc.c b/tools/zuc.c index e2013fc5..c4396bd5 100644 --- a/tools/zuc.c +++ b/tools/zuc.c @@ -118,7 +118,7 @@ bad: return -1; } if (strlen(keystr) != 32) { - printf("keystr len = %d\n", strlen(keystr)); + printf("keystr len = %zu\n", strlen(keystr)); error_print(); return -1; }