diff --git a/Configure b/Configure index 54225301..1d07a04c 100755 --- a/Configure +++ b/Configure @@ -312,7 +312,7 @@ $config{sdirs} = [ "evp", "asn1", "pem", "x509", "x509v3", "conf", "txt_db", "pkcs7", "pkcs12", "comp", "ocsp", "ui", "cms", "ts", "srp", "cmac", "ct", "async", "kdf", "sm3", "sms4", "kdf2", "ecies", "ffx", "sm2", "paillier", "cpk", "otp", "gmapi", "ec2", - "bfibe", "bb1ibe", "sm9" + "bfibe", "bb1ibe", "sm9", "saf", "sdf", "skf", "sof" ]; # Known TLS and DTLS protocols @@ -406,6 +406,8 @@ my @disablables = ( "weak-ssl-ciphers", "zlib", "zlib-dynamic", + "sm3", "sms4", "kdf2", "ecies", "ffx", "sm2", "paillier", "cpk", "otp", "gmapi", "ec2", + "bfibe", "bb1ibe", "sm9", "saf", "sdf", "skf", "sof" ); foreach my $proto ((@tls, @dtls)) { diff --git a/apps/progs.h b/apps/progs.h index 65e03fa0..f5f60adb 100644 --- a/apps/progs.h +++ b/apps/progs.h @@ -218,7 +218,9 @@ static FUNCTION functions[] = { #ifndef OPENSSL_NO_GOST { FT_md, "gost", dgst_main}, #endif +#ifndef OPENSSL_NO_SM3 { FT_md, "sm3", dgst_main}, +#endif { FT_md, "sha1", dgst_main}, { FT_md, "sha224", dgst_main}, { FT_md, "sha256", dgst_main}, @@ -236,10 +238,18 @@ static FUNCTION functions[] = { #ifndef OPENSSL_NO_BLAKE2 { FT_md, "blake2s256", dgst_main}, #endif +#ifndef OPENSSL_NO_SMS4 { FT_cipher, "sms4-cbc", enc_main, enc_options }, +#endif +#ifndef OPENSSL_NO_SMS4 { FT_cipher, "sms4-ecb", enc_main, enc_options }, +#endif +#ifndef OPENSSL_NO_SMS4 { FT_cipher, "sms4-ofb", enc_main, enc_options }, +#endif +#ifndef OPENSSL_NO_SMS4 { FT_cipher, "sms4-cfb", enc_main, enc_options }, +#endif { FT_cipher, "aes-128-cbc", enc_main, enc_options }, { FT_cipher, "aes-128-ecb", enc_main, enc_options }, { FT_cipher, "aes-192-cbc", enc_main, enc_options }, diff --git a/crypto/err/err.c b/crypto/err/err.c index 86b356ce..5f6ec7e9 100644 --- a/crypto/err/err.c +++ b/crypto/err/err.c @@ -68,6 +68,10 @@ static ERR_STRING_DATA ERR_str_libraries[] = { {ERR_PACK(ERR_LIB_BFIBE, 0, 0), "BFIBE routines"}, {ERR_PACK(ERR_LIB_BB1IBE, 0, 0), "BB1IBE routines"}, {ERR_PACK(ERR_LIB_SM9, 0, 0), "SM9 routines"}, + {ERR_PACK(ERR_LIB_SAF, 0, 0), "SAF routines"}, + {ERR_PACK(ERR_LIB_SDF, 0, 0), "SDF routines"}, + {ERR_PACK(ERR_LIB_SKF, 0, 0), "SKF routines"}, + {ERR_PACK(ERR_LIB_SOF, 0, 0), "SOF routines"}, {0, NULL}, }; @@ -121,6 +125,10 @@ static ERR_STRING_DATA ERR_str_reasons[] = { {ERR_R_BFIBE_LIB, "BFIBE lib"}, {ERR_R_BB1IBE_LIB, "BB1IBE lib"}, {ERR_R_SM9_LIB, "SM9 lib"}, + {ERR_R_SAF_LIB, "SAF lib"}, + {ERR_R_SDF_LIB, "SDF lib"}, + {ERR_R_SKF_LIB, "SKF lib"}, + {ERR_R_SOF_LIB, "SOF lib"}, {ERR_R_NESTED_ASN1_ERROR, "nested asn1 error"}, {ERR_R_MISSING_ASN1_EOS, "missing asn1 eos"}, diff --git a/crypto/err/err_all.c b/crypto/err/err_all.c index 900bd6a0..7bf9e9a4 100644 --- a/crypto/err/err_all.c +++ b/crypto/err/err_all.c @@ -48,6 +48,10 @@ #include #include #include +#include +#include +#include +#include int err_load_crypto_strings_int(void) { @@ -137,6 +141,18 @@ int err_load_crypto_strings_int(void) # ifndef OPENSSL_NO_SM9 ERR_load_SM9_strings() == 0 || # endif +# ifndef OPENSSL_NO_SAF + ERR_load_SAF_strings() == 0 || +# endif +# ifndef OPENSSL_NO_SDF + ERR_load_SDF_strings() == 0 || +# endif +# ifndef OPENSSL_NO_SKF + ERR_load_SKF_strings() == 0 || +# endif +# ifndef OPENSSL_NO_SOF + ERR_load_SOF_strings() == 0 || +# endif #endif ERR_load_KDF_strings() == 0) return 0; diff --git a/crypto/err/openssl.ec b/crypto/err/openssl.ec index 87a2a45f..de4e5298 100644 --- a/crypto/err/openssl.ec +++ b/crypto/err/openssl.ec @@ -44,6 +44,10 @@ L GMAPI include/openssl/gmapi.h crypto/gmapi/gmapi_err.c L BFIBE include/openssl/bfibe.h crypto/bfibe/bfibe_err.c L BB1IBE include/openssl/bb1ibe.h crypto/bb1ibe/bb1ibe_err.c L SM9 include/openssl/sm9.h crypto/sm9/sm9_err.c +L SAF include/openssl/gmsaf.h crypto/saf/saf_err.c +L SDF include/openssl/gmsdf.h crypto/sdf/sdf_err.c +L SKF include/openssl/gmskf.h crypto/skf/skf_err.c +L SOF include/openssl/gmsof.h crypto/sof/sof_err.c # additional header files to be scanned for function names L NONE crypto/x509/x509_vfy.h NONE diff --git a/crypto/saf/build.info b/crypto/saf/build.info new file mode 100644 index 00000000..f9491f45 --- /dev/null +++ b/crypto/saf/build.info @@ -0,0 +1,4 @@ +LIBS=../../libcrypto +SOURCE[../../libcrypto]=saf_lib.c saf_errstr.c saf_app.c saf_keyhandle.c \ + saf_ec.c saf_sm2.c saf_rand.c saf_hash.c saf_enc.c saf_mac.c saf_symmkeyobj.c \ + saf_base64.c saf_cert.c saf_err.c diff --git a/crypto/saf/saf_app.c b/crypto/saf/saf_app.c new file mode 100644 index 00000000..fabeafd2 --- /dev/null +++ b/crypto/saf/saf_app.c @@ -0,0 +1,133 @@ +/* ==================================================================== + * Copyright (c) 2016 The GmSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the GmSSL Project. + * (http://gmssl.org/)" + * + * 4. The name "GmSSL Project" must not be used to endorse or promote + * products derived from this software without prior written + * permission. For written permission, please contact + * guanzhi1980@gmail.com. + * + * 5. Products derived from this software may not be called "GmSSL" + * nor may "GmSSL" appear in their names without prior written + * permission of the GmSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the GmSSL Project + * (http://gmssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE GmSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GmSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES + * LOSS OF USE, DATA, OR PROFITS OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ +/* + * the software implementation of SAF application and related storage + * is determined by a standard OpenSSL configuration file `openssl.cnf`. + * If no config file is given, the default openssl config file will be + * used. This means that the SAF API is only a wrapper of the EVP API. + * + * The OpenSSL use file-level access control, i.e. private keys are + * encrypted by passwords, there is no default container-level access + * control mechnsims such as the Java Keytool for the application-level + * access control of SAF API. + * + * We use the AppHandle to preserve the CONF object. + * + * So we dont provide such access control. The Login() will always + * success. And the ChangePin() has no effects. + */ + +#include +#include +#include +#include +#include + +/* 7.1.2 */ +int SAF_Initialize( + void **phAppHandle, + char *pubCfgFilePath) +{ + + return SAR_Ok; +} + +/* 7.1.3 */ +int SAF_Finalize( + void *hAppHandle) +{ + return SAR_Ok; +} + +/* 7.1.4 */ +int SAF_GetVersion( + unsigned int *puiVersion) +{ + *puiVersion = 0x01000000; + return SAR_Ok; +} + +/* 7.1.5 */ +int SAF_Login( + void *hAppHandle, + unsigned int uiUsrType, + unsigned char *pucContainerName, + unsigned int uiContainerNameLen, + unsigned char *pucPin, + unsigned int uiPinLen, + unsigned int *puiRemainCount) +{ + *puiRemainCount = 100; + return SAR_Ok; +} + +/* 7.1.6 */ +int SAF_ChangePin( + void *hAppHandle, + unsigned int uiUsrType, + unsigned char *pucContainerName, + unsigned int uiContainerNameLen, + unsigned char *pucOldPin, + unsigned int uiOldPinLen, + unsigned char *pucNewPin, + unsigned int uiNewPinLen, + unsigned int *puiRemainCount) +{ + *puiRemainCount = 100; + return SAR_Ok; +} + +/* 7.1.7 */ +int SAF_Logout( + void *hAppHandle, + unsigned int uiUsrType) +{ + return SAR_Ok; +} + diff --git a/crypto/saf/saf_base64.c b/crypto/saf/saf_base64.c new file mode 100644 index 00000000..a3353118 --- /dev/null +++ b/crypto/saf/saf_base64.c @@ -0,0 +1,412 @@ +/* ==================================================================== + * Copyright (c) 2016 The GmSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the GmSSL Project. + * (http://gmssl.org/)" + * + * 4. The name "GmSSL Project" must not be used to endorse or promote + * products derived from this software without prior written + * permission. For written permission, please contact + * guanzhi1980@gmail.com. + * + * 5. Products derived from this software may not be called "GmSSL" + * nor may "GmSSL" appear in their names without prior written + * permission of the GmSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the GmSSL Project + * (http://gmssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE GmSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GmSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES + * LOSS OF USE, DATA, OR PROFITS OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +#include +#include +#include +#include +#include +#include +#include +#include "saf_lcl.h" + +/* 7.3.4 */ +int SAF_Base64_CreateBase64Obj( + void **phBase64Obj) +{ + int ret = SAR_UnknownErr; + SAF_BASE64OBJ *obj = NULL; + + if (!(obj = OPENSSL_malloc(sizeof(*obj)))) { + SAFerr(SAF_F_SAF_BASE64_CREATEBASE64OBJ, ERR_R_MALLOC_FAILURE); + return SAR_MemoryErr; + } + + if (!(obj->ctx = EVP_ENCODE_CTX_new())) { + SAFerr(SAF_F_SAF_BASE64_CREATEBASE64OBJ, ERR_R_MALLOC_FAILURE); + ret = SAR_MemoryErr; + goto end; + } + obj->inited = 0; + + *phBase64Obj = obj; + ret = SAR_OK; + +end: + if (ret != SAR_OK) { + EVP_ENCODE_CTX_free(obj->ctx); + OPENSSL_free(obj); + } + return ret; +} + +/* 7.3.5 */ +/* always return success for software implementation */ +int SAF_Base64_DestroyBase64Obj( + void *hBase64Obj) +{ + SAF_BASE64OBJ *obj = (SAF_BASE64OBJ *)hBase64Obj; + if (obj) { + EVP_ENCODE_CTX_free(obj->ctx); + } + OPENSSL_free(obj); + return SAR_OK; +} + +/* 7.3.6 */ +int SAF_Base64_EncodeUpdate( + void *hBase64Obj, + unsigned char *pucInData, + unsigned int puiInDataLen, + unsigned char *pucOutData, + unsigned int *puiOutDataLen) +{ + SAF_BASE64OBJ *obj = (SAF_BASE64OBJ *)hBase64Obj; + int inlen, outlen; + + if (!hBase64Obj || !pucInData || !pucOutData || !puiOutDataLen) { + SAFerr(SAF_F_SAF_BASE64_ENCODEUPDATE, ERR_R_PASSED_NULL_PARAMETER); + return SAR_IndataErr; + } + /* GMAPI dont check function specific length, leave to EVP */ + if (puiInDataLen > INT_MAX) { + SAFerr(SAF_F_SAF_BASE64_ENCODEUPDATE, SAF_R_INT_OVERFLOW); + return SAR_IndataLenErr; + } + /* GMAPI dont check function specific length, leave to EVP */ + if (*puiOutDataLen > INT_MAX) { + SAFerr(SAF_F_SAF_BASE64_ENCODEUPDATE, SAF_R_INT_OVERFLOW); + return SAR_IndataLenErr; + } + + /* check handle */ + if (!obj->ctx) { + SAFerr(SAF_F_SAF_BASE64_ENCODEUPDATE, SAF_R_INVALID_HANDLE); + return SAR_ObjErr; + } + + if (!obj->inited) { + EVP_EncodeInit(obj->ctx); + obj->inited = 1; + } + + inlen = (int)puiInDataLen; + outlen = (int)(*puiOutDataLen); + //TODO: check outlen, or EVP will fail without error messages + if (!EVP_EncodeUpdate(obj->ctx, pucOutData, &outlen, pucInData, inlen)) { + SAFerr(SAF_F_SAF_BASE64_ENCODEUPDATE, ERR_R_EVP_LIB); + return SAR_UnknownErr; + } + + *puiOutDataLen = (unsigned int)outlen; + return SAR_OK; +} + +/* 7.3.7 */ +int SAF_Base64_EncodeFinal( + void *hBase64Obj, + unsigned char *pucOutData, + unsigned int *puiOutDataLen) +{ + SAF_BASE64OBJ *obj = (SAF_BASE64OBJ *)hBase64Obj; + int len; + + if (!hBase64Obj || !pucOutData || !puiOutDataLen) { + SAFerr(SAF_F_SAF_BASE64_ENCODEFINAL, ERR_R_PASSED_NULL_PARAMETER); + return SAR_IndataErr; + } + if (*puiOutDataLen > INT_MAX) { + SAFerr(SAF_F_SAF_BASE64_ENCODEFINAL, SAF_R_INT_OVERFLOW); + return SAR_IndataLenErr; + } + if (*puiOutDataLen < 66) { + SAFerr(SAF_F_SAF_BASE64_ENCODEFINAL, SAF_R_BUFFER_TOO_SMALL); + return SAR_IndataLenErr; + } + + if (!obj->ctx || !obj->inited) { + SAFerr(SAF_F_SAF_BASE64_ENCODEFINAL, SAF_R_INVALID_HANDLE); + return SAR_ObjErr; + } + + /* the max output length of EVP_EncodeFinal() is 66 + * this function return void, so we need to check `*outlen` + */ + len = (int)(*puiOutDataLen); + //TODO: check outlen, or EVP will fail without error messages + EVP_EncodeFinal(obj->ctx, pucOutData, &len); + + + *puiOutDataLen = (unsigned int)len; + return SAR_OK; +} + +/* 7.3.8 */ +int SAF_Base64_DecodeUpdate( + void *hBase64Obj, + unsigned char *pucInData, + unsigned int puiInDataLen, + unsigned char *pucOutData, + unsigned int *puiOutDataLen) +{ + SAF_BASE64OBJ *obj = (SAF_BASE64OBJ *)hBase64Obj; + int inlen, outlen; + + if (!hBase64Obj || !pucInData || !pucOutData || !puiOutDataLen) { + SAFerr(SAF_F_SAF_BASE64_DECODEUPDATE, ERR_R_PASSED_NULL_PARAMETER); + return SAR_IndataErr; + } + /* GMAPI dont check function specific length, leave to EVP */ + if (puiInDataLen > INT_MAX) { + SAFerr(SAF_F_SAF_BASE64_DECODEUPDATE, SAF_R_INT_OVERFLOW); + return SAR_IndataLenErr; + } + /* GMAPI dont check function specific length, leave to EVP */ + if (*puiOutDataLen > INT_MAX) { + SAFerr(SAF_F_SAF_BASE64_DECODEUPDATE, SAF_R_INT_OVERFLOW); + return SAR_IndataLenErr; + } + + if (!obj->ctx) { + SAFerr(SAF_F_SAF_BASE64_DECODEUPDATE, SAF_R_INVALID_HANDLE); + return SAR_ObjErr; + } + + if (!obj->inited) { + EVP_DecodeInit(obj->ctx); + obj->inited = 1; + } + + inlen = (int)puiInDataLen; + outlen = (int)(*puiOutDataLen); + //TODO: check outlen, or EVP will fail without error messages + + /* + * EVP_DecodeUpdate() return -1 for error, 0 or 1 for success + * 0 means the last char of the input is `=` + */ + if (EVP_DecodeUpdate(obj->ctx, pucOutData, &outlen, pucInData, inlen) < 0) { + SAFerr(SAF_F_SAF_BASE64_DECODEUPDATE, ERR_R_EVP_LIB); + return SAR_UnknownErr; + } + + *puiOutDataLen = (unsigned int)outlen; + return SAR_OK; +} + +/* 7.3.9 */ +int SAF_Base64_DecodeFinal( + void *hBase64Obj, + unsigned char *pucOutData, + unsigned int *puiOutDataLen) +{ + SAF_BASE64OBJ *obj = (SAF_BASE64OBJ *)hBase64Obj; + int len; + + if (!hBase64Obj || !pucOutData || !puiOutDataLen) { + SAFerr(SAF_F_SAF_BASE64_DECODEFINAL, ERR_R_PASSED_NULL_PARAMETER); + return SAR_IndataErr; + } + if (*puiOutDataLen > INT_MAX) { + SAFerr(SAF_F_SAF_BASE64_DECODEFINAL, SAF_R_INT_OVERFLOW); + return SAR_IndataLenErr; + } + + if (!obj->ctx || !obj->inited) { + SAFerr(SAF_F_SAF_BASE64_DECODEFINAL, SAF_R_INVALID_HANDLE); + return SAR_ObjErr; + } + + len = (int)(*puiOutDataLen); + //TODO: check outlen, or EVP will fail without error messages + if (!EVP_DecodeFinal(obj->ctx, pucOutData, &len)) { + SAFerr(SAF_F_SAF_BASE64_DECODEFINAL, ERR_R_EVP_LIB); + return SAR_UnknownErr; + } + + *puiOutDataLen = (unsigned int)len; + return SAR_OK; +} + +/* 7.3.2 */ +int SAF_Base64_Encode( + unsigned char *pucInData, + unsigned int puiInDataLen, + unsigned char *pucOutData, + unsigned int *puiOutDataLen) +{ + int ret = SAR_UnknownErr; + void *handle = NULL; + unsigned char *p; + unsigned int len; + + if (!pucInData || !pucOutData || !puiOutDataLen) { + SAFerr(SAF_F_SAF_BASE64_ENCODE, ERR_R_PASSED_NULL_PARAMETER); + return SAR_IndataErr; + } + + if ((ret = SAF_Base64_CreateBase64Obj(&handle)) != SAR_OK) { + SAFerr(SAF_F_SAF_BASE64_ENCODE, ERR_R_GMAPI_LIB); + goto end; + } + + p = pucOutData; + len = *puiOutDataLen; + + if ((ret = SAF_Base64_EncodeUpdate(handle, pucInData, puiInDataLen, + p, &len)) != SAR_OK) { + SAFerr(SAF_F_SAF_BASE64_ENCODE, ERR_R_GMAPI_LIB); + goto end; + } + p += len; + + len = *puiOutDataLen - len; + if ((ret = SAF_Base64_EncodeFinal(handle, p, &len)) != SAR_OK) { + SAFerr(SAF_F_SAF_BASE64_ENCODE, ERR_R_GMAPI_LIB); + goto end; + } + p += len; + + *puiOutDataLen = p - pucOutData; + ret = SAR_OK; + +end: + SAF_Base64_DestroyBase64Obj(handle); + return ret; +} + +/* 7.3.3 */ +int SAF_Base64_Decode( + unsigned char *pucInData, + unsigned int puiInDataLen, + unsigned char *pucOutData, + unsigned int *puiOutDataLen) +{ + int ret = SAR_UnknownErr; + void *handle = NULL; + unsigned char *p; + unsigned int len; + + if ((ret = SAF_Base64_CreateBase64Obj(&handle)) != SAR_OK) { + SAFerr(SAF_F_SAF_BASE64_DECODE, ERR_R_GMAPI_LIB); + goto end; + } + + p = pucOutData; + len = *puiOutDataLen; + + if ((ret = SAF_Base64_DecodeUpdate(handle, pucInData, puiInDataLen, + p, &len)) != SAR_OK) { + SAFerr(SAF_F_SAF_BASE64_DECODE, ERR_R_GMAPI_LIB); + goto end; + } + p += len; + + len = *puiOutDataLen - len; + if ((ret = SAF_Base64_DecodeFinal(handle, p, &len)) != SAR_OK) { + SAFerr(SAF_F_SAF_BASE64_DECODE, ERR_R_GMAPI_LIB); + goto end; + } + p += len; + + *puiOutDataLen = p - pucOutData; + ret = SAR_OK; + +end: + SAF_Base64_DestroyBase64Obj(handle); + return ret; +} + +int SAF_Base64_test(int verbose) +{ + int ret = SAR_UnknownErr; + /* sizeof(buf1)%3 == 1 makes base64 ended with "==" */ + unsigned char buf1[121]; + unsigned char buf2[512]; + unsigned char buf3[512]; + unsigned int len1, len2, len3; + + /* generate some random binary for testing */ + RAND_bytes(buf1, sizeof(buf1)); + memset(buf2, 0, sizeof(buf2)); + memset(buf3, 0, sizeof(buf3)); + + len1 = (unsigned int)sizeof(buf1); + len2 = (unsigned int)sizeof(buf2); + if ((ret = SAF_Base64_Encode(buf1, len1, buf2, &len2)) != SAR_OK) { + ERR_print_errors_fp(stderr); + goto end; + } + if (verbose) { + printf("%s\n", buf2); + } + + len3 = sizeof(buf3); + if ((ret = SAF_Base64_Decode(buf2, len2, buf3, &len3)) != SAR_OK) { + ERR_print_errors_fp(stderr); + goto end; + } + + /* check correctness */ + if (len1 == len3 && memcmp(buf1, buf3, len1) == 0) { + ret = SAR_OK; + } else { + /* make sure to assign `ret`, or it might be set as OK by + * previous functions */ + ret = SAR_UnknownErr; + } + +end: + if (verbose) { + printf("%s %s\n", __FUNCTION__, + ret == SAR_OK ? "passed" : "failed"); + } + + return SAR_OK; +} diff --git a/crypto/saf/saf_cert.c b/crypto/saf/saf_cert.c new file mode 100644 index 00000000..99d6fafb --- /dev/null +++ b/crypto/saf/saf_cert.c @@ -0,0 +1,254 @@ +/* ==================================================================== + * Copyright (c) 2016 The GmSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the GmSSL Project. + * (http://gmssl.org/)" + * + * 4. The name "GmSSL Project" must not be used to endorse or promote + * products derived from this software without prior written + * permission. For written permission, please contact + * guanzhi1980@gmail.com. + * + * 5. Products derived from this software may not be called "GmSSL" + * nor may "GmSSL" appear in their names without prior written + * permission of the GmSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the GmSSL Project + * (http://gmssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE GmSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GmSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES + * LOSS OF USE, DATA, OR PROFITS OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +#include +#include +#include +#include +#include +#include + + +/* 7.2.2 */ +int SAF_AddTrustedRootCaCertificate( + void *hAppHandle, + unsigned char *pucCertificate, + unsigned int uiCertificateLen) +{ + return SAR_NotSupportYetErr; +} + +/* 7.2.3 */ +int SAF_GetRootCaCertificateCount( + void *hAppHandle, + unsigned int *puiCount) +{ + *puiCount = 0; + return SAR_Ok; +} + +/* 7.2.4 */ +int SAF_GetRootCaCertificate( + void *hAppHandle, + unsigned int uiIndex, + unsigned char *pucCertificate, + unsigned int *puiCertificateLen) +{ + return SAR_NotSupportYetErr; +} + +/* 7.2.5 */ +int SAF_RemoveRootCaCertificate( + void *hAppHandle, + unsigned int uiIndex) +{ + return SAR_NotSupportYetErr; +} + +/* 7.2.6 */ +int SAF_AddCaCertificate( + void *hAppHandle, + unsigned char *pucCertificate, + unsigned int *puiCertificateLen) +{ + return SAR_NotSupportYetErr; +} + +/* 7.2.7 */ +int SAF_GetCaCertificateCount( + void *hAppHandle, + unsigned int *puiCount) +{ + return SAR_NotSupportYetErr; +} + +/* 7.2.8 */ +int SAF_GetCaCertificate( + void *hAppHandle, + unsigned int uiIndex, + unsigned char *pucCertificate, + unsigned int *puiCertificateLen) +{ + return SAR_NotSupportYetErr; +} + +/* 7.2.9 */ +int SAF_RemoveCaCertificate( + void *hAppHandle, + unsigned int uiIndex) +{ + return SAR_NotSupportYetErr; +} + +/* 7.2.10 */ +int SAF_AddCrl( + void *hAppHandle, + unsigned char *pucDerCrl, + unsigned int uiDerCrlLen) +{ + return SAR_NotSupportYetErr; +} + +/* 7.2.11 */ +int SAF_VerifyCertificate( + void *hAppHandle, + unsigned char *pucUsrCertificate, + unsigned int uiUsrCertificateLen) +{ + return SAR_NotSupportYetErr; +} + +/* 7.2.12 */ +int SAF_VerifyCertificateByCrl( + void *hAppHandle, + unsigned char *pucUsrCertificate, + unsigned int uiUsrCertificateLen, + unsigned char *pucDerCrl, + unsigned int uiDerCrlLen) +{ + return SAR_NotSupportYetErr; +} + +/* 7.2.13 */ +int SAF_GetCertificateStateByOCSP( + void *hAppHandle, + unsigned char *pcOcspHostURL, + unsigned int uiOcspHostURLLen, + unsigned char *pucUsrCertificate, + unsigned int uiUsrCertificateLen, + unsigned char *pucCACertificate, + unsigned int uiCACertficateLen) +{ + return SAR_NotSupportYetErr; +} + +/* 7.2.14 */ +int SAF_GetCertFromLdap( + void *hAppHandle, + char *pcLdapHostURL, + unsigned int uiLdapHostURLLen, + unsigned char *pucQueryDN, + unsigned int uiQueryDNLen, + unsigned char *pucOutCert, + unsigned int *puiOutCertLen) +{ + return SAR_NotSupportYetErr; +} + +/* 7.2.15 */ +int SAF_GetCrlFromLdap( + void *hAppHandle, + char *pcLdapHostURL, + unsigned int uiLdapHostURLLen, + unsigned char *pucCertificate, + unsigned int uiCertificateLen, + unsigned char *pucCrlData, + unsigned int *puiCrlDataLen) +{ + return SAR_NotSupportYetErr; +} + +/* 7.2.16 */ +int SAF_GetCertificateInfo( + void *hAppHandle, + unsigned char *pucCertificate, + unsigned int uiCertificateLen, + unsigned int uiInfoType, + unsigned char *pucInfo, + unsigned int *puiInfoLen) +{ + return SAR_NotSupportYetErr; +} + +/* 7.2.17 */ +int SAF_GetExtTypeInfo( + void *hAppHandle, + unsigned char *pucDerCert, + unsigned int uiDerCertLen, + unsigned int uiInfoType, + unsigned char *pucPriOid, + unsigned int uiPriOidLen, + unsigned char *pucInfo, + unsigned int *puiInfoLen) +{ + return SAR_NotSupportYetErr; +} + +/* 7.2.18 */ +int SAF_EnumCertificates( + void *hAppHandle, + SGD_USR_CERT_ENUMLIST *usrCerts) +{ + return SAR_NotSupportYetErr; +} + +/* 7.2.19 */ +int SAF_EnumKeyContainerInfo( + void *hAppHandle, + SGD_KEYCONTAINERINFO_ENUMLIST *keyContainerInfo) +{ + return SAR_NotSupportYetErr; +} + +/* 7.2.20 */ +int SAF_EnumCertificatesFree( + void *hAppHandle, + SGD_USR_CERT_ENUMLIST *usrCerts) +{ + return SAR_NotSupportYetErr; +} + +/* 7.2.21 */ +int SAF_EnumKeyContainerInfoFree( + void *hAppHandle, + SGD_KEYCONTAINERINFO_ENUMLIST *keyContainerInfo) +{ + return SAR_NotSupportYetErr; +} + diff --git a/crypto/saf/saf_ec.c b/crypto/saf/saf_ec.c new file mode 100644 index 00000000..ca2c7fb3 --- /dev/null +++ b/crypto/saf/saf_ec.c @@ -0,0 +1,719 @@ +/* ==================================================================== + * Copyright (c) 2016 The GmSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the GmSSL Project. + * (http://gmssl.org/)" + * + * 4. The name "GmSSL Project" must not be used to endorse or promote + * products derived from this software without prior written + * permission. For written permission, please contact + * guanzhi1980@gmail.com. + * + * 5. Products derived from this software may not be called "GmSSL" + * nor may "GmSSL" appear in their names without prior written + * permission of the GmSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the GmSSL Project + * (http://gmssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE GmSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GmSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +/* GM/T 0019-2012: 7.3.23 */ +/* + * uiKeyUsage in {SGD_SM2_1, SGD_SM2_2, SGD_SM2_3} + * uiExportFlag = 1 means exportable, 0 means non-exportable + * we will generate a key pair and import into ENGINE + * or use ENGINE to generate key pair + */ + +#include +#include +#include + +int saf_save_ec_keypair( + void *hAppHandle, + unsigned char *pucContainerName, + unsigned int uiContainerNameLen, + unsigned int uiKeyBits, + unsigned int uiKeyUsage, + unsigned int uiExportFlag, + ECCrefPublicKey *pucPublicKey, + ECCrefPrivateKey *pucPrivateKey) +{ + return -1; +} + +/* 7.3.23 */ +int SAF_GenEccKeyPair( + void *hAppHandle, + unsigned char *pucContainerName, + unsigned int uiContainerNameLen, + unsigned int uiKeyBits, + unsigned int uiKeyUsage, + unsigned int uiExportFlag) +{ + int ret = -1; + ECCrefPublicKey publicKey; + ECCrefPrivateKey privateKey; + + /* check arguments */ + if (!hAppHandle || !pucContainerName) { + SAFerr(SAF_F_SAF_GENECCKEYPAIR, + ERR_R_PASSED_NULL_PARAMETER); + return SAR_IndataErr; + } + if (uiContainerNameLen <= 0 || uiContainerName > SGD_MAX_NAME_SIZE || + strlen((char *)pucContainerName) != uiContainerNameLen) { + SAFerr(SAF_F_SAF_GENECCKEYPAIR, + SAF_R_INVALID_INPUT_LENGTH); + return SAR_NameLenErr; + } + if (uiKeyBits < 160 || uiKeyBits > ECCref_MAX_BITS) { + SAFerr(SAF_F_SAF_GENECCKEYPAIR, + SAF_R_INVALID_KEY_LENGTH); + return SAR_ModulusLenErr; + } + if (uiKeyUsage != SGD_SM2_1 && uiKeyUsage != SGD_SM2_2 && + uiKeyUsage != SGD_SM2_3) { + SAFerr(SAF_F_SAF_GENECCKEYPAIR, + SAF_R_INVALID_KEY_USAGE); + return SAR_KeyUsageErr; + } + + /* generate keypair */ + if (SDF_GenerateKeyPair_ECC( + NULL, + uiKeyUsage, + uiKeyBits, + &publicKey, + &privateKey) != SDR_OK) { + + SAFerr(SAF_F_SAF_GENECCKEYPAIR, SAF_R_SAF_ERROR); + goto end; + } + + /* save keypair */ + if (saf_save_ec_keypair( + hAppHandle, + pucContainerName, + uiContainerNameLen, + uiKeyBits, + uiKeyUsage, + uiExportFlag, + &publicKey, + &privateKey) != SAR_Ok) { + + SAFerr(SAF_F_SAF_GENECCKEYPAIR, ERR_R_GMAPI_LIB); + goto end; + } + + /* set return value */ + ret = SAR_Ok; + +end: + /* clear private key */ + memset(&privateKey, 0, sizeof(ECCrefPrivateKey)); + return ret; +} + +int saf_get_sdf_session_and_keyindex( + void *hAppHandle, + unsigned char *pucContainerName, + unsigned int uiContainerNameLen, + unsigned int uiKeyUsage, + void *phSessionHandle, + unsigned int puiKeyIndex) +{ + return -1; +} + +void saf_release_sdf_session( + void *hSessionHandle) +{ +} + +/* + * `crypto/ec` only support `i2o_ECPublicKey` and `o2i_ECPublicKey`, there + * are no DER encoding/decoding routines for EC public key. The encoding of + * `i2o` is just the result of `EC_POINT_point2oct` on the public key point. + */ +/* 7.3.24 */ +int SAF_GetEccPublicKey( + void *hAppHandle, + unsigned char *pucContainerName, + unsigned int uiContainerNameLen, + unsigned int uiKeyUsage, + unsigned char *pucPublicKey, + unsigned int *puiPublicKeyLen) +{ + int ret = -1; + void *hSessionHandle = NULL; + unsigned int uiKeyIndex; + int rv; + + /* check arguments */ + if (!hAppHandle || !pucContainerNamae || !pucPUblicKey || + !puiPublicKeyLen) { + SAFerr(SAF_F_SAF_GETECCPUBLICKEY, + ERR_R_PASSED_NULL_PARAMETER); + return SAR_IndataErr; + } + if (uiContainerNameLen <= 0 || + uiContainerNameLen > SGD_MAX_NAME_SIZE || + strlen((char *)pucContainerName) != uiContainerNameLen) { + SAFerr(SAF_F_SAF_GETECCPUBLICKEY, + SAF_R_INVALID_INPUT_LENGTH); + return SAR_NameLenErr; + } + if (uiKeyUsage != SGD_SM2_1 && uiKeyUsage != SGD_SM2_2 && + uiKeyUsage != SGD_SM2_3) { + SAFerr(SAF_F_SAF_GETECCPUBLICKEY, + SAF_R_INVALID_KEY_USAGE); + return SAR_KeyUsageErr; + } + if ((size_t)*puiPublicKeyLen != sizeof(ECCrefPublicKey)) { + SAFerr(SAF_F_SAF_GETECCPUBLICKEY, + SAF_R_BUFFER_TOO_SMALL); + return SAR_IndataErr; + } + + /* get session and key index*/ + if ((rv = saf_get_sdf_session_and_keyindex( + hAppHandle, + pucContainerName, + uiContainerNameLen, + uiKeyUsage, + &hSessionHandle, + &uiKeyIndex)) != SAR_Ok) { + + SAFerr(SAF_F_SAF_GETECCPUBLICKEY, ERR_R_GMAPI_LIB); + ret = rv; + goto end; + } + + /* load key */ + if (uiKeyUsage == SGD_SM2_1) { + if (SDF_ExportSignPublicKey_ECC( + hSessionHandle, + uiKeyIndex, + (ECCrefPublicKey *)pucPublicKey) != SDR_OK) { + + SAFerr(SAF_F_SAF_GETECCPUBLICKEY, ERR_R_GMAPI_LIB); + goto end; + } + } else { + if (SDF_ExportEncPublicKey_ECC( + hSessionHandle, + uiKeyIndex, + (ECCrefPublicKey *)pucPublicKey) != SDR_OK) { + + SAFerr(SAF_F_SAF_GETECCPUBLICKEY, ERR_R_GMAPI_LIB); + goto end; + } + } + + /* set return value */ + *puiPublicKeyLen = (unsigned int)sizeof(ECCrefPublicKey); + ret = SAR_Ok; + +end: + sdf_release_sdf_session(hSessionHandle); + return ret; +} + +/* 7.3.25 */ +/* input data is message, not digest + * otuput is the DER encoding of the signature + * + * WHY do we need a seperate function for EC and RSA? + */ +int saf_get_sdf_session_and_ecsignkey( + void *hAppHandle, + unsigned char *pucContainerName, + unsigned int uiContainerNameLen, + unsigned int uiAlgorithmID, /* SGD_SM2_1 */ + void **phSessionhandle, + unsigned int *puiISKIndex); + +int SAF_EccSign( + void *hAppHandle, + unsigned char *pucContainerName, + unsigned int uiContainerNameLen, + unsigned int uiAlgorithmID, /* SGD_SM2_1 */ + unsigned char *pucInData, + unsigned int uiInDataLen, + unsigned char *pucSignData, + unsigned int *puiSignDataLen) +{ + int ret = SAR_UnknownErr; + void *hSessionHandle = NULL; + unsigned int uiISKIndex; + + /* check arguments */ + if (!hAppHandle || !pucContainerNamae || !pucPUblicKey || + !pucSignData || !pucSignDataLen) { + SAFerr(SAF_F_SAF_ECCSIGN, + ERR_R_PASSED_NULL_PARAMETER); + return SAR_IndataErr; + } + if (uiContainerNameLen <= 0 || + uiContainerNameLen > SGD_MAX_NAME_SIZE || + strlen((char *)pucContainerName) != uiContainerNameLen) { + SAFerr(SAF_F_SAF_ECCSIGN, SAF_R_INVALID_INPUT_LENGTH); + return SAR_NameLenErr; + } + if (uiAlgorithmID != SGD_SM2_1) { + SAFerr(SAF_F_SAF_ECCSIGN, SAF_R_INVALID_ALGOR); + return SAR_AlgoTypeErr; + } + if (uiInDataLen != SM3_DIGEST_LENGTH) { + SAFerr(SAF_F_SAF_ECCSIGN, SAF_R_INVALID_INPUT_LENGTH); + return SAR_IndataLenErr; + } + if ((size_t)*puiSignDataLen != sizeof(ECCSignature)) { + SAFerr(SAF_F_SAF_ECCSIGN, SAF_R_BUFFER_TOO_SMALL); + return SAR_IndataErr; + } + + /* get session and ec sign key */ + if ((rv = saf_get_sdf_session_and_ecsignkey( + hAppHandle, + pucContainerName, + uiContainerNameLen, + uiAlgorithmID, + &hSessionHandle, + &uiISKIndex)) != SAR_Ok) { + + SAFerr(SAF_F_SAF_ECCSIGN, ERR_R_GMAPI_LIB); + ret = rv; + goto end; + } + + /* sign */ + if (SDF_InternalSign_ECC( + hSessionHandle, + uiISKIndex, + pucInData, + uiInDataLen, + (ECCSignature *)pucSignData) != SDR_OK) { + + SAFerr(SAF_F_SAF_ECCSIGN, ERR_R_GMAPI_LIB); + goto end; + } + + /* set return value */ + *puiSignDataLen = (unsigned int)sizeof(ECCSignature); + ret = SAR_Ok; + +end: + saf_release_sdf_session(hSessionhandle); + return ret; +} + +/* 7.3.26 */ +/* it seems that we need the public key has more info */ +int SAF_EccVerifySign( + unsigned char *pucPublicKey, + unsigned int uiPublicKeyLen, + unsigned int uiAlgorithmID, + unsigned char *pucInData, + unsigned int uiInDataLen, + unsigned char *pucSignData, + unsigned int uiSignDataLen) +{ + int ret = SAR_UnknownErr; + + /* check arguments */ + if (!pucPublicKey || !pucInData || !pucSignData) { + SAFerr(SAF_F_SAF_ECCVERIFYSIGN, ERR_R_PASSED_NULL_PARAMETER); + return SAR_IndataErr); + } + if (uiPublicKeyLen != sizeof(ECCrefPublic)) { + SAFerr(SAF_F_SAF_ECCVERIFYSIGN, SAF_R_INVALID_INPUT_LENGTH); + return SAR_IndataLenErr; + } + if (uiAlgorithmID != SGD_SM2_1) { + SAFerr(SAF_F_SAF_ECCVERIFYSIGN, SAF_R_INVALID_ALGOR); + return SAR_AlgoTypeErr; + } + if (uiInDataLen != SM3_DIGEST_LENGTH) { + SAFerr(SAF_F_SAF_ECCVERIFYSIGN, SAF_R_INVALID_INPUT_LENGTH); + return SAR_IndataLenErr; + } + if (uiSignDataLen != sizeof(ECCSignature)) { + SAFerr(SAF_F_SAF_ECCVERIFYSIGN, SAF_R_INVALID_INPUT_LENGTH); + return SAR_IndataLenErr; + } + + if (SDF_ExternalVerify_ECC( + NULL, /* hSessionHandle */ + uiAlgorithmID, + (ECCrefPublicKey *)pucPublicKey, + pucInData, + uiInDataLen, + (ECCSignature *)pucSignData) != SDR_OK) { + + SAFerr(SAF_F_SAF_ECCVERIFYSIGN, ERR_R_GMAPI_LIB); + goto end; + } + + ret = SAR_Ok; + +end: + return ret; +} + +/* 7.3.27 */ +int SAF_EccPublicKeyEnc( + unsigned char *pucPublicKey, + unsigned int uiPublicKeyLen, + unsigned int uiAlgorithmID, + unsigned char *pucInData, + unsigned int uiInDataLen, + unsigned char *pucOutData, + unsigned int *puiOutDataLen) +{ + /* check arguments */ + if (!pucPublicKey || !pucInData || !pucOutData || !puiOutDataLen) { + SAFerr(SAF_F_SAF_ECCPUBLICKEYENC, + ERR_R_PASSED_NULL_PARAMETER); + return SAR_IndataErr; + } + if (uiPublicKeyLen != sizeof(ECCrefPublic)) { + SAFerr(SAF_F_SAF_ECCPUBLICKEYENC, + SAF_R_INVALID_INPUT_LENGTH); + return SAR_IndataLenErr; + } + if (uiAlgorithmID != SGD_SM2_3) { + SAFerr(SAF_F_SAF_ECCPUBLICKEYENC, + SAF_R_INVALID_ALGOR); + return SAR_AlgoTypeErr; + } + if (uiInDataLen <= 0 || uiInDataLen > ECCref_MAX_CIPHER_LEN) { + SAFerr(SAF_F_SAF_ECCPUBLICKEYENC, + SAF_R_INVALID_INPUT_LENGTH); + return SAR_IndataLenErr; + } + if (*puiOutDataLen != sizeof(ECCCipher)) { + SAFerr(SAF_F_SAF_ECCPUBLICKEYENC, + SAF_R_INVALID_INPUT_LENGTH); + return SAR_IndataLenErr; + } + + /* encrypt */ + if (SDF_ExternalEncrypt_ECC( + NULL, /* hSessionHandle */ + uiAlgorithmID, + (ECCrefPublicKey *)pucPublicKey, + pucInData, + uiInDataLen, + (ECCCipher *)pucOutData) != SDR_OK) { + + SAFerr(SAF_F_SAF_ECCPUBLICKEYENC, ERR_R_GMAPI_LIB); + goto end; + } + + ret = SAR_Ok; + +end: + return ret; +} + +int saf_get_ec_public_key_from_cert( + unsigned char *pucCertificate, + unsigned int uiCertificateLen, + ECCrefPublicKey *pucPublicKey) +{ + return -1; +} + +/* 7.3.28 */ +int SAF_EccPublicKeyEncByCert( + unsigned char *pucCertificate, + unsigned int uiCertificateLen, + unsigned int uiAlgorithmID, + unsigned char *pucInData, + unsigned int uiInDataLen, + unsigned char *pucOutData, + unsigned int *puiOutDataLen) +{ + int ret = SAR_UnknownErr; + ECCrefPublicKey publicKey; + int rv; + + /* check arguments */ + if (!pucCertificate || !pucInData || !pucOutData || !puiOutDataLen) { + SAFerr(SAF_F_SAF_ECCPUBLICKEYENCBYCERT, + ERR_R_PASSED_NULL_PARAMETER); + return SAR_IndataErr); + } + if (uiCertificateLen <= 0 || uiCertificate > INT_MAX) { + SAFerr(SAF_F_SAF_ECCPUBLICKEYENCBYCERT, + SAF_R_INVALID_INPUT_LENGTH); + return SAR_IndataLenErr; + } + if (uiAlgorithmID != SGD_SM2_3) { + SAFerr(SAF_F_SAF_ECCPUBLICKEYENCBYCERT, + SAF_R_INVALID_ALGOR); + return SAR_AlgoTypeErr; + } + if (uiInDataLen <= 0 || uiInDataLen > ECCref_MAX_CIPHER_LEN) { + SAFerr(SAF_F_SAF_ECCPUBLICKEYENCBYCERT, + SAF_R_INVALID_INPUT_LENGTH); + return SAR_IndataLenErr; + } + if (*puiOutDataLen != sizeof(ECCCipher)) { + SAFerr(SAF_F_SAF_ECCPUBLICKEYENCBYCERT, + SAF_R_INVALID_INPUT_LENGTH); + return SAR_IndataLenErr; + } + + /* get public key from cert */ + if ((rv = saf_get_ec_public_key_from_cert( + pucCertificate, + uiCertificateLen, + &publicKey)) != SAR_OK) { + + SAFerr(SAF_F_SAF_ECCPUBLICKEYENCBYCERT, ERR_R_GMAPI_LIB); + ret = rv; + goto end; + } + + /* encrypt */ + if (SAF_EccPublicKeyEnc( + (unsigned char *)&publicKey, + (unsigned int)sizeof(ECCrefPublicKey), + uiAlgorithmID, + pucInData, + uiInDataLen, + pucOutData, + puiOutDataLen) != SAR_OK) { + + SAFerr(SAF_F_SAF_ECCPUBLICKEYENCBYCERT, ERR_R_GMAPI_LIB); + goto end; + } + + /* set return value */ + ret = SAR_Ok; + +end: + return ret; +} + +/* 7.3.29 */ +int SAF_EccVerifySignByCert( + unsigned int uiAlgorithmID, + unsigned char *pucCertificate, + unsigned int uiCertificateLen, + unsigned char *pucInData, + unsigned int uiInDataLen, + unsigned char *pucSignData, + unsigned int uiSignDataLen) +{ + int ret = SAR_UnknownErr; + ECCrefPublicKey publicKey; + int rv; + + /* check arguments */ + if (!pucCertificate || !pucInData || !pucSignData) { + SAFerr(SAF_F_SAF_ECCVERIFYSIGNBYCERT, + ERR_R_PASSED_NULL_PARAMETER); + return SAR_IndataErr); + } + if (uiCertificateLen <= 0 || uiCertificate > INT_MAX) { + SAFerr(SAF_F_SAF_ECCVERIFYSIGNBYCERT, + SAF_R_INVALID_INPUT_LENGTH); + return SAR_IndataLenErr; + } + if (uiAlgorithmID != SGD_SM2_1) { + SAFerr(SAF_F_SAF_ECCVERIFYSIGNBYCERT, + SAF_R_INVALID_ALGOR); + return SAR_AlgoTypeErr; + } + if (uiInDataLen != SM3_DIGEST_LENGTH) { + SAFerr(SAF_F_SAF_ECCVERIFYSIGNBYCERT, + SAF_R_INVALID_INPUT_LENGTH); + return SAR_IndataLenErr; + } + if (uiSignDataLen != sizeof(ECCSignature)) { + SAFerr(SAF_F_SAF_ECCVERIFYSIGNBYCERT, + SAF_R_INVALID_INPUT_LENGTH); + return SAR_IndataLenErr; + } + + /* load public key form cert */ + if ((rv = saf_get_ec_public_key_from_cert( + pucCertificate, + uiCertificateLen, + &publicKey))!= SAR_OK) { + + SAFerr(SAF_F_SAF_ECCVERIFYSIGNBYCERT, ERR_R_GMAPI_LIB); + ret = rv; + goto end; + } + + /* verify */ + if (SAF_EccVerifySign( + (unsigned char *)&publicKey, + (unsigned int )sizeof(ECCrefPublicKey), + uiAlgorithmID, + pucInData, + uiInDataLen, + pucSignData, + uiSignDataLen)!= SAR_Ok) { + + SAFerr(SAF_F_SAF_ECCVERIFYSIGNBYCERT, ERR_R_GMAPI_LIB); + goto end; + } + + /* set return value */ + ret = SAR_Ok; + +end: + return ret; +} + +/* 7.3.33 */ +int SAF_GenerateAgreementDataWithECC( + void *hSymmKeyObj, + unsigned int uiISKIndex, + unsigned int uiKeyBits, + unsigned char *pucSponsorID, + unsigned int uiSponsorIDLength, + unsigned char *pucSponsorPublicKey, + unsigned int *puiSponsorPublicKeyLen, + unsigned char *pucSponsorTmpPublicKey, + unsigned int *puiSponsorTmpPublicKeyLen, + void **phAgreementHandle) +{ + int ret = -1; + void *hSessionHandle = NULL; + unsigned int uiISKIndex; + + + if (SDF_GenerateAgreementDataWithECC( + hSessionHandle, + uiISKIndex, + uiKeyBits, + pucSponsorID, + uiSponsorIDLength, + (ECCrefPublicKey *)pucSponsorPublicKey, + (ECCrefPublicKey *)pucSponsorTmpPublicKey, + phAgreementHandle) != SDR_OK) { + + SAFerr(SAF_F_SAF_GENERATEAGREEMENTDATAWITHECC, + ERR_R_GMAPI_LIB); + goto end; + } + + ret = SAR_Ok; +end: + return ret; +} + +/* 7.3.34 */ +int SAF_GenerateKeyWithECC( + void *phAgreementHandle, + unsigned char *pucResponseID, + unsigned int uiResponseIDLength, + unsigned char *pucResponsePublicKey, + unsigned int uiResponsePublicKeyLen, + unsigned char *pucResponseTmpPublicKey, + unsigned int uiResponseTmpPublicKeyLen, + void **phKeyHandle) +{ + int ret = -1; + + if (SDF_GenerateKeyWithECC( + NULL, /*hSessionHandle */ + pucResponseID, + uiResponseIDLength, + (ECCrefPublicKey *)pucResponsePublicKey, + (ECCrefPublicKey *)pucResponseTmpPublicKey, + phAgreementHandle, + phKeyHandle) != SDR_OK) { + + SAFerr(SAF_F_SAF_GENERATEKEYWITHECC, ERR_R_GMAPI_LIB); + goto end; + } + + return 0; +} + +/* 7.3.35 */ +int SAF_GenerateAgreementDataAdnKeyWithECC( + void *hSymmKeyObj, + unsigned int uiISKIndex, + unsigned int uiKeyBits, + unsigned char *pucResponseID, + unsigned int uiResponseIDLength, + unsigned char *pucSponsorID, + unsigned int uiSponsorIDLength, + unsigned char *pucSponsorPublicKey, + unsigned int *puiSponsorPublicKeyLen, + unsigned char *pucSponsorTmpPublicKey, + unsigned int *puiSponsorTmpPublicKeyLen, + unsigned char *pucResponsePublicKey, + unsigned int uiResponsePublicKeyLen, + unsigned char *pucResponseTmpPublicKey, + unsigned int uiResponseTmpPublicKeyLen, + void **phKeyHandle) +{ + int ret; + void *hAgreementHandle = NULL; + + if ((ret = SAF_GenerateAgreementDataWithECC( + hSymmKeyObj, + uiISKIndex, + uiKeyBits, + pucSponsorID, + uiSponsorIDLength, + pucSponsorPublicKey, + puiSponsorPublicKeyLen, + pucSponsorTmpPublicKey, + puiSponsorTmpPublicKeyLen, + &hAgreementHandle)) != SAR_OK) { + } + + if ((ret = SAF_GenerateKeyWithECC( + hAgreementHandle, + pucResponseID, + uiResponseIDLength, + pucResponsePublicKey, + uiResponsePublicKeyLen, + pucResponseTmpPublicKey, + uiResponseTmpPublicKeyLen, + phKeyHandle)) != SAR_OK) { + } + + return 0; +} diff --git a/crypto/saf/saf_ec.d.tmp b/crypto/saf/saf_ec.d.tmp new file mode 100644 index 00000000..cdae33c4 --- /dev/null +++ b/crypto/saf/saf_ec.d.tmp @@ -0,0 +1,16 @@ +crypto/saf/saf_ec.o: crypto/saf/saf_ec.c include/openssl/gmapi.h \ + include/openssl/ec.h include/openssl/opensslconf.h \ + include/openssl/asn1.h include/openssl/e_os2.h include/openssl/bio.h \ + include/openssl/crypto.h include/openssl/stack.h \ + include/openssl/safestack.h include/openssl/opensslv.h \ + include/openssl/ossl_typ.h include/openssl/symhacks.h \ + include/openssl/bn.h include/openssl/sm2.h include/openssl/err.h \ + include/openssl/lhash.h include/openssl/evp.h \ + include/openssl/objects.h include/openssl/obj_mac.h \ + include/openssl/kdf2.h include/openssl/kdf.h include/openssl/x509.h \ + include/openssl/buffer.h include/openssl/rsa.h include/openssl/dsa.h \ + include/openssl/dh.h include/openssl/sha.h include/openssl/x509_vfy.h \ + include/openssl/pkcs7.h include/openssl/ecdsa.h include/openssl/sm3.h \ + include/openssl/sgd.h include/openssl/saf.h include/openssl/sdf.h \ + include/openssl/skf.h include/openssl/sof.h include/openssl/gmsdf.h \ + include/openssl/gmsaf.h diff --git a/crypto/saf/saf_enc.c b/crypto/saf/saf_enc.c new file mode 100644 index 00000000..99ed2ef4 --- /dev/null +++ b/crypto/saf/saf_enc.c @@ -0,0 +1,272 @@ +/* ==================================================================== + * Copyright (c) 2016 The GmSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the GmSSL Project. + * (http://gmssl.org/)" + * + * 4. The name "GmSSL Project" must not be used to endorse or promote + * products derived from this software without prior written + * permission. For written permission, please contact + * guanzhi1980@gmail.com. + * + * 5. Products derived from this software may not be called "GmSSL" + * nor may "GmSSL" appear in their names without prior written + * permission of the GmSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the GmSSL Project + * (http://gmssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE GmSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GmSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES + * LOSS OF USE, DATA, OR PROFITS OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +#include +#include +#include +#include + +/* 7.3.39 */ +int SAF_SymmEncryptUpdate( + void *hKeyHandle, + const unsigned char *pucInData, + unsigned int uiInDataLen, + unsigned char *pucOutData, + unsigned int *puiOutDataLen) +{ + int ret = SAR_UnknownErr; + SAF_KEY_HANDLE *hkey = (SAF_KEY_HANDLE *)hKeyHandle; + unsigned char *out = pucOutData; + int inlen, outlen; + + if (!hKeyHandle || !pucInData || !pucOutData || !puiOutDataLen) { + SAFerr(SAF_F_SAF_SYMMENCRYPTUPDATE, ERR_R_PASSED_NULL_PARAMETER); + return SAR_IndataErr; + } + if (uiInDataLen > INT_MAX) { + SAFerr(SAF_F_SAF_SYMMENCRYPTUPDATE, SAF_R_INVALID_LENGTH); + return SAR_IndataLenErr; + } + + if (!hkey->cipher_ctx) { + unsigned char iv[32]; + int ivlen; + + if (!(hkey->cipher_ctx = EVP_CIPHER_CTX_new())) { + SAFerr(SAF_F_SAF_SYMMENCRYPTUPDATE, ERR_R_MALLOC_FAILURE); + ret = SAR_MemoryErr; + goto end; + } + + /* generate random iv and output */ + ivlen = EVP_CIPHER_block_size(hkey->cipher); + if (ivlen <= 0 || ivlen > sizeof(iv)) { + SAFerr(SAF_F_SAF_SYMMENCRYPTUPDATE, SAF_R_INVALID_CONTEXT); + ret = SAR_ObjErr; + goto end; + } + if (!RAND_bytes(iv, ivlen)) { + SAFerr(SAF_F_SAF_SYMMENCRYPTUPDATE, SAF_R_GEN_RANDOM); + ret = SAR_GenRandErr; + goto end; + } + + /* output iv, update out pointer */ + memcpy(out, iv, ivlen); + out += ivlen; + + if (!EVP_EncryptInit(hkey->cipher_ctx, hkey->cipher, hkey->key, iv)) { + SAFerr(SAF_F_SAF_SYMMENCRYPTUPDATE, ERR_R_EVP_LIB); + goto end; + } + } + + inlen = (int)uiInDataLen; + if (!EVP_EncryptUpdate(hkey->cipher_ctx, out, &outlen, pucInData, inlen)) { + SAFerr(SAF_F_SAF_SYMMENCRYPTUPDATE, ERR_R_EVP_LIB); + goto end; + } + + *puiOutDataLen = (unsigned int)outlen; + ret = SAR_OK; + +end: + if (ret != SAR_OK && hkey->cipher_ctx) { + EVP_CIPHER_CTX_free(hkey->cipher_ctx); + hkey->cipher_ctx = NULL; + } + return ret; +} + +/* 7.3.40 */ +int SAF_SymmEncryptFinal( + void *hKeyHandle, + unsigned char *pucOutData, + unsigned int *puiOutDataLen) +{ + return 0; +} + +/* 7.3.42 */ +int SAF_SymmDecryptUpdate( + void *hKeyHandle, + unsigned char *pucInData, + unsigned int uiInDataLen, + unsigned char *pucOutData, + unsigned int *puiOutDataLen) +{ + int ret = SAR_UnknownErr; + SAF_KEY_HANDLE *hkey = (SAF_KEY_HANDLE *)hKeyHandle; + unsigned char *in = pucInData; + int inlen, outlen; + + if (!hKeyHandle || !pucInData || !pucOutData || !puiOutDataLen) { + SAFerr(SAF_F_SAF_SYMMDECRYPTUPDATE, ERR_R_PASSED_NULL_PARAMETER); + return SAR_IndataErr; + } + if (uiInDataLen > INT_MAX) { + SAFerr(SAF_F_SAF_SYMMDECRYPTUPDATE, SAF_R_INVALID_LENGTH); + return SAR_IndataLenErr; + } + + inlen = (int)uiInDataLen; + + if (!hkey->cipher_ctx) { + unsigned char iv[32]; + int ivlen; + + if (!(hkey->cipher_ctx = EVP_CIPHER_CTX_new())) { + SAFerr(SAF_F_SAF_SYMMDECRYPTUPDATE, ERR_R_MALLOC_FAILURE); + ret = SAR_MemoryErr; + goto end; + } + + /* get iv from input */ + ivlen = EVP_CIPHER_block_size(hkey->cipher); + if (ivlen <= 0 || ivlen > sizeof(iv)) { + SAFerr(SAF_F_SAF_SYMMDECRYPTUPDATE, SAF_R_INVALID_CONTEXT); + ret = SAR_ObjErr; + goto end; + } + + memcpy(iv, in, ivlen); + in += ivlen; + inlen -= ivlen; + + if (!EVP_DecryptInit(hkey->cipher_ctx, hkey->cipher, hkey->key, iv)) { + SAFerr(SAF_F_SAF_SYMMDECRYPTUPDATE, ERR_R_EVP_LIB); + goto end; + } + } + + if (!EVP_DecryptUpdate(hkey->cipher_ctx, pucOutData, &outlen, in, inlen)) { + SAFerr(SAF_F_SAF_SYMMDECRYPTUPDATE, ERR_R_EVP_LIB); + goto end; + } + + *puiOutDataLen = (unsigned int)outlen; + ret = SAR_OK; + +end: + if (ret != SAR_OK && hkey->cipher_ctx) { + EVP_CIPHER_CTX_free(hkey->cipher_ctx); + hkey->cipher_ctx = NULL; + } + return ret; +} + +/* 7.3.43 */ +int SAF_SymmDecryptFinal( + void *hKeyHandle, + const unsigned char *pucInData, + unsigned int uiInDataLen, + unsigned char *pucOutData, + unsigned int *puiOutDataLen) +{ + return 0; +} + +/* 7.3.38 */ +int SAF_SymmEncrypt( + void *hKeyHandle, + const unsigned char *pucInData, + unsigned int uiInDataLen, + unsigned char *pucOutData, + unsigned int *puiOutDataLen) +{ + int ret; + unsigned char *out; + unsigned int outlen; + + out = pucOutData; + outlen = *puiOutDataLen; + + if ((ret = SAF_SymmEncryptUpdate(hKeyHandle, pucInData, uiInDataLen, + out, &outlen)) != SAR_OK) { + return ret; + } + out += outlen; + if ((ret = SAF_SymmEncryptFinal(hKeyHandle, out, &outlen)) != SAR_OK) { + return ret; + } + out += outlen; + + *puiOutDataLen = out - pucOutData; + return SAR_OK; +} + +/* 7.3.41 */ +int SAF_SymmDecrypt( + void *hKeyHandle, + unsigned char *pucInData, + unsigned int uiInDataLen, + unsigned char *pucOutData, + unsigned int *puiOutDataLen) +{ + int ret; + unsigned char *out; + unsigned int outlen; + + out = pucOutData; + outlen = *puiOutDataLen; + + if ((ret = SAF_SymmDecryptUpdate(hKeyHandle, pucInData, uiInDataLen, + out, &outlen)) != SAR_OK) { + return ret; + } + out += outlen; + if ((ret = SAF_SymmDecryptFinal(hKeyHandle, out, &outlen)) != SAR_OK) { + return ret; + } + out += outlen; + + *puiOutDataLen = out - pucOutData; + return SAR_OK; +} + diff --git a/crypto/saf/saf_err.c b/crypto/saf/saf_err.c new file mode 100644 index 00000000..c2360af9 --- /dev/null +++ b/crypto/saf/saf_err.c @@ -0,0 +1,84 @@ +/* + * Generated by util/mkerr.pl DO NOT EDIT + * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include +#include + +/* BEGIN ERROR CODES */ +#ifndef OPENSSL_NO_ERR + +# define ERR_FUNC(func) ERR_PACK(ERR_LIB_SAF,func,0) +# define ERR_REASON(reason) ERR_PACK(ERR_LIB_SAF,0,reason) + +static ERR_STRING_DATA SAF_str_functs[] = { + {ERR_FUNC(SAF_F_SAF_BASE64_CREATEBASE64OBJ), + "SAF_Base64_CreateBase64Obj"}, + {ERR_FUNC(SAF_F_SAF_BASE64_DECODE), "SAF_Base64_Decode"}, + {ERR_FUNC(SAF_F_SAF_BASE64_DECODEFINAL), "SAF_Base64_DecodeFinal"}, + {ERR_FUNC(SAF_F_SAF_BASE64_DECODEUPDATE), "SAF_Base64_DecodeUpdate"}, + {ERR_FUNC(SAF_F_SAF_BASE64_ENCODE), "SAF_Base64_Encode"}, + {ERR_FUNC(SAF_F_SAF_BASE64_ENCODEFINAL), "SAF_Base64_EncodeFinal"}, + {ERR_FUNC(SAF_F_SAF_BASE64_ENCODEUPDATE), "SAF_Base64_EncodeUpdate"}, + {ERR_FUNC(SAF_F_SAF_CREATESYMMKEYOBJ), "SAF_CreateSymmKeyObj"}, + {ERR_FUNC(SAF_F_SAF_ECCPUBLICKEYENC), "SAF_EccPublicKeyEnc"}, + {ERR_FUNC(SAF_F_SAF_ECCPUBLICKEYENCBYCERT), "SAF_EccPublicKeyEncByCert"}, + {ERR_FUNC(SAF_F_SAF_ECCSIGN), "SAF_EccSign"}, + {ERR_FUNC(SAF_F_SAF_ECCVERIFYSIGN), "SAF_EccVerifySign"}, + {ERR_FUNC(SAF_F_SAF_ECCVERIFYSIGNBYCERT), "SAF_EccVerifySignByCert"}, + {ERR_FUNC(SAF_F_SAF_GENECCKEYPAIR), "SAF_GenEccKeyPair"}, + {ERR_FUNC(SAF_F_SAF_GENERATEAGREEMENTDATAWITHECC), + "SAF_GenerateAgreementDataWithECC"}, + {ERR_FUNC(SAF_F_SAF_GENERATEKEYWITHECC), "SAF_GenerateKeyWithECC"}, + {ERR_FUNC(SAF_F_SAF_GETECCPUBLICKEY), "SAF_GetEccPublicKey"}, + {ERR_FUNC(SAF_F_SAF_MACFINAL), "SAF_MacFinal"}, + {ERR_FUNC(SAF_F_SAF_MACUPDATE), "SAF_MacUpdate"}, + {ERR_FUNC(SAF_F_SAF_PKCS7_DECODEDIGESTEDDATA), + "SAF_Pkcs7_DecodeDigestedData"}, + {ERR_FUNC(SAF_F_SAF_PKCS7_ENCODEDIGESTEDDATA), + "SAF_Pkcs7_EncodeDigestedData"}, + {ERR_FUNC(SAF_F_SAF_SYMMDECRYPTUPDATE), "SAF_SymmDecryptUpdate"}, + {ERR_FUNC(SAF_F_SAF_SYMMENCRYPTUPDATE), "SAF_SymmEncryptUpdate"}, + {0, NULL} +}; + +static ERR_STRING_DATA SAF_str_reasons[] = { + {ERR_REASON(SAF_R_BUFFER_TOO_SMALL), "buffer too small"}, + {ERR_REASON(SAF_R_CBCMAC_FAILURE), "cbcmac failure"}, + {ERR_REASON(SAF_R_GEN_RANDOM), "gen random"}, + {ERR_REASON(SAF_R_INT_OVERFLOW), "int overflow"}, + {ERR_REASON(SAF_R_INVALID_ALGOR), "invalid algor"}, + {ERR_REASON(SAF_R_INVALID_CONTEXT), "invalid context"}, + {ERR_REASON(SAF_R_INVALID_DIGEST_ALGOR), "invalid digest algor"}, + {ERR_REASON(SAF_R_INVALID_HANDLE), "invalid handle"}, + {ERR_REASON(SAF_R_INVALID_INPUT_LENGTH), "invalid input length"}, + {ERR_REASON(SAF_R_INVALID_KEY_LENGTH), "invalid key length"}, + {ERR_REASON(SAF_R_INVALID_KEY_USAGE), "invalid key usage"}, + {ERR_REASON(SAF_R_INVALID_LENGTH), "invalid length"}, + {ERR_REASON(SAF_R_MAC_FAILURE), "mac failure"}, + {ERR_REASON(SAF_R_OPERATION_NOT_INITIALIZED), + "operation not initialized"}, + {ERR_REASON(SAF_R_SAF_ERROR), "saf error"}, + {0, NULL} +}; + +#endif + +int ERR_load_SAF_strings(void) +{ +#ifndef OPENSSL_NO_ERR + + if (ERR_func_error_string(SAF_str_functs[0].error) == NULL) { + ERR_load_strings(0, SAF_str_functs); + ERR_load_strings(0, SAF_str_reasons); + } +#endif + return 1; +} diff --git a/crypto/saf/saf_errstr.c b/crypto/saf/saf_errstr.c new file mode 100644 index 00000000..e86642b4 --- /dev/null +++ b/crypto/saf/saf_errstr.c @@ -0,0 +1,105 @@ +/* ==================================================================== + * Copyright (c) 2016 The GmSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the GmSSL Project. + * (http://gmssl.org/)" + * + * 4. The name "GmSSL Project" must not be used to endorse or promote + * products derived from this software without prior written + * permission. For written permission, please contact + * guanzhi1980@gmail.com. + * + * 5. Products derived from this software may not be called "GmSSL" + * nor may "GmSSL" appear in their names without prior written + * permission of the GmSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the GmSSL Project + * (http://gmssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE GmSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GmSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +#include +#include +#include "../../e_os.h" + +static ERR_STRING_DATA saf_errstr[] = { + { SAR_Ok, "Success" }, + { SAR_UnknownErr, "Unknown error" }, + { SAR_NotSupportYetErr, "Not supported yet error" }, + { SAR_FileErr, "File error" }, + { SAR_ProviderTypeErr, "Provider type error" }, + { SAR_LoadProviderErr, "Load provider error" }, + { SAR_LoadDevMngApiErr, "Load Device management API error" }, + { SAR_AlgoTypeErr, "Algorithm type error" }, + { SAR_NameLenErr, "Name length error" }, + { SAR_KeyUsageErr, "Key usage error" }, + { SAR_ModulusLenErr, "Modulus length error" }, + { SAR_NotInitializeErr, "Not initialized error" }, + { SAR_ObjErr, "Object error" }, + { SAR_MemoryErr, "Memory error" }, + { SAR_TimeoutErr, "Timeout error" }, + { SAR_IndataLenErr, "Input data length error" }, + { SAR_IndataErr, "Input data error" }, + { SAR_GenRandErr, "Generate random error" }, + { SAR_HashObjErr, "Hash object error" }, + { SAR_HashErr, "Hash error" }, + { SAR_GenRsaKeyErr, "Generate RSA key error" }, + { SAR_RsaModulusLenErr, "RSA modulus length error" }, + { SAR_CspImportPubKeyErr,"CSP import public key error" }, + { SAR_RsaEncErr, "RSA encryption error" }, + { SAR_RsaDecErr, "RSA decryption error" }, + { SAR_HashNotEqualErr, "Hash not equal error" }, + { SAR_KeyNotFoundErr, "Key not found error" }, + { SAR_CertNotFoundErr, "Certificate not found error" }, + { SAR_NotExportErr, "Non-exportable error" }, + { SAR_CertRevokedErr, "Certificate revoked error" }, + { SAR_CertNotYetValidErr,"Certificate not yet valid error" }, + { SAR_CerthashExpiredErr,"Certificate hash expirted error" }, + { SAR_CertVerifyErr, "Certificate verification error" }, + { SAR_CertEncodeErr, "Certificate encoding error" }, + { SAR_DecryptPadErr, "Decryption padding error" }, + { SAR_MacLenErr, "MAC length error" }, + { SAR_KeyInfoTypeErr, "Key information type error" }, + { SAR_NotLogin, "Not login" }, +}; + +char *SAF_GetErrorString(int err) +{ + int i; + for (i = 0; i < OSSL_NELEM(saf_errstr); i++) { + if (err == saf_errstr[i].error) { + return saf_errstr[i].string; + } + } + return "(undef)"; +} + diff --git a/crypto/saf/saf_hash.c b/crypto/saf/saf_hash.c new file mode 100644 index 00000000..029ee0f6 --- /dev/null +++ b/crypto/saf/saf_hash.c @@ -0,0 +1,147 @@ +/* ==================================================================== + * Copyright (c) 2016 The GmSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the GmSSL Project. + * (http://gmssl.org/)" + * + * 4. The name "GmSSL Project" must not be used to endorse or promote + * products derived from this software without prior written + * permission. For written permission, please contact + * guanzhi1980@gmail.com. + * + * 5. Products derived from this software may not be called "GmSSL" + * nor may "GmSSL" appear in their names without prior written + * permission of the GmSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the GmSSL Project + * (http://gmssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE GmSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GmSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES + * LOSS OF USE, DATA, OR PROFITS OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +#include +#include +#include +#include +#include + +/* 7.3.12 */ +int SAF_CreateHashObj(void **phHashObj, + unsigned int uiAlgoType, + unsigned char *pucPublicKey, + unsigned int uiPublicKeyLen, + unsigned char *pucID, + unsigned int ulIDLen) +{ + int ret = SAR_UnkownErr; + const EVP_MD *md; + EVP_MD_CTX *ctx = NULL; + + if (!(md = EVP_get_digestbysgd(uiAlgorithmType))) { + return SAR_AlgoTypeErr; + } + + if (!(ctx = EVP_MD_CTX_new())) { + return 0; + } + + if (!EVP_DigestInit(ctx, md)) { + return 0; + } + + *phHashObj = ctx; + +end: + if (ret != SAR_OK) { + EVP_MD_CTX_free(ctx); + *phHashObj = NULL; + } + return ret; +} + +/* 7.3.13 */ +int SAF_DestroyHashObj( + void *phHashObj) +{ + EVP_MD_CTX_free((EVP_MD_CTX *)phHashObj); + return SAR_OK; +} + +/* 7.3.14 */ +int SAF_HashUpdate( + void *phHashObj, + const unsigned char *pucInData, + unsigned int uiInDataLen) +{ + if (!EVP_DigestUpdate((EVP_MD_CTX *)phHashObj, pucInData, (size_t)uiInDataLne)) { + return SAR_HashErr; + } + return SAR_OK; +} + +/* 7.3.15 */ +int SAF_HashFinal(void *phHashObj, + unsigned char *pucOutData, + unsigned int *uiOutDataLen) +{ + if (!EVP_DigestFinal((EVP_MD_CTX *)phHashObj, pucOutData, uiOutDataLen)) { + return SAR_HashErr; + } + return SAR_OK; +} + +/* 7.3.11 */ +int SAF_Hash( + unsigned int uiAlgoType, + unsigned char *pucInData, + unsigned int uiInDataLen, + unsigned char *pucPublicKey, + unsigned int uiPublicKeyLen, + unsigned char *pubID, + unsigned int ulIDLen, + unsigned char *pucOutData, + unsigned int *puiOutDataLen) +{ + const EVP_MD *md; + size_t siz; + + if (!(md = EVP_get_digestbysgd(uiAlgoType))) { + return SAR_AlgoTypeErr; + } + + siz = (size_t)uiInDataLen; + if (!EVP_Digest(pucInData, siz, pucOutData, puiOutDataLen, md, NULL)) { + return SAR_HashErr; + } + + return SAR_OK; +} + diff --git a/crypto/saf/saf_keyhandle.c b/crypto/saf/saf_keyhandle.c new file mode 100644 index 00000000..54380751 --- /dev/null +++ b/crypto/saf/saf_keyhandle.c @@ -0,0 +1,112 @@ +/* ==================================================================== + * Copyright (c) 2016 The GmSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the GmSSL Project. + * (http://gmssl.org/)" + * + * 4. The name "GmSSL Project" must not be used to endorse or promote + * products derived from this software without prior written + * permission. For written permission, please contact + * guanzhi1980@gmail.com. + * + * 5. Products derived from this software may not be called "GmSSL" + * nor may "GmSSL" appear in their names without prior written + * permission of the GmSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the GmSSL Project + * (http://gmssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE GmSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GmSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES + * LOSS OF USE, DATA, OR PROFITS OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +#include +#include +#include +#include +#include "saf_lcl.h" + +/* 7.3.31 + * Generate session key returned by `phKeyHandle` + * Encrypt the symmetric key `hSymmKeyObj` with the input public key + * `pucPublicKey`, output the encrypted results to `pucSymmKey`, + * + * how can we encrypt data with public key? + * it this function relies on ther SAF API? + * + * The function don't care the input public key. It should be an exported + * public key. Some extra information should be appened into the output key. + */ +int SAF_GenerateKeyWithEPK( + void *hSymmKeyObj, + unsigned char *pucPublicKey, + unsigned int uiPublicKeyLen, + unsigned char *pucSymmKey, + unsigned int uiSymmKeyLen, + void **phKeyHandle) +{ + int pkey_type; + EVP_PKEY *pkey = NULL; + + + if (!(pkey = d2i_PublicKey(pkey_type, NULL, &p, + (long)uiPublicKeyLen))) { + } + + +} + +/* 7.3.32 */ +/* all the inforamtion should be kept in encrypted key + * the encrytped key can be decrypted with the default private key + */ +int SAF_ImportEncedKey( + void *hSymmKeyObj, + unsigned char *pucSymmKey, + unsigned int uiSymmKeyLen, + void **phKeyHandle) +{ + return 0; +} + +/* 7.3.37 */ +int SAF_DestroyKeyHandle( + void *hKeyHandle) +{ + SAF_KeyHandle *hkey = (SAF_KeyHandle *)hKeyHandle; + + if (!hKeyHandle) { + return SAR_OK; + } + + OPENSSL_clear_free(hkey->key, hkey->keylen); + return SAR_OK; +} + diff --git a/crypto/saf/saf_lcl.h b/crypto/saf/saf_lcl.h new file mode 100644 index 00000000..551aae09 --- /dev/null +++ b/crypto/saf/saf_lcl.h @@ -0,0 +1,137 @@ +/* ==================================================================== + * Copyright (c) 2016 The GmSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the GmSSL Project. + * (http://gmssl.org/)" + * + * 4. The name "GmSSL Project" must not be used to endorse or promote + * products derived from this software without prior written + * permission. For written permission, please contact + * guanzhi1980@gmail.com. + * + * 5. Products derived from this software may not be called "GmSSL" + * nor may "GmSSL" appear in their names without prior written + * permission of the GmSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the GmSSL Project + * (http://gmssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE GmSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GmSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES + * LOSS OF USE, DATA, OR PROFITS OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + + +#include +#include +#include +#include + + +typedef struct { + const char *config_path; + ENGINE *engine; +} SAF_APP; + +typedef struct { + EVP_ENCODE_CTX *ctx; + int inited; +} SAF_BASE64OBJ; + +typedef struct { + void *hAppHandle; + unsigned char *pucContainerName; + unsigned int uiContainerLen; + unsigned char *pucIV; + unsigned int uiIVLen; + unsigned int uiEncOrDec; + unsigned int uiCryptoAlgID; +} SAF_SymmKeyObj; + +typedef struct { + unsigned char *key; + size_t keylen; + + /* used by `SAF_SymmEncryptUpdate`, `SAF_SymmEncryptFinal`, + * `SAF_SymmDecryptUpdate`, `SAF_SymmDecryptFinal` + */ + EVP_CIPHER_CTX *cipher_ctx; + const EVP_CIPHER *cipher; + CMAC_CTX *cmac_ctx; +} SAF_KEY_HANDLE; + +int saf_readfile( + const char *file, + unsigned char **pout, + size_t *len); + +int saf_save_ec_keypair( + void *hAppHandle, + unsigned char *pucContainerName, + unsigned int uiContainerNameLen, + unsigned int uiKeyBits, + unsigned int uiKeyUsage, + unsigned int uiExportFlag, + ECCrefPublicKey *pucPublicKey, + ECCrefPrivateKey *pucPrivateKey); + +int saf_save_rsa_keypair( + void *hAppHandle, + unsigned char *pucContainerName, + unsigned int uiContainerNameLen, + unsigned int uiKeyBits, + unsigned int uiKeyUsage, + unsigned int uiExportFlag, + RSArefPublicKey *pucPublicKey, + RSArefPrivateKey *pucPrivateKey); + +int saf_get_sdf_session_and_keyindex( + void *hAppHandle, + unsigned char *pucContainerName, + unsigned int uiContainerNameLen, + unsigned int uiKeyUsage, + void *phSessionHandle, + unsigned int puiKeyIndex); + +int saf_get_sdf_session_and_ecsignkey( + void *hAppHandle, + unsigned char *pucContainerName, + unsigned int uiContainerNameLen, + unsigned int uiAlgorithmID, /* SGD_SM2_1 */ + void **phSessionhandle, + unsigned int *puiISKIndex); + +void saf_release_sdf_session( + void *hSessionHandle); + +int saf_get_ec_public_key_from_cert( + unsigned char *pucCertificate, + unsigned int uiCertificateLen, + ECCrefPublicKey *pucPublicKey); + diff --git a/crypto/saf/saf_lib.c b/crypto/saf/saf_lib.c new file mode 100644 index 00000000..0ca1dd18 --- /dev/null +++ b/crypto/saf/saf_lib.c @@ -0,0 +1,135 @@ +/* ==================================================================== + * Copyright (c) 2016 The GmSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the GmSSL Project. + * (http://gmssl.org/)" + * + * 4. The name "GmSSL Project" must not be used to endorse or promote + * products derived from this software without prior written + * permission. For written permission, please contact + * guanzhi1980@gmail.com. + * + * 5. Products derived from this software may not be called "GmSSL" + * nor may "GmSSL" appear in their names without prior written + * permission of the GmSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the GmSSL Project + * (http://gmssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE GmSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GmSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +#include +#include "saf_lcl.h" + +//FIXME: use PEM_write_bio_ECPrivateKey in next version +int saf_save_ec_keypair( + void *hAppHandle, + unsigned char *pucContainerName, + unsigned int uiContainerNameLen, + unsigned int uiKeyBits, + unsigned int uiKeyUsage, + unsigned int uiExportFlag, + ECCrefPublicKey *pucPublicKey, + ECCrefPrivateKey *pucPrivateKey) +{ + return -1; +} + +int saf_save_rsa_keypair(void *hAppHandle, + unsigned char *pucContainerName, + unsigned int uiContainerNameLen, + unsigned int uiKeyBits, + unsigned int uiKeyUsage, + unsigned int uiExportFlag, + RSArefPublicKey *pucPublicKey, + RSArefPrivateKey *pucPrivateKey) +{ + return -1; +} + +int saf_get_sdf_session_and_keyindex( + void *hAppHandle, + unsigned char *pucContainerName, + unsigned int uiContainerNameLen, + unsigned int uiKeyUsage, + void *phSessionHandle, + unsigned int puiKeyIndex) +{ + return -1; +} + +void saf_release_sdf_session(void *hSessionHandle) +{ +} + +int saf_get_sdf_session_and_ecsignkey( + void *hAppHandle, + unsigned char *pucContainerName, + unsigned int uiContainerNameLen, + unsigned int uiAlgorithmID, /* SGD_SM2_1 */ + void **phSessionhandle, + unsigned int *puiISKIndex) +{ + return -1; +} + +int saf_get_ec_public_key_from_cert( + unsigned char *pucCertificate, + unsigned int uiCertificateLen, + ECCrefPublicKey *pucPublicKey) +{ + return -1; +} + +static int readfile(const char *file, unsigned char **pout, size_t *len) +{ + FILE *fp = fopen(file, "rb"); + fseek(fp, 0, SEEK_END); + long fsize = ftell(fp); + fseek(fp, 0, SEEK_SET); + char *out = malloc(fsize); + fread(out, fsize, 1, f); + fclose(f); + *pout = out; + *len = fsize; + return SAR_OK; +} + +static int cert_get_pubkey( + unsigned char *pucCertificate, + unsigned int uiCertificateLen, + unsigned char **pout, + unsigned int *outlen) +{ + return 0; +} + diff --git a/crypto/saf/saf_mac.c b/crypto/saf/saf_mac.c new file mode 100644 index 00000000..c4a8e174 --- /dev/null +++ b/crypto/saf/saf_mac.c @@ -0,0 +1,147 @@ +/* ==================================================================== + * Copyright (c) 2016 The GmSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the GmSSL Project. + * (http://gmssl.org/)" + * + * 4. The name "GmSSL Project" must not be used to endorse or promote + * products derived from this software without prior written + * permission. For written permission, please contact + * guanzhi1980@gmail.com. + * + * 5. Products derived from this software may not be called "GmSSL" + * nor may "GmSSL" appear in their names without prior written + * permission of the GmSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the GmSSL Project + * (http://gmssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE GmSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GmSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES + * LOSS OF USE, DATA, OR PROFITS OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +#include +#include +#include +#include +#include + +/* 7.3.45 */ +int SAF_MacUpdate( + void *hKeyHandle, + const unsigned char *pucInData, + unsigned int uiInDataLen) +{ + int ret = SAR_UnknownErr; + SAF_KEY_HANDLE *hkey = (SAF_KEY_HANDLE *)hKeyHandle; + + if (!hKeyHandle || !pucInData) { + SAFerr(SAF_F_SAF_MACUPDATE, ERR_R_PASSED_NULL_PARAMETER); + return SAR_IndataErr; + } + + if (!hkey->cbcmac_ctx) { + if (!(hkey->cbcmac_ctx = CBCMAC_CTX_new())) { + SAFerr(SAF_F_SAF_MACUPDATE, ERR_R_MALLOC_FAILURE); + goto end; + } + if (!CBCMAC_Init(hkey->cbcmac_ctx, hkey->key, hkey->keylen, hkey->cipher, NULL)) { + SAFerr(SAF_F_SAF_MACUPDATE, SAF_R_CBCMAC_FAILURE); + goto end; + } + } + + if (!CBCMAC_Update(hkey->cbcmac_ctx, pucInData, (size_t)uiInDataLen)) { + SAFerr(SAF_F_SAF_MACUPDATE, SAF_R_CBCMAC_FAILURE); + return SAR_UnknownErr; + } + + ret = SAR_OK; + +end: + if (ret != SAR_OK && hkey->cbcmac_ctx) { + CBCMAC_CTX_free(hkey->cbcmac_ctx); + hkey->cbcmac_ctx = NULL; + } + return ret; +} + +/* 7.3.46 */ +int SAF_MacFinal( + void *hKeyHandle, + unsigned char *pucOutData, + unsigned int *puiOutDataLen) +{ + SAF_KEY_HANDLE *hkey = (SAF_KEY_HANDLE *)hKeyHandle; + size_t siz; + + if (!hKeyHandle || !pucOutData || !puiOutDataLen) { + SAFerr(SAF_F_SAF_MACFINAL, ERR_R_PASSED_NULL_PARAMETER); + return SAR_IndataErr; + } + + if (*puiOutDataLen < EVP_CIPHER_block_size(hkey->cipher)) { + SAFerr(SAF_F_SAF_MACFINAL, SAF_R_BUFFER_TOO_SMALL); + return SAR_IndataLenErr; + } + + if (!hkey->cbcmac_ctx) { + SAFerr(SAF_F_SAF_MACFINAL, SAF_R_OPERATION_NOT_INITIALIZED); + return SAR_UnknownErr; + } + + siz = EVP_CIPHER_block_size(hkey->cipher); + if (!CBCMAC_Final(hkey->cbcmac_ctx, pucOutData, &siz)) { + SAFerr(SAF_F_SAF_MACFINAL, SAF_R_MAC_FAILURE); + return SAR_UnknownErr; + } + + *puiOutDataLen = siz; + return SAR_OK; +} + +/* 7.4.44 */ +int SAF_Mac( + void *hKeyHandle, + const unsigned char *pucInData, + unsigned int uiInDataLen, + unsigned char *pucOutData, + unsigned int *puiOutDataLen) +{ + int ret; + if ((ret = SAF_MacUpdate(hKeyHandle, pucInData, uiInDataLen)) != SAR_OK) { + return ret; + } + if ((ret = SAF_MacFinal(hKeyHandle, pucOutData, puiOutDataLen)) != SAR_OK) { + return ret; + } + return SAR_OK; +} + diff --git a/crypto/saf/saf_pkcs7.c b/crypto/saf/saf_pkcs7.c new file mode 100644 index 00000000..487cf634 --- /dev/null +++ b/crypto/saf/saf_pkcs7.c @@ -0,0 +1,404 @@ +/* ==================================================================== + * Copyright (c) 2016 The GmSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the GmSSL Project. + * (http://gmssl.org/)" + * + * 4. The name "GmSSL Project" must not be used to endorse or promote + * products derived from this software without prior written + * permission. For written permission, please contact + * guanzhi1980@gmail.com. + * + * 5. Products derived from this software may not be called "GmSSL" + * nor may "GmSSL" appear in their names without prior written + * permission of the GmSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the GmSSL Project + * (http://gmssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE GmSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GmSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +#include +#include +#include +#incluce "saf_lcl.h" + +/* + +In GMAPI we will use private keys handled by ENGINE, the keys in ENGINE +is referenced by ENGINE and key label `key_id` +*/ + +EVP_PKEY *saf_load_private_key( void *hAppHandle, + unsigned char *containerName, unsigned int containerNameLen, + unsigned int keyUsage) +{ + return NULL; +} + +int GMAPI_CONTAINER_get_cert_and_key(GMAPI_CONTAINER *container, + int key_usage, X509 **cert, EVP_PKEY **pkey) +{ + return 0; +} + +/* 7.4.2 */ +/* we need AppHandle before doing this + * App + Container + KeyUsage => sign_key + * the private key is referenced by a string label `key_id` + */ +int SAF_Pkcs7_EncodeData( + void *hAppHandle, + unsigned char *pucSignContainerName, + unsigned int uiSignContainerNameLen, + unsigned int uiSignKeyUsage, + unsigned char *pucSignerCertificate, + unsigned int uiSignerCertificateLen, + unsigned int uiDigestAlgorithm, + unsigned char *pucEncCertificate, + unsigned int uiEncCertificateLen, + unsigned char *pucData, + unsigned int uiDataLen, + unsigned char *pucDerP7Data, + unsigned int *puiDerP7DataLen) +{ + int ret = SAR_UnknownErr; + PKCS7 *p7 = NULL; + EVP_PKEY *pkey = NULL; + const EVP_MD *md; + + p7 = PKCS7_new(); + + pkey = saf_load_private_key(hAppHandle, + pucSignContainerName, uiSignContainerNameLen + uiSignKeyUsage); + + PKCS7_set_type(p7, 0); + + + + + return 0; +} + + +/* 7.4.3 */ +int SAF_Pkcs7_DecodeData( + void *hAppHandle) +{ + return 0; +} + +/* 7.4.4 */ +int SAF_Pkcs7_EncodeSignedData( + void *hAppHandle, + unsigned char *pucSignContainerName, + unsigned int uiSignContainerNameLen, + unsigned int uiSignKeyUsage, + unsigned char *pucSignerCertificate, + unsigned int uiSignerCertificateLen, + unsigned int uiDigestAlgorithm, + unsigned char *pucData, + unsigned int uiDataLen, + unsigned char *pucDerP7Data, + unsigned int *puiDerP7DataLen) +{ + + int flags; + BIO *bio = NULL; + EVP_PKEY *pkey = NULL; + X509 *cert = NULL; + unsigned char *p; + + if (!(pkey = saf_load_private_key(hAppHandle, pucSignContainerName, + uiSignContainerNameLen, uiSignKeyUsage))) { + } + + /* decode certificate, check no extra input */ + p = pucSignerCertificate; + if (!(cert = d2i_X509(NULL, &p, (long)uiSignerCertificateLen))) { + } + if (p - pucSignerCertificate != uiSignerCertificateLen) { + } + + /* data bio */ + if (!(bio = BIO_new_mem_buf(pucData, (int)uiDataLen))) { + } + + /* set digest */ + if (!(md = EVP_get_digestbysgd(uiDigestAlgorithm))) { + } + + flags = PKCS7_BINARY; + p7 = PKCS7_sign(cert, pkey, NULL, bio, flags); + + + p = pucDerP7Data; + if (i2d_PKCS7(p7, &p) < 0) { + } + + *puiDerP7DataLen = p - pucDerP7Data; + + return 0; +} + +/* 7.4.5 */ +/* + * The content data in PKCS #7 SignedData format is optional, as the + * `SAF_Pkcs7_DecodeSignedData` function has explicit content data input + * with parameter `pucData`, the `SAF_Pkcs7_EncodeSignedData` will not carry + * content data, with the `PKCS7_DETACHED` flag bit set. + */ +int SAF_Pkcs7_DecodeSignedData( + void *hAppHandle, + unsigned char *pucDerP7SignedData, + unsigned int uiDerP7SignedDataLen, + unsigned char *pucSignerCertificate, + unsigned int uiSignerCertificateLen, + unsigned int uiDigestAlgorithm, + unsigned char *pucData, + unsigned int uiDataLen, + unsigned char *pucSign, + unsigned int *puiSignLen) +{ + int ret; + PKCS7 *p7 = NULL; + X509 *cert = NULL; + const EVP_MD *md; + BIO *bio = NULL; + STACK_OF(X509) *certs = NULL; + X509_STORE *store = NULL; + int flags = 0; + + p = pucDerP7SignedData; + if (!(p7 = d2i_PKCS7(NULL, &p, (long)uiDerP7SignedDataLen))) { + } + if (p - pucDerP7SignedData != uiDerP7SignedDataLen) { + } + + p = pucSignerCertificate; + if (!(cert = d2i_X509(NULL, &p, (long)uiSignerCertificateLen))) { + } + if (p - pucSignerCertificate != uiSignerCertificateLen) { + } + + if (!(md = EVP_get_digestbysgd(uiDigestAlgorithm))) { + } + if (!PKCS7_set_digest(p7, md)) { + } + + if (!PKCS7_verify(p7, cert, store, bio, NULL, flags)) { + } + + + return 0; +} + +/* 7.4.6 */ +int SAF_Pkcs7_EncodeEnvelopedData( + void *hAppHandle, + unsigned char *pucData, + unsigned int uiDataLen, + unsigned char *pucEncCertificate, + unsigned int uiEncCertificateLen, + unsigned int uiSymmAlgorithm, + unsigned char *pucDerP7EnvelopedData, + unsigned int *puiDerP7EnvelopedDataLen) +{ + int ret = SAR_UnknownErr; + PKCS7 *p7 = NULL; + X509 *cert = NULL; + BIO *bio = NULL; + const EVP_CIPHER *cipher; + int flags; + + cipher = EVP_get_cipherbysgd(uiSymmAlgorithm); + bio = BIO_new(BIO_s_mem()); + // set data to bio + + p = pucEncCertificate; + cert = d2i_X509(NULL, &p, uiEncCertificateLen); + + p7 = PKCS7_encrypt(cert, bio, cipher, flags); +end: + PKCS7_free(p7); + return ret; +} + +/* 7.4.7 */ +/* key is referenced by App.Container.KeyUsage */ +int SAF_Pkcs7_DecodeEnvelopedData( + void *hAppHandle, + unsigned char *pucDecContainerName, + unsigned int uiDecContainerNameLen, + unsigned int uiDecKeyUsage, + unsigned char *pucDerP7EnvelopedData, + unsigned int uiDerP7EnvelopedDataLen, + unsigned char *pucData, + unsigned int *puiDataLen) +{ + PKCS7 *p7 = NULL; + BIO *bio = NULL; + X509 *cert = NULL; + EVP_PKEY *pkey = NULL; + + // get cert and pkey from App.Container.KeyUsage + + PKCS7_decrypt(p7, pkey, cert, bio, flags); + + return 0; +} + +/* 7.4.8 */ +/* the `hAppHandle` and key is not required in digest */ +int SAF_Pkcs7_EncodeDigestedData( + void *hAppHandle, + unsigned int uiDigestAlgorithm, + unsigned char *pucData, + unsigned int uiDataLen, + unsigned char *pucDerP7DigestedData, + unsigned int *puiDerP7DigestedDataLen) +{ + int ret = SAR_UnknownErr; + PKCS7 *p7 = NULL; + BIO *bio = NULL; + const EVP_MD *md; + unsigned char *p; + int len; + + if (!hAppHandle || !pucData || !pucDerP7DigestedData || !puiDerP7DigestedDataLen) { + SAFerr(SAF_F_SAF_PKCS7_ENCODEDIGESTEDDATA, ERR_R_PASSED_NULL_PARAMETER); + return SAR_IndataErr; + } + if (!(md = EVP_get_digestbysgd(uiDigestAlgorithm))) { + SAFerr(SAF_F_SAF_PKCS7_ENCODEDIGESTEDDATA, SAF_R_INVALID_DIGEST_ALGOR); + return SAR_AlgoTypeErr; + } + if (uiDataLen > INT_MAX) { + return SAR_IndataLenErr; + } + len = (int)uiDataLen; + + if (!(p7 = PKCS7_new())) { + SAFerr(SAF_F_SAF_PKCS7_ENCODEDIGESTEDDATA, ERR_R_MALLOC_FAILURE); + goto end; + } + if (!PKCS7_set_type(p7, NID_pkcs7_digest)) { + SAFerr(SAF_F_SAF_PKCS7_ENCODEDIGESTEDDATA, ERR_R_PKCS7_LIB); + goto end; + } + + /* set digest */ + if (!PKCS7_set_digest(p7, md)) { + SAFerr(SAF_F_SAF_PKCS7_ENCODEDIGESTEDDATA, ERR_R_PKCS7_LIB); + goto end; + } + + /* set content */ + if (!PKCS7_content_new(p7, NID_pkcs7_data)) { + SAFerr(SAF_F_SAF_PKCS7_ENCODEDIGESTEDDATA, ERR_R_PKCS7_LIB); + goto end; + } + if (!(bio = PKCS7_dataInit(p7, NULL))) { + SAFerr(SAF_F_SAF_PKCS7_ENCODEDIGESTEDDATA, ERR_R_PKCS7_LIB); + goto end; + } + if (!BIO_write(bio, pucData, len)) { + SAFerr(SAF_F_SAF_PKCS7_ENCODEDIGESTEDDATA, ERR_R_GMAPI_LIB); + goto end; + } + if (!BIO_flush(bio)) { + SAFerr(SAF_F_SAF_PKCS7_ENCODEDIGESTEDDATA, ERR_R_GMAPI_LIB); + goto end; + } + if (!PKCS7_dataFinal(p7, bio)) { + SAFerr(SAF_F_SAF_PKCS7_ENCODEDIGESTEDDATA, ERR_R_PKCS7_LIB); + goto end; + } + + /* check output buffer length */ + if ((len = i2d_PKCS7(p7, NULL)) <= 0) { + SAFerr(SAF_F_SAF_PKCS7_ENCODEDIGESTEDDATA, ERR_R_PKCS7_LIB); + goto end; + } + if (*puiDerP7DigestedDataLen < len) { + SAFerr(SAF_F_SAF_PKCS7_ENCODEDIGESTEDDATA, SAF_R_BUFFER_TOO_SMALL); + goto end; + } + + /* der encoding */ + p = pucDerP7DigestedData; + if ((len = i2d_PKCS7(p7, &p)) <= 0) { + SAFerr(SAF_F_SAF_PKCS7_ENCODEDIGESTEDDATA, ERR_R_PKCS7_LIB); + goto end; + } + + *puiDerP7DigestedDataLen = (unsigned int)len; + ret = SAR_OK; + +end: + PKCS7_free(p7); + return ret; +} + +/* 7.4.9 */ +/* parse pkcs7 and get data and digest */ +int SAF_Pkcs7_DecodeDigestedData( + void *hAppHandle, + unsigned int uiDigestAlgorithm, + unsigned char *pucDerP7DigestedData, + unsigned int uiDerP7DigestedDataLen, + unsigned char *pucData, + unsigned int uiDataLen, + unsigned char *pucDigest, + unsigned int *puiDigestLen) +{ + int ret = SAR_UnknownErr; + PKCS7 *p7 = NULL; + unsigned char *p; + long len; + + if (!(md = EVP_get_digestbysgd(uiDigestAlgorithm))) { + SAFerr(SAF_F_SAF_PKCS7_DECODEDIGESTEDDATA, SAF_R_INVALID_DIGEST_ALGOR); + return SAR_AlgoTypeErr; + } + + p = pucDerP7DigestedData; + len = uiDerP7DigestedDataLen; + if (!(p7 = d2i_PKCS7(NULL, &p, len))) { + goto end; + } + + + return ret; +} + diff --git a/crypto/saf/saf_rand.c b/crypto/saf/saf_rand.c new file mode 100644 index 00000000..556bc1f1 --- /dev/null +++ b/crypto/saf/saf_rand.c @@ -0,0 +1,72 @@ +/* ==================================================================== + * Copyright (c) 2016 The GmSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the GmSSL Project. + * (http://gmssl.org/)" + * + * 4. The name "GmSSL Project" must not be used to endorse or promote + * products derived from this software without prior written + * permission. For written permission, please contact + * guanzhi1980@gmail.com. + * + * 5. Products derived from this software may not be called "GmSSL" + * nor may "GmSSL" appear in their names without prior written + * permission of the GmSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the GmSSL Project + * (http://gmssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE GmSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GmSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES + * LOSS OF USE, DATA, OR PROFITS OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +#include +#include +#include +#include +#include +#include +#include "saf_lcl.h" + +/* 7.3.10 */ +int SAF_GenRandom( + unsigned int uiRandLen, + unsigned char *pucRand) +{ + int len; + if (uiRandLen > 1024 * 1024) { + return SAR_IndataLenErr; + } + len = (int)uiRandLen; + if (!RAND_bytes(pucRand, len)) { + return SAR_GenRandErr; + } + return SAR_OK; +} diff --git a/crypto/saf/saf_rsa.c b/crypto/saf/saf_rsa.c new file mode 100644 index 00000000..051ebf19 --- /dev/null +++ b/crypto/saf/saf_rsa.c @@ -0,0 +1,246 @@ +/* ==================================================================== + * Copyright (c) 2016 The GmSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the GmSSL Project. + * (http://gmssl.org/)" + * + * 4. The name "GmSSL Project" must not be used to endorse or promote + * products derived from this software without prior written + * permission. For written permission, please contact + * guanzhi1980@gmail.com. + * + * 5. Products derived from this software may not be called "GmSSL" + * nor may "GmSSL" appear in their names without prior written + * permission of the GmSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the GmSSL Project + * (http://gmssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE GmSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GmSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES + * LOSS OF USE, DATA, OR PROFITS OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + + +#include +#include +#include "saf_lcl.h" + + +/* 7.3.16 */ +int SAF_GenRsaKeyPair(void *hAppHandle, + unsigned char *pucContainerName, + unsigned int uiContainerNameLen, + unsigned int uiKeyBits, + unsigned int uiKeyUsage, + unsigned int uiExportFlag) +{ + RSArefPublicKey publicKey; + RSArefPrivateKey privateKey; + + if (SDR_OK != SDF_GenerateKeyPair_RSA( + NULL, + uiKeyBits, + &publicKey, + &privateKey)) { + } + + if ((ret = saf_save_rsa_keypair( + hAppHandle, + pucContainerName, + uiContainerNameLen, + uiKeyBits, + uiKeyUsage, + uiExportFlag, + &publicKey, + &privateKey)) + != SAR_Ok) { + } + + return SAR_NotSupportYetErr; +} + +/* 7.3.17 */ +int SAF_GetPublicKey( + void *hAppHandle, + unsigned char *pucContainerName, + unsigned int uiContainerNameLen, + unsigned int uiKeyUsage, + unsigned char *pucPublicKey, + unsigned int *puiPublicKeyLen) +{ + + unsigned int uiAlgID; + + + if (uiAlgID = SGD_RSA) { + if (uiKeyUsage == 1) { + if (SDF_ExportSignPublicKey_RSA( + hSessionHandle, + uiKeyIndex, + (RSArefPublicKey *)pucPublicKey) != SDR_OK) { + } + } else { + if (SDF_ExportEncPublicKey_RSA( + hSessionHandle, + uiKeyIndex, + (RSArefPublicKey *)pucPublicKey) != SDR_OK) { + } + } + *puiPublicKeyLen = (unsigned int)sizeof(RSArefPublicKey); + } else { + if (uiKeyUsage == 1) { + if (SDF_ExportSignPublicKey_ECC( + hSessionHandle, + uiKeyIndex, + (ECCrefPublicKey *)pucPublicKey) != SDR_OK) { + } + } else { + if (SDF_ExportEncPublicKey_ECC( + hSessionHandle, + uiKeyIndex, + (ECCrefPublicKey *)pucPublicKey) != SDR_OK) { + } + } + *puiPublicKeyLen = (unsigned int)sizeof(ECCrefPublicKey); + } + + return SAR_NotSupportYetErr; +} + +/* 7.3.18 */ +/* the `pucInData` is message, not digest */ +int SAF_RsaSign( + void *hAppHandle, + unsigned char *pucContainerName, + unsigned int uiContainerNameLen, + unsigned int uiHashAlgoType, + unsigned char *pucInData, + unsigned int uiInDataLen, + unsigned char *pucSignature, + unsigned int *puiSignatureLen) +{ + + + return SAR_NotSupportYetErr; +} + +/* 7.3.19 */ +int SAF_RsaSignFile( + void *hAppHandle, + unsigned char *pucContainerName, + unsigned int uiContainerNameLen, + unsigned int uiHashAlgoType, + unsigned char *pucFileName, + unsigned char *pucSignature, + unsigned int *puiSignatureLen) +{ + int ret; + unsigned char *buf = NULL; + unsigned int buflen; + + if ((ret = readfile(pucFileName, &buf, &buflen)) != SAR_OK) { + return ret; + } + if ((ret = SAF_RsaSign(hAppHandle, pucContainerName, uiContainerNameLen, + uiHashAlgoType, buf, buflen, pucSignature, puiSignatureLen)) != SAR_OK) { + OPENSSL_free(buf); + return ret; + } + + OPENSSL_free(buf); + return SAR_OK; +} + +/* 7.3.20 */ +int SAF_RsaVerifySign( + unsigned int uiHashAlgoType, + unsigned char *pucPublicKey, + unsigned int uiPublicKeyLen, + unsigned char *pucInData, + unsigned int uiInDataLen, + unsigned char *pucSignature, + unsigned int uiSignatureLen) +{ + return SAR_NotSupportYetErr; +} + +/* 7.3.21 */ +int SAF_RsaVerifySignFile( + unsigned int uiHashAlgoType, + unsigned char *pucPublicKey, + unsigned int uiPublicKeyLen, + unsigned char *pucFileName, + unsigned char *pucSignature, + unsigned int uiSignatureLen) +{ + int ret; + unsigned char *buf = NULL; + unsigned int buflen; + + if ((ret = readfile(pucFileName, &buf, &buflen)) != SAR_OK) { + return ret; + } + if ((ret = SAF_RsaVerifySign(uiHashAlgoType, pucPublicKey, uiPublicKeyLen, + buf, buflen, pucSignature, puiSignatureLen)) != SAR_OK) { + OPENSSL_free(buf); + return ret; + } + + OPENSSL_free(buf); + return SAR_OK; +} + +/* 7.3.22 */ +int SAF_VerifySignByCert( + unsigned int uiHashAlgoType, + unsigned char *pucCertificate, + unsigned int uiCertificateLen, + unsigned char *pucInData, + unsigned int uiInDataLen, + unsigned char *pucSignature, + unsigned int uiSignatureLen) +{ + int ret; + unsigned char *buf = NULL; + unsigned int buflen; + + if ((ret = cert_get_pubkey(pucCertificate, uiCertificateLen, &buf, &buflen)) != SAR_OK) { + return ret; + } + if ((ret = SAF_RsaVerifySign(uiHashAlgoType, pucPublicKey, uiPublicKeyLen, + buf, buflen, pucSignature, puiSignatureLen)) != SAR_OK) { + OPENSSL_free(buf); + return ret; + } + + OPENSSL_free(buf); + return SAR_OK; +} + diff --git a/crypto/saf/saf_sm2.c b/crypto/saf/saf_sm2.c new file mode 100644 index 00000000..d134c7dc --- /dev/null +++ b/crypto/saf/saf_sm2.c @@ -0,0 +1,255 @@ +/* ==================================================================== + * Copyright (c) 2016 The GmSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the GmSSL Project. + * (http://gmssl.org/)" + * + * 4. The name "GmSSL Project" must not be used to endorse or promote + * products derived from this software without prior written + * permission. For written permission, please contact + * guanzhi1980@gmail.com. + * + * 5. Products derived from this software may not be called "GmSSL" + * nor may "GmSSL" appear in their names without prior written + * permission of the GmSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the GmSSL Project + * (http://gmssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE GmSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GmSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +#include +#include +#include +#include "saf_lcl.h" + +/* 7.4.10 */ +int SAF_SM2_EncodeSignedAndEnvelopedData( + void *hAppHandle, + unsigned char *pucSignContainerName, + unsigned int uiSignContainerNameLen, + unsigned int uiSignKeyUsage, + unsigned char *pucSignerCertificate, + unsigned int uiSignerCertificateLen, + unsigned int uiDigestAlgorithm, + unsigned char *pucEncCertificate, + unsigned int uiEncCertificateLen, + unsigned int uiSymmAlgorithm, + unsigned char *pucData, + unsigned int uiDataLen, + unsigned char *pucDerSignedAndEnvelopedData, + unsigned int *puiDerSignedAndEnvelopedDataLen) +{ + int ret = SAR_UnknownErr; + PKCS7 *p7 = NULL; + EVP_PKEY *pkey = NULL; + const EVP_MD *md; + + p7 = PKCS7_new(); + + pkey = saf_load_private_key(hAppHandle, + pucSignContainerName, uiSignContainerNameLen + uiSignKeyUsage); + + PKCS7_set_type(p7, 0); + return 0; +} + +/* 7.4.11 */ +int SAF_SM2_DecodeSignedAndEnvelopedData( + void *hAppHandle, + unsigned char *pucDerContainerName, + unsigned int uiDerContainerNameLen, + unsigned int uiDecKeyUsage, + unsigned char *pucDerSignedAndEnvelopedData, + unsigned int uiDerSignedAndEnvelopedDataLen, + unsigned char *pucData, + unsigned int *puiDataLen, + unsigned char *pucSignerCertificate, + unsigned int *puiSignerCertificateLen, + unsigned int *puiDigestAlgorithms) +{ + return 0; +} + +/* 7.4.12 */ +int SAF_SM2_EncodeSignedData( + void *hAppHandle, + unsigned char *pucSignContainerName, + unsigned int uiSignContainerNameLen, + unsigned int uiSignKeyUsage, + unsigned char *pucSignerCertificate, + unsigned int uiSignerCertificateLen, + unsigned int uiDigestAlgorithm, + unsigned char *pucData, + unsigned int uiDataLen, + unsigned char *pucDerSignedData, + unsigned int *puiDerSignedDataLen) +{ + + int flags; + BIO *bio = NULL; + EVP_PKEY *pkey = NULL; + X509 *cert = NULL; + unsigned char *p; + + if (!(pkey = saf_load_private_key(hAppHandle, pucSignContainerName, + uiSignContainerNameLen, uiSignKeyUsage))) { + } + + /* decode certificate, check no extra input */ + p = pucSignerCertificate; + if (!(cert = d2i_X509(NULL, &p, (long)uiSignerCertificateLen))) { + } + if (p - pucSignerCertificate != uiSignerCertificateLen) { + } + + /* data bio */ + if (!(bio = BIO_new_mem_buf(pucData, (int)uiDataLen))) { + } + + /* set digest */ + if (!(md = EVP_get_digestbysgd(uiDigestAlgorithm))) { + } + + flags = PKCS7_BINARY; + p7 = PKCS7_sign(cert, pkey, NULL, bio, flags); + + + p = pucDerP7Data; + if (i2d_PKCS7(p7, &p) < 0) { + } + + *puiDerP7DataLen = p - pucDerP7Data; + + return 0; +} + +/* 7.4.13 */ +int SAF_SM2_DecodeSignedData( + void *hAppHandle, + unsigned char *pucDerSignedData, + unsigned int uiDerSignedDataLen, + unsigned char *pucSignerCertificate, + unsigned int uiSignerCertificateLen, + unsigned int uiDigestAlgorithm, + unsigned char *pucData, + unsigned int uiDataLen, + unsigned char *pucSign, + unsigned int *puiSignLen) +{ + int ret; + PKCS7 *p7 = NULL; + X509 *cert = NULL; + const EVP_MD *md; + BIO *bio = NULL; + STACK_OF(X509) *certs = NULL; + X509_STORE *store = NULL; + int flags = 0; + + p = pucDerP7SignedData; + if (!(p7 = d2i_PKCS7(NULL, &p, (long)uiDerP7SignedDataLen))) { + } + if (p - pucDerP7SignedData != uiDerP7SignedDataLen) { + } + + p = pucSignerCertificate; + if (!(cert = d2i_X509(NULL, &p, (long)uiSignerCertificateLen))) { + } + if (p - pucSignerCertificate != uiSignerCertificateLen) { + } + + if (!(md = EVP_get_digestbysgd(uiDigestAlgorithm))) { + } + if (!PKCS7_set_digest(p7, md)) { + } + + if (!PKCS7_verify(p7, cert, store, bio, NULL, flags)) { + } + + + return 0; +} + +/* 7.4.14 */ +int SAF_SM2_EncodeEnvelopedData( + void *hAppHandle, + unsigned char *pucData, + unsigned int uiDataLen, + unsigned char *pucEncCertificate, + unsigned int uiEncCertificateLen, + unsigned int uiSymmAlgorithm, + unsigned char *pucDerEnvelopedData, + unsigned int *puiDerEnvelopedDataLen) +{ + int ret = SAR_UnknownErr; + PKCS7 *p7 = NULL; + X509 *cert = NULL; + BIO *bio = NULL; + const EVP_CIPHER *cipher; + int flags; + + cipher = EVP_get_cipherbysgd(uiSymmAlgorithm); + bio = BIO_new(BIO_s_mem()); + // set data to bio + + p = pucEncCertificate; + cert = d2i_X509(NULL, &p, uiEncCertificateLen); + + p7 = PKCS7_encrypt(cert, bio, cipher, flags); +end: + PKCS7_free(p7); + return ret; +} + +/* 7.4.15 */ +int SAF_SM2_DecodeEnvelopedData( + void *hAppHandle, + unsigned char *pucDecContainerName, + unsigned int uiDecContainerNameLen, + unsigned int uiDecKeyUsage, + unsigned char *pucDerEnvelopedData, + unsigned int uiDerEnvelopedDataLen, + unsigned char *pucData, + unsigned int *puiDataLen) +{ + PKCS7 *p7 = NULL; + BIO *bio = NULL; + X509 *cert = NULL; + EVP_PKEY *pkey = NULL; + + // get cert and pkey from App.Container.KeyUsage + + PKCS7_decrypt(p7, pkey, cert, bio, flags); + + return 0; +} diff --git a/crypto/saf/saf_symmkeyobj.c b/crypto/saf/saf_symmkeyobj.c new file mode 100644 index 00000000..29e71ea6 --- /dev/null +++ b/crypto/saf/saf_symmkeyobj.c @@ -0,0 +1,144 @@ +/* ==================================================================== + * Copyright (c) 2016 The GmSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the GmSSL Project. + * (http://gmssl.org/)" + * + * 4. The name "GmSSL Project" must not be used to endorse or promote + * products derived from this software without prior written + * permission. For written permission, please contact + * guanzhi1980@gmail.com. + * + * 5. Products derived from this software may not be called "GmSSL" + * nor may "GmSSL" appear in their names without prior written + * permission of the GmSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the GmSSL Project + * (http://gmssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE GmSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GmSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES + * LOSS OF USE, DATA, OR PROFITS OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +#include +#include +#include +#include +#include "saf_lcl.h" + + +/* 7.3.30 + * All symmetric keys in GMAPI are session objects. + * The `SymmKeyObj` is a EVP_CIPHER_CTX + */ +int SAF_CreateSymmKeyObj( + void *hAppHandle, + void **phSymmKeyObj, + unsigned char *pucContainerName, + unsigned int uiContainerLen, + unsigned char *pucIV, + unsigned int uiIVLen, + unsigned int uiEncOrDec, + unsigned int uiCryptoAlgID) +{ + int ret = SAR_UnknownErr; + SAF_SymmKeyObj *obj = NULL; + + /* check arguments */ + if (!hAppHandle || !phSymmKeyObj || !pucContainerName || !pucIV) { + SAFerr(SAF_F_SAF_CREATESYMMKEYOBJ, + ERR_R_PASSED_NULL_PARAMETER); + return -1; + } + if (uiContainerLen > INT_MAX) { + SAFerr(SAF_F_SAF_CREATESYMMKEYOBJ, + SAF_R_INVALID_INPUT_LENGTH); + return -1; + } + if (uiIVLen > EVP_MAX_IV_LENGTH) { + SAFerr(SAF_F_SAF_CREATESYMMKEYOBJ, + SAF_R_INVALID_INPUT_LENGTH); + return -1; + } + + /* init object */ + if (!(obj = OPENSSL_zalloc(sizeof(*obj)))) { + SAFerr(SAF_F_SAF_CREATESYMMKEYOBJ, + ERR_R_MALLOC_FAILURE); + goto end; + } + + obj->hAppHandle = hAppHandle; + if (!(obj->pucContainerName = OPENSSL_memdup(pucContainerName, + (size_t)uiContainerLen))) { + SAFerr(SAF_F_SAF_CREATESYMMKEYOBJ, + ERR_R_MALLOC_FAILURE); + goto end; + } + if (!(obj->pucIV = OPENSSL_memdup(pucIV, (size_t)uiIVLen))) { + SAFerr(SAF_F_SAF_CREATESYMMKEYOBJ, + ERR_R_MALLOC_FAILURE); + goto end; + } + obj->uiEncOrDec = uiEncOrDec; + + if (!EVP_get_cipherbysgd(uiCryptoAlgID)) { + SAFerr(SAF_F_SAF_CREATESYMMKEYOBJ, + SAF_R_INVALID_ALGOR); + goto end; + } + obj->uiCryptoAlgID = uiCryptoAlgID; + + /* set output */ + *phSymmKeyObj = obj; + obj = NULL; + + ret = SAR_OK; + +end: + (void)SAF_DestroySymmAlgoObj(obj); + return ret; +} + +/* 7.3.36 */ +int SAF_DestroySymmAlgoObj( + void *hSymmKeyObj) +{ + SAF_SymmKeyObj *obj = (SAF_SymmKeyObj *)hSymmKeyObj; + + if (!hSymmKeyObj) { + return SAR_OK; + } + + OPENSSL_free(obj->pucContainerName); + OPENSSL_free(obj->pucIV); + memset(obj, 0, sizeof(*obj)); + return SAR_OK; +} diff --git a/crypto/sdf/build.info b/crypto/sdf/build.info new file mode 100644 index 00000000..07225b35 --- /dev/null +++ b/crypto/sdf/build.info @@ -0,0 +1,17 @@ +LIBS=../../libcrypto +SOURCE[../../libcrypto]=\ + sdf_dev.c \ + sdf_ec.c \ + sdf_enc.c \ + sdf_err.c \ + sdf_errstr.c \ + sdf_ext.c \ + sdf_file.c \ + sdf_hash.c \ + sdf_key.c \ + sdf_key2.c \ + sdf_lib.c \ + sdf_mac.c \ + sdf_rand.c \ + sdf_rsa.c \ + sdf_session.c diff --git a/crypto/sdf/sdf_dev.c b/crypto/sdf/sdf_dev.c new file mode 100644 index 00000000..2ff7e25d --- /dev/null +++ b/crypto/sdf/sdf_dev.c @@ -0,0 +1,119 @@ +/* ==================================================================== + * Copyright (c) 2016 The GmSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the GmSSL Project. + * (http://gmssl.org/)" + * + * 4. The name "GmSSL Project" must not be used to endorse or promote + * products derived from this software without prior written + * permission. For written permission, please contact + * guanzhi1980@gmail.com. + * + * 5. Products derived from this software may not be called "GmSSL" + * nor may "GmSSL" appear in their names without prior written + * permission of the GmSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the GmSSL Project + * (http://gmssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE GmSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GmSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES + * LOSS OF USE, DATA, OR PROFITS OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +#include +#include +#include +#include +#include +#include +#include +#include "sdf_lcl.h" + +char *deviceHandle = "SDF Device Handle"; + +int SDF_OpenDevice( + void **phDeviceHandle) +{ + if (!phDeviceHandle) { + SDFerr(SDF_F_SDF_OPENDEVICE, ERR_R_PASSED_NULL_PARAMETER); + return SDR_OUTARGERR; + } + +#ifndef OPENSSL_NO_ENGINE + ENGINE_load_builtin_engines(); +#endif + + *phDeviceHandle = deviceHandle; + return SDR_OK; +} + +int SDF_CloseDevice( + void *hDeviceHandle) +{ + if (hDeviceHandle != deviceHandle) { + SDFerr(SDF_F_SDF_CLOSEDEVICE, SDF_R_INVALID_DEVICE_HANDLE); + return SDR_INARGERR; + } +#ifndef OPENSSL_NO_ENGINE + ENGINE_cleanup(); +#endif + return SDR_OK; +} + +int SDF_GetDeviceInfo( + void *hSessionHandle, + DEVICEINFO *pstDeviceInfo) +{ + SDF_SESSION *session = (SDF_SESSION *)hSessionHandle; + + if (!hSessionHandle || !pstDeviceInfo) { + SDFerr(SDF_F_SDF_GETDEVICEINFO, ERR_R_PASSED_NULL_PARAMETER); + return SDR_INARGERR; + } + if (session->magic != SDF_SESSION_MAGIC) { + SDFerr(SDF_F_SDF_GETDEVICEINFO, SDF_R_INVALID_SESSION_HANDLE); + return SDR_INARGERR; + } + + memset(pstDeviceInfo, 0, sizeof(*pstDeviceInfo)); + strncpy((char *)pstDeviceInfo->IssuerName, "GmSSL Project (http://gmssl.org)", 40); + strncpy((char *)pstDeviceInfo->DeviceName, "GmSSL Soft SDF", 16); + strncpy((char *)pstDeviceInfo->DeviceSerial, "201608020010123", 16); + pstDeviceInfo->DeviceVersion = 2; + pstDeviceInfo->StandardVersion = 1; + pstDeviceInfo->AsymAlgAbility[0] = SGD_RSA|SGD_SM2_1; + pstDeviceInfo->AsymAlgAbility[1] = SGD_RSA|SGD_SM2_3; + pstDeviceInfo->SymAlgAbility = SGD_SM1|SGD_SSF33|SGD_SM4|SGD_ZUC; + pstDeviceInfo->HashAlgAbility = SGD_SM3|SGD_SHA1|SGD_SHA256; + pstDeviceInfo->BufferSize = 0; + + return SDR_OK; +} + diff --git a/crypto/sdf/sdf_ec.c b/crypto/sdf/sdf_ec.c new file mode 100644 index 00000000..9fadadc7 --- /dev/null +++ b/crypto/sdf/sdf_ec.c @@ -0,0 +1,920 @@ +/* ==================================================================== + * Copyright (c) 2016 The GmSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the GmSSL Project. + * (http://gmssl.org/)" + * + * 4. The name "GmSSL Project" must not be used to endorse or promote + * products derived from this software without prior written + * permission. For written permission, please contact + * guanzhi1980@gmail.com. + * + * 5. Products derived from this software may not be called "GmSSL" + * nor may "GmSSL" appear in their names without prior written + * permission of the GmSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the GmSSL Project + * (http://gmssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE GmSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GmSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +#include +#include +#include +#include +#include +#include "sdf_lcl.h" + +/* + * For all the ECC signing/verification, the to be signed data `pucData` + * should be the digest of the message, instead of the original message. If + * the application requires a GM standard signature with the hashed identity + * `Z`, then `SDF_HashInit` must be called with the `pucPublicKey` and + * `pucID` provided. + */ + +/* + * some of these functions require an `uiAlgID` to specify the algorithm. + * Currently only `SGD_SM2_1` and `SGD_SM2_3` should be used. Maybe for some + * implementations might also support international algorithms such as ECDSA + * and ECIES. + */ +/* + * there are limits on the max size of input plaintext, for SM2 encryptions, + * the length will be equal to the `ECCref_MAX_CIPHER_LEN` + */ +/* + * Symmetric Encryption: + * `SDF_Encrypt` + * `SDF_Decrypt` + * + * we will not provide two-step operations for SDF API which means the + * caller can not assign the `pucEnData` to be NULL hoping that the API will + * return the proper out length through `*puiEncDataLength`. The reason is + * that the maximum output length can be easily estimated in almost all the + * APIs of SDF. So when `pucEncData` is NULL or `*puiEncDataLength` is not + * large enough, the API will just return with an error. + * + * The implementation will not carefully to estimate the output length, so + * always prepare the max output buffer. For exmaple, prepare at least two + * extra blocks for symmetric encryption, prepare max digest length of known + * hash functions as the MAC buffer size. + * + * Note: the GM/T 0018-2012 standard requires the implementation MUST NOT do + * any padding operatons, and the input data length should be multiple block + * length. Thus these two functions can be used for modes such as CBC, the + * caller can use a function more than once and do the padding himself. + */ + + + +int SDF_GenerateKeyPair_ECC( + void *hSessionHandle, + unsigned int uiAlgID, + unsigned int uiKeyBits, + ECCrefPublicKey *pucPublicKey, + ECCrefPrivateKey *pucPrivateKey) +{ + int ret = SDR_UNKNOWERR; + EC_KEY *ec_key = NULL; + + /* check arguments */ + if (!hSessionHandle || !pucPublicKey || !pucPrivateKey) { + SDFerr(SDF_F_SDF_GENERATEKEYPAIR_ECC, + ERR_R_PASSED_NULL_PARAMETER); + return SDR_UNKNOWERR; + } + if (uiAlgID != SGD_SM2 && uiAlgID != SGD_SM2_1 && + uiAlgID != SGD_SM2_2 && uiAlgID != SGD_SM2_3) { + SDFerr(SDF_F_SDF_GENERATEKEYPAIR_ECC, + SDF_R_INVALID_ALGOR); + return SDR_UNKNOWERR; + } + if (uiKeyBits != 256) { + SDFerr(SDF_F_SDF_GENERATEKEYPAIR_ECC, + SDF_R_INVALID_KEY_LENGTH); + return SDR_UNKNOWERR; + } + + /* generate */ + if(!(ec_key = EC_KEY_new_by_curve_name(NID_sm2p256v1))) { + SDFerr(SDF_F_SDF_GENERATEKEYPAIR_ECC, ERR_R_EC_LIB); + goto end; + } + + /* convert */ + if (!EC_KEY_get_ECCrefPublicKey(ec_key, pucPublicKey)) { + SDFerr(SDF_F_SDF_GENERATEKEYPAIR_ECC, + SDF_R_GET_PUBLIC_KEY_FAILED); + goto end; + } + if (!EC_KEY_get_ECCrefPrivateKey(ec_key, pucPrivateKey)) { + SDFerr(SDF_F_SDF_GENERATEKEYPAIR_ECC, + SDF_R_GET_PRIVATE_KEY_FAILED); + goto end; + } + + ret = SAR_OK; +end: + EC_KEY_free(ec_key); + return ret; +} + +int SDF_ExportSignPublicKey_ECC( + void *hSessionHandle, + unsigned int uiKeyIndex, + ECCrefPublicKey *pucPublicKey) +{ + int ret = SDR_UNKNOWERR; + EVP_PKEY *pkey = NULL; + unsigned int uiKeyUsage = SGD_SM2_1; + + /* check arguments */ + if (!hSessionHandle || !pucPublicKey) { + SDFerr(SDF_F_SDF_EXPORTSIGNPUBLICKEY_ECC, + ERR_R_PASSED_NULL_PARAMETER); + return SDR_UNKNOWERR; + } + + /* load key */ + if (!(pkey = sdf_load_ec_public_key(hSessionHandle, + uiKeyIndex, uiKeyUsage))) { + SDFerr(SDF_F_SDF_EXPORTSIGNPUBLICKEY_ECC, + ERR_R_GMAPI_LIB); + goto end; + } + + /* set return value */ + if (!EC_KEY_get_ECCrefPublicKey(EVP_PKEY_get0_EC_KEY(pkey), + pucPublicKey)) { + SDFerr(SDF_F_SDF_EXPORTSIGNPUBLICKEY_ECC, + ERR_R_GMAPI_LIB); + goto end; + } + ret = SDR_OK; + +end: + EVP_PKEY_free(pkey); + return ret; +} + +int SDF_ExportEncPublicKey_ECC( + void *hSessionHandle, + unsigned int uiKeyIndex, + ECCrefPublicKey *pucPublicKey) +{ + int ret = SDR_UNKNOWERR; + EVP_PKEY *pkey = NULL; + unsigned int uiKeyUsage = 1; + + /* check arguments */ + if (!hSessionHandle || !pucPublicKey) { + SDFerr(SDF_F_SDF_EXPORTENCPUBLICKEY_ECC, + ERR_R_PASSED_NULL_PARAMETER); + return SDR_UNKNOWERR; + } + + /* load key */ + if (!(pkey = sdf_load_ec_public_key(hSessionHandle, + uiKeyIndex, uiKeyUsage))) { + SDFerr(SDF_F_SDF_EXPORTENCPUBLICKEY_ECC, + ERR_R_GMAPI_LIB); + goto end; + } + + /* set return value */ + if (!EC_KEY_get_ECCrefPublicKey(EVP_PKEY_get0_EC_KEY(pkey), + pucPublicKey)) { + SDFerr(SDF_F_SDF_EXPORTENCPUBLICKEY_ECC, + ERR_R_GMAPI_LIB); + goto end; + } + ret = SDR_OK; + +end: + EVP_PKEY_free(pkey); + return ret; +} + +int SDF_GenerateAgreementDataWithECC( + void *hSessionHandle, + unsigned int uiISKIndex, + unsigned int uiKeyBits, + unsigned char *pucSponsorID, + unsigned int uiSponsorIDLength, + ECCrefPublicKey *pucSponsorPublicKey, + ECCrefPublicKey *pucSponsorTmpPublicKey, + void **phAgreementHandle) +{ + return 0; +} + +int SDF_GenerateKeyWithECC( + void *hSessionHandle, + unsigned char *pucResponseID, + unsigned int uiResponseIDLength, + ECCrefPublicKey *pucResponsePublicKey, + ECCrefPublicKey *pucResponseTmpPublicKey, + void *hAgreementHandle, + void **phKeyHandle) +{ + return 0; +} + +int SDF_GenerateAgreementDataAndKeyWithECC( + void *hSessionHandle, + unsigned int uiISKIndex, + unsigned int uiKeyBits, + unsigned char *pucResponseID, + unsigned int uiResponseIDLength, + unsigned char *pucSponsorID, + unsigned int uiSponsorIDLength, + ECCrefPublicKey *pucSponsorPublicKey, + ECCrefPublicKey *pucSponsorTmpPublicKey, + ECCrefPublicKey *pucResponsePublicKey, + ECCrefPublicKey *pucResponseTmpPublicKey, + void **phKeyHandle) +{ + return 0; +} + +/* generate a session key and encrypt it with internal public key + * we can first random a key, + * export the public key, + * and then use the SDF_GenerateKeyWithEPK_ECC to encrypt the key + * the output key handle is only a pointer to the key buffer. + */ +int SDF_GenerateKeyWithIPK_ECC( + void *hSessionHandle, + unsigned int uiIPKIndex, + unsigned int uiKeyBits, /* output session key length */ + ECCCipher *pucKey, + void **phKeyHandle) +{ + int ret = SDR_UNKNOWERR; + SDF_KEY *key = NULL; + unsigned int uiAlgID = SGD_SM2_3; + + /* check arguments */ + if (!hSessionHandle || !pucKey || !phKeyHandle) { + SDFerr(SDF_F_SDF_GENERATEKEYWITHIPK_ECC, + ERR_R_PASSED_NULL_PARAMETER); + return SDR_UNKNOWERR; + } + if (uiKeyBits <= 0 || uiKeyBits > EVP_MAX_KEY_LENGTH * 8 || + uiKeyBits % 8) { + SDFerr(SDF_F_SDF_GENERATEKEYWITHIPK_ECC, + SDF_R_INVALID_KEY_LENGTH); + return SDR_UNKNOWERR; + } + + /* random key */ + if (!(key = OPENSSL_zalloc(sizeof(*key)))) { + SDFerr(SDF_F_SDF_GENERATEKEYWITHIPK_ECC, + ERR_R_MALLOC_FAILURE); + goto end; + } + key->keylen = uiKeyBits/8; + if ((ret = SDF_GenerateRandom(hSessionHandle, key->keylen, + key->key)) != SDR_OK) { + SDFerr(SDF_F_SDF_GENERATEKEYWITHIPK_ECC, + ERR_R_GMAPI_LIB); + goto end; + } + + /* encrypt key with external ec public key */ + if ((ret = SDF_InternalEncrypt_ECC( + hSessionHandle, + uiIPKIndex, + uiAlgID, + key->key, + key->keylen, + pucKey)) != SDR_OK) { + SDFerr(SDF_F_SDF_GENERATEKEYWITHIPK_ECC, + ERR_R_GMAPI_LIB); + goto end; + } + + /* set return value */ + *phKeyHandle = key; + key = NULL; + ret = SDR_OK; + +end: + OPENSSL_clear_free(key, sizeof(*key)); + return ret; +} + +int SDF_GenerateKeyWithEPK_ECC( + void *hSessionHandle, + unsigned int uiKeyBits, + unsigned int uiAlgID, /* must be SGD_SM2_3 */ + ECCrefPublicKey *pucPublicKey, + ECCCipher *pucKey, + void **phKeyHandle) +{ + int ret = SDR_UNKNOWERR; + SDF_KEY *key = NULL; + + /* check arguments */ + if (!hSessionHandle || !pucPublicKey || !pucKey || !phKeyHandle) { + SDFerr(SDF_F_SDF_GENERATEKEYWITHEPK_ECC, + ERR_R_PASSED_NULL_PARAMETER); + return SDR_UNKNOWERR; + } + if (uiKeyBits <= 0 || uiKeyBits >= EVP_MAX_KEY_LENGTH * 8 || + uiKeyBits % 8) { + SDFerr(SDF_F_SDF_GENERATEKEYWITHEPK_ECC, + SDF_R_INVALID_KEY_LENGTH); + return SDR_UNKNOWERR; + } + if (uiAlgID != SGD_SM2_3) { + SDFerr(SDF_F_SDF_GENERATEKEYWITHEPK_ECC, + SDF_R_INVALID_ALGOR); + return SDR_UNKNOWERR; + } + + /* random key */ + if (!(key = OPENSSL_zalloc(sizeof(*key)))) { + SDFerr(SDF_F_SDF_GENERATEKEYWITHEPK_ECC, + ERR_R_MALLOC_FAILURE); + goto end; + } + key->keylen = uiKeyBits/8; + if ((ret = SDF_GenerateRandom(hSessionHandle, key->keylen, + key->key)) != SDR_OK) { + SDFerr(SDF_F_SDF_GENERATEKEYWITHEPK_ECC, + ERR_R_GMAPI_LIB); + goto end; + } + + /* encrypt key with external ec public key */ + if ((ret = SDF_ExternalEncrypt_ECC( + hSessionHandle, + uiAlgID, + pucPublicKey, + key->key, + key->keylen, + pucKey)) != SDR_OK) { + SDFerr(SDF_F_SDF_GENERATEKEYWITHEPK_ECC, + ERR_R_GMAPI_LIB); + goto end; + } + + /* set return value */ + *phKeyHandle = key; + key = NULL; + ret = SDR_OK; + +end: + OPENSSL_clear_free(key, sizeof(*key)); + return ret; +} + +/* import session key + * use the engine to decrypt the ECCipher + */ +int SDF_ImportKeyWithISK_ECC( + void *hSessionHandle, + unsigned int uiISKIndex, + ECCCipher *pucKey, + void **phKeyHandle) +{ + int ret = SDR_UNKNOWERR; + SDF_KEY *key = NULL; + unsigned int uiAlgID = SGD_SM2_3; + + /* check arguments */ + if (!hSessionHandle || !pucKey || !phKeyHandle) { + SDFerr(SDF_F_SDF_IMPORTKEYWITHISK_ECC, + ERR_R_PASSED_NULL_PARAMETER); + return SDR_UNKNOWERR; + } + + /* prepare key */ + if (!(key = OPENSSL_zalloc(sizeof(*key)))) { + SDFerr(SDF_F_SDF_IMPORTKEYWITHISK_ECC, + ERR_R_MALLOC_FAILURE); + goto end; + } + key->keylen = EVP_MAX_KEY_LENGTH; + + /* decrypt with internal ec private key */ + if ((ret = SDF_InternalDecrypt_ECC( + hSessionHandle, + uiISKIndex, + uiAlgID, + pucKey, + key->key, + &key->keylen)) != SDR_OK) { + SDFerr(SDF_F_SDF_IMPORTKEYWITHISK_ECC, + ERR_R_GMAPI_LIB); + goto end; + } + + /* set return value */ + *phKeyHandle = key; + key = NULL; + ret = SDR_OK; + +end: + OPENSSL_clear_free(key, sizeof(*key)); + return ret; +} + +int SDF_ExchangeDigitEnvelopeBaseOnECC( + void *hSessionHandle, + unsigned int uiKeyIndex, + unsigned int uiAlgID, + ECCrefPublicKey *pucPublicKey, + ECCCipher *pucEncDataIn, + ECCCipher *pucEncDataOut) +{ + return 0; +} + +/* + * Implementation of SM2 signing + * + * Although the digest and signing operations should be the wrapping of the EVP + * API, it will be simpler when using the native API of the `sm2` module. + * Another consideration is that the usage of SM2 EVP might be changed, and the + * operations might also be different from the GM standards, like signing the + * H(Z||H(M)) instead of signing H(Z||M). So in the GMAPI we use the SM2 API + * directly. + */ + +int SDF_ExternalSign_ECC( + void *hSessionHandle, /* no use so not checked */ + unsigned int uiAlgID, /* must be SGD_SM2_1 */ + ECCrefPrivateKey *pucPrivateKey, + unsigned char *pucData, /* digest */ + unsigned int uiDataLength, + ECCSignature *pucSignature) +{ + int ret = SDR_UNKNOWERR; + EC_KEY *ec_key = NULL; + ECDSA_SIG *sig = NULL; + + /* check arguments */ + if (!hSessionHandle || !pucData || !pucSignature) { + SDFerr(SDF_F_SDF_EXTERNALSIGN_ECC, + ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + if (uiAlgID != SGD_SM2_1) { + SDFerr(SDF_F_SDF_EXTERNALSIGN_ECC, + SDF_R_INVALID_ALGOR); + return 0; + } + if (uiDataLength > INT_MAX) { + SDFerr(SDF_F_SDF_EXTERNALSIGN_ECC, + SDF_R_INVALID_INPUT_LENGTH); + return 0; + } + + /* load ec private key */ + if (!(ec_key = EC_KEY_new_from_ECCrefPrivateKey(pucPrivateKey))) { + SDFerr(SDF_F_SDF_EXTERNALSIGN_ECC, + ERR_R_GMAPI_LIB); + goto end; + } + if (!(sig = SM2_do_sign(pucData, uiDataLength, ec_key))) { + SDFerr(SDF_F_SDF_EXTERNALSIGN_ECC, + ERR_R_EC_LIB); + goto end; + } + + /* set return value */ + if (!ECDSA_SIG_get_ECCSignature(sig, pucSignature)) { + SDFerr(SDF_F_SDF_EXTERNALSIGN_ECC, + ERR_R_GMAPI_LIB); + goto end; + } + ret = SDR_OK; + +end: + EC_KEY_free(ec_key); + ECDSA_SIG_free(sig); + return ret; +} + +int SDF_ExternalVerify_ECC( + void *hSessionHandle, + unsigned int uiAlgID, + ECCrefPublicKey *pucPublicKey, + unsigned char *pucDataInput, + unsigned int uiInputLength, + ECCSignature *pucSignature) +{ + int ret = SDR_UNKNOWERR; + EC_KEY *ec_key = NULL; + ECDSA_SIG *sig = NULL; + + /* check arguments */ + if (!hSessionHandle || !pucPublicKey || !pucDataInput || + !pucSignature) { + SDFerr(SDF_F_SDF_EXTERNALVERIFY_ECC, + ERR_R_PASSED_NULL_PARAMETER); + return SDR_UNKNOWERR; + } + if (uiAlgID != SGD_SM2_1) { + SDFerr(SDF_F_SDF_EXTERNALVERIFY_ECC, + SDF_R_INVALID_ALGOR); + return SDR_UNKNOWERR; + } + if (uiInputLength != SM3_DIGEST_LENGTH) { + SDFerr(SDF_F_SDF_EXTERNALVERIFY_ECC, + SDF_R_INVALID_INPUT_LENGTH); + return SDR_UNKNOWERR; + } + + /* parse arguments */ + if (!(ec_key = EC_KEY_new_from_ECCrefPublicKey(pucPublicKey))) { + SDFerr(SDF_F_SDF_EXTERNALVERIFY_ECC, + SDF_R_INVALID_EC_PUBLIC_KEY); + goto end; + } + if (!(sig = SM2_do_sign(pucDataInput, uiInputLength, ec_key))) { + SDFerr(SDF_F_SDF_EXTERNALVERIFY_ECC, ERR_R_EC_LIB); + goto end; + } + if (!ECDSA_SIG_get_ECCSignature(sig, pucSignature)) { + SDFerr(SDF_F_SDF_EXTERNALVERIFY_ECC, ERR_R_GMAPI_LIB); + goto end; + } + + /* set return value */ + ret = SDR_OK; + +end: + EC_KEY_free(ec_key); + ECDSA_SIG_free(sig); + return ret; +} + +int SDF_ExternalEncrypt_ECC( + void *hSessionHandle, + unsigned int uiAlgID, /* SGD_SM2_3 */ + ECCrefPublicKey *pucPublicKey, + unsigned char *pucData, + unsigned int uiDataLength, + ECCCipher *pucEncData) +{ + int ret = SDR_UNKNOWERR; + EC_KEY *ec_key = NULL; + SM2_CIPHERTEXT_VALUE *cv = NULL; + SM2_ENC_PARAMS params; + + /* check arguments */ + if (!hSessionHandle || !pucPublicKey || !pucData || !pucEncData) { + SDFerr(SDF_F_SDF_EXTERNALENCRYPT_ECC, + ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + if (uiAlgID != SGD_SM2_3) { + SDFerr(SDF_F_SDF_EXTERNALENCRYPT_ECC, + SDF_R_INVALID_ALGOR); + return 0; + } + /* FIXME + if (uiDataLength > ECCref_MAX_CIPHER_LEN) { + SDFerr(SDF_F_SDF_EXTERNALENCRYPT_ECC, + SDF_R_INVALID_INPUT_LENGTH); + return 0; + } + */ + + /* parse public key */ + if (!(ec_key = EC_KEY_new_from_ECCrefPublicKey(pucPublicKey))) { + SDFerr(SDF_F_SDF_EXTERNALENCRYPT_ECC, ERR_R_GMAPI_LIB); + goto end; + } + + /* encrypt */ + (void)SM2_ENC_PARAMS_init_with_recommended(¶ms); + if (!(cv = SM2_do_encrypt(¶ms, pucData, (size_t)uiDataLength, + ec_key))) { + SDFerr(SDF_F_SDF_EXTERNALENCRYPT_ECC, ERR_R_EC_LIB); + goto end; + } + /* encode ciphertext */ + if (!SM2_CIPHERTEXT_VALUE_get_ECCCipher(cv, pucEncData)) { + SDFerr(SDF_F_SDF_EXTERNALENCRYPT_ECC, ERR_R_EC_LIB); + goto end; + } + + ret = SDR_OK; + +end: + EC_KEY_free(ec_key); + SM2_CIPHERTEXT_VALUE_free(cv); + return ret; +} + +int SDF_ExternalDecrypt_ECC( + void *hSessionHandle, + unsigned int uiAlgID, + ECCrefPrivateKey *pucPrivateKey, + ECCCipher *pucEncData, + unsigned char *pucData, + unsigned int *puiDataLength) +{ + int ret = SDR_UNKNOWERR; + EC_KEY *ec_key = NULL; + SM2_CIPHERTEXT_VALUE *cv = NULL; + SM2_ENC_PARAMS params; + size_t siz; + + /* check arguments */ + if (!hSessionHandle || !pucPrivateKey || !pucEncData || + !pucData || !puiDataLength) { + SDFerr(SDF_F_SDF_EXTERNALDECRYPT_ECC, + ERR_R_PASSED_NULL_PARAMETER); + return SDR_UNKNOWERR; + } + /* FIXME + if (*puiDataLength < ECCref_MAX_CIPHER_LEN) { + SDFerr(SDF_F_SDF_EXTERNALDECRYPT_ECC, + SDF_R_BUFFER_TOO_SMALL); + return SDR_UNKNOWERR; + } + */ + + /* parse arguments */ + if (!(ec_key = EC_KEY_new_from_ECCrefPrivateKey(pucPrivateKey))) { + SDFerr(SDF_F_SDF_EXTERNALDECRYPT_ECC, + SDF_R_INVALID_EC_PRIVATE_KEY); + goto end; + } + if (!(cv = SM2_CIPHERTEXT_VALUE_new_from_ECCCipher(pucEncData))) { + SDFerr(SDF_F_SDF_EXTERNALDECRYPT_ECC, + SDF_R_INVALID_EC_CIPHERTEXT); + goto end; + } + + /* decrypt */ + (void)SM2_ENC_PARAMS_init_with_recommended(¶ms); + siz = (size_t)*puiDataLength; + if (!SM2_do_decrypt(¶ms, cv, pucData, &siz, ec_key)) { + SDFerr(SDF_F_SDF_EXTERNALDECRYPT_ECC, ERR_R_EC_LIB); + } + + /* set return value */ + *puiDataLength = (unsigned int)siz; + ret = SDR_OK; + +end: + EC_KEY_free(ec_key); + SM2_CIPHERTEXT_VALUE_free(cv); + return ret; +} + +/* internal private key operation will use ENGINE */ +int SDF_InternalSign_ECC( + void *hSessionHandle, + unsigned int uiISKIndex, + unsigned char *pucData, + unsigned int uiDataLength, + ECCSignature *pucSignature) +{ + int ret = 0; + SDF_SESSION *session = (SDF_SESSION *)hSessionHandle; + EVP_PKEY_CTX *ctx = NULL; + EVP_PKEY *pkey = NULL; + unsigned char buf[256/4 + 32]; + size_t siz; + + /* check arguments */ + if (!hSessionHandle || !pucData || !pucSignature) { + SDFerr(SDF_F_SDF_INTERNALSIGN_ECC, + ERR_R_PASSED_NULL_PARAMETER); + return SDR_UNKNOWERR; + } + if (uiDataLength > SM3_DIGEST_LENGTH) { + SDFerr(SDF_F_SDF_INTERNALSIGN_ECC, + SDF_R_INVALID_INPUT_LENGTH); + return SDR_UNKNOWERR; + } + + /* parse arguments */ + if (!(pkey = sdf_load_ec_private_key(hSessionHandle, uiISKIndex, + SGD_PK_SIGN))) { + SDFerr(SDF_F_SDF_INTERNALSIGN_ECC, + SDF_R_INVALID_KEY_HANDLE); + goto end; + } + + /* sign + * use the EVP API instead of the native SM2 API to use ENGINE + */ + if (!(ctx = EVP_PKEY_CTX_new(pkey, session->engine))) { + SDFerr(SDF_F_SDF_INTERNALSIGN_ECC, ERR_R_EVP_LIB); + goto end; + } + if (!EVP_PKEY_sign_init(ctx)) { + SDFerr(SDF_F_SDF_INTERNALSIGN_ECC, ERR_R_EVP_LIB); + goto end; + } + if (!EVP_PKEY_CTX_set_ec_sign_type(ctx, NID_sm_scheme)) { + SDFerr(SDF_F_SDF_INTERNALSIGN_ECC, ERR_R_EVP_LIB); + goto end; + } + siz = sizeof(buf); + if (!EVP_PKEY_sign(ctx, buf, &siz, pucData, (size_t)uiDataLength)) { + SDFerr(SDF_F_SDF_INTERNALSIGN_ECC, ERR_R_EVP_LIB); + goto end; + } + + /* convert signature buf to ECCSignature */ + if (!sdf_decode_ec_signature(pucSignature, buf, siz)) { + SDFerr(SDF_F_SDF_INTERNALSIGN_ECC, ERR_R_GMAPI_LIB); + goto end; + } + + /* set return value */ + ret = SDR_OK; + +end: + EVP_PKEY_CTX_free(ctx); + EVP_PKEY_free(pkey); + return ret; +} + +int SDF_InternalVerify_ECC( + void *hSessionHandle, + unsigned int uiIPKIndex, + unsigned char *pucData, + unsigned int uiDataLength, + ECCSignature *pucSignature) +{ + int ret = SDR_UNKNOWERR; + SDF_SESSION *session = (SDF_SESSION *)hSessionHandle; + EVP_PKEY *pkey = NULL; + EVP_PKEY_CTX *ctx = NULL; + unsigned char buf[521/4 + 32]; + size_t siz; + + /* check arguments */ + if (!hSessionHandle || !pucData || !pucSignature) { + SDFerr(SDF_F_SDF_INTERNALVERIFY_ECC, + ERR_R_PASSED_NULL_PARAMETER); + return SDR_UNKNOWERR; + } + if (uiDataLength != SM3_DIGEST_LENGTH) { + SDFerr(SDF_F_SDF_INTERNALVERIFY_ECC, + SDF_R_INVALID_INPUT_LENGTH); + return SDR_UNKNOWERR; + } + + /* parse arguments */ + if (!(pkey = sdf_load_ec_public_key(hSessionHandle, uiIPKIndex, + SGD_PK_SIGN))) { + SDFerr(SDF_F_SDF_INTERNALVERIFY_ECC, ERR_R_GMAPI_LIB); + goto end; + } + siz = sizeof(buf); + if (!sdf_encode_ec_signature(pucSignature, buf, &siz)) { + SDFerr(SDF_F_SDF_INTERNALVERIFY_ECC, ERR_R_GMAPI_LIB); + goto end; + } + + /* verify with EVP API and ENGINE */ + if (!(ctx = EVP_PKEY_CTX_new(pkey, session->engine))) { + SDFerr(SDF_F_SDF_INTERNALVERIFY_ECC, ERR_R_EVP_LIB); + goto end; + } + if (!EVP_PKEY_verify_init(ctx)) { + SDFerr(SDF_F_SDF_INTERNALVERIFY_ECC, ERR_R_EVP_LIB); + goto end; + } + if (!EVP_PKEY_CTX_set_ec_sign_type(ctx, NID_sm_scheme)) { + SDFerr(SDF_F_SDF_INTERNALVERIFY_ECC, ERR_R_EVP_LIB); + goto end; + } + if (1 != EVP_PKEY_verify(ctx, buf, siz, pucData, + (size_t)uiDataLength)) { + SDFerr(SDF_F_SDF_INTERNALVERIFY_ECC, ERR_R_EVP_LIB); + goto end; + } + + ret = SDR_OK; + +end: + EVP_PKEY_CTX_free(ctx); + EVP_PKEY_free(pkey); + return ret; +} + +int SDF_InternalEncrypt_ECC( + void *hSessionHandle, + unsigned int uiIPKIndex, + unsigned int uiAlgID, + unsigned char *pucData, + unsigned int uiDataLength, + ECCCipher *pucEncData) +{ + int ret = 0; + EVP_PKEY *pkey = NULL; + SM2_CIPHERTEXT_VALUE *cv = NULL; + SM2_ENC_PARAMS params; + + /* check arguments */ + if (!hSessionHandle || !pucData || !pucEncData) { + SDFerr(SDF_F_SDF_INTERNALENCRYPT_ECC, + ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + if (uiDataLength > ECCref_MAX_LEN) { + SDFerr(SDF_F_SDF_INTERNALENCRYPT_ECC, + SDF_R_INVALID_INPUT_LENGTH); + return 0; + } + + if (!(pkey = sdf_load_ec_public_key((SDF_SESSION *)hSessionHandle, + uiIPKIndex, uiAlgID))) { + SDFerr(SDF_F_SDF_INTERNALENCRYPT_ECC, ERR_R_GMAPI_LIB); + goto end; + } + + (void)SM2_ENC_PARAMS_init_with_recommended(¶ms); + + /* we need to use the EVP_PKEY interface to use ENGINE ?*/ + if (!(cv = SM2_do_encrypt(¶ms, pucData, (size_t)uiDataLength, + EVP_PKEY_get0_EC_KEY(pkey)))) { + SDFerr(SDF_F_SDF_INTERNALENCRYPT_ECC, ERR_R_EC_LIB); + goto end; + } + + if (!SM2_CIPHERTEXT_VALUE_get_ECCCipher(cv, pucEncData)) { + SDFerr(SDF_F_SDF_INTERNALENCRYPT_ECC, ERR_R_EC_LIB); + goto end; + } + + ret = SDR_OK; + +end: + EVP_PKEY_free(pkey); + SM2_CIPHERTEXT_VALUE_free(cv); + return ret; +} + +int SDF_InternalDecrypt_ECC( + void *hSessionHandle, + unsigned int uiISKIndex, + unsigned int uiAlgID, + ECCCipher *pucEncData, + unsigned char *pucData, + unsigned int *puiDataLength) +{ + int ret = 0; + EVP_PKEY *pkey = NULL; + + + /* check arguments */ + if (!hSessionHandle || !pucEncData || !pucData || !puiDataLength) { + SDFerr(SDF_F_SDF_INTERNALDECRYPT_ECC, + ERR_R_PASSED_NULL_PARAMETER); + return SDR_UNKNOWERR; + } + + if (!(pkey = sdf_load_ec_private_key(hSessionHandle, + uiISKIndex, uiAlgID))) { + SDFerr(SDF_F_SDF_INTERNALDECRYPT_ECC, ERR_R_GMAPI_LIB); + goto end; + } + + +end: + return 0; +} + diff --git a/crypto/sdf/sdf_enc.c b/crypto/sdf/sdf_enc.c new file mode 100644 index 00000000..9e278944 --- /dev/null +++ b/crypto/sdf/sdf_enc.c @@ -0,0 +1,215 @@ +/* ==================================================================== + * Copyright (c) 2016 The GmSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the GmSSL Project. + * (http://gmssl.org/)" + * + * 4. The name "GmSSL Project" must not be used to endorse or promote + * products derived from this software without prior written + * permission. For written permission, please contact + * guanzhi1980@gmail.com. + * + * 5. Products derived from this software may not be called "GmSSL" + * nor may "GmSSL" appear in their names without prior written + * permission of the GmSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the GmSSL Project + * (http://gmssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE GmSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GmSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES + * LOSS OF USE, DATA, OR PROFITS OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +#include +#include +#include +#include +#include +#include +#include +#include "sdf_lcl.h" + +/* TODO: current max input length is INT_MAX + * we will return error when the input is longer than INT_MAX. + * do not fixed this in GmSSL 2.x, fixed it in the future. + * we can seperate the input to multiple of INT_MAX with multiple upadtes. + */ +/* + * Implement with ENGINE + * as some of the ciphers such as SM1/SSF33 can not be supported by + * software, we can use ENGINEs hoping that such ciphers can be supported. + */ +int SDF_Encrypt( + void *hSessionHandle, + void *hKeyHandle, + unsigned int uiAlgID, + unsigned char *pucIV, + unsigned char *pucData, + unsigned int uiDataLength, + unsigned char *pucEncData, + unsigned int *puiEncDataLength) +{ + int ret = SDR_UNKNOWERR; + SDF_SESSION *session = (SDF_SESSION *)hSessionHandle; + SDF_KEY *key = (SDF_KEY *)hKeyHandle; + EVP_CIPHER_CTX *ctx = NULL; + const EVP_CIPHER *cipher; + unsigned char *p; + int len; + + /* check arguments */ + if (!hSessionHandle || !hKeyHandle || !pucIV || !pucData || !pucEncData + || !puiEncDataLength) { + SDFerr(SDF_F_SDF_ENCRYPT, ERR_R_PASSED_NULL_PARAMETER); + return SDR_UNKNOWERR; + } + if (uiDataLength <= 0 || uiDataLength > INT_MAX) { + SDFerr(SDF_F_SDF_ENCRYPT, SDF_R_INVALID_INPUT_LENGTH); + return SDR_UNKNOWERR; + } + if (*puiEncDataLength < uiDataLength + EVP_MAX_BLOCK_LENGTH * 2) { + SDFerr(SDF_F_SDF_ENCRYPT, SDF_R_BUFFER_TOO_SMALL); + return SDR_UNKNOWERR; + } + + /* parse arguments */ + if (!(cipher = sdf_get_cipher(hSessionHandle, uiAlgID))) { + SDFerr(SDF_F_SDF_ENCRYPT, SDF_R_INVALID_ALGOR); + goto end; + } + if (key->keylen != EVP_CIPHER_key_length(cipher)) { + SDFerr(SDF_F_SDF_ENCRYPT, SDF_R_INVALID_KEY_HANDLE); + goto end; + } + + /* encrypt */ + if (!(ctx = EVP_CIPHER_CTX_new())) { + SDFerr(SDF_F_SDF_ENCRYPT, ERR_R_MALLOC_FAILURE); + goto end; + } + if (!EVP_EncryptInit_ex(ctx, cipher, session->engine, key->key, pucIV)) { + SDFerr(SDF_F_SDF_ENCRYPT, ERR_R_EVP_LIB); + goto end; + } + p = pucEncData; + if (!EVP_EncryptUpdate(ctx, p, &len, pucData, (int)uiDataLength)) { + SDFerr(SDF_F_SDF_ENCRYPT, ERR_R_EVP_LIB); + goto end; + } + p += len; + if (!EVP_EncryptFinal_ex(ctx, p, &len)) { + SDFerr(SDF_F_SDF_ENCRYPT, ERR_R_EVP_LIB); + goto end; + } + p += len; + + /* set return value */ + *puiEncDataLength = p - pucEncData; + ret = SDR_OK; + +end: + EVP_CIPHER_CTX_free(ctx); + return 0; +} + +int SDF_Decrypt( + void *hSessionHandle, + void *hKeyHandle, + unsigned int uiAlgID, + unsigned char *pucIV, + unsigned char *pucEncData, + unsigned int uiEncDataLength, + unsigned char *pucData, + unsigned int *puiDataLength) +{ + int ret = SDR_UNKNOWERR; + SDF_SESSION *session = (SDF_SESSION *)hSessionHandle; + SDF_KEY *key = (SDF_KEY *)hKeyHandle; + const EVP_CIPHER *cipher; + EVP_CIPHER_CTX *ctx = NULL; + unsigned char *p; + int len; + + /* check arguments */ + if (!hSessionHandle || !hKeyHandle || !pucIV || !pucEncData || + !pucData || !puiDataLength) { + SDFerr(SDF_F_SDF_DECRYPT, ERR_R_PASSED_NULL_PARAMETER); + return SDR_UNKNOWERR; + } + if (uiEncDataLength <= 0 || uiEncDataLength > INT_MAX) { + SDFerr(SDF_F_SDF_DECRYPT, SDF_R_INVALID_INPUT_LENGTH); + return SDR_UNKNOWERR; + } + if (*puiDataLength < uiEncDataLength) { + SDFerr(SDF_F_SDF_DECRYPT, SDF_R_BUFFER_TOO_SMALL); + return SDR_UNKNOWERR; + } + + /* parse arguments */ + if (!(cipher = sdf_get_cipher(hSessionHandle, uiAlgID))) { + SDFerr(SDF_F_SDF_DECRYPT, SDF_R_INVALID_ALGOR); + goto end; + } + if (key->keylen != EVP_CIPHER_key_length(cipher)) { + SDFerr(SDF_F_SDF_DECRYPT, SDF_R_INVALID_KEY_HANDLE); + goto end; + } + + /* decrypt */ + if (!(ctx = EVP_CIPHER_CTX_new())) { + SDFerr(SDF_F_SDF_DECRYPT, ERR_R_MALLOC_FAILURE); + goto end; + } + if (!EVP_DecryptInit_ex(ctx, cipher, session->engine, key->key, pucIV)) { + SDFerr(SDF_F_SDF_DECRYPT, ERR_R_EVP_LIB); + goto end; + } + p = pucData; + if (!EVP_DecryptUpdate(ctx, p, &len, pucEncData, + (int)uiEncDataLength)) { + SDFerr(SDF_F_SDF_DECRYPT, ERR_R_EVP_LIB); + goto end; + } + p += len; + if (!EVP_DecryptFinal_ex(ctx, p, &len)) { + SDFerr(SDF_F_SDF_DECRYPT, ERR_R_EVP_LIB); + goto end; + } + p += len; + + /* set return value */ + *puiDataLength = p - pucEncData; + ret =SDR_OK; + +end: + EVP_CIPHER_CTX_free(ctx); + return ret; +} + diff --git a/crypto/sdf/sdf_err.c b/crypto/sdf/sdf_err.c new file mode 100644 index 00000000..887c5c02 --- /dev/null +++ b/crypto/sdf/sdf_err.c @@ -0,0 +1,129 @@ +/* + * Generated by util/mkerr.pl DO NOT EDIT + * Copyright 1995-2017 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include +#include + +/* BEGIN ERROR CODES */ +#ifndef OPENSSL_NO_ERR + +# define ERR_FUNC(func) ERR_PACK(ERR_LIB_SDF,func,0) +# define ERR_REASON(reason) ERR_PACK(ERR_LIB_SDF,0,reason) + +static ERR_STRING_DATA SDF_str_functs[] = { + {ERR_FUNC(SDF_F_SDF_CALCULATEMAC), "SDF_CalculateMAC"}, + {ERR_FUNC(SDF_F_SDF_CLOSEDEVICE), "SDF_CloseDevice"}, + {ERR_FUNC(SDF_F_SDF_CLOSESESSION), "SDF_CloseSession"}, + {ERR_FUNC(SDF_F_SDF_DECODE_EC_SIGNATURE), "sdf_decode_ec_signature"}, + {ERR_FUNC(SDF_F_SDF_DECRYPT), "SDF_Decrypt"}, + {ERR_FUNC(SDF_F_SDF_ENCODE_EC_SIGNATURE), "sdf_encode_ec_signature"}, + {ERR_FUNC(SDF_F_SDF_ENCRYPT), "SDF_Encrypt"}, + {ERR_FUNC(SDF_F_SDF_EXPORTENCPUBLICKEY_ECC), + "SDF_ExportEncPublicKey_ECC"}, + {ERR_FUNC(SDF_F_SDF_EXPORTENCPUBLICKEY_RSA), + "SDF_ExportEncPublicKey_RSA"}, + {ERR_FUNC(SDF_F_SDF_EXPORTSIGNPUBLICKEY_ECC), + "SDF_ExportSignPublicKey_ECC"}, + {ERR_FUNC(SDF_F_SDF_EXPORTSIGNPUBLICKEY_RSA), + "SDF_ExportSignPublicKey_RSA"}, + {ERR_FUNC(SDF_F_SDF_EXTERNALDECRYPT_ECC), "SDF_ExternalDecrypt_ECC"}, + {ERR_FUNC(SDF_F_SDF_EXTERNALENCRYPT_ECC), "SDF_ExternalEncrypt_ECC"}, + {ERR_FUNC(SDF_F_SDF_EXTERNALPRIVATEKEYOPERATION_RSA), + "SDF_ExternalPrivateKeyOperation_RSA"}, + {ERR_FUNC(SDF_F_SDF_EXTERNALPUBLICKEYOPERATION_RSA), + "SDF_ExternalPublicKeyOperation_RSA"}, + {ERR_FUNC(SDF_F_SDF_EXTERNALSIGN_ECC), "SDF_ExternalSign_ECC"}, + {ERR_FUNC(SDF_F_SDF_EXTERNALVERIFY_ECC), "SDF_ExternalVerify_ECC"}, + {ERR_FUNC(SDF_F_SDF_GENERATEKEYPAIR_ECC), "SDF_GenerateKeyPair_ECC"}, + {ERR_FUNC(SDF_F_SDF_GENERATEKEYPAIR_RSA), "SDF_GenerateKeyPair_RSA"}, + {ERR_FUNC(SDF_F_SDF_GENERATEKEYWITHEPK_ECC), + "SDF_GenerateKeyWithEPK_ECC"}, + {ERR_FUNC(SDF_F_SDF_GENERATEKEYWITHEPK_RSA), + "SDF_GenerateKeyWithEPK_RSA"}, + {ERR_FUNC(SDF_F_SDF_GENERATEKEYWITHIPK_ECC), + "SDF_GenerateKeyWithIPK_ECC"}, + {ERR_FUNC(SDF_F_SDF_GENERATEKEYWITHIPK_RSA), + "SDF_GenerateKeyWithIPK_RSA"}, + {ERR_FUNC(SDF_F_SDF_GENERATERANDOM), "SDF_GenerateRandom"}, + {ERR_FUNC(SDF_F_SDF_GETDEVICEINFO), "SDF_GetDeviceInfo"}, + {ERR_FUNC(SDF_F_SDF_GETPRIVATEKEYACCESSRIGHT), + "SDF_GetPrivateKeyAccessRight"}, + {ERR_FUNC(SDF_F_SDF_GET_CIPHER), "sdf_get_cipher"}, + {ERR_FUNC(SDF_F_SDF_GET_DIGEST), "sdf_get_digest"}, + {ERR_FUNC(SDF_F_SDF_HASHFINAL), "SDF_HashFinal"}, + {ERR_FUNC(SDF_F_SDF_HASHINIT), "SDF_HashInit"}, + {ERR_FUNC(SDF_F_SDF_HASHUPDATE), "SDF_HashUpdate"}, + {ERR_FUNC(SDF_F_SDF_IMPORTKEY), "SDF_ImportKey"}, + {ERR_FUNC(SDF_F_SDF_IMPORTKEYWITHISK_ECC), "SDF_ImportKeyWithISK_ECC"}, + {ERR_FUNC(SDF_F_SDF_IMPORTKEYWITHISK_RSA), "SDF_ImportKeyWithISK_RSA"}, + {ERR_FUNC(SDF_F_SDF_INTERNALDECRYPT_ECC), "SDF_InternalDecrypt_ECC"}, + {ERR_FUNC(SDF_F_SDF_INTERNALENCRYPT_ECC), "SDF_InternalEncrypt_ECC"}, + {ERR_FUNC(SDF_F_SDF_INTERNALPRIVATEKEYOPERATION_RSA), + "SDF_InternalPrivateKeyOperation_RSA"}, + {ERR_FUNC(SDF_F_SDF_INTERNALPUBLICKEYOPERATION_RSA), + "SDF_InternalPublicKeyOperation_RSA"}, + {ERR_FUNC(SDF_F_SDF_INTERNALSIGN_ECC), "SDF_InternalSign_ECC"}, + {ERR_FUNC(SDF_F_SDF_INTERNALVERIFY_ECC), "SDF_InternalVerify_ECC"}, + {ERR_FUNC(SDF_F_SDF_LOAD_EC_PRIVATE_KEY), "sdf_load_ec_private_key"}, + {ERR_FUNC(SDF_F_SDF_LOAD_EC_PUBLIC_KEY), "sdf_load_ec_public_key"}, + {ERR_FUNC(SDF_F_SDF_LOAD_RSA_PRIVATE_KEY), "sdf_load_rsa_private_key"}, + {ERR_FUNC(SDF_F_SDF_LOAD_RSA_PUBLIC_KEY), "sdf_load_rsa_public_key"}, + {ERR_FUNC(SDF_F_SDF_OPENDEVICE), "SDF_OpenDevice"}, + {ERR_FUNC(SDF_F_SDF_OPENSESSION), "SDF_OpenSession"}, + {ERR_FUNC(SDF_F_SDF_RELEASEPRIVATEKEYACCESSRIGHT), + "SDF_ReleasePrivateKeyAccessRight"}, + {0, NULL} +}; + +static ERR_STRING_DATA SDF_str_reasons[] = { + {ERR_REASON(SDF_R_BUFFER_TOO_SMALL), "buffer too small"}, + {ERR_REASON(SDF_R_BUUTER_TOO_SMALL), "buuter too small"}, + {ERR_REASON(SDF_R_CBCMAC_FAILURE), "cbcmac failure"}, + {ERR_REASON(SDF_R_CMAC_FAILURE), "cmac failure"}, + {ERR_REASON(SDF_R_COMPUTE_SM2_ID_FAILURE), "compute sm2 id failure"}, + {ERR_REASON(SDF_R_ENGINE_LOAD_KEY_FAILURE), "engine load key failure"}, + {ERR_REASON(SDF_R_GET_PRIVATE_KEY_FAILED), "get private key failed"}, + {ERR_REASON(SDF_R_GET_PUBLIC_KEY_FAILED), "get public key failed"}, + {ERR_REASON(SDF_R_INVALID_ALGOR), "invalid algor"}, + {ERR_REASON(SDF_R_INVALID_DEVICE_HANDLE), "invalid device handle"}, + {ERR_REASON(SDF_R_INVALID_EC_CIPHERTEXT), "invalid ec ciphertext"}, + {ERR_REASON(SDF_R_INVALID_EC_PRIVATE_KEY), "invalid ec private key"}, + {ERR_REASON(SDF_R_INVALID_EC_PUBLIC_KEY), "invalid ec public key"}, + {ERR_REASON(SDF_R_INVALID_INPUT_LENGTH), "invalid input length"}, + {ERR_REASON(SDF_R_INVALID_KEY_HANDLE), "invalid key handle"}, + {ERR_REASON(SDF_R_INVALID_KEY_INDEX), "invalid key index"}, + {ERR_REASON(SDF_R_INVALID_KEY_LENGTH), "invalid key length"}, + {ERR_REASON(SDF_R_INVALID_KEY_USAGE), "invalid key usage"}, + {ERR_REASON(SDF_R_INVALID_LENGTH), "invalid length"}, + {ERR_REASON(SDF_R_INVALID_OPERATION_STATE), "invalid operation state"}, + {ERR_REASON(SDF_R_INVALID_PASSWORD_LENGTH), "invalid password length"}, + {ERR_REASON(SDF_R_INVALID_SESSION), "invalid session"}, + {ERR_REASON(SDF_R_INVALID_SESSION_HANDLE), "invalid session handle"}, + {ERR_REASON(SDF_R_KEY_TYPE_NOT_MATCH), "key type not match"}, + {ERR_REASON(SDF_R_LOAD_ENGINE_FAILURE), "load engine failure"}, + {ERR_REASON(SDF_R_RANDOM_FAILURE), "random failure"}, + {ERR_REASON(SDF_R_SDF_SESSION_NO_ENGINE), "sdf session no engine"}, + {0, NULL} +}; + +#endif + +int ERR_load_SDF_strings(void) +{ +#ifndef OPENSSL_NO_ERR + + if (ERR_func_error_string(SDF_str_functs[0].error) == NULL) { + ERR_load_strings(0, SDF_str_functs); + ERR_load_strings(0, SDF_str_reasons); + } +#endif + return 1; +} diff --git a/crypto/sdf/sdf_errstr.c b/crypto/sdf/sdf_errstr.c new file mode 100644 index 00000000..add89a03 --- /dev/null +++ b/crypto/sdf/sdf_errstr.c @@ -0,0 +1,99 @@ +/* ==================================================================== + * Copyright (c) 2016 The GmSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the GmSSL Project. + * (http://gmssl.org/)" + * + * 4. The name "GmSSL Project" must not be used to endorse or promote + * products derived from this software without prior written + * permission. For written permission, please contact + * guanzhi1980@gmail.com. + * + * 5. Products derived from this software may not be called "GmSSL" + * nor may "GmSSL" appear in their names without prior written + * permission of the GmSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the GmSSL Project + * (http://gmssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE GmSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GmSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +#include +#include +#include "../../e_os.h" + +static ERR_STRING_DATA sdf_errstr[] = { + { SDR_OK, "Success" }, + { SDR_BASE, "Base" }, + { SDR_UNKNOWERR, "Unknown error" }, + { SDR_NOTSUPPORT, "Not supported" }, + { SDR_COMMFAIL, "Commnunication failure" }, + { SDR_HARDFAIL, "Hardware failure" }, + { SDR_OPENDEVICE, "Open device" }, + { SDR_OPENSESSION, "Open session" }, + { SDR_PARDENY, "Private key access denied (for index 0)" }, + { SDR_KEYNOTEXIST, "Key not exist" }, + { SDR_ALGNOTSUPPOT, "Algorithm not supported" }, + { SDR_ALGMODNOTSUPPORT, "Algorithm mode not supported" }, + { SDR_PKOPERR, "Public key operation error" }, + { SDR_SKOPERR, "Private key operation error" }, + { SDR_SIGNERR, "Signature generation error" }, + { SDR_VERIFYERR, "Singature verification error" }, + { SDR_SYMOPERR, "Symmetric encryption error" }, + { SDR_STEPERR, "Multi-step operation error" }, + { SDR_FILESIZEERR, "File size error" }, + { SDR_FILENOEXIST, "File not exist" }, + { SDR_FILEOFSERR, "File offset error" }, + { SDR_KEYTYPEERR, "Key type error" }, + { SDR_KEYERR, "Key error" }, + { SDR_ENCDATAERR, "ECC encrypted data error" }, + { SDR_RANDERR, "Random number generator error" }, + { SDR_PRKRERR, "Private key privilege error" }, + { SDR_MACERR, "MAC computation error" }, + { SDR_FILEEXSITS, "File already exist" }, + { SDR_FILEWERR, "File write error" }, + { SDR_NOBUFFER, "No buffer" }, + { SDR_INARGERR, "Input argument error" }, + { SDR_OUTARGERR, "Output argument error" }, +}; + +const char *SDF_GetErrorString(int err) +{ + int i; + for (i = 0; i < OSSL_NELEM(sdf_errstr); i++) { + if (err == sdf_errstr[i].error) { + return sdf_errstr[i].string; + } + } + return "(undef)"; +} + diff --git a/crypto/sdf/sdf_ext.c b/crypto/sdf/sdf_ext.c new file mode 100644 index 00000000..f973eacc --- /dev/null +++ b/crypto/sdf/sdf_ext.c @@ -0,0 +1,238 @@ +/* ==================================================================== + * Copyright (c) 2016 The GmSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the GmSSL Project. + * (http://gmssl.org/)" + * + * 4. The name "GmSSL Project" must not be used to endorse or promote + * products derived from this software without prior written + * permission. For written permission, please contact + * guanzhi1980@gmail.com. + * + * 5. Products derived from this software may not be called "GmSSL" + * nor may "GmSSL" appear in their names without prior written + * permission of the GmSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the GmSSL Project + * (http://gmssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE GmSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GmSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES + * LOSS OF USE, DATA, OR PROFITS OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +#include +#include +#include +#include +#include +#include "sdf_lcl.h" + +int SDF_PrintDeviceInfo(FILE *fp, DEVICEINFO *devInfo) +{ + char issuerName[41]; + char deviceName[17]; + char deviceSerial[17]; + + /* IssuerName */ + memcpy(issuerName, devInfo->IssuerName, 40); + issuerName[40] = 0; + fprintf(fp, "IssuerName = %s\n", issuerName); + + /* DeviceName */ + memcpy(deviceName, devInfo->DeviceName, 16); + deviceName[16] = 0; + fprintf(fp, "DeviceName = %s\n", deviceName); + + /* DeviceSerial */ + memcpy(deviceSerial, devInfo->DeviceSerial, 16); + deviceSerial[16] = 0; + fprintf(fp, "DeviceSerial = %s\n", deviceSerial); + + /* DeviceVersion */ + fprintf(fp, "DeviceVersion = 0x%08X\n", devInfo->DeviceVersion); + + /* StandardVersion */ + fprintf(fp, "StandardVersion = 0x%08X\n", devInfo->StandardVersion); + + /* AsymAlgAbility */ + fputs("AsymAlgAbility[0] =", fp); + if (devInfo->AsymAlgAbility[0] & SGD_RSA) { + fputs(" RSA", fp); + } + if (devInfo->AsymAlgAbility[0] & SGD_SM2) { + fputs(" SM2", fp); + } + fputs("\n", fp); + fprintf(fp, "AsymAlgAbility[1] = 0x%08X\n", devInfo->AsymAlgAbility[1]); + + /* SymAlgAbility */ + fputs("SymAlgAbility =", fp); + if (devInfo->SymAlgAbility & SGD_SM1) + fputs(" SM1", fp); + if (devInfo->SymAlgAbility & SGD_SSF33) + fputs(" SSF33", fp); + if (devInfo->SymAlgAbility & SGD_SM4) + fputs(" SM4", fp); + if (devInfo->SymAlgAbility & SGD_ZUC) + fputs(" ZUC", fp); + fputs("\n", fp); + + /* HashAlgAbility */ + fputs("HashAlgAbility =", fp); + if (devInfo->HashAlgAbility & SGD_SM3) + fputs(" SM3", fp); + if (devInfo->HashAlgAbility & SGD_SHA1) + fputs(" SHA1", fp); + if (devInfo->HashAlgAbility & SGD_SHA256) + fputs(" SHA256", fp); + fputs("\n", fp); + + /* BufferSize */ + fprintf(fp, "BufferSize = %u\n", devInfo->BufferSize); + + return SDR_OK; +} + +int SDF_PrintRSAPublicKey(FILE *fp, RSArefPublicKey *pk) +{ + int i; + + /* bits */ + (void)fprintf(fp, "bits = %u\n", pk->bits); + + /* m */ + (void)fputs("m = ", fp); + for (i = 0; i < RSAref_MAX_LEN; i++) { + (void)fprintf(fp, "%02X", pk->m[i]); + } + (void)fputs("\n", fp); + + /* e */ + (void)fputs("e = ", fp); + for (i = 0; i < RSAref_MAX_LEN; i++) { + (void)fprintf(fp, "%02X", pk->e[i]); + } + (void)fputs("\n", fp); + + return 1; +} + +int SDF_PrintRSAPrivateKey(FILE *fp, RSArefPrivateKey *sk) +{ + return 0; +} + +int SDF_PrintECCPublicKey(FILE *fp, ECCrefPublicKey *pk) +{ + int i; + + /* bits */ + (void)fprintf(fp, "bits = %u\n", pk->bits); + + /* x */ + (void)fputs("x = ", fp); + for (i = 0; i < ECCref_MAX_LEN; i++) { + (void)fprintf(fp, "%02X", pk->x[i]); + } + (void)fputs("\n", fp); + + /* y */ + (void)fputs("y = ", fp); + for (i = 0; i < ECCref_MAX_LEN; i++) { + (void)fprintf(fp, "%02X", pk->y[i]); + } + (void)fputs("\n", fp); + + return 1; +} + +int SDF_PrintECCPrivateKey(FILE *fp, ECCrefPrivateKey *pk) +{ + return 0; +} + +int SDF_PrintECCCipher(FILE *fp, ECCCipher *cipher) +{ + int i; + + /* x */ + (void)fputs("x = ", fp); + for (i = 0; i < ECCref_MAX_LEN; i++) { + (void)fprintf(fp, "%02X", cipher->x[i]); + } + (void)fputs("\n", fp); + + /* y */ + (void)fputs("y = ", fp); + for (i = 0; i < ECCref_MAX_LEN; i++) { + (void)fprintf(fp, "%02X", cipher->y[i]); + } + (void)fputs("\n", fp); + + /* M */ + (void)fputs("M = ", fp); + for (i = 0; i < 32; i++) { + (void)fprintf(fp, "%02X", cipher->M[i]); + } + (void)fputs("\n", fp); + + /* L */ + (void)fprintf(fp, "L = %u\n", cipher->L); + + /* C */ + for (i = 0; i < cipher->L; i++) { + (void)fprintf(fp, "%02X", cipher->C[i]); + } + (void)fputs("\n", fp); + + return 1; +} + +int SDF_PrintECCSignature(FILE *fp, ECCSignature *sig) +{ + int i; + + /* r */ + (void)fputs("r = ", fp); + for (i = 0; i < ECCref_MAX_LEN; i++) { + (void)fprintf(fp, "%02X", sig->r[i]); + } + (void)fputs("\n", fp); + + /* s */ + (void)fputs("s = ", fp); + for (i = 0; i < ECCref_MAX_LEN; i++) { + (void)fprintf(fp, "%02X", sig->s[i]); + } + (void)fputs("\n", fp); + + return 1; +} + diff --git a/crypto/sdf/sdf_file.c b/crypto/sdf/sdf_file.c new file mode 100644 index 00000000..cc714698 --- /dev/null +++ b/crypto/sdf/sdf_file.c @@ -0,0 +1,89 @@ +/* ==================================================================== + * Copyright (c) 2016 The GmSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the GmSSL Project. + * (http://gmssl.org/)" + * + * 4. The name "GmSSL Project" must not be used to endorse or promote + * products derived from this software without prior written + * permission. For written permission, please contact + * guanzhi1980@gmail.com. + * + * 5. Products derived from this software may not be called "GmSSL" + * nor may "GmSSL" appear in their names without prior written + * permission of the GmSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the GmSSL Project + * (http://gmssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE GmSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GmSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES + * LOSS OF USE, DATA, OR PROFITS OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +#include + +int SDF_CreateFile( + void *hSessionHandle, + unsigned char *pucFileName, + unsigned int uiNameLen, + unsigned int uiFileSize) +{ + return SDR_NOTSUPPORT; +} + +int SDF_ReadFile( + void *hSessionHandle, + unsigned char *pucFileName, + unsigned int uiNameLen, + unsigned int uiOffset, + unsigned int *puiReadLength, + unsigned char *pucBuffer) +{ + return SDR_NOTSUPPORT; +} + +int SDF_WriteFile( + void *hSessionHandle, + unsigned char *pucFileName, + unsigned int uiNameLen, + unsigned int uiOffset, + unsigned int uiWriteLength, + unsigned char *pucBuffer) +{ + return SDR_NOTSUPPORT; +} + +int SDF_DeleteFile( + void *hSessionHandle, + unsigned char *pucFileName, + unsigned int uiNameLen) +{ + return SDR_NOTSUPPORT; +} diff --git a/crypto/sdf/sdf_hash.c b/crypto/sdf/sdf_hash.c new file mode 100644 index 00000000..ff106777 --- /dev/null +++ b/crypto/sdf/sdf_hash.c @@ -0,0 +1,217 @@ +/* ==================================================================== + * Copyright (c) 2016 The GmSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the GmSSL Project. + * (http://gmssl.org/)" + * + * 4. The name "GmSSL Project" must not be used to endorse or promote + * products derived from this software without prior written + * permission. For written permission, please contact + * guanzhi1980@gmail.com. + * + * 5. Products derived from this software may not be called "GmSSL" + * nor may "GmSSL" appear in their names without prior written + * permission of the GmSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the GmSSL Project + * (http://gmssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE GmSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GmSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES + * LOSS OF USE, DATA, OR PROFITS OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +#include +#include +#include +#include +#include +#include +#include +#include "sdf_lcl.h" + +int SDF_HashInit( + void *hSessionHandle, + unsigned int uiAlgID, + ECCrefPublicKey *pucPublicKey, + unsigned char *pucID, + unsigned int uiIDLength) +{ + int ret = SDR_UNKNOWERR; + SDF_SESSION *session = (SDF_SESSION *)hSessionHandle; + EVP_MD_CTX *md_ctx = NULL; + const EVP_MD *md; + + /* check arguments */ + if (!hSessionHandle) { + SDFerr(SDF_F_SDF_HASHINIT, ERR_R_PASSED_NULL_PARAMETER); + return SDR_INARGERR; + } + if (pucID && (uiIDLength <= 0 || uiIDLength > INT_MAX)) { + SDFerr(SDF_F_SDF_HASHINIT, SDF_R_INVALID_LENGTH); + return SDR_INARGERR; + } + if (session->md_ctx) { + SDFerr(SDF_F_SDF_HASHINIT, SDF_R_INVALID_OPERATION_STATE); + return SDR_INARGERR; + } + if (!(md = EVP_get_digestbysgd(uiAlgID))) { + SDFerr(SDF_F_SDF_HASHINIT, SDF_R_INVALID_ALGOR); + return SDR_INARGERR; + } + + /* malloc and init */ + if (!(md_ctx = EVP_MD_CTX_new())) { + SDFerr(SDF_F_SDF_HASHINIT, ERR_R_MALLOC_FAILURE); + ret = SDR_NOBUFFER; + goto end; + } + if (!EVP_DigestInit_ex(md_ctx, md, session->engine)) { + SDFerr(SDF_F_SDF_HASHINIT, ERR_R_EVP_LIB); + ret = SDR_UNKNOWERR; + goto end; + } + + /* compute ZA and update */ + if (pucPublicKey) { + EC_KEY *ec_key = NULL; + unsigned char za[EVP_MAX_MD_SIZE]; + size_t zalen = sizeof(za); + char *id; + size_t idlen; + + if (pucID) { + id = (char *)pucID; + idlen = uiIDLength; + } else { + id = SM2_DEFAULT_ID; + idlen = strlen(SM2_DEFAULT_ID); + } + + if (!(ec_key = EC_KEY_new_from_ECCrefPublicKey(pucPublicKey))) { + SDFerr(SDF_F_SDF_HASHINIT, ERR_R_GMAPI_LIB); + ret = SDR_INARGERR; + goto end; + } + + if (!SM2_compute_id_digest(md, id, idlen, za, &zalen, ec_key)) { + SDFerr(SDF_F_SDF_HASHINIT, + SDF_R_COMPUTE_SM2_ID_FAILURE); + ret = SDR_UNKNOWERR; + EC_KEY_free(ec_key); + goto end; + } + + EC_KEY_free(ec_key); + + if (!EVP_DigestUpdate(md_ctx, za, zalen)) { + SDFerr(SDF_F_SDF_HASHINIT, ERR_R_EVP_LIB); + ret = SDR_UNKNOWERR; + goto end; + } + } + + session->md_ctx = md_ctx; + md_ctx = NULL; + ret = SDR_OK; + +end: + EVP_MD_CTX_free(md_ctx); + return ret; +} + +int SDF_HashUpdate( + void *hSessionHandle, + unsigned char *pucData, + unsigned int uiDataLength) +{ + SDF_SESSION *session = (SDF_SESSION *)hSessionHandle; + + /* check arguments */ + if (!hSessionHandle || !pucData) { + SDFerr(SDF_F_SDF_HASHUPDATE, ERR_R_PASSED_NULL_PARAMETER); + return SDR_INARGERR; + } + if (session->magic != SDF_SESSION_MAGIC) { + SDFerr(SDF_F_SDF_HASHUPDATE, SDF_R_INVALID_SESSION); + return SDR_INARGERR; + } + if (!session->md_ctx) { + SDFerr(SDF_F_SDF_HASHUPDATE, SDF_R_INVALID_OPERATION_STATE); + return SDR_INARGERR; + } + + /* update */ + if (!EVP_DigestUpdate(session->md_ctx, pucData, (size_t)uiDataLength)) { + SDFerr(SDF_F_SDF_HASHUPDATE, ERR_R_EVP_LIB); + return SDR_UNKNOWERR; + } + + return SDR_OK; +} + +int SDF_HashFinal( + void *hSessionHandle, + unsigned char *pucHash, + unsigned int *puiHashLength) +{ + SDF_SESSION *session = (SDF_SESSION *)hSessionHandle; + + /* check arguments */ + if (!hSessionHandle || !pucHash || !puiHashLength) { + SDFerr(SDF_F_SDF_HASHFINAL, ERR_R_PASSED_NULL_PARAMETER); + return SDR_INARGERR; + } + if (session->magic != SDF_SESSION_MAGIC) { + SDFerr(SDF_F_SDF_HASHFINAL, SDF_R_INVALID_SESSION); + return SDR_INARGERR; + } + if (!session->md_ctx) { + SDFerr(SDF_F_SDF_HASHFINAL, + SDF_R_INVALID_OPERATION_STATE); + return SDR_INARGERR; + } + if (*puiHashLength < EVP_MD_CTX_size(session->md_ctx)) { + SDFerr(SDF_F_SDF_HASHFINAL, SDF_R_BUFFER_TOO_SMALL); + return SDR_INARGERR; + } + + /* digest final */ + if (!EVP_DigestFinal_ex(session->md_ctx, pucHash, puiHashLength)) { + SDFerr(SDF_F_SDF_HASHFINAL, ERR_R_EVP_LIB); + return SDR_UNKNOWERR; + } + + /* note: only success, the md_ctx can be free-ed */ + EVP_MD_CTX_free(session->md_ctx); + session->md_ctx = NULL; + + return SDR_OK; +} + diff --git a/crypto/sdf/sdf_key.c b/crypto/sdf/sdf_key.c new file mode 100644 index 00000000..a302e190 --- /dev/null +++ b/crypto/sdf/sdf_key.c @@ -0,0 +1,97 @@ +/* ==================================================================== + * Copyright (c) 2016 The GmSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the GmSSL Project. + * (http://gmssl.org/)" + * + * 4. The name "GmSSL Project" must not be used to endorse or promote + * products derived from this software without prior written + * permission. For written permission, please contact + * guanzhi1980@gmail.com. + * + * 5. Products derived from this software may not be called "GmSSL" + * nor may "GmSSL" appear in their names without prior written + * permission of the GmSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the GmSSL Project + * (http://gmssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE GmSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GmSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES + * LOSS OF USE, DATA, OR PROFITS OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ +/* + * In the standard GM/T 0018, the value of `uiKeyIndex` should start from 1, + * and the maximum value is defined by the vendor. + * The password length should be at least 8-byte. + */ + +#include +#include +#include +#include +#include +#include +#include +#include "sdf_lcl.h" + +int SDF_GenerateKeyWithKEK( + void *hSessionHandle, + unsigned int uiKeyBits, + unsigned int uiAlgID, + unsigned int uiKEKIndex, + unsigned char *pucKey, + unsigned int *puiKeyLength, + void **phKeyHandle) +{ + return SDR_NOTSUPPORT; +} + +int SDF_ImportKeyWithKEK( + void *hSessionHandle, + unsigned int uiAlgID, + unsigned int uiKEKIndex, + unsigned char *pucKey, + unsigned int uiKeyLength, + void **phKeyHandle) +{ + /* dont support this in GmSSL 2.x */ + return SDR_NOTSUPPORT; +} + +/* the destroy operation will always success! */ +int SDF_DestroyKey( + void *hSessionHandle, + void *hKeyHandle) +{ + SDF_KEY *key = (SDF_KEY *)hKeyHandle; + OPENSSL_clear_free(key, sizeof(*key)); + return SDR_OK; +} + diff --git a/crypto/sdf/sdf_key2.c b/crypto/sdf/sdf_key2.c new file mode 100644 index 00000000..528a0244 --- /dev/null +++ b/crypto/sdf/sdf_key2.c @@ -0,0 +1,99 @@ +/* ==================================================================== + * Copyright (c) 2016 The GmSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the GmSSL Project. + * (http://gmssl.org/)" + * + * 4. The name "GmSSL Project" must not be used to endorse or promote + * products derived from this software without prior written + * permission. For written permission, please contact + * guanzhi1980@gmail.com. + * + * 5. Products derived from this software may not be called "GmSSL" + * nor may "GmSSL" appear in their names without prior written + * permission of the GmSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the GmSSL Project + * (http://gmssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE GmSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GmSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES + * LOSS OF USE, DATA, OR PROFITS OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +#include +#include +#include +#include +#include +#include +#include +#include "sdf_lcl.h" + +int SDF_ImportKey( + void *hSessionHandle, + unsigned char *pucKey, + unsigned int uiKeyLength, + void **phKeyHandle) +{ + int ret = 0; + SDF_KEY *key = NULL; + + /* check arguments */ + if (!hSessionHandle || !pucKey || !phKeyHandle) { + SDFerr(SDF_F_SDF_IMPORTKEY, + ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + if (uiKeyLength <= 0 || uiKeyLength > EVP_MAX_KEY_LENGTH) { + SDFerr(SDF_F_SDF_IMPORTKEY, + SDF_R_INVALID_KEY_LENGTH); + return 0; + } + + /* create object */ + if (!(key = OPENSSL_zalloc(sizeof(*key)))) { + SDFerr(SDF_F_SDF_IMPORTKEY, ERR_R_MALLOC_FAILURE); + goto end; + } + + /* copy key data */ + memcpy(key->key, pucKey, uiKeyLength); + key->keylen = uiKeyLength; + + /* set output */ + *phKeyHandle = key; + key = NULL; + ret = SDR_OK; + +end: + OPENSSL_clear_free(key, sizeof(*key)); + return ret; +} + diff --git a/crypto/sdf/sdf_lcl.h b/crypto/sdf/sdf_lcl.h new file mode 100644 index 00000000..3754ddfa --- /dev/null +++ b/crypto/sdf/sdf_lcl.h @@ -0,0 +1,81 @@ +/* ==================================================================== + * Copyright (c) 2016 The GmSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the GmSSL Project. + * (http://gmssl.org/)" + * + * 4. The name "GmSSL Project" must not be used to endorse or promote + * products derived from this software without prior written + * permission. For written permission, please contact + * guanzhi1980@gmail.com. + * + * 5. Products derived from this software may not be called "GmSSL" + * nor may "GmSSL" appear in their names without prior written + * permission of the GmSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the GmSSL Project + * (http://gmssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE GmSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GmSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES + * LOSS OF USE, DATA, OR PROFITS OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + + +#include +#include + +extern char *deviceHandle; + +#define SDF_ENGINE_ID "openssl" +#define SDF_SESSION_MAGIC 0x12345678 + +typedef struct { + uint32_t magic; + char *app; + ENGINE *engine; + char *password[SDF_MAX_KEY_INDEX]; + EVP_MD_CTX *md_ctx; +} SDF_SESSION; + +typedef struct { + unsigned char key[EVP_MAX_KEY_LENGTH]; + unsigned int keylen; +} SDF_KEY; + +const EVP_CIPHER *sdf_get_cipher(SDF_SESSION *session, unsigned int uiAlgoID); +const EVP_MD *sdf_get_digest(SDF_SESSION *session, unsigned int uiAlgoID); +EVP_PKEY *sdf_load_rsa_public_key(SDF_SESSION *session, unsigned int uiKeyIndex, unsigned int uiKeyUsage); +EVP_PKEY *sdf_load_rsa_private_key(SDF_SESSION *session, unsigned int uiKeyIndex, unsigned int uiKeyUsage); +EVP_PKEY *sdf_load_ec_public_key(SDF_SESSION *session, unsigned int uiKeyIndex, unsigned int uiKeyUsage); +EVP_PKEY *sdf_load_ec_private_key(SDF_SESSION *session, unsigned int uiKeyIndex, unsigned int uiKeyUsage); +int sdf_encode_ec_signature(ECCSignature *ref, unsigned char *out, size_t *outlen); +int sdf_decode_ec_signature(ECCSignature *ref, const unsigned char *in, size_t inlen); + + diff --git a/crypto/sdf/sdf_lib.c b/crypto/sdf/sdf_lib.c new file mode 100644 index 00000000..2ff31611 --- /dev/null +++ b/crypto/sdf/sdf_lib.c @@ -0,0 +1,327 @@ +/* ==================================================================== + * Copyright (c) 2016 The GmSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the GmSSL Project. + * (http://gmssl.org/)" + * + * 4. The name "GmSSL Project" must not be used to endorse or promote + * products derived from this software without prior written + * permission. For written permission, please contact + * guanzhi1980@gmail.com. + * + * 5. Products derived from this software may not be called "GmSSL" + * nor may "GmSSL" appear in their names without prior written + * permission of the GmSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the GmSSL Project + * (http://gmssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE GmSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GmSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES + * LOSS OF USE, DATA, OR PROFITS OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +#include +#include +#include +#include +#include +#include "sdf_lcl.h" + +/* + * We always get these objects from engine, hardware-based engine, + * software-based engine with storage, or just ossl default engine. + */ + +const EVP_CIPHER *sdf_get_cipher(SDF_SESSION *session, + unsigned int uiAlgoID) +{ + int nid; + + if (!session->engine) { + SDFerr(SDF_F_SDF_GET_CIPHER, + SDF_R_SDF_SESSION_NO_ENGINE); + return NULL; + } + if ((nid = GMAPI_sgd2ciphernid(uiAlgoID)) == NID_undef) { + SDFerr(SDF_F_SDF_GET_CIPHER, + SDF_R_INVALID_ALGOR); + return NULL; + } + + return ENGINE_get_cipher(session->engine, nid); +} + +const EVP_MD *sdf_get_digest(SDF_SESSION *session, + unsigned int uiAlgoID) +{ + int nid; + + if (!session->engine) { + SDFerr(SDF_F_SDF_GET_DIGEST, + SDF_R_SDF_SESSION_NO_ENGINE); + return NULL; + } + if ((nid = GMAPI_sgd2mdnid(uiAlgoID)) == NID_undef) { + SDFerr(SDF_F_SDF_GET_DIGEST, + SDF_R_INVALID_ALGOR); + return NULL; + } + + return ENGINE_get_digest(session->engine, nid); +} + +/* we assume that the SDF ENGINE implementations follow the same design of + * the SKF key storage model: app/container/keyusage. And we assume the + * session is binded with app, the container is refered by key index, and + * the key usage is the same. So the `key_id` string used for ENGINE is as + * follows: + * "AppName/ContainerNameOrIndex/KeyUsage" + */ +//FIXME: we should change the following 4 functions into 1 and 4 macros +EVP_PKEY *sdf_load_rsa_public_key(SDF_SESSION *session, + unsigned int uiKeyIndex, unsigned int uiKeyUsage) +{ + EVP_PKEY *ret = NULL; + EVP_PKEY *pkey = NULL; + char key_id[256]; + char *app = ""; + char *usage; + + if (!session->engine) { + SDFerr(SDF_F_SDF_LOAD_RSA_PUBLIC_KEY, + SDF_R_SDF_SESSION_NO_ENGINE); + return NULL; + } + if (!(usage = GMAPI_keyusage2str(uiKeyUsage))) { + SDFerr(SDF_F_SDF_LOAD_RSA_PUBLIC_KEY, + SDF_R_INVALID_KEY_USAGE); + return NULL; + } + + snprintf(key_id, sizeof(key_id), "%s/%u/%s", app, uiKeyIndex, usage); + + if (!(pkey = ENGINE_load_public_key(session->engine, key_id, + NULL, NULL))) { + SDFerr(SDF_F_SDF_LOAD_RSA_PUBLIC_KEY, + SDF_R_ENGINE_LOAD_KEY_FAILURE); + goto end; + } + + if (EVP_PKEY_id(pkey) != EVP_PKEY_RSA) { + SDFerr(SDF_F_SDF_LOAD_RSA_PUBLIC_KEY, + SDF_R_KEY_TYPE_NOT_MATCH); + goto end; + } + + ret = pkey; + pkey = NULL; + +end: + EVP_PKEY_free(pkey); + return ret; +} + +EVP_PKEY *sdf_load_rsa_private_key(SDF_SESSION *session, + unsigned int uiKeyIndex, unsigned int uiKeyUsage) +{ + EVP_PKEY *ret = NULL; + EVP_PKEY *pkey = NULL; + char key_id[256]; + char *app = ""; + char *usage; + + if (!session->engine) { + SDFerr(SDF_F_SDF_LOAD_RSA_PRIVATE_KEY, + SDF_R_SDF_SESSION_NO_ENGINE); + return NULL; + } + if (!(usage = GMAPI_keyusage2str(uiKeyUsage))) { + SDFerr(SDF_F_SDF_LOAD_RSA_PRIVATE_KEY, + SDF_R_INVALID_KEY_USAGE); + return NULL; + } + + snprintf(key_id, sizeof(key_id), "%s/%u/%s", app, uiKeyIndex, usage); + + if (!(pkey = ENGINE_load_private_key(session->engine, key_id, + NULL, NULL))) { + SDFerr(SDF_F_SDF_LOAD_RSA_PRIVATE_KEY, + SDF_R_ENGINE_LOAD_KEY_FAILURE); + goto end; + } + + if (EVP_PKEY_id(pkey) != EVP_PKEY_RSA) { + SDFerr(SDF_F_SDF_LOAD_RSA_PRIVATE_KEY, + SDF_R_KEY_TYPE_NOT_MATCH); + goto end; + } + + ret = pkey; + pkey = NULL; + +end: + EVP_PKEY_free(pkey); + return ret; +} + +EVP_PKEY *sdf_load_ec_public_key(SDF_SESSION *session, + unsigned int uiKeyIndex, unsigned int uiKeyUsage) +{ + EVP_PKEY *ret = NULL; + EVP_PKEY *pkey = NULL; + char key_id[256]; + char *app = ""; + char *usage; + + if (!session->engine) { + SDFerr(SDF_F_SDF_LOAD_EC_PUBLIC_KEY, + SDF_R_SDF_SESSION_NO_ENGINE); + return NULL; + } + if (!(usage = GMAPI_keyusage2str(uiKeyUsage))) { + SDFerr(SDF_F_SDF_LOAD_EC_PUBLIC_KEY, + SDF_R_INVALID_KEY_USAGE); + return NULL; + } + + snprintf(key_id, sizeof(key_id), "%s/%u/%s", app, uiKeyIndex, usage); + + if (!(pkey = ENGINE_load_public_key(session->engine, key_id, + NULL, NULL))) { + SDFerr(SDF_F_SDF_LOAD_EC_PUBLIC_KEY, + SDF_R_ENGINE_LOAD_KEY_FAILURE); + goto end; + } + if (EVP_PKEY_id(pkey) != EVP_PKEY_EC) { + SDFerr(SDF_F_SDF_LOAD_EC_PUBLIC_KEY, + SDF_R_KEY_TYPE_NOT_MATCH); + goto end; + } + + ret = pkey; + pkey = NULL; + +end: + EVP_PKEY_free(pkey); + return ret; +} + +EVP_PKEY *sdf_load_ec_private_key(SDF_SESSION *session, + unsigned int uiKeyIndex, unsigned int uiKeyUsage) +{ + EVP_PKEY *ret = NULL; + EVP_PKEY *pkey = NULL; + char key_id[256]; + char *app = ""; + char *usage; + + if (!session->engine) { + SDFerr(SDF_F_SDF_LOAD_EC_PRIVATE_KEY, + SDF_R_SDF_SESSION_NO_ENGINE); + return NULL; + } + if (!(usage = GMAPI_keyusage2str(uiKeyUsage))) { + SDFerr(SDF_F_SDF_LOAD_EC_PRIVATE_KEY, + SDF_R_INVALID_KEY_USAGE); + return NULL; + } + + snprintf(key_id, sizeof(key_id), "%s/%u/%s", app, uiKeyIndex, usage); + + if (!(pkey = ENGINE_load_private_key(session->engine, key_id, + NULL, NULL))) { + SDFerr(SDF_F_SDF_LOAD_EC_PRIVATE_KEY, + SDF_R_ENGINE_LOAD_KEY_FAILURE); + goto end; + } + if (EVP_PKEY_id(pkey) != EVP_PKEY_EC) { + SDFerr(SDF_F_SDF_LOAD_EC_PRIVATE_KEY, + SDF_R_KEY_TYPE_NOT_MATCH); + goto end; + } + + ret = pkey; + pkey = NULL; + +end: + EVP_PKEY_free(pkey); + return ret; +} + +int sdf_encode_ec_signature(ECCSignature *ref, unsigned char *out, + size_t *outlen) +{ + int ret = 0; + ECDSA_SIG *sig = NULL; + unsigned char *p; + int len; + + if (!(sig = ECDSA_SIG_new_from_ECCSignature(ref))) { + SDFerr(SDF_F_SDF_ENCODE_EC_SIGNATURE, ERR_R_GMAPI_LIB); + goto end; + } + + p = out; + if ((len = i2d_ECDSA_SIG(sig, &p)) <= 0) { + SDFerr(SDF_F_SDF_ENCODE_EC_SIGNATURE, ERR_R_EC_LIB); + goto end; + } + + ret = 1; + +end: + ECDSA_SIG_free(sig); + return ret; +} + +int sdf_decode_ec_signature(ECCSignature *ref, const unsigned char *in, + size_t inlen) +{ + int ret = 0; + ECDSA_SIG *sig = NULL; + const unsigned char *p; + + p = in; + if (!(sig = d2i_ECDSA_SIG(NULL, &p, inlen))) { + SDFerr(SDF_F_SDF_DECODE_EC_SIGNATURE, ERR_R_EC_LIB); + goto end; + } + + if (!ECDSA_SIG_get_ECCSignature(sig, ref)) { + SDFerr(SDF_F_SDF_DECODE_EC_SIGNATURE, ERR_R_GMAPI_LIB); + goto end; + } + + ret = 1; + +end: + ECDSA_SIG_free(sig); + return ret; +} diff --git a/crypto/sdf/sdf_mac.c b/crypto/sdf/sdf_mac.c new file mode 100644 index 00000000..9e8a2af7 --- /dev/null +++ b/crypto/sdf/sdf_mac.c @@ -0,0 +1,131 @@ +/* ==================================================================== + * Copyright (c) 2016 The GmSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the GmSSL Project. + * (http://gmssl.org/)" + * + * 4. The name "GmSSL Project" must not be used to endorse or promote + * products derived from this software without prior written + * permission. For written permission, please contact + * guanzhi1980@gmail.com. + * + * 5. Products derived from this software may not be called "GmSSL" + * nor may "GmSSL" appear in their names without prior written + * permission of the GmSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the GmSSL Project + * (http://gmssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE GmSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GmSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES + * LOSS OF USE, DATA, OR PROFITS OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +#include +#include +#include +#include +#include +#include +#include +#include "sdf_lcl.h" + +int SDF_CalculateMAC( + void *hSessionHandle, + void *hKeyHandle, + unsigned int uiAlgID, + unsigned char *pucIV, + unsigned char *pucData, + unsigned int uiDataLength, + unsigned char *pucMAC, + unsigned int *puiMACLength) +{ + int ret = SDR_UNKNOWERR; + SDF_SESSION *session = (SDF_SESSION *)hSessionHandle; + SDF_KEY *key = (SDF_KEY *)hKeyHandle; + CMAC_CTX *ctx = NULL; + const EVP_CIPHER *cipher; + size_t siz; + + /* check arguments, omit the useless pucIV in CBC-MAC */ + if (!hSessionHandle || !hKeyHandle || !pucData || + !pucMAC || !puiMACLength) { + SDFerr(SDF_F_SDF_CALCULATEMAC, + ERR_R_PASSED_NULL_PARAMETER); + return SDR_UNKNOWERR; + } + /* the CBC-MAC API accept size_t input length, but we don't + * know whether future MAC implementation will change this */ + if (uiDataLength <= 0 || uiDataLength > INT_MAX) { + SDFerr(SDF_F_SDF_CALCULATEMAC, + SDF_R_INVALID_INPUT_LENGTH); + return SDR_UNKNOWERR; + } + + /* parse arguments */ + if (!(cipher = sdf_get_cipher(hSessionHandle, uiAlgID))) { + SDFerr(SDF_F_SDF_CALCULATEMAC, SDF_R_INVALID_ALGOR); + goto end; + } + if (key->keylen != EVP_CIPHER_key_length(cipher)) { + SDFerr(SDF_F_SDF_CALCULATEMAC, + SDF_R_INVALID_KEY_HANDLE); + goto end; + } + if (*puiMACLength < EVP_CIPHER_block_size(cipher)) { + SDFerr(SDF_F_SDF_CALCULATEMAC, SDF_R_BUUTER_TOO_SMALL); + goto end; + } + + /* generate mac */ + if (!(ctx = CMAC_CTX_new())) { + SDFerr(SDF_F_SDF_CALCULATEMAC, ERR_R_MALLOC_FAILURE); + goto end; + } + if (!CMAC_Init(ctx, key->key, key->keylen, cipher, session->engine)) { + SDFerr(SDF_F_SDF_CALCULATEMAC, SDF_R_CMAC_FAILURE); + goto end; + } + if (!CMAC_Update(ctx, pucData, (size_t)uiDataLength)) { + SDFerr(SDF_F_SDF_CALCULATEMAC, SDF_R_CMAC_FAILURE); + goto end; + } + if (!CMAC_Final(ctx, pucMAC, &siz)) { + SDFerr(SDF_F_SDF_CALCULATEMAC, SDF_R_CMAC_FAILURE); + goto end; + } + + *puiMACLength = (unsigned int)siz; + ret = SDR_OK; + +end: + CMAC_CTX_free(ctx); + return ret; +} + diff --git a/crypto/sdf/sdf_rand.c b/crypto/sdf/sdf_rand.c new file mode 100644 index 00000000..4102d8c9 --- /dev/null +++ b/crypto/sdf/sdf_rand.c @@ -0,0 +1,95 @@ +/* ==================================================================== + * Copyright (c) 2016 The GmSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the GmSSL Project. + * (http://gmssl.org/)" + * + * 4. The name "GmSSL Project" must not be used to endorse or promote + * products derived from this software without prior written + * permission. For written permission, please contact + * guanzhi1980@gmail.com. + * + * 5. Products derived from this software may not be called "GmSSL" + * nor may "GmSSL" appear in their names without prior written + * permission of the GmSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the GmSSL Project + * (http://gmssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE GmSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GmSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES + * LOSS OF USE, DATA, OR PROFITS OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "sdf_lcl.h" + +int SDF_GenerateRandom( + void *hSessionHandle, + unsigned int uiLength, + unsigned char *pucRandom) +{ + SDF_SESSION *session = (SDF_SESSION *)hSessionHandle; + + if (!hSessionHandle || !pucRandom) { + SDFerr(SDF_F_SDF_GENERATERANDOM, + ERR_R_PASSED_NULL_PARAMETER); + return SDR_INARGERR; + } + + if (uiLength > INT_MAX) { + SDFerr(SDF_F_SDF_GENERATERANDOM, SDF_R_INVALID_LENGTH); + return SDR_INARGERR; + } + +#ifndef OPENSSL_NO_ENGINE + /* try to use the hardware random generator */ + if (session->engine) { + if (!RAND_set_rand_engine(session->engine)) { + //SDFerr(SDF_F_SDF_GENERATERANDOM, ERR_R_RAND_LIB); + return SDR_UNKNOWERR; + } + } +#endif + + if (!RAND_bytes(pucRandom, (int)uiLength)) { + SDFerr(SDF_F_SDF_GENERATERANDOM, SDF_R_RANDOM_FAILURE); + return SDR_RANDERR; + } + + return SDR_OK; +} + diff --git a/crypto/sdf/sdf_rsa.c b/crypto/sdf/sdf_rsa.c new file mode 100644 index 00000000..e1e95576 --- /dev/null +++ b/crypto/sdf/sdf_rsa.c @@ -0,0 +1,570 @@ +/* ==================================================================== + * Copyright (c) 2016 The GmSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the GmSSL Project. + * (http://gmssl.org/)" + * + * 4. The name "GmSSL Project" must not be used to endorse or promote + * products derived from this software without prior written + * permission. For written permission, please contact + * guanzhi1980@gmail.com. + * + * 5. Products derived from this software may not be called "GmSSL" + * nor may "GmSSL" appear in their names without prior written + * permission of the GmSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the GmSSL Project + * (http://gmssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE GmSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GmSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES + * LOSS OF USE, DATA, OR PROFITS OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "sdf_lcl.h" + +/* As there are two APIs for export signing key and decryption key, this + * means that keys with different usage can be referenced by the same + * `uiKeyIndex`, and `uiKeyIndex` is the index of a key container. + */ +int SDF_ExportSignPublicKey_RSA( + void *hSessionHandle, + unsigned int uiKeyIndex, + RSArefPublicKey *pucPublicKey) +{ + int ret = 0; + EVP_PKEY *pkey = NULL; + unsigned int uiKeyUsage = 0; + + if (!hSessionHandle || !pucPublicKey) { + SDFerr(SDF_F_SDF_EXPORTSIGNPUBLICKEY_RSA, + ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + if (!(pkey = sdf_load_rsa_public_key((SDF_SESSION *)hSessionHandle, + uiKeyIndex, uiKeyUsage))) { + SDFerr(SDF_F_SDF_EXPORTSIGNPUBLICKEY_RSA, ERR_R_GMAPI_LIB); + goto end; + } + + if (!RSA_get_RSArefPublicKey(EVP_PKEY_get0_RSA(pkey), pucPublicKey)) { + SDFerr(SDF_F_SDF_EXPORTSIGNPUBLICKEY_RSA, ERR_R_GMAPI_LIB); + goto end; + } + + ret = SDR_OK; + +end: + EVP_PKEY_free(pkey); + return ret; +} + +int SDF_ExportEncPublicKey_RSA( + void *hSessionHandle, + unsigned int uiKeyIndex, + RSArefPublicKey *pucPublicKey) +{ + int ret = 0; + EVP_PKEY *pkey = NULL; + unsigned int uiKeyUsage = 1; //FIXME + + if (!hSessionHandle || !pucPublicKey) { + SDFerr(SDF_F_SDF_EXPORTENCPUBLICKEY_RSA, + ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + if (!(pkey = sdf_load_rsa_public_key((SDF_SESSION *)hSessionHandle, + uiKeyIndex, uiKeyUsage))) { + SDFerr(SDF_F_SDF_EXPORTENCPUBLICKEY_RSA, ERR_R_GMAPI_LIB); + goto end; + } + + if (!RSA_get_RSArefPublicKey(EVP_PKEY_get0_RSA(pkey), pucPublicKey)) { + SDFerr(SDF_F_SDF_EXPORTENCPUBLICKEY_RSA, ERR_R_GMAPI_LIB); + goto end; + } + + ret = SDR_OK; + +end: + EVP_PKEY_free(pkey); + return ret; +} + +/* + * Generate RSA key pair. + * The MAX RSA bits is defined as 2048 in GM/T 0018-2012. As 1024 is not very + * secure, applications should always use 2048-bit. Use 1024-bit only for + * legacy applications. + */ +int SDF_GenerateKeyPair_RSA( + void *hSessionHandle, /* not used */ + unsigned int uiKeyBits, + RSArefPublicKey *pucPublicKey, + RSArefPrivateKey *pucPrivateKey) +{ + int ret = 0; + RSA *rsa = NULL; + + if (!hSessionHandle || !pucPublicKey || !pucPrivateKey) { + SDFerr(SDF_F_SDF_GENERATEKEYPAIR_RSA, + ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + if (!(rsa = RSA_new())) { + SDFerr(SDF_F_SDF_GENERATEKEYPAIR_RSA, + ERR_R_MALLOC_FAILURE); + goto end; + } + if (!RSA_generate_key_ex(rsa, uiKeyBits, NULL, NULL)) { + SDFerr(SDF_F_SDF_GENERATEKEYPAIR_RSA, ERR_R_RSA_LIB); + goto end; + } + + if (!RSA_get_RSArefPublicKey(rsa, pucPublicKey)) { + SDFerr(SDF_F_SDF_GENERATEKEYPAIR_RSA, ERR_R_GMAPI_LIB); + goto end; + } + if (!RSA_get_RSArefPrivateKey(rsa, pucPrivateKey)) { + SDFerr(SDF_F_SDF_GENERATEKEYPAIR_RSA, ERR_R_GMAPI_LIB); + goto end; + } + + ret = SDR_OK; + +end: + RSA_free(rsa); + return ret; +} + +/* + * In a cryptographic API the symmetric keys (and otehr keys) can be + * classified into session keys and storage keys. The storage keys will be + * persistantly stored in the secure storage of a cryptograhic hardware + * device. While the session keys only exist in the session period, after + * the session is finished, it will be destroyed even if the symmetric key + * operations are performed inside the hardware. + * + * The `gmapi` module only support session keys. + */ +/* + * In the current version of GmSSL (2.x), the session keys will be kept in + * the host memory intead of the cryptographic hardware's internal memory. + * So the key handle will suffer memory attacks. + */ + +/* + * Generate a symmetric key with bit length `uiKeyBits`, encrypt the key data + * with an internal RSA public key with index `uiIPKIndex`, output the + * encrypted key data to buffer `pucKey` and length `puiKeyLength`, also return + * the handle of the generated key `phKeyHandle`. + */ + +/* generate session key and encrypt with internal public key */ +int SDF_GenerateKeyWithIPK_RSA( + void *hSessionHandle, + unsigned int uiIPKIndex, + unsigned int uiKeyBits, /* generate key length */ + unsigned char *pucKey, + unsigned int *puiKeyLength, + void **phKeyHandle) +{ + int ret = 0; + SDF_KEY *hkey = NULL; + + if (!hSessionHandle || !pucKey || !puiKeyLength || !phKeyHandle) { + SDFerr(SDF_F_SDF_GENERATEKEYWITHIPK_RSA, + ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + if (uiKeyBits <= 0 || uiKeyBits % 8 || uiKeyBits > EVP_MAX_KEY_LENGTH) { + SDFerr(SDF_F_SDF_GENERATEKEYWITHIPK_RSA, + SDF_R_INVALID_KEY_LENGTH); + return 0; + } + + if (!(hkey = OPENSSL_zalloc(sizeof(*hkey)))) { + SDFerr(SDF_F_SDF_GENERATEKEYWITHIPK_RSA, + ERR_R_MALLOC_FAILURE); + return 0; + } + + if ((ret = SDF_InternalPublicKeyOperation_RSA( + hSessionHandle, + uiIPKIndex, + hkey->key, + hkey->keylen, + pucKey, + puiKeyLength)) != SDR_OK) { + SDFerr(SDF_F_SDF_GENERATEKEYWITHIPK_RSA, ERR_R_GMAPI_LIB); + goto end; + } + + *phKeyHandle = hkey; + hkey = NULL; + ret = SDR_OK; + +end: + OPENSSL_clear_free(hkey, sizeof(*hkey)); + return ret; +} + +/* + * Generate a symmetric key with bit length `uiKeyBits`, encrypt the key data + * with an external RSA public key with data `pucPublicKey` in format + * `RSArefPublickey`, output the encrypted key data to buffer `pucKey` and + * length `puiKeyLength`, also return the handle `phKeyHandle` of the generated + * key. + */ +int SDF_GenerateKeyWithEPK_RSA( + void *hSessionHandle, + unsigned int uiKeyBits, + RSArefPublicKey *pucPublicKey, + unsigned char *pucKey, + unsigned int *puiKeyLength, + void **phKeyHandle) +{ + int ret = 0; + SDF_KEY *key = NULL; + + if (!hSessionHandle || !pucPublicKey || !pucKey || !puiKeyLength || + !phKeyHandle) { + SDFerr(SDF_F_SDF_GENERATEKEYWITHEPK_RSA, + ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + if (uiKeyBits <= 0 || uiKeyBits % 8 || uiKeyBits > + EVP_MAX_KEY_LENGTH) { + SDFerr(SDF_F_SDF_GENERATEKEYWITHEPK_RSA, + SDF_R_INVALID_KEY_LENGTH); + return 0; + } + + if (!(key = OPENSSL_zalloc(sizeof(*key)))) { + SDFerr(SDF_F_SDF_GENERATEKEYWITHEPK_RSA, + ERR_R_MALLOC_FAILURE); + goto end; + } + + if ((ret = SDF_ExternalPublicKeyOperation_RSA( + hSessionHandle, + pucPublicKey, + key->key, + key->keylen, + pucKey, + puiKeyLength)) != SDR_OK) { + SDFerr(SDF_F_SDF_GENERATEKEYWITHEPK_RSA, ERR_R_GMAPI_LIB); + goto end; + } + + *phKeyHandle = key; + key = NULL; + ret = SDR_OK; + +end: + OPENSSL_clear_free(key, sizeof(*key)); + return ret; +} + +/* + * Import the encrypted key generated from `SDF_GenerateKeyWithIPK_RSA` to the + * session context, the internal RSA key index `uiISKIndex` should be the same + * index of the parameter `uiIPKIndex` of `SDF_GenerateKeyWithIPK_RSA`. + */ + +/* Import session key `pucKey` encrypted by the internal public key indexed + * by `uiISKIndex`. As there are no session key in device, we need to + * decrypt the `pucKey` with the internal key `uiISKIndex`. + */ +int SDF_ImportKeyWithISK_RSA( + void *hSessionHandle, + unsigned int uiISKIndex, + unsigned char *pucKey, + unsigned int uiKeyLength, + void **phKeyHandle) +{ + int ret = 0; + SDF_KEY *key = NULL; + + if (!hSessionHandle || !pucKey || !phKeyHandle) { + SDFerr(SDF_F_SDF_IMPORTKEYWITHISK_RSA, + ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + if (!(key = OPENSSL_zalloc(sizeof(*key)))) { + SDFerr(SDF_F_SDF_IMPORTKEYWITHISK_RSA, + ERR_R_MALLOC_FAILURE); + goto end; + } + + key->keylen = EVP_MAX_KEY_LENGTH; + if ((ret = SDF_InternalPrivateKeyOperation_RSA( + hSessionHandle, + uiISKIndex, + pucKey, + uiKeyLength, + key->key, + &key->keylen)) != SDR_OK) { + SDFerr(SDF_F_SDF_IMPORTKEYWITHISK_RSA, ERR_R_GMAPI_LIB); + goto end; + } + + *phKeyHandle = key; + key = NULL; + ret = SDR_OK; + +end: + OPENSSL_clear_free(key, sizeof(*key)); + return ret; +} + +/* + * Convert internal public key encrypted symmetric key into ciphertext + * encrypted by external public key. The input `pucDEInput` is the symmetric + * key encrypted by internal public key `uiKeyIndex`. The output `pucDEOutput` + * is encrypted under the external public key `pucPublicKey`. + * + * Note: This function is very dangerous. It convert a well protected symmetric + * key into a state with security unknown. If the external private key is not + * well protected, this function is the same as to unwrap of the symmetric key + * and output the plaintext. + */ + +/* + * convert the `pucDEInput` encrypted by internal RSA public key + * `uiKeyIndex` to `pucDEOutput` encrypted by the external RSA public key + * `pucPublicKey` + */ +int SDF_ExchangeDigitEnvelopeBaseOnRSA( + void *hSessionHandle, + unsigned int uiKeyIndex, + RSArefPublicKey *pucPublicKey, + unsigned char *pucDEInput, + unsigned int uiDELength, + unsigned char *pucDEOutput, + unsigned int *puiDELength) +{ + return 0; +} + +int SDF_ExternalPublicKeyOperation_RSA( + void *hSessionHandle, + RSArefPublicKey *pucPublicKey, + unsigned char *pucDataInput, + unsigned int uiInputLength, + unsigned char *pucDataOutput, + unsigned int *puiOutputLength) +{ + int ret = 0; + RSA *rsa = NULL; + int outlen; + + if (!hSessionHandle || !pucPublicKey || !pucDataInput || + !pucDataOutput || !puiOutputLength) { + SDFerr(SDF_F_SDF_EXTERNALPUBLICKEYOPERATION_RSA, + ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + if (!(rsa = RSA_new_from_RSArefPublicKey(pucPublicKey))) { + SDFerr(SDF_F_SDF_EXTERNALPUBLICKEYOPERATION_RSA, + ERR_R_GMAPI_LIB); + goto end; + } + + if ((outlen = RSA_public_encrypt((int)uiInputLength, pucDataInput, + pucDataOutput, rsa, RSA_NO_PADDING)) < 0) { + SDFerr(SDF_F_SDF_EXTERNALPUBLICKEYOPERATION_RSA, + ERR_R_RSA_LIB); + goto end; + } + + *puiOutputLength = (unsigned int)outlen; + ret = SDR_OK; + +end: + RSA_free(rsa); + return ret; +} + +/* + * The RSA Operations include + * `SDF_ExternalPublicKeyOperation_RSA` + * `SDF_InternalPublicKeyOperation_RSA` + * `SDF_InternalPrivateKeyOperation_RSA` + * + * Noramlly RSA operations should be working with some padding methods, such + * as PKCS #1 OAEP padding or PSS padding. As the SDF API does not provide any + * parameter to set padding method, and it is neither specified in the GM/T + * 0018-2012 standard, application developers need to ask the vendor or try + * testing. The GmSSL SDF implementation will always try to use the PKCS #1 + * padding, but the underlying ENGINEs might not support this padding options. + * + * It should be noted that the SDF API does not support external private key + * operations. + */ + +int SDF_ExternalPrivateKeyOperation_RSA( + void *hSessionHandle, + RSArefPrivateKey *pucPrivateKey, + unsigned char *pucDataInput, + unsigned int uiInputLength, + unsigned char *pucDataOutput, + unsigned int *puiOutputLength) +{ + int ret = 0; + RSA *rsa = NULL; + int outlen; + + if (!hSessionHandle || !pucPrivateKey || !pucDataInput || + !pucDataOutput || !puiOutputLength) { + SDFerr(SDF_F_SDF_EXTERNALPRIVATEKEYOPERATION_RSA, + ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + if (!(rsa = RSA_new_from_RSArefPrivateKey(pucPrivateKey))) { + SDFerr(SDF_F_SDF_EXTERNALPRIVATEKEYOPERATION_RSA, + ERR_R_GMAPI_LIB); + goto end; + } + + if ((outlen = RSA_private_decrypt((int)uiInputLength, pucDataInput, + pucDataOutput, rsa, RSA_NO_PADDING)) < 0) { + SDFerr(SDF_F_SDF_EXTERNALPRIVATEKEYOPERATION_RSA, + ERR_R_RSA_LIB); + goto end; + } + + *puiOutputLength = (unsigned int)outlen; + ret = SDR_OK; + +end: + RSA_free(rsa); + return ret; +} + + +int SDF_InternalPublicKeyOperation_RSA( + void *hSessionHandle, + unsigned int uiKeyIndex, + unsigned char *pucDataInput, + unsigned int uiInputLength, + unsigned char *pucDataOutput, + unsigned int *puiOutputLength) +{ + int ret = 0; + EVP_PKEY *pkey = NULL; + int outlen; + unsigned int uiKeyUsage = -12345; //FIXME: which key should we use? + + if (!hSessionHandle || !pucDataInput || !pucDataOutput || + !puiOutputLength) { + SDFerr(SDF_F_SDF_INTERNALPUBLICKEYOPERATION_RSA, + ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + if (!(pkey = sdf_load_rsa_public_key((SDF_SESSION *)hSessionHandle, + uiKeyIndex, uiKeyUsage))) { + SDFerr(SDF_F_SDF_INTERNALPUBLICKEYOPERATION_RSA, + ERR_R_GMAPI_LIB); + goto end; + } + + if ((outlen = RSA_public_encrypt((int)uiInputLength, pucDataInput, + pucDataOutput, EVP_PKEY_get0_RSA(pkey), RSA_NO_PADDING)) < 0) { + SDFerr(SDF_F_SDF_INTERNALPUBLICKEYOPERATION_RSA, + ERR_R_RSA_LIB); + goto end; + } + + *puiOutputLength = (unsigned int)outlen; + ret = SDR_OK; + +end: + EVP_PKEY_free(pkey); + return ret; +} + +int SDF_InternalPrivateKeyOperation_RSA( + void *hSessionHandle, + unsigned int uiKeyIndex, + unsigned char *pucDataInput, + unsigned int uiInputLength, + unsigned char *pucDataOutput, + unsigned int *puiOutputLength) +{ + int ret = 0; + EVP_PKEY *pkey = NULL; + int outlen; + unsigned int uiKeyUsage; //FIXME + + if (!hSessionHandle || !pucDataInput || !pucDataOutput || + !puiOutputLength) { + SDFerr(SDF_F_SDF_INTERNALPRIVATEKEYOPERATION_RSA, + ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + if (!(pkey = sdf_load_rsa_private_key((SDF_SESSION *)hSessionHandle, + uiKeyIndex, uiKeyUsage))) { + SDFerr(SDF_F_SDF_INTERNALPRIVATEKEYOPERATION_RSA, + ERR_R_GMAPI_LIB); + goto end; + } + + if ((outlen = RSA_private_decrypt(uiInputLength, pucDataInput, + pucDataOutput, EVP_PKEY_get0_RSA(pkey), RSA_NO_PADDING)) < 0) { + SDFerr(SDF_F_SDF_INTERNALPRIVATEKEYOPERATION_RSA, + ERR_R_RSA_LIB); + goto end; + } + + *puiOutputLength = (unsigned int)outlen; + ret = SDR_OK; + +end: + EVP_PKEY_free(pkey); + return ret; +} + diff --git a/crypto/sdf/sdf_session.c b/crypto/sdf/sdf_session.c new file mode 100644 index 00000000..5f736aec --- /dev/null +++ b/crypto/sdf/sdf_session.c @@ -0,0 +1,237 @@ +/* ==================================================================== + * Copyright (c) 2016 The GmSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the GmSSL Project. + * (http://gmssl.org/)" + * + * 4. The name "GmSSL Project" must not be used to endorse or promote + * products derived from this software without prior written + * permission. For written permission, please contact + * guanzhi1980@gmail.com. + * + * 5. Products derived from this software may not be called "GmSSL" + * nor may "GmSSL" appear in their names without prior written + * permission of the GmSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the GmSSL Project + * (http://gmssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE GmSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GmSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES + * LOSS OF USE, DATA, OR PROFITS OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "sdf_lcl.h" + +/* + * Unlike the `SDF_OpenDevice`, we always assume that the `SDF_OpenSession` can + * be called multiple times, and the implementation will always return a new + * session handle on success. But noramlly the hardware and the software can + * only support limited sessions, so this function can also failed. + * + * For portability, the application should assume that only one cryptographic + * operation can be processed over one session. For example, do not mix + * symmetric encryption and hash functions over the same session. The + * implementation might support multiple operations, check the vendor's manual. + */ + +/* + * there are two purpose for session: + * (1) hold session information + * (2) a reference to ENGINE + */ +/* +typedef struct { + uint32_t magic; + char *app; + ENGINE *engine; + char *passwords[SDF_MAX_KEY_INDEX]; + EVP_MD_CTX *md_ctx; +} SDF_SESSION; +*/ + +int SDF_OpenSession( + void *hDeviceHandle, + void **phSessionHandle) +{ + int ret = SDR_UNKNOWERR; + SDF_SESSION *session = NULL; + + if (!hDeviceHandle || !phSessionHandle) { + SDFerr(SDF_F_SDF_OPENSESSION, ERR_R_PASSED_NULL_PARAMETER); + return SDR_INARGERR; + } + if (hDeviceHandle != deviceHandle) { + SDFerr(SDF_F_SDF_OPENSESSION, SDF_R_INVALID_DEVICE_HANDLE); + return SDR_INARGERR; + } + + if (!(session = OPENSSL_zalloc(sizeof(*session)))) { + SDFerr(SDF_F_SDF_OPENSESSION, ERR_R_MALLOC_FAILURE); + ret = SDR_NOBUFFER; + goto end; + } + + session->magic = SDF_SESSION_MAGIC; + +#ifndef OPENSSL_NO_ENGINE + if (!(session->engine = ENGINE_by_id(SDF_ENGINE_ID))) { + SDFerr(SDF_F_SDF_OPENSESSION, SDF_R_LOAD_ENGINE_FAILURE); + ret = SDR_HARDFAIL; + goto end; + } +#endif + + *phSessionHandle = session; + session = NULL; + ret = SDR_OK; + +end: + OPENSSL_free(session); + return ret; +} + +int SDF_CloseSession( + void *hSessionHandle) +{ + SDF_SESSION *session = (SDF_SESSION *)hSessionHandle; + int i; + + if (!hSessionHandle) { + return SDR_OK; + } + + if (session->magic != SDF_SESSION_MAGIC) { + SDFerr(SDF_F_SDF_CLOSESESSION, SDF_R_INVALID_SESSION); + return SDR_INARGERR; + } + +#ifndef OPENSSL_NO_ENGINE + if (session->engine) { + ENGINE_finish(session->engine); + ENGINE_free(session->engine); + session->engine = NULL; + } +#endif + + for (i = 0; i <= SDF_MAX_KEY_INDEX; i++) { + OPENSSL_clear_free(session->password[i], + strlen(session->password[i])); + session->password[i] = NULL; + } + + OPENSSL_free(session); + return SDR_OK; +} + +/* we try that the password is correct by `ENGINE_load_private_key`, then we + * destory the returned `EVP_PKEY` and keep the verified password in the + * session. We can use `UI_set_result` to pass the password to the ENGINE + */ +int SDF_GetPrivateKeyAccessRight( + void *hSessionHandle, + unsigned int uiKeyIndex, + unsigned char *pucPassword, + unsigned int uiPwdLength) +{ + SDF_SESSION *session = (SDF_SESSION *)hSessionHandle; + EVP_PKEY *pkey = NULL; + char *key_id = NULL; + UI_METHOD *ui_meth = NULL; + void *cb_data = NULL; + + if (!hSessionHandle || !pucPassword) { + SDFerr(SDF_F_SDF_GETPRIVATEKEYACCESSRIGHT, + ERR_R_PASSED_NULL_PARAMETER); + return SDR_INARGERR; + } + if (session->magic != SDF_SESSION_MAGIC) { + SDFerr(SDF_F_SDF_GETPRIVATEKEYACCESSRIGHT, + SDF_R_INVALID_SESSION_HANDLE); + return SDR_INARGERR; + } + if (uiKeyIndex <= 0 || uiKeyIndex > SDF_MAX_KEY_INDEX) { + SDFerr(SDF_F_SDF_GETPRIVATEKEYACCESSRIGHT, + SDF_R_INVALID_KEY_INDEX); + return -1; + } + if (uiPwdLength <= 0 || uiPwdLength > INT_MAX) { + SDFerr(SDF_F_SDF_GETPRIVATEKEYACCESSRIGHT, + SDF_R_INVALID_PASSWORD_LENGTH); + return SDR_INARGERR; + } + + if (!(pkey = ENGINE_load_private_key(session->engine, key_id, + ui_meth, cb_data))) { + SDFerr(SDF_F_SDF_GETPRIVATEKEYACCESSRIGHT, ERR_R_ENGINE_LIB); + return 0; + } + + return SDR_OK; +} + +int SDF_ReleasePrivateKeyAccessRight( + void *hSessionHandle, + unsigned int uiKeyIndex) +{ + SDF_SESSION *session = (SDF_SESSION *)hSessionHandle; + + if (!hSessionHandle) { + SDFerr(SDF_F_SDF_RELEASEPRIVATEKEYACCESSRIGHT, + ERR_R_PASSED_NULL_PARAMETER); + return SDR_INARGERR; + } + if (session->magic != SDF_SESSION_MAGIC) { + SDFerr(SDF_F_SDF_RELEASEPRIVATEKEYACCESSRIGHT, + SDF_R_INVALID_SESSION_HANDLE); + return SDR_INARGERR; + } + if (uiKeyIndex <= 0 || uiKeyIndex > SDF_MAX_KEY_INDEX) { + SDFerr(SDF_F_SDF_RELEASEPRIVATEKEYACCESSRIGHT, + SDF_R_INVALID_KEY_INDEX); + return -1; + } + + if (session->password[uiKeyIndex]) { + OPENSSL_clear_free(session->password[uiKeyIndex], + strlen(session->password[uiKeyIndex])); + session->password[uiKeyIndex] = NULL; + } + + return SDR_OK; +} + diff --git a/crypto/skf/build.info b/crypto/skf/build.info new file mode 100644 index 00000000..1fe2a316 --- /dev/null +++ b/crypto/skf/build.info @@ -0,0 +1,15 @@ +LIBS=../../libcrypto +SOURCE[../../libcrypto]=\ + skf_dev.c \ + skf_dgst.c \ + skf_ec.c \ + skf_enc.c \ + skf_err.c \ + skf_errstr.c \ + skf_handle.c \ + skf_mac.c \ + skf_rand.c \ + skf_rsa.c \ + skf_sesskey.c \ + skf_print.c \ + skf_token.c diff --git a/crypto/skf/skf_dev.c b/crypto/skf/skf_dev.c new file mode 100644 index 00000000..8d070509 --- /dev/null +++ b/crypto/skf/skf_dev.c @@ -0,0 +1,190 @@ +/* crypto/gmapi/skf_dev.c */ +/* ==================================================================== + * 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. + * ==================================================================== + * + */ + +#include +#include +#include +#include +#include "skf_lcl.h" + +#define DEV_NAME "pseudo_dev" +#define DEV_NAME_LIST DEV_NAME"\0" + +SKF_HANDLE skf_dev_handle; + +ULONG DEVAPI SKF_EnumDev(BOOL bPresent, + LPSTR szNameList, + ULONG *pulSize) +{ + if (!szNameList) { + *pulSize = sizeof(DEV_NAME_LIST); + return SAR_OK; + } + + if (*pulSize < sizeof(DEV_NAME_LIST)) { + return SAR_FAIL; + } + + memcpy(szNameList, DEV_NAME_LIST, sizeof(DEV_NAME_LIST)); + return SAR_OK; +} + +ULONG DEVAPI SKF_ConnectDev(LPSTR szName, + DEVHANDLE *phDev) +{ + *phDev = &skf_dev_handle; + return SAR_OK; +} + +ULONG DEVAPI SKF_DisConnectDev(DEVHANDLE hDev) +{ + //FIXME: close all handles + hDev = NULL; + return SAR_OK; +} + +ULONG DEVAPI SKF_GetDevState(LPSTR szDevName, + ULONG *pulDevState) +{ + if (!pulDevState) { + SKFerr(SKF_F_SKF_GETDEVSTATE, SKF_R_NULL_ARGUMENT); + return SAR_INVALIDPARAMERR; + } + + *pulDevState = DEV_PRESENT_STATE; + return SAR_OK; +} + +ULONG DEVAPI SKF_GetDevInfo(DEVHANDLE hDev, + DEVINFO *pDevInfo) +{ + DEVINFO devInfo; + + if (!pDevInfo) { + SKFerr(SKF_F_SKF_GETDEVINFO, SKF_R_NULL_ARGUMENT); + 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 Softotken"); + strcpy((char *)&devInfo.SerialNumber, "1"); + devInfo.HWVersion.major = 1; + devInfo.HWVersion.minor = 0; + devInfo.FirmwareVersion.major = 1; + devInfo.FirmwareVersion.minor = 0; + devInfo.AlgSymCap = 0x0000041F; + devInfo.AlgAsymCap = 0x00030700; + devInfo.AlgHashCap = 0x00000007; + devInfo.DevAuthAlgId = SGD_SM4_CBC; + devInfo.TotalSpace = 0; + devInfo.FreeSpace = 0; + devInfo.MaxECCBufferSize = 0; /* FIXME: max inlen of ECC encrypt */ + devInfo.MaxBufferSize = 0; /* FIXME: max inlen of SM4 encrypt */ + + memcpy(pDevInfo, &devInfo, sizeof(DEVINFO)); + return SAR_OK; +} + +int SKF_print_dev_info(DEVINFO *devInfo) +{ + printf("Device Info:\n"); + printf(" Device Version : %d.%d\n", devInfo->Version.major, devInfo->Version.minor); + printf(" Manufacturer : %s\n", devInfo->Manufacturer); + printf(" Issuer : %s\n", devInfo->Issuer); + printf(" Label : %s\n", devInfo->Label); + printf(" Serial Number : %s\n", devInfo->SerialNumber); + printf(" Hardware Version : %d.%d\n", devInfo->HWVersion.major, devInfo->HWVersion.minor); + printf(" Firmware Version : %d.%d\n", devInfo->FirmwareVersion.major, devInfo->FirmwareVersion.minor); + printf(" AlgSymCap : 0x%08x\n", devInfo->AlgSymCap); + printf(" AlgAsymCap : 0x%08x\n", devInfo->AlgAsymCap); + printf(" AlgHashCap : 0x%08x\n", devInfo->AlgHashCap); + printf(" AlgHashCap : 0x%08x\n", devInfo->DevAuthAlgId); + printf(" Total Space : %u\n", devInfo->TotalSpace); + printf(" Free Space : %u\n", devInfo->FreeSpace); + printf(" MaxECCBuffer : %u\n", devInfo->MaxECCBufferSize); + printf(" MaxBuffer : %u\n", devInfo->MaxBufferSize); + + return 1; +} + +const char *SKF_get_alg_name(ULONG ulAlgID) +{ + //FIXME: make these name compatible with OBJ short name + 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-OFB"; + case SGD_SM1_MAC: return "SM1-MAC"; + case SGD_SM4_ECB: return "SM4-ECB"; + case SGD_SM4_CBC: return "SM4-CBC"; + case SGD_SM4_CFB: return "SM4-CFB"; + case SGD_SM4_OFB: return "SM4-OFB"; + case SGD_SM4_MAC: return "SM4-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-OFB"; + case SGD_SSF33_MAC: return "SSF33-MAC"; + case SGD_RSA: return "RSA"; + case SGD_SM2_1: return "SM2-1"; + case SGD_SM2_2: return "SM2-2"; + case SGD_SM2_3: return "SM2-3"; + case SGD_SM3: return "SM3"; + case SGD_SHA1: return "SHA-1"; + case SGD_SHA256: return "SHA256"; + } + return "(unknown)"; +} diff --git a/crypto/skf/skf_dgst.c b/crypto/skf/skf_dgst.c new file mode 100644 index 00000000..caa249b2 --- /dev/null +++ b/crypto/skf/skf_dgst.c @@ -0,0 +1,235 @@ +/* ==================================================================== + * 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. + * ==================================================================== + * + */ + +#include +#include +#include +#include +#include "skf_lcl.h" + + +ULONG DEVAPI SKF_DigestInit(DEVHANDLE hDev, + ULONG ulAlgID, + ECCPUBLICKEYBLOB *pPubKey, + BYTE *pbID, + ULONG ulIDLen, + HANDLE *phHash) +{ + ULONG ret = SAR_FAIL; + const EVP_MD *md; + EVP_MD_CTX *mdctx = NULL; + EC_KEY *ec_key = NULL; + SKF_HANDLE *hHash; + + switch (ulAlgID) { + case SGD_SM3: + md = EVP_sm3(); + break; + case SGD_SHA1: + md = EVP_sha1(); + break; + case SGD_SHA256: + md = EVP_sha256(); + break; + default: + SKFerr(SKF_F_SKF_DIGESTINIT, SKF_R_INVALID_ALGID); + return SAR_INVALIDPARAMERR; + } + + if (!(mdctx = EVP_MD_CTX_create())) { + SKFerr(SKF_F_SKF_DIGESTINIT, SKF_R_MALLOC_FAILED); + return SAR_FAIL; + } + + if (!EVP_DigestInit_ex(mdctx, md, NULL)) { + SKFerr(SKF_F_SKF_DIGESTINIT, ERR_R_EVP_LIB); + goto end; + } + + if (pPubKey) { + + if (!(ec_key = EC_KEY_new_from_ECCPUBLICKEYBLOB(pPubKey))) { + SKFerr(SKF_F_SKF_DIGESTINIT, SKF_R_INVALID_BLOB); + ret = SAR_INVALIDPARAMERR; + goto end; + } + + /* + //FIXME + if (pbID) { + if (ulIDLen <= 0 || ulIDLen > SM2_MAX_ID_LENGTH) { + SKFerr(SKF_F_SKF_DIGESTINIT, SKF_R_INVALID_ID_LENGTH); + ret = SAR_INVALIDPARAMERR; + goto end; + } + + OPENSSL_assert(strlen((char *)pbID) == ulIDLen); + if (!SM2_set_id(ec_key, (char *)pbID)) { + SKFerr(SKF_F_SKF_DIGESTINIT, ERR_R_SM2_LIB); + ret = SAR_FAIL; + goto end; + } + } + + dgstlen = sizeof(dgst); + if (!SM2_compute_id_digest(md, dgst, &dgstlen, ec_key)) { + SKFerr(SKF_F_SKF_DIGESTINIT, ERR_R_SM2_LIB); + goto end; + } + + if (!EVP_DigestUpdate(mdctx, dgst, dgstlen)) { + goto end; + } + */ + + } else { + if (pbID) { + SKFerr(SKF_F_SKF_DIGESTINIT, SKF_R_NO_PUBLIC_KEY); + ret = SAR_INVALIDPARAMERR; + goto end; + } + } + + + if (!(hHash = OPENSSL_malloc(sizeof(*hHash)))) { + SKFerr(SKF_F_SKF_DIGESTINIT, ERR_R_MALLOC_FAILURE); + goto end; + } + + memset(hHash, 0, sizeof(*hHash)); + hHash->magic = SKF_HANDLE_MAGIC; + hHash->type = SKF_HASH_HANDLE; + hHash->u.md_ctx = mdctx; + mdctx = NULL; + + *phHash = hHash; + ret = SAR_OK; +end: + EVP_MD_CTX_destroy(mdctx); + EC_KEY_free(ec_key); + return ret; +} + + +ULONG DEVAPI SKF_DigestUpdate(HANDLE hHash, + BYTE *pbData, + ULONG ulDataLen) +{ + EVP_MD_CTX *md_ctx; + + if (!(md_ctx = SKF_HANDLE_get_md_ctx(hHash))) { + SKFerr(SKF_F_SKF_DIGESTUPDATE, SKF_R_INVALID_HASH_HANDLE); + return SAR_INVALIDPARAMERR; + } + + if (!pbData) { + SKFerr(SKF_F_SKF_DIGESTUPDATE, SKF_R_INVALID_ARGUMENTS); + return SAR_INVALIDPARAMERR; + } + + if (ulDataLen == 0) { + return SAR_OK; + } + + if (!EVP_DigestUpdate(md_ctx, pbData, ulDataLen)) { + SKFerr(SKF_F_SKF_DIGESTUPDATE, ERR_R_EVP_LIB); + return SAR_FAIL; + } + + return SAR_OK; +} + +ULONG DEVAPI SKF_DigestFinal(HANDLE hHash, + BYTE *pHashData, + ULONG *pulHashLen) +{ + EVP_MD_CTX *mdctx; + + if (!(mdctx = SKF_HANDLE_get_md_ctx(hHash))) { + SKFerr(SKF_F_SKF_DIGESTFINAL, SKF_R_INVALID_HANDLE); + return SAR_INVALIDPARAMERR; + } + + if (!pulHashLen) { + SKFerr(SKF_F_SKF_DIGESTFINAL, SKF_R_NULL_ARGUMENT); + return SAR_INVALIDPARAMERR; + } + + if (!EVP_DigestFinal_ex(mdctx, pHashData, pulHashLen)) { + SKFerr(SKF_F_SKF_DIGESTFINAL, ERR_R_EVP_LIB); + return SAR_FAIL; + } + + EVP_MD_CTX_destroy(mdctx); + ((SKF_HANDLE *)hHash)->u.md_ctx = NULL; + return SAR_OK; +} + +ULONG DEVAPI SKF_Digest(HANDLE hHash, + BYTE *pbData, + ULONG ulDataLen, + BYTE *pbHashData, + ULONG *pulHashLen) +{ + ULONG rv; + + if ((rv = SKF_DigestUpdate(hHash, pbData, ulDataLen)) != SAR_OK) { + SKFerr(SKF_F_SKF_DIGEST, ERR_R_GMAPI_LIB); + return rv; + } + + if ((rv = SKF_DigestFinal(hHash, pbHashData, pulHashLen)) != SAR_OK) { + SKFerr(SKF_F_SKF_DIGEST, ERR_R_GMAPI_LIB); + return rv; + } + + return SAR_OK; +} + diff --git a/crypto/skf/skf_ec.c b/crypto/skf/skf_ec.c new file mode 100644 index 00000000..2865ed82 --- /dev/null +++ b/crypto/skf/skf_ec.c @@ -0,0 +1,272 @@ +/* ==================================================================== + * Copyright (c) 2016 The GmSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the GmSSL Project. + * (http://gmssl.org/)" + * + * 4. The name "GmSSL Project" must not be used to endorse or promote + * products derived from this software without prior written + * permission. For written permission, please contact + * guanzhi1980@gmail.com. + * + * 5. Products derived from this software may not be called "GmSSL" + * nor may "GmSSL" appear in their names without prior written + * permission of the GmSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the GmSSL Project + * (http://gmssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE GmSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GmSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +#include +#include +#include +#include +#include "skf_lcl.h" + +ULONG DEVAPI SKF_GenExtECCKeyPair(DEVHANDLE hDev, + ECCPRIVATEKEYBLOB *priKey, + ECCPUBLICKEYBLOB *pubKey) +{ + ULONG ret = SAR_FAIL; + EC_KEY *ec_key = NULL; + + if(!(ec_key = EC_KEY_new_by_curve_name(NID_sm2p256v1))) { + SKFerr(SKF_F_SKF_GENEXTECCKEYPAIR, ERR_R_EC_LIB); + return SAR_FAIL; + } + if (!EC_KEY_get_ECCPRIVATEKEYBLOB(ec_key, priKey)) { + SKFerr(SKF_F_SKF_GENEXTECCKEYPAIR, SKF_R_GET_PRIVATE_KEY_FAILED); + goto end; + } + if (!EC_KEY_get_ECCPUBLICKEYBLOB(ec_key, pubKey)) { + SKFerr(SKF_F_SKF_GENEXTECCKEYPAIR, SKF_R_GET_PUBLIC_KEY_FAILED); + goto end; + } + ret = SAR_OK; +end: + EC_KEY_free(ec_key); + return ret; +} + +ULONG DEVAPI SKF_ExtECCSign(DEVHANDLE hDev, + ECCPRIVATEKEYBLOB *pECCPriKeyBlob, + BYTE *pbData, + ULONG ulDataLen, + ECCSIGNATUREBLOB *pSignature) +{ + ULONG ret = SAR_FAIL; + EC_KEY *ec_key = NULL; + ECDSA_SIG *sig = NULL; + + if (!pECCPriKeyBlob || !pbData || !pSignature) { + SKFerr(SKF_F_SKF_EXTECCSIGN, SKF_R_NULL_ARGUMENT); + return SAR_INVALIDPARAMERR; + } + + if (ulDataLen != SM3_DIGEST_LENGTH) { + SKFerr(SKF_F_SKF_EXTECCSIGN, SKF_R_INVALID_DIGEST_LENGTH); + return SAR_INVALIDPARAMERR; + } + + if (!(ec_key = EC_KEY_new_from_ECCPRIVATEKEYBLOB(pECCPriKeyBlob))) { + SKFerr(SKF_F_SKF_EXTECCSIGN, SKF_R_INVALID_ECC_PRIVATE_KEY); + goto end; + } + + if (!(sig = SM2_do_sign(pbData, (int)ulDataLen, ec_key))) { + SKFerr(SKF_F_SKF_EXTECCSIGN, SKF_R_SIGN_FAILED); + goto end; + } + + if (!ECDSA_SIG_get_ECCSIGNATUREBLOB(sig, pSignature)) { + SKFerr(SKF_F_SKF_EXTECCSIGN, SKF_R_ENCODE_SIGNATURE_FAILED); + goto end; + } + + ret = SAR_OK; +end: + EC_KEY_free(ec_key); + ECDSA_SIG_free(sig); + return ret; +} + +ULONG DEVAPI SKF_ExtECCVerify(DEVHANDLE hDev, + ECCPUBLICKEYBLOB *pECCPubKeyBlob, + BYTE *pbData, + ULONG ulDataLen, + ECCSIGNATUREBLOB *pSignature) +{ + ULONG ret = SAR_FAIL; + EC_KEY *ec_key = NULL; + ECDSA_SIG *sig = NULL; + + if (!pECCPubKeyBlob || !pbData || pSignature) { + SKFerr(SKF_F_SKF_EXTECCVERIFY, SKF_R_NULL_ARGUMENT); + return SAR_INVALIDPARAMERR; + } + + if (ulDataLen != SM3_DIGEST_LENGTH) { + SKFerr(SKF_F_SKF_EXTECCVERIFY, SKF_R_INVALID_DIGEST_LENGTH); + return SAR_INVALIDPARAMERR; + } + + if (!(ec_key = EC_KEY_new_from_ECCPUBLICKEYBLOB(pECCPubKeyBlob))) { + SKFerr(SKF_F_SKF_EXTECCVERIFY, SKF_R_INVALID_ECC_PUBLIC_KEY); + goto end; + } + + if (!(sig = ECDSA_SIG_new_from_ECCSIGNATUREBLOB(pSignature))) { + SKFerr(SKF_F_SKF_EXTECCVERIFY, SKF_R_INVALID_SIGNATURE); + goto end; + } + + if (1 != SM2_do_verify(pbData, (int)ulDataLen, sig, ec_key)) { + SKFerr(SKF_F_SKF_EXTECCVERIFY, SKF_R_VERIFY_NOT_PASS); + goto end; + } + + ret = SAR_OK; + +end: + EC_KEY_free(ec_key); + ECDSA_SIG_free(sig); + return ret; +} + +ULONG DEVAPI SKF_ECCVerify(DEVHANDLE hDev, + ECCPUBLICKEYBLOB *pECCPubKeyBlob, + BYTE *pbData, + ULONG ulDataLen, + ECCSIGNATUREBLOB *pSignature) +{ + return SKF_ExtECCVerify(hDev, pECCPubKeyBlob, pbData, ulDataLen, pSignature); +} + +ULONG DEVAPI SKF_ExtECCEncrypt(DEVHANDLE hDev, + ECCPUBLICKEYBLOB *pECCPubKeyBlob, + BYTE *pbPlainText, + ULONG ulPlainTextLen, + ECCCIPHERBLOB *pCipherText) +{ + ULONG ret = SAR_FAIL; + EC_KEY *ec_key = NULL; + SM2_CIPHERTEXT_VALUE *cv = NULL; + SM2_ENC_PARAMS params; + + if (!pECCPubKeyBlob || !pbPlainText || !pCipherText) { + SKFerr(SKF_F_SKF_EXTECCENCRYPT, SKF_R_NULL_ARGUMENT); + return SAR_INVALIDPARAMERR; + } + + if (ulPlainTextLen <= 0) { + SKFerr(SKF_F_SKF_EXTECCENCRYPT, SKF_R_INVALID_PLAINTEXT_LENGTH); + return SAR_INVALIDPARAMERR; + } + + if (!(ec_key = EC_KEY_new_from_ECCPUBLICKEYBLOB(pECCPubKeyBlob))) { + SKFerr(SKF_F_SKF_EXTECCENCRYPT, SKF_R_INVALID_EC_PUBLIC_KEY); + goto end; + } + + SM2_ENC_PARAMS_init_with_recommended(¶ms); + if (!(cv = SM2_do_encrypt(¶ms, pbPlainText, ulPlainTextLen, ec_key))) { + SKFerr(SKF_F_SKF_EXTECCENCRYPT, SKF_R_ENCRYPT_FAILED); + goto end; + } + + if (!SM2_CIPHERTEXT_VALUE_get_ECCCIPHERBLOB(cv, pCipherText)) { + SKFerr(SKF_F_SKF_EXTECCENCRYPT, SKF_R_ENCODE_CIPHERTEXT_FAILED); + goto end; + } + + ret = SAR_OK; + +end: + EC_KEY_free(ec_key); + SM2_CIPHERTEXT_VALUE_free(cv); + return ret; +} + +ULONG DEVAPI SKF_ExtECCDecrypt(DEVHANDLE hDev, + ECCPRIVATEKEYBLOB *pECCPriKeyBlob, + ECCCIPHERBLOB *pCipherText, + BYTE *pbPlainText, + ULONG *pulPlainTextLen) +{ + ULONG ret = SAR_FAIL; + EC_KEY *ec_key = NULL; + SM2_CIPHERTEXT_VALUE *cv = NULL; + SM2_ENC_PARAMS params; + size_t len; + + if (!pECCPriKeyBlob || !pCipherText || !pulPlainTextLen) { + SKFerr(SKF_F_SKF_EXTECCDECRYPT, SKF_R_NULL_ARGUMENT); + return SAR_INVALIDPARAMERR; + } + + if (pCipherText->CipherLen <= 0) { + SKFerr(SKF_F_SKF_EXTECCDECRYPT, SKF_R_INVALID_CIPHERTEXT_LENGTH); + return SAR_INVALIDPARAMERR; + } + + if (!pbPlainText) { + *pulPlainTextLen = pCipherText->CipherLen; + return SAR_OK; + } + + if (!(ec_key = EC_KEY_new_from_ECCPRIVATEKEYBLOB(pECCPriKeyBlob))) { + SKFerr(SKF_F_SKF_EXTECCDECRYPT, SKF_R_INVALID_EC_PRIVATE_KEY); + goto end; + } + + if (!(cv = SM2_CIPHERTEXT_VALUE_new_from_ECCCIPHERBLOB(pCipherText))) { + SKFerr(SKF_F_SKF_EXTECCDECRYPT, SKF_R_INVALID_CIPHERTEXT); + goto end; + } + + SM2_ENC_PARAMS_init_with_recommended(¶ms); + len = *pulPlainTextLen; //FIXME: check length? + if (!SM2_do_decrypt(¶ms, cv, pbPlainText, &len, ec_key)) { + SKFerr(SKF_F_SKF_EXTECCDECRYPT, SKF_R_DECRYPT_FAILED); + goto end; + } + *pulPlainTextLen = (ULONG)len; + + ret = SAR_OK; + +end: + EC_KEY_free(ec_key); + SM2_CIPHERTEXT_VALUE_free(cv); + return ret; +} + diff --git a/crypto/skf/skf_enc.c b/crypto/skf/skf_enc.c new file mode 100644 index 00000000..7c24b1d8 --- /dev/null +++ b/crypto/skf/skf_enc.c @@ -0,0 +1,404 @@ +/* ==================================================================== + * 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. + * ==================================================================== + */ + +#include +#include +#include +#include +#include +#include "skf_lcl.h" + +#define PADDING_TYPE_NO_PADDING 0 +#define PADDING_TYPE_PKCS5 1 + +/* +229 typedef struct Struct_BLOCKCIPHERPARAM { +230 BYTE IV[MAX_IV_LEN]; +231 ULONG IVLen; +232 ULONG PaddingType; +233 ULONG FeedBitLen; +234 } BLOCKCIPHERPARAM, *PBLOCKCIPHERPARAM; +*/ + +int SKF_nid_to_encparams(int nid, ULONG *algID, BLOCKCIPHERPARAM *params) +{ + ULONG ulAlgID = 0; + + switch (nid) { + case NID_ssf33_ecb: + ulAlgID = SGD_SSF33_ECB; + break; + case NID_ssf33_cbc: + ulAlgID = SGD_SSF33_CBC; + break; + case NID_ssf33_cfb1: + case NID_ssf33_cfb8: + case NID_ssf33_cfb128: + ulAlgID = SGD_SSF33_CFB; + break; + case NID_ssf33_ofb128: + ulAlgID = SGD_SSF33_OFB; + break; + case NID_sm1_ecb: + ulAlgID = SGD_SM1_ECB; + break; + case NID_sm1_cbc: + ulAlgID = SGD_SM1_CBC; + break; + case NID_sm1_cfb1: + case NID_sm1_cfb8: + case NID_sm1_cfb128: + ulAlgID = SGD_SM1_CFB; + break; + case NID_sm1_ofb128: + ulAlgID = SGD_SM1_OFB; + break; + case NID_sms4_ecb: + ulAlgID = SGD_SM4_ECB; + break; + case NID_sms4_cbc: + ulAlgID = SGD_SM4_CBC; + break; + case NID_sms4_cfb1: + case NID_sms4_cfb8: + case NID_sms4_cfb128: + ulAlgID = SGD_SM4_CFB; + break; + case NID_sms4_ofb128: + ulAlgID = SGD_SM4_OFB; + break; + default: + return 0; + } + + *algID = ulAlgID; + + switch (nid) { + case NID_sm1_cfb1: + case NID_sms4_cfb1: + case NID_ssf33_cfb1: + params->FeedBitLen = 1; + break; + case NID_sm1_cfb8: + case NID_sms4_cfb8: + case NID_ssf33_cfb8: + params->FeedBitLen = 8; + break; + case NID_sm1_cfb128: + case NID_sms4_cfb128: + case NID_ssf33_cfb128: + params->FeedBitLen = 128; + break; + default: + params->FeedBitLen = 0; + } + + switch (nid) { + case NID_sm1_cbc: + case NID_sms4_cbc: + case NID_ssf33_cbc: + params->PaddingType = SKF_PKCS5_PADDING; + break; + default: + params->PaddingType = SKF_NO_PADDING; + } + + return 1; +} + + +ULONG DEVAPI SKF_EncryptInit(HANDLE hKey, + BLOCKCIPHERPARAM encryptParam) +{ + ULONG ret = SAR_FAIL; + BLOCKCIPHERPARAM *encparam = &encryptParam; + EVP_CIPHER_CTX *ctx = NULL; + const EVP_CIPHER *cipher; + unsigned char *key; + unsigned char *iv; + + if (!(cipher = SKF_HANDLE_get_cipher(hKey, encparam))) { + SKFerr(SKF_F_SKF_ENCRYPTINIT, SKF_R_INVALID_KEY_HANDLE); + return SAR_INVALIDPARAMERR; + } + + if (!(key = SKF_HANDLE_get_key(hKey))) { + SKFerr(SKF_F_SKF_ENCRYPTINIT, SKF_R_INVALID_KEY_HANDLE); + return SAR_INVALIDPARAMERR; + } + + if (encparam->IVLen != SMS4_IV_LENGTH) { + SKFerr(SKF_F_SKF_ENCRYPTINIT, SKF_R_INVALID_IV_LENGTH); + return SAR_INVALIDPARAMERR; + } + iv = encparam->IV; + + if (!(ctx = EVP_CIPHER_CTX_new())) { + SKFerr(SKF_F_SKF_ENCRYPTINIT, ERR_R_EVP_LIB); + return SAR_INVALIDPARAMERR; + } + + if (!EVP_EncryptInit_ex(ctx, cipher, NULL, key, iv)) { + SKFerr(SKF_F_SKF_ENCRYPTINIT, ERR_R_EVP_LIB); + goto end; + } + + ((SKF_HANDLE *)hKey)->type = SKF_CIPHER_HANDLE; + ((SKF_HANDLE *)hKey)->u.cipher_ctx = ctx; + ctx = NULL; + + ret = SAR_OK; +end: + EVP_CIPHER_CTX_free(ctx); + return ret; +} + +ULONG DEVAPI SKF_EncryptUpdate(HANDLE hKey, + BYTE *pbData, + ULONG ulDataLen, + BYTE *pbEncryptedData, + ULONG *pulEncryptedLen) +{ + EVP_CIPHER_CTX *ctx; + int inlen, outlen; + + if (!(ctx = SKF_HANDLE_get_cipher_ctx(hKey))) { + SKFerr(SKF_F_SKF_ENCRYPTUPDATE, SKF_R_INVALID_CIPHER_CTX_HANDLE); + return SAR_INVALIDPARAMERR; + } + + //FIXME: check INT_MAX + inlen = ulDataLen; + outlen = *pulEncryptedLen; + if (!EVP_EncryptUpdate(ctx, pbEncryptedData, &outlen, pbData, inlen)) { + SKFerr(SKF_F_SKF_ENCRYPTUPDATE, ERR_R_EVP_LIB); + return SAR_FAIL; + } + + *pulEncryptedLen = outlen; + return SAR_OK; +} + +ULONG DEVAPI SKF_EncryptFinal(HANDLE hKey, + BYTE *pbEncryptedData, + ULONG *pulEncryptedDataLen) +{ + EVP_CIPHER_CTX *ctx; + int outlen; + + if (!(ctx = SKF_HANDLE_get_cipher_ctx(hKey))) { + SKFerr(SKF_F_SKF_ENCRYPTFINAL, SKF_R_INVALID_CIPHER_CTX_HANDLE); + return SAR_INVALIDPARAMERR; + } + + outlen = *pulEncryptedDataLen; + if (!EVP_EncryptFinal(ctx, pbEncryptedData, &outlen)) { + SKFerr(SKF_F_SKF_ENCRYPTFINAL, ERR_R_EVP_LIB); + return SAR_FAIL; + } + + *pulEncryptedDataLen = outlen; + EVP_CIPHER_CTX_free(ctx); + ((SKF_HANDLE *)hKey)->u.cipher_ctx = NULL; + ((SKF_HANDLE *)hKey)->type = SKF_KEY_HANDLE; + return SAR_OK; +} + +ULONG DEVAPI SKF_DecryptInit(HANDLE hKey, + BLOCKCIPHERPARAM DecryptParam) +{ + ULONG ret = SAR_FAIL; + BLOCKCIPHERPARAM *param = &DecryptParam; + EVP_CIPHER_CTX *ctx = NULL; + const EVP_CIPHER *cipher; + unsigned char *key; + unsigned char *iv; + + if (!(cipher = SKF_HANDLE_get_cipher(hKey, param))) { + SKFerr(SKF_F_SKF_DECRYPTINIT, SKF_R_INVALID_KEY_HANDLE); + return SAR_INVALIDPARAMERR; + } + if (!(key = SKF_HANDLE_get_key(hKey))) { + SKFerr(SKF_F_SKF_DECRYPTINIT, SKF_R_INVALID_KEY_HANDLE); + return SAR_INVALIDPARAMERR; + } + if (param->IVLen != SMS4_IV_LENGTH) { + SKFerr(SKF_F_SKF_DECRYPTINIT, SKF_R_INVALID_IV_LENGTH); + ret = SAR_INVALIDPARAMERR; + goto end; + } + iv = param->IV; + + if (!(ctx = EVP_CIPHER_CTX_new())) { + SKFerr(SKF_F_SKF_DECRYPTINIT, ERR_R_EVP_LIB); + goto end; + } + + if (!EVP_DecryptInit_ex(ctx, cipher, NULL, key, iv)) { + SKFerr(SKF_F_SKF_DECRYPTINIT, ERR_R_EVP_LIB); + goto end; + } + + ((SKF_HANDLE *)hKey)->type = SKF_CIPHER_HANDLE; + ((SKF_HANDLE *)hKey)->u.cipher_ctx = ctx; + ctx = NULL; + + ret = SAR_OK; +end: + EVP_CIPHER_CTX_free(ctx); + return ret; + + return SAR_OK; +} + +ULONG DEVAPI SKF_DecryptUpdate(HANDLE hKey, + BYTE *pbEncryptedData, + ULONG ulEncryptedLen, + BYTE *pbData, + ULONG *pulDataLen) +{ + EVP_CIPHER_CTX *ctx; + int inlen, outlen; + + if (!(ctx = SKF_HANDLE_get_cipher_ctx(hKey))) { + SKFerr(SKF_F_SKF_DECRYPTUPDATE, SKF_R_INVALID_CIPHER_CTX_HANDLE); + return SAR_INVALIDPARAMERR; + } + + //FIXME: check INT_MAX + inlen = ulEncryptedLen; + outlen = *pulDataLen; + if (!EVP_DecryptUpdate(ctx, pbData, &outlen, pbEncryptedData, inlen)) { + SKFerr(SKF_F_SKF_DECRYPTUPDATE, ERR_R_EVP_LIB); + return SAR_FAIL; + } + + *pulDataLen = outlen; + return SAR_OK; +} + +ULONG DEVAPI SKF_DecryptFinal(HANDLE hKey, + BYTE *pbDecryptedData, + ULONG *pulDecryptedDataLen) +{ + EVP_CIPHER_CTX *ctx; + int len; + + if (!(ctx = SKF_HANDLE_get_cipher_ctx(hKey))) { + SKFerr(SKF_F_SKF_DECRYPTFINAL, SKF_R_INVALID_KEY_HANDLE); + return SAR_INVALIDPARAMERR; + } + + if (!EVP_DecryptFinal(ctx, pbDecryptedData, &len)) { + return SAR_FAIL; + } + + *pulDecryptedDataLen = len; + EVP_CIPHER_CTX_free(ctx); + ((SKF_HANDLE *)hKey)->u.cipher_ctx = NULL; + ((SKF_HANDLE *)hKey)->type = SKF_KEY_HANDLE; + return SAR_OK; +} + +ULONG DEVAPI SKF_Encrypt(HANDLE hKey, + BYTE *pbData, + ULONG ulDataLen, + BYTE *pbEncryptedData, + ULONG *pulEncryptedLen) +{ + ULONG rv; + BYTE *p; + ULONG len; + + p = pbEncryptedData; + len = *pulEncryptedLen; + if ((rv = SKF_EncryptUpdate(hKey, pbData, ulDataLen, p, &len)) != SAR_OK) { + SKFerr(SKF_F_SKF_ENCRYPT, ERR_R_GMAPI_LIB); + return rv; + } + + p += len; + len = *pulEncryptedLen - len; + if ((rv = SKF_EncryptFinal(hKey, p, &len)) != SAR_OK) { + SKFerr(SKF_F_SKF_ENCRYPT, ERR_R_GMAPI_LIB); + return rv; + } + + *pulEncryptedLen = p + len - pbEncryptedData; + return SAR_OK; +} + +ULONG DEVAPI SKF_Decrypt(HANDLE hKey, + BYTE *pbEncryptedData, + ULONG ulEncryptedLen, + BYTE *pbData, + ULONG *pulDataLen) +{ + ULONG rv; + BYTE *p; + ULONG len; + + p = pbData; + len = *pulDataLen; + if ((rv = SKF_DecryptUpdate(hKey, pbEncryptedData, ulEncryptedLen, p, &len)) != SAR_OK) { + SKFerr(SKF_F_SKF_DECRYPT, ERR_R_GMAPI_LIB); + return rv; + } + + p += len; + len = *pulDataLen - len; + if ((rv = SKF_DecryptFinal(hKey, p, &len)) != SAR_OK) { + SKFerr(SKF_F_SKF_DECRYPT, ERR_R_GMAPI_LIB); + return rv; + } + + *pulDataLen = p + len - pbData; + return SAR_OK; +} + diff --git a/crypto/skf/skf_err.c b/crypto/skf/skf_err.c new file mode 100644 index 00000000..3a62ebe1 --- /dev/null +++ b/crypto/skf/skf_err.c @@ -0,0 +1,121 @@ +/* + * Generated by util/mkerr.pl DO NOT EDIT + * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include +#include + +/* BEGIN ERROR CODES */ +#ifndef OPENSSL_NO_ERR + +# define ERR_FUNC(func) ERR_PACK(ERR_LIB_SKF,func,0) +# define ERR_REASON(reason) ERR_PACK(ERR_LIB_SKF,0,reason) + +static ERR_STRING_DATA SKF_str_functs[] = { + {ERR_FUNC(SKF_F_SKF_CLOSEHANDLE), "SKF_CloseHandle"}, + {ERR_FUNC(SKF_F_SKF_DECRYPT), "SKF_Decrypt"}, + {ERR_FUNC(SKF_F_SKF_DECRYPTFINAL), "SKF_DecryptFinal"}, + {ERR_FUNC(SKF_F_SKF_DECRYPTINIT), "SKF_DecryptInit"}, + {ERR_FUNC(SKF_F_SKF_DECRYPTUPDATE), "SKF_DecryptUpdate"}, + {ERR_FUNC(SKF_F_SKF_DIGEST), "SKF_Digest"}, + {ERR_FUNC(SKF_F_SKF_DIGESTFINAL), "SKF_DigestFinal"}, + {ERR_FUNC(SKF_F_SKF_DIGESTINIT), "SKF_DigestInit"}, + {ERR_FUNC(SKF_F_SKF_DIGESTUPDATE), "SKF_DigestUpdate"}, + {ERR_FUNC(SKF_F_SKF_ENCRYPT), "SKF_Encrypt"}, + {ERR_FUNC(SKF_F_SKF_ENCRYPTFINAL), "SKF_EncryptFinal"}, + {ERR_FUNC(SKF_F_SKF_ENCRYPTINIT), "SKF_EncryptInit"}, + {ERR_FUNC(SKF_F_SKF_ENCRYPTUPDATE), "SKF_EncryptUpdate"}, + {ERR_FUNC(SKF_F_SKF_EXTECCDECRYPT), "SKF_ExtECCDecrypt"}, + {ERR_FUNC(SKF_F_SKF_EXTECCENCRYPT), "SKF_ExtECCEncrypt"}, + {ERR_FUNC(SKF_F_SKF_EXTECCSIGN), "SKF_ExtECCSign"}, + {ERR_FUNC(SKF_F_SKF_EXTECCVERIFY), "SKF_ExtECCVerify"}, + {ERR_FUNC(SKF_F_SKF_EXTRSAPRIKEYOPERATION), "SKF_ExtRSAPriKeyOperation"}, + {ERR_FUNC(SKF_F_SKF_EXTRSAPUBKEYOPERATION), "SKF_ExtRSAPubKeyOperation"}, + {ERR_FUNC(SKF_F_SKF_GENEXTECCKEYPAIR), "SKF_GenExtECCKeyPair"}, + {ERR_FUNC(SKF_F_SKF_GENEXTRSAKEY), "SKF_GenExtRSAKey"}, + {ERR_FUNC(SKF_F_SKF_GENRANDOM), "SKF_GenRandom"}, + {ERR_FUNC(SKF_F_SKF_GETDEVINFO), "SKF_GetDevInfo"}, + {ERR_FUNC(SKF_F_SKF_GETDEVSTATE), "SKF_GetDevState"}, + {ERR_FUNC(SKF_F_SKF_HANDLE_GET_CBCMAC_CTX), "SKF_HANDLE_get_cbcmac_ctx"}, + {ERR_FUNC(SKF_F_SKF_HANDLE_GET_CIPHER), "SKF_HANDLE_get_cipher"}, + {ERR_FUNC(SKF_F_SKF_HANDLE_GET_CIPHER_CTX), "SKF_HANDLE_get_cipher_ctx"}, + {ERR_FUNC(SKF_F_SKF_HANDLE_GET_KEY), "SKF_HANDLE_get_key"}, + {ERR_FUNC(SKF_F_SKF_HANDLE_GET_MD_CTX), "SKF_HANDLE_get_md_ctx"}, + {ERR_FUNC(SKF_F_SKF_MAC), "SKF_Mac"}, + {ERR_FUNC(SKF_F_SKF_MACFINAL), "SKF_MacFinal"}, + {ERR_FUNC(SKF_F_SKF_MACINIT), "SKF_MacInit"}, + {ERR_FUNC(SKF_F_SKF_MACUPDATE), "SKF_MacUpdate"}, + {ERR_FUNC(SKF_F_SKF_SETSYMMKEY), "SKF_SetSymmKey"}, + {0, NULL} +}; + +static ERR_STRING_DATA SKF_str_reasons[] = { + {ERR_REASON(SKF_R_BUFFER_TOO_SMALL), "buffer too small"}, + {ERR_REASON(SKF_R_CTX_NOT_CREATED), "ctx not created"}, + {ERR_REASON(SKF_R_DECRYPT_FAILED), "decrypt failed"}, + {ERR_REASON(SKF_R_ENCODE_CIPHERTEXT_FAILED), "encode ciphertext failed"}, + {ERR_REASON(SKF_R_ENCODE_FAILED), "encode failed"}, + {ERR_REASON(SKF_R_ENCODE_SIGNATURE_FAILED), "encode signature failed"}, + {ERR_REASON(SKF_R_ENCRYPT_FAILED), "encrypt failed"}, + {ERR_REASON(SKF_R_FAIL), "fail"}, + {ERR_REASON(SKF_R_GEN_RSA_FAILED), "gen rsa failed"}, + {ERR_REASON(SKF_R_GET_PRIVATE_KEY_FAILED), "get private key failed"}, + {ERR_REASON(SKF_R_GET_PUBLIC_KEY_FAILED), "get public key failed"}, + {ERR_REASON(SKF_R_INVALID_ALGID), "invalid algid"}, + {ERR_REASON(SKF_R_INVALID_ALGOR), "invalid algor"}, + {ERR_REASON(SKF_R_INVALID_ARGUMENTS), "invalid arguments"}, + {ERR_REASON(SKF_R_INVALID_BLOB), "invalid blob"}, + {ERR_REASON(SKF_R_INVALID_CIPHERTEXT), "invalid ciphertext"}, + {ERR_REASON(SKF_R_INVALID_CIPHERTEXT_LENGTH), + "invalid ciphertext length"}, + {ERR_REASON(SKF_R_INVALID_CIPHER_CTX_HANDLE), + "invalid cipher ctx handle"}, + {ERR_REASON(SKF_R_INVALID_DIGEST_LENGTH), "invalid digest length"}, + {ERR_REASON(SKF_R_INVALID_ECC_PRIVATE_KEY), "invalid ecc private key"}, + {ERR_REASON(SKF_R_INVALID_ECC_PUBLIC_KEY), "invalid ecc public key"}, + {ERR_REASON(SKF_R_INVALID_EC_PRIVATE_KEY), "invalid ec private key"}, + {ERR_REASON(SKF_R_INVALID_EC_PUBLIC_KEY), "invalid ec public key"}, + {ERR_REASON(SKF_R_INVALID_FEED_BIT_LENGTH), "invalid feed bit length"}, + {ERR_REASON(SKF_R_INVALID_HANDLE), "invalid handle"}, + {ERR_REASON(SKF_R_INVALID_HANDLE_ALGOR), "invalid handle algor"}, + {ERR_REASON(SKF_R_INVALID_HANDLE_MAGIC), "invalid handle magic"}, + {ERR_REASON(SKF_R_INVALID_HANDLE_TYPE), "invalid handle type"}, + {ERR_REASON(SKF_R_INVALID_HASH_HANDLE), "invalid hash handle"}, + {ERR_REASON(SKF_R_INVALID_ID_LENGTH), "invalid id length"}, + {ERR_REASON(SKF_R_INVALID_INPUT_LENGTH), "invalid input length"}, + {ERR_REASON(SKF_R_INVALID_IV_LENGTH), "invalid iv length"}, + {ERR_REASON(SKF_R_INVALID_KEY_HANDLE), "invalid key handle"}, + {ERR_REASON(SKF_R_INVALID_KEY_LENGTH), "invalid key length"}, + {ERR_REASON(SKF_R_INVALID_MAC_HANDLE), "invalid mac handle"}, + {ERR_REASON(SKF_R_INVALID_PLAINTEXT_LENGTH), "invalid plaintext length"}, + {ERR_REASON(SKF_R_INVALID_RANDOM_LENGTH), "invalid random length"}, + {ERR_REASON(SKF_R_INVALID_RSA_PUBLIC_KEY), "invalid rsa public key"}, + {ERR_REASON(SKF_R_INVALID_SIGNATURE), "invalid signature"}, + {ERR_REASON(SKF_R_MALLOC_FAILED), "malloc failed"}, + {ERR_REASON(SKF_R_NO_PUBLIC_KEY), "no public key"}, + {ERR_REASON(SKF_R_NULL_ARGUMENT), "null argument"}, + {ERR_REASON(SKF_R_SIGN_FAILED), "sign failed"}, + {ERR_REASON(SKF_R_VERIFY_NOT_PASS), "verify not pass"}, + {0, NULL} +}; + +#endif + +int ERR_load_SKF_strings(void) +{ +#ifndef OPENSSL_NO_ERR + + if (ERR_func_error_string(SKF_str_functs[0].error) == NULL) { + ERR_load_strings(0, SKF_str_functs); + ERR_load_strings(0, SKF_str_reasons); + } +#endif + return 1; +} diff --git a/crypto/skf/skf_errstr.c b/crypto/skf/skf_errstr.c new file mode 100644 index 00000000..4a192e19 --- /dev/null +++ b/crypto/skf/skf_errstr.c @@ -0,0 +1,118 @@ +/* ==================================================================== + * Copyright (c) 2016 The GmSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the GmSSL Project. + * (http://gmssl.org/)" + * + * 4. The name "GmSSL Project" must not be used to endorse or promote + * products derived from this software without prior written + * permission. For written permission, please contact + * guanzhi1980@gmail.com. + * + * 5. Products derived from this software may not be called "GmSSL" + * nor may "GmSSL" appear in their names without prior written + * permission of the GmSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the GmSSL Project + * (http://gmssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE GmSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GmSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + */ + +#include +#include +#include "../../e_os.h" + +static ERR_STRING_DATA skf_errstr[] = { + { SAR_OK, "Success" }, + { SAR_FAIL, "Failure" }, + { SAR_UNKNOWNERR, "Unknown error" }, + { SAR_NOTSUPPORTYETERR, "Not supported" }, + { SAR_FILEERR, "File error" }, + { SAR_INVALIDHANDLEERR, "Invalid handle" }, + { SAR_INVALIDPARAMERR, "Invalid parameter" }, + { SAR_READFILEERR, "Read file error" }, + { SAR_WRITEFILEERR, "Write file error" }, + { SAR_NAMELENERR, "Name length error" }, + { SAR_KEYUSAGEERR, "Key usage error" }, + { SAR_MODULUSLENERR, "Modulus length error" }, + { SAR_NOTINITIALIZEERR, "Not initialized" }, + { SAR_OBJERR, "Object error" }, + { SAR_MEMORYERR, "Memory error" }, + { SAR_TIMEOUTERR, "Time out" }, + { SAR_INDATALENERR, "Input data length error" }, + { SAR_INDATAERR, "Input data error" }, + { SAR_GENRANDERR, "Generate randomness error" }, + { SAR_HASHOBJERR, "Hash object error" }, + { SAR_HASHERR, "Hash error" }, + { SAR_GENRSAKEYERR, "Genenerate RSA key error" }, + { SAR_RSAMODULUSLENERR, "RSA modulus length error" }, + { SAR_CSPIMPRTPUBKEYERR, "CSP import public key error" }, + { SAR_RSAENCERR, "RSA encryption error" }, + { SAR_RSADECERR, "RSA decryption error" }, + { SAR_HASHNOTEQUALERR, "Hash not equal" }, + { SAR_KEYNOTFOUNTERR, "Key not found" }, + { SAR_CERTNOTFOUNTERR, "Certificate not found" }, + { SAR_NOTEXPORTERR, "Not exported" }, + { SAR_DECRYPTPADERR, "Decrypt pad error" }, + { SAR_MACLENERR, "MAC length error" }, + { SAR_BUFFER_TOO_SMALL, "Buffer too small" }, + { SAR_KEYINFOTYPEERR, "Key info type error" }, + { SAR_NOT_EVENTERR, "No event error" }, + { SAR_DEVICE_REMOVED, "Device removed" }, + { SAR_PIN_INCORRECT, "PIN incorrect" }, + { SAR_PIN_LOCKED, "PIN locked" }, + { SAR_PIN_INVALID, "PIN invalid" }, + { SAR_PIN_LEN_RANGE, "PIN length error" }, + { SAR_USER_ALREADY_LOGGED_IN, "User already logged in" }, + { SAR_USER_PIN_NOT_INITIALIZED, "User PIN not initialized" }, + { SAR_USER_TYPE_INVALID, "User type invalid" }, + { SAR_APPLICATION_NAME_INVALID, "Application name invalid" }, + { SAR_APPLICATION_EXISTS, "Application already exist" }, + { SAR_USER_NOT_LOGGED_IN, "User not logged in" }, + { SAR_APPLICATION_NOT_EXISTS, "Application not exist" }, + { SAR_FILE_ALREADY_EXIST, "File already exist" }, + { SAR_NO_ROOM, "No file space" }, + { SAR_FILE_NOT_EXIST, "File not exist" } +}; + +char *SKF_GetErrorString(ULONG ulError) +{ + int i; + for (i = 0; i < OSSL_NELEM(skf_errstr); i++) { + if (ulError == skf_errstr[i].error) { + return skf_errstr[i].string; + } + } + return "(undef)"; +} + diff --git a/crypto/skf/skf_handle.c b/crypto/skf/skf_handle.c new file mode 100644 index 00000000..87e933f3 --- /dev/null +++ b/crypto/skf/skf_handle.c @@ -0,0 +1,248 @@ +/* crypto/gmapi/skf_handle.c */ +/* ==================================================================== + * Copyright (c) 2016 The GmSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the GmSSL Project. + * (http://gmssl.org/)" + * + * 4. The name "GmSSL Project" must not be used to endorse or promote + * products derived from this software without prior written + * permission. For written permission, please contact + * guanzhi1980@gmail.com. + * + * 5. Products derived from this software may not be called "GmSSL" + * nor may "GmSSL" appear in their names without prior written + * permission of the GmSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the GmSSL Project + * (http://gmssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE GmSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GmSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + */ + +#include +#include +#include +#include "skf_lcl.h" + +unsigned char *SKF_HANDLE_get_key(HANDLE hKey) +{ + SKF_HANDLE *handle; + + if (!(handle = (SKF_HANDLE *)hKey)) { + SKFerr(SKF_F_SKF_HANDLE_GET_KEY, ERR_R_PASSED_NULL_PARAMETER); + return NULL; + } + if (handle->magic != SKF_HANDLE_MAGIC) { + SKFerr(SKF_F_SKF_HANDLE_GET_KEY, SKF_R_INVALID_HANDLE_MAGIC); + return NULL; + } + if (handle->type < SKF_KEY_HANDLE) { + SKFerr(SKF_F_SKF_HANDLE_GET_KEY, SKF_R_INVALID_HANDLE_TYPE); + return NULL; + } + + switch (handle->algid) { + case SGD_SM4_ECB: + case SGD_SM4_CBC: + case SGD_SM4_CFB: + case SGD_SM4_OFB: + case SGD_SM4_MAC: + break; + default: + SKFerr(SKF_F_SKF_HANDLE_GET_KEY, SKF_R_INVALID_ALGOR); + return NULL; + } + + if (!handle->keylen) { + SKFerr(SKF_F_SKF_HANDLE_GET_KEY, SKF_R_INVALID_KEY_HANDLE); + return NULL; + } + return handle->key; +} + +const EVP_CIPHER *SKF_HANDLE_get_cipher(HANDLE hKey, BLOCKCIPHERPARAM *param) +{ + SKF_HANDLE *handle = (SKF_HANDLE *)hKey; + if (!SKF_HANDLE_get_key(hKey)) { + SKFerr(SKF_F_SKF_HANDLE_GET_CIPHER, SKF_R_INVALID_KEY_HANDLE); + return NULL; + } + + switch (handle->algid) { + case SGD_SM4_ECB: + return EVP_sms4_ecb(); + case SGD_SM4_CBC: + return EVP_sms4_cbc(); + case SGD_SM4_OFB: + return EVP_sms4_ofb(); + case SGD_SM4_CFB: + switch (param->FeedBitLen) { + case 1: return EVP_sms4_cfb1(); + case 8: return EVP_sms4_cfb8(); + case 128: return EVP_sms4_cfb128(); + } + SKFerr(SKF_F_SKF_HANDLE_GET_CIPHER, SKF_R_INVALID_FEED_BIT_LENGTH); + return NULL; + } + + SKFerr(SKF_F_SKF_HANDLE_GET_CIPHER, SKF_R_INVALID_HANDLE_ALGOR); + return NULL; +} + +EVP_MD_CTX *SKF_HANDLE_get_md_ctx(HANDLE hHash) +{ + EVP_MD_CTX *ret; + SKF_HANDLE *handle; + + if (!(handle = (SKF_HANDLE *)hHash)) { + SKFerr(SKF_F_SKF_HANDLE_GET_MD_CTX, ERR_R_PASSED_NULL_PARAMETER); + return NULL; + } + if (handle->magic != SKF_HANDLE_MAGIC) { + SKFerr(SKF_F_SKF_HANDLE_GET_MD_CTX, SKF_R_INVALID_HANDLE_MAGIC); + return NULL; + } + if (handle->type != SKF_HASH_HANDLE) { + SKFerr(SKF_F_SKF_HANDLE_GET_MD_CTX, SKF_R_INVALID_HANDLE_TYPE); + return NULL; + } + + if (!(ret = handle->u.md_ctx)) { + SKFerr(SKF_F_SKF_HANDLE_GET_MD_CTX, SKF_R_CTX_NOT_CREATED); + return NULL; + } + return ret; +} + +CMAC_CTX *SKF_HANDLE_get_cbcmac_ctx(HANDLE hMac) +{ + CMAC_CTX *ret; + SKF_HANDLE *handle; + + if (!(handle = (SKF_HANDLE *)hMac)) { + SKFerr(SKF_F_SKF_HANDLE_GET_CMAC_CTX, ERR_R_PASSED_NULL_PARAMETER); + return NULL; + } + if (handle->magic != SKF_HANDLE_MAGIC) { + SKFerr(SKF_F_SKF_HANDLE_GET_CMAC_CTX, SKF_R_INVALID_HANDLE_MAGIC); + return NULL; + } + if (handle->type != SKF_MAC_HANDLE) { + SKFerr(SKF_F_SKF_HANDLE_GET_CMAC_CTX, SKF_R_INVALID_HANDLE_TYPE); + return NULL; + } + + if (!(ret = handle->u.cbcmac_ctx)) { + SKFerr(SKF_F_SKF_HANDLE_GET_CMAC_CTX, SKF_R_CTX_NOT_CREATED); + return NULL; + } + return ret; +} + +EVP_CIPHER_CTX *SKF_HANDLE_get_cipher_ctx(HANDLE hKey) +{ + EVP_CIPHER_CTX *ret; + SKF_HANDLE *handle; + + if (!(handle = (SKF_HANDLE *)hKey)) { + SKFerr(SKF_F_SKF_HANDLE_GET_CIPHER_CTX, ERR_R_PASSED_NULL_PARAMETER); + return NULL; + } + if (handle->magic != SKF_HANDLE_MAGIC) { + SKFerr(SKF_F_SKF_HANDLE_GET_CIPHER_CTX, SKF_R_INVALID_HANDLE_MAGIC); + return NULL; + } + if (handle->type != SKF_CIPHER_HANDLE) { + SKFerr(SKF_F_SKF_HANDLE_GET_CIPHER_CTX, SKF_R_INVALID_HANDLE_TYPE); + return NULL; + } + + if (!(ret = handle->u.cipher_ctx)) { + SKFerr(SKF_F_SKF_HANDLE_GET_CIPHER_CTX, SKF_R_CTX_NOT_CREATED); + return NULL; + } + return ret; +} + +int SKF_HANDLE_free(HANDLE handle) +{ + return 0; +} + + +HANDLE SKF_HANDLE_new(int type) +{ + + return NULL; +} + +ULONG DEVAPI SKF_CloseHandle(HANDLE hHandle) +{ + SKF_HANDLE *handle; + return SAR_OK; //FIXME: + + if (!(handle = (SKF_HANDLE *)hHandle)) { + return SAR_OK; + } + + if (handle->magic != SKF_HANDLE_MAGIC) { + SKFerr(SKF_F_SKF_CLOSEHANDLE, SKF_R_INVALID_HANDLE_MAGIC); + return SAR_INVALIDPARAMERR; + } + + switch (handle->type) { + case SKF_KEY_HANDLE: + OPENSSL_cleanse(handle->key, EVP_MAX_KEY_LENGTH); + // FIXME: we need to make sure there are no pending operation + if (handle->u.cipher_ctx) { + EVP_CIPHER_CTX_cleanup(handle->u.cipher_ctx); + } + break; + + case SKF_MAC_HANDLE: + CMAC_CTX_cleanup(handle->u.cbcmac_ctx); + break; + + case SKF_HASH_HANDLE: + EVP_MD_CTX_cleanup(handle->u.md_ctx); + break; + + default: + SKFerr(SKF_F_SKF_CLOSEHANDLE, SKF_R_INVALID_HANDLE_TYPE); + return SAR_INVALIDPARAMERR; + } + + /* now we remove this handle from list */ + + return SAR_OK; +} diff --git a/crypto/skf/skf_handle.d.tmp b/crypto/skf/skf_handle.d.tmp new file mode 100644 index 00000000..3748cdef --- /dev/null +++ b/crypto/skf/skf_handle.d.tmp @@ -0,0 +1,16 @@ +crypto/skf/skf_handle.o: crypto/skf/skf_handle.c include/openssl/gmskf.h \ + include/openssl/sgd.h include/openssl/skf.h include/openssl/gmapi.h \ + include/openssl/ec.h include/openssl/opensslconf.h \ + include/openssl/asn1.h include/openssl/e_os2.h include/openssl/bio.h \ + include/openssl/crypto.h include/openssl/stack.h \ + include/openssl/safestack.h include/openssl/opensslv.h \ + include/openssl/ossl_typ.h include/openssl/symhacks.h \ + include/openssl/bn.h include/openssl/sm2.h include/openssl/err.h \ + include/openssl/lhash.h include/openssl/evp.h \ + include/openssl/objects.h include/openssl/obj_mac.h \ + include/openssl/kdf2.h include/openssl/kdf.h include/openssl/x509.h \ + include/openssl/buffer.h include/openssl/rsa.h include/openssl/dsa.h \ + include/openssl/dh.h include/openssl/sha.h include/openssl/x509_vfy.h \ + include/openssl/pkcs7.h include/openssl/ecdsa.h include/openssl/sm3.h \ + include/openssl/saf.h include/openssl/sdf.h include/openssl/sof.h \ + crypto/skf/skf_lcl.h include/openssl/cmac.h diff --git a/crypto/skf/skf_lcl.h b/crypto/skf/skf_lcl.h new file mode 100644 index 00000000..1e50aadc --- /dev/null +++ b/crypto/skf/skf_lcl.h @@ -0,0 +1,107 @@ +/* ==================================================================== + * Copyright (c) 2016 The GmSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the GmSSL Project. + * (http://gmssl.org/)" + * + * 4. The name "GmSSL Project" must not be used to endorse or promote + * products derived from this software without prior written + * permission. For written permission, please contact + * guanzhi1980@gmail.com. + * + * 5. Products derived from this software may not be called "GmSSL" + * nor may "GmSSL" appear in their names without prior written + * permission of the GmSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the GmSSL Project + * (http://gmssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE GmSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GmSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +#ifndef HEADER_GMAPI_LCL_H +#define HEADER_GMAPI_LCL_H + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define SKF_HANDLE_MAGIC 0x31323334 +#define SKF_HASH_HANDLE 1 +#define SKF_MAC_HANDLE 2 +#define SKF_KEY_HANDLE 10 +#define SKF_CIPHER_HANDLE 11 + + +typedef struct { + CMAC_CTX *ctx; + int inited; +} SAF_MAC_CTX; + +typedef struct { + CMAC_CTX *cbcmac_ctx; + EVP_CIPHER_CTX *cipher_ctx; + unsigned char *key; + unsigned int keylen; + const EVP_CIPHER *cipher; +} SAF_KEY_HANDLE; + +struct SKF_HANDLE { + unsigned int magic; + int type; + int algid; + unsigned int keylen; + unsigned char key[EVP_MAX_KEY_LENGTH]; + union { + EVP_MD_CTX *md_ctx; + CMAC_CTX *cbcmac_ctx; + EVP_CIPHER_CTX *cipher_ctx; + } u; + struct SKF_HANDLE *next; + struct SKF_HANDLE *prev; +}; + +typedef struct SKF_HANDLE SKF_HANDLE; + +EVP_MD_CTX *SKF_HANDLE_get_md_ctx(HANDLE hHash); +CMAC_CTX *SKF_HANDLE_get_cbcmac_ctx(HANDLE hMac); +const EVP_CIPHER *SKF_HANDLE_get_cipher(HANDLE hKey, BLOCKCIPHERPARAM *param); +EVP_CIPHER_CTX *SKF_HANDLE_get_cipher_ctx(HANDLE hKey); +unsigned char *SKF_HANDLE_get_key(HANDLE hKey); + + +#ifdef __cplusplus +} +#endif +#endif diff --git a/crypto/skf/skf_mac.c b/crypto/skf/skf_mac.c new file mode 100644 index 00000000..31e5170d --- /dev/null +++ b/crypto/skf/skf_mac.c @@ -0,0 +1,180 @@ +/* ==================================================================== + * 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. + * ==================================================================== + */ + +#include +#include +#include +#include +#include +#include +#include "skf_lcl.h" + + +ULONG DEVAPI SKF_MacInit(HANDLE hKey, + BLOCKCIPHERPARAM *pMacParam, + HANDLE *phMac) +{ + SKF_HANDLE *key; + SKF_HANDLE *hMac = NULL; + const EVP_CIPHER *cipher; + + if (!(key = (SKF_HANDLE *)hKey)) { + SKFerr(SKF_F_SKF_MACINIT, SKF_R_NULL_ARGUMENT); + return SAR_INVALIDPARAMERR; + } + + //TODO: check pMacParam + + if (key->magic != SKF_HANDLE_MAGIC) { + SKFerr(SKF_F_SKF_MACINIT, SKF_R_INVALID_HANDLE_MAGIC); + return SAR_INVALIDPARAMERR; + } + + if (key->type < SKF_KEY_HANDLE) { + SKFerr(SKF_F_SKF_MACINIT, SKF_R_INVALID_KEY_HANDLE); + return SAR_INVALIDPARAMERR; + } + + if (key->algid != SGD_SM4_MAC) { + SKFerr(SKF_F_SKF_MACINIT, SKF_R_INVALID_ALGOR); + return SAR_INVALIDPARAMERR; + } + cipher = EVP_sms4_ecb(); + + if (key->keylen < SMS4_KEY_LENGTH) { + SKFerr(SKF_F_SKF_MACINIT, SKF_R_INVALID_KEY_LENGTH); + return SAR_INVALIDPARAMERR; + } + + if (!(hMac = OPENSSL_malloc(sizeof(*hMac)))) { + SKFerr(SKF_F_SKF_MACINIT, SKF_R_FAIL); + return SAR_FAIL; + } + + hMac->magic = SKF_HANDLE_MAGIC; + hMac->type = SKF_MAC_HANDLE; + hMac->algid = key->algid; + + if (!(hMac->u.cbcmac_ctx = CMAC_CTX_new())) { + SKFerr(SKF_F_SKF_MACINIT, ERR_R_GMAPI_LIB); + goto end; + } + + if (!CMAC_Init(hMac->u.cbcmac_ctx, key->key, key->keylen, cipher, NULL)) { + SKFerr(SKF_F_SKF_MACINIT, ERR_R_GMAPI_LIB); + return SAR_FAIL; + } + + *phMac = hMac; +end: + return SAR_OK; +} + +ULONG DEVAPI SKF_MacUpdate(HANDLE hMac, + BYTE *pbData, + ULONG ulDataLen) +{ + CMAC_CTX *ctx; + + if (!(ctx = SKF_HANDLE_get_cbcmac_ctx(hMac))) { + SKFerr(SKF_F_SKF_MACUPDATE, SKF_R_INVALID_MAC_HANDLE); + return SAR_INVALIDPARAMERR; + } + + if (!CMAC_Update(ctx, pbData, ulDataLen)) { + SKFerr(SKF_F_SKF_MACUPDATE, ERR_R_GMAPI_LIB); + return SAR_FAIL; + } + + return SAR_OK; +} + +ULONG DEVAPI SKF_MacFinal(HANDLE hMac, + BYTE *pbMacData, + ULONG *pulMacDataLen) +{ + CMAC_CTX *ctx; + size_t size; + + if (!(ctx = SKF_HANDLE_get_cbcmac_ctx(hMac))) { + SKFerr(SKF_F_SKF_MACFINAL, SKF_R_INVALID_MAC_HANDLE); + return SAR_INVALIDPARAMERR; + } + + size = *pulMacDataLen; + if (!CMAC_Final(ctx, pbMacData, &size)) { + SKFerr(SKF_F_SKF_MACFINAL, ERR_R_GMAPI_LIB); + return SAR_FAIL; + } + + *pulMacDataLen = (ULONG)size; + return SAR_OK; +} + +ULONG DEVAPI SKF_Mac(HANDLE hMac, + BYTE *pbData, + ULONG ulDataLen, + BYTE *pbMacData, + ULONG *pulMacLen) +{ + ULONG rv; + + if ((rv = SKF_MacUpdate(hMac, pbData, ulDataLen)) != SAR_OK) { + SKFerr(SKF_F_SKF_MAC, ERR_R_GMAPI_LIB); + return rv; + } + + if ((rv = SKF_MacFinal(hMac, pbMacData, pulMacLen)) != SAR_OK) { + SKFerr(SKF_F_SKF_MAC, ERR_R_GMAPI_LIB); + return rv; + } + + return SAR_OK; +} + diff --git a/crypto/skf/skf_print.c b/crypto/skf/skf_print.c new file mode 100644 index 00000000..28f68427 --- /dev/null +++ b/crypto/skf/skf_print.c @@ -0,0 +1,90 @@ +/* ==================================================================== + * 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. + * ==================================================================== + */ + +#include +#include +#include +#include +#include +#include "skf_lcl.h" + +int SKF_PrintDeviceInfo(FILE *fp, DEVINFO *devInfo) +{ + return 0; +} + +int SKF_PrintRSAPublicKey(FILE *fp, RSAPUBLICKEYBLOB *pk) +{ + return 0; +} + +int SKF_PrintRSAPrivateKey(FILE *fp, RSAPRIVATEKEYBLOB *pk) +{ + return 0; +} + +int SKF_PrintECCPublicKey(FILE *fp, ECCPUBLICKEYBLOB *pk) +{ + return 0; +} + +int SKF_PrintECCPrivateKey(FILE *fp, ECCPRIVATEKEYBLOB *pk) +{ + return 0; +} + +int SKF_PrintECCCipher(FILE *fp, ECCCIPHERBLOB *cipher) +{ + return 0; +} + +int SKF_PrintECCSignature(FILE *fp, ECCSIGNATUREBLOB *sig) +{ + return 0; +} diff --git a/crypto/skf/skf_rand.c b/crypto/skf/skf_rand.c new file mode 100644 index 00000000..843b5ec7 --- /dev/null +++ b/crypto/skf/skf_rand.c @@ -0,0 +1,84 @@ +/* crypto/skf/skf_rand.c */ +/* ==================================================================== + * 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. + * ==================================================================== + * + */ + +#include +#include +#include +#include +#include +#include "skf_lcl.h" + +#define SKF_DEV_AUTH_RANDOM_LENGTH 16 +#define SKF_MAX_RANDOM_LENGTH (1024*1024*1024) +//FIXME: INT_MAX + +ULONG DEVAPI SKF_GenRandom(DEVHANDLE hDev, + BYTE *pbRandom, + ULONG ulRandomLen) +{ + if (!pbRandom) { + SKFerr(SKF_F_SKF_GENRANDOM, SKF_R_NULL_ARGUMENT); + return SAR_INVALIDPARAMERR; + } + + if (ulRandomLen > SKF_MAX_RANDOM_LENGTH) { + SKFerr(SKF_F_SKF_GENRANDOM, SKF_R_INVALID_RANDOM_LENGTH); + return SAR_INVALIDPARAMERR; + } + + if (!RAND_bytes(pbRandom, ulRandomLen)) { + SKFerr(SKF_F_SKF_GENRANDOM, ERR_R_GMAPI_LIB); + return SAR_GENRANDERR; + } + + return SAR_OK; +} + diff --git a/crypto/skf/skf_rsa.c b/crypto/skf/skf_rsa.c new file mode 100644 index 00000000..c4ab35d0 --- /dev/null +++ b/crypto/skf/skf_rsa.c @@ -0,0 +1,222 @@ +/* ==================================================================== + * 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. + * ==================================================================== + * + */ + +#include +#include +#include +#include +#include "../rsa/rsa_locl.h" + + +ULONG DEVAPI SKF_GenExtRSAKey(DEVHANDLE hDev, + ULONG ulBitsLen, + RSAPRIVATEKEYBLOB *pBlob) +{ + ULONG ret = SAR_FAIL; + RSA *rsa = NULL; + + if ((ulBitsLen > MAX_RSA_MODULUS_LEN * 8) || (ulBitsLen < 1024) || + (ulBitsLen % 8 != 0)) { + SKFerr(SKF_F_SKF_GENEXTRSAKEY, SKF_R_INVALID_KEY_LENGTH); + return SAR_INVALIDPARAMERR; + } + + if (!pBlob) { + SKFerr(SKF_F_SKF_GENEXTRSAKEY, SKF_R_NULL_ARGUMENT); + return SAR_INVALIDPARAMERR; + } + + if (!(rsa = RSA_new())) { + SKFerr(SKF_F_SKF_GENEXTRSAKEY, SKF_R_MALLOC_FAILED); + return SAR_FAIL; + } + + if (!RSA_generate_key_ex(rsa, ulBitsLen, NULL, NULL)) { + SKFerr(SKF_F_SKF_GENEXTRSAKEY, SKF_R_GEN_RSA_FAILED); + goto end; + } + + if (!RSA_get_RSAPRIVATEKEYBLOB(rsa, pBlob)) { + SKFerr(SKF_F_SKF_GENEXTRSAKEY, SKF_R_ENCODE_FAILED); + goto end; + } + + ret = SAR_OK; +end: + RSA_free(rsa); + return ret; +} + +ULONG DEVAPI SKF_ExtRSAPubKeyOperation(DEVHANDLE hDev, + RSAPUBLICKEYBLOB *pRSAPubKeyBlob, + BYTE *pbInput, + ULONG ulInputLen, + BYTE *pbOutput, + ULONG *pulOutputLen) +{ + ULONG ret = SAR_FAIL; + RSA *rsa = NULL; + int inlen, outlen; + + if (!pRSAPubKeyBlob || !pbInput || !pulOutputLen) { + SKFerr(SKF_F_SKF_EXTRSAPUBKEYOPERATION, SKF_R_NULL_ARGUMENT); + return SAR_INVALIDPARAMERR; + } + + if (pRSAPubKeyBlob->AlgID != SGD_RSA) { + SKFerr(SKF_F_SKF_EXTRSAPUBKEYOPERATION, SKF_R_INVALID_ALGOR); + return SAR_INVALIDPARAMERR; + } + if (pRSAPubKeyBlob->BitLen % 8) { + SKFerr(SKF_F_SKF_EXTRSAPUBKEYOPERATION, SKF_R_INVALID_KEY_LENGTH); + return SAR_INVALIDPARAMERR; + } + + if (ulInputLen * 8 != pRSAPubKeyBlob->BitLen) { + SKFerr(SKF_F_SKF_EXTRSAPUBKEYOPERATION, SKF_R_INVALID_INPUT_LENGTH); + return SAR_INVALIDPARAMERR; + } + + if (!pbOutput) { + *pulOutputLen = pRSAPubKeyBlob->BitLen / 8; + return SAR_OK; + } + + if (*pulOutputLen < pRSAPubKeyBlob->BitLen / 8) { + SKFerr(SKF_F_SKF_EXTRSAPUBKEYOPERATION, SKF_R_BUFFER_TOO_SMALL); + return SAR_BUFFER_TOO_SMALL; + } + + if (!(rsa = RSA_new_from_RSAPUBLICKEYBLOB(pRSAPubKeyBlob))) { + SKFerr(SKF_F_SKF_EXTRSAPUBKEYOPERATION, SKF_R_INVALID_RSA_PUBLIC_KEY); + goto end; + } + + inlen = (int)ulInputLen; + if ((outlen = RSA_public_encrypt(inlen, pbInput, pbOutput, rsa, RSA_NO_PADDING)) < 0) { + SKFerr(SKF_F_SKF_EXTRSAPUBKEYOPERATION, ERR_R_RSA_LIB); + goto end; + } + + *pulOutputLen = outlen; + ret = SAR_OK; +end: + RSA_free(rsa); + return ret; +} + +ULONG DEVAPI SKF_ExtRSAPriKeyOperation(DEVHANDLE hDev, + RSAPRIVATEKEYBLOB *pRSAPriKeyBlob, + BYTE *pbInput, + ULONG ulInputLen, + BYTE *pbOutput, + ULONG *pulOutputLen) +{ + ULONG ret = SAR_FAIL; + RSA *rsa = NULL; + int inlen, outlen; + + if (!pRSAPriKeyBlob || !pbInput || !pulOutputLen) { + SKFerr(SKF_F_SKF_EXTRSAPRIKEYOPERATION, SKF_R_NULL_ARGUMENT); + return SAR_INVALIDPARAMERR; + } + + if (pRSAPriKeyBlob->AlgID != SGD_RSA) { + SKFerr(SKF_F_SKF_EXTRSAPRIKEYOPERATION, SKF_R_INVALID_ALGOR); + return SAR_INVALIDPARAMERR; + } + if (pRSAPriKeyBlob->BitLen % 8) { + SKFerr(SKF_F_SKF_EXTRSAPRIKEYOPERATION, SKF_R_INVALID_KEY_LENGTH); + return SAR_INVALIDPARAMERR; + } + + if (ulInputLen * 8 != pRSAPriKeyBlob->BitLen) { + SKFerr(SKF_F_SKF_EXTRSAPRIKEYOPERATION, SKF_R_INVALID_INPUT_LENGTH); + return SAR_INVALIDPARAMERR; + } + + if (!pbOutput) { + *pulOutputLen = pRSAPriKeyBlob->BitLen / 8; + return SAR_OK; + } + + if (*pulOutputLen < pRSAPriKeyBlob->BitLen / 8) { + SKFerr(SKF_F_SKF_EXTRSAPRIKEYOPERATION, SKF_R_BUFFER_TOO_SMALL); + return SAR_BUFFER_TOO_SMALL; + } + + if (!(rsa = RSA_new_from_RSAPRIVATEKEYBLOB(pRSAPriKeyBlob))) { + SKFerr(SKF_F_SKF_EXTRSAPRIKEYOPERATION, SKF_R_INVALID_RSA_PUBLIC_KEY); + goto end; + } + + inlen = (int)ulInputLen; + if ((outlen = RSA_private_decrypt(inlen, pbInput, pbOutput, rsa, RSA_NO_PADDING)) < 0) { + SKFerr(SKF_F_SKF_EXTRSAPRIKEYOPERATION, ERR_R_RSA_LIB); + goto end; + } + + *pulOutputLen = outlen; + ret = SAR_OK; +end: + RSA_free(rsa); + return ret; +} + +ULONG DEVAPI SKF_RSAVerify(DEVHANDLE hDev, + RSAPUBLICKEYBLOB *pRSAPubKeyBlob, + BYTE *pbData, + ULONG ulDataLen, + BYTE *pbSignature, + ULONG ulSignLen) +{ + return SAR_FAIL; +} + diff --git a/crypto/skf/skf_sesskey.c b/crypto/skf/skf_sesskey.c new file mode 100644 index 00000000..2a9f3e6b --- /dev/null +++ b/crypto/skf/skf_sesskey.c @@ -0,0 +1,98 @@ +/* crypto/skf/skf_sesskey.c */ +/* ==================================================================== + * 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. + * ==================================================================== + * + */ + +#include +#include +#include +#include +#include +#include +#include "skf_lcl.h" + +#define PADDING_TYPE_NO_PADDING 0 +#define PADDING_TYPE_PKCS5 1 + + +ULONG DEVAPI SKF_SetSymmKey(DEVHANDLE hDev, + BYTE *pbKey, + ULONG ulAlgID, + HANDLE *phKey) +{ + SKF_HANDLE *hKey = NULL; + + if (!(hKey = OPENSSL_malloc(sizeof(*hKey)))) { + SKFerr(SKF_F_SKF_SETSYMMKEY, SKF_R_MALLOC_FAILED); + return SAR_FAIL; + } + memset(hKey, 0, sizeof(*hKey)); + + hKey->magic = SKF_HANDLE_MAGIC; + hKey->type = SKF_KEY_HANDLE; + + switch (ulAlgID) { + case SGD_SM4_ECB: + case SGD_SM4_CBC: + case SGD_SM4_CFB: + case SGD_SM4_OFB: + case SGD_SM4_MAC: + hKey->algid = ulAlgID; + hKey->keylen = SMS4_KEY_LENGTH; + break; + default: + SKFerr(SKF_F_SKF_SETSYMMKEY, SKF_R_INVALID_ALGOR); + return SAR_INVALIDPARAMERR; + } + memcpy(hKey->key, pbKey, hKey->keylen); + + *phKey = hKey; + return SAR_OK; +} + diff --git a/crypto/skf/skf_token.c b/crypto/skf/skf_token.c new file mode 100644 index 00000000..98845555 --- /dev/null +++ b/crypto/skf/skf_token.c @@ -0,0 +1,394 @@ +/* crypto/skf/skf_app.c */ +/* ==================================================================== + * 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. + * ==================================================================== + * + */ + +#include +#include + +ULONG DEVAPI SKF_WaitForDevEvent(LPSTR szDevName, + ULONG *pulDevNameLen, + ULONG *pulEvent) +{ + return SAR_NOTSUPPORTYETERR; +} + +ULONG DEVAPI SKF_CancelWaitForDevEvent(void) +{ + return SAR_NOTSUPPORTYETERR; +} + +ULONG DEVAPI SKF_SetLabel(DEVHANDLE hDev, + LPSTR szLabel) +{ + return SAR_NOTSUPPORTYETERR; +} + +ULONG DEVAPI SKF_LockDev(DEVHANDLE hDev, + ULONG ulTimeOut) +{ + return SAR_NOTSUPPORTYETERR; +} + +ULONG DEVAPI SKF_UnlockDev(DEVHANDLE hDev) +{ + return SAR_NOTSUPPORTYETERR; +} + +ULONG DEVAPI SKF_Transmit(DEVHANDLE hDev, + BYTE* pbCommand, + ULONG ulCommandLen, + BYTE* pbData, + ULONG* pulDataLen) +{ + return SAR_NOTSUPPORTYETERR; +} + +ULONG DEVAPI SKF_ChangeDevAuthKey(DEVHANDLE hDev, + BYTE *pbKeyValue, + ULONG ulKeyLen) +{ + return SAR_NOTSUPPORTYETERR; +} + +ULONG DEVAPI SKF_DevAuth(DEVHANDLE hDev, + BYTE *pbAuthData, + ULONG ulLen) +{ + return SAR_OK; +} + +ULONG DEVAPI SKF_CreateApplication(DEVHANDLE hDev, + LPSTR szAppName, + LPSTR szAdminPin, + DWORD dwAdminPinRetryCount, + LPSTR szUserPin, + DWORD dwUserPinRetryCount, + DWORD dwCreateFileRights, + HAPPLICATION *phApplication) +{ + return SAR_NOTSUPPORTYETERR; +} + +ULONG DEVAPI SKF_EnumApplication(DEVHANDLE hDev, + LPSTR szAppName, + ULONG *pulSize) +{ + return SAR_NOTSUPPORTYETERR; +} + +ULONG DEVAPI SKF_DeleteApplication(DEVHANDLE hDev, + LPSTR szAppName) +{ + return SAR_NOTSUPPORTYETERR; +} + +ULONG DEVAPI SKF_OpenApplication(DEVHANDLE hDev, + LPSTR szAppName, + HAPPLICATION *phApplication) +{ + return SAR_NOTSUPPORTYETERR; +} + +ULONG DEVAPI SKF_CloseApplication(HAPPLICATION hApplication) +{ + return SAR_NOTSUPPORTYETERR; +} + +ULONG DEVAPI SKF_ChangePIN(HAPPLICATION hApplication, + ULONG ulPINType, + LPSTR szOldPin, + LPSTR szNewPin, + ULONG *pulRetryCount) +{ + return SAR_NOTSUPPORTYETERR; +} + +LONG DEVAPI SKF_GetPINInfo(HAPPLICATION hApplication, + ULONG ulPINType, + ULONG *pulMaxRetryCount, + ULONG *pulRemainRetryCount, + BOOL *pbDefaultPin) +{ + return SAR_NOTSUPPORTYETERR; +} + +ULONG DEVAPI SKF_VerifyPIN(HAPPLICATION hApplication, + ULONG ulPINType, + LPSTR szPIN, + ULONG *pulRetryCount) +{ + return SAR_NOTSUPPORTYETERR; +} + +ULONG DEVAPI SKF_UnblockPIN(HAPPLICATION hApplication, + LPSTR szAdminPIN, + LPSTR szNewUserPIN, + ULONG *pulRetryCount) +{ + return SAR_NOTSUPPORTYETERR; +} + +ULONG DEVAPI SKF_ClearSecureState(HAPPLICATION hApplication) +{ + return SAR_NOTSUPPORTYETERR; +} + +ULONG DEVAPI SKF_CreateContainer(HAPPLICATION hApplication, + LPSTR szContainerName, + HCONTAINER *phContainer) +{ + return SAR_NOTSUPPORTYETERR; +} + +ULONG DEVAPI SKF_DeleteContainer(HAPPLICATION hApplication, + LPSTR szContainerName) +{ + return SAR_NOTSUPPORTYETERR; +} + +ULONG DEVAPI SKF_EnumContainer(HAPPLICATION hApplication, + LPSTR szContainerName, + ULONG *pulSize) +{ + return SAR_NOTSUPPORTYETERR; +} + +ULONG DEVAPI SKF_OpenContainer(HAPPLICATION hApplication, + LPSTR szContainerName, + HCONTAINER *phContainer) +{ + return SAR_NOTSUPPORTYETERR; +} + +ULONG DEVAPI SKF_CloseContainer(HCONTAINER hContainer) +{ + return SAR_NOTSUPPORTYETERR; +} + +ULONG DEVAPI SKF_GetContainerType(HCONTAINER hContainer, + ULONG *pulContainerType) +{ + return SAR_NOTSUPPORTYETERR; +} + +ULONG DEVAPI SKF_ImportCertificate(HCONTAINER hContainer, + BOOL bSignFlag, + BYTE *pbCert, + ULONG ulCertLen) +{ + return SAR_NOTSUPPORTYETERR; +} + +ULONG DEVAPI SKF_ExportCertificate(HCONTAINER hContainer, + BOOL bSignFlag, + BYTE *pbCert, + ULONG *pulCertLen) +{ + return SAR_NOTSUPPORTYETERR; +} + +ULONG DEVAPI SKF_CreateFile(HAPPLICATION hApplication, + LPSTR szFileName, + ULONG ulFileSize, + ULONG ulReadRights, + ULONG ulWriteRights) +{ + return SAR_NOTSUPPORTYETERR; +} + +ULONG DEVAPI SKF_EnumFiles(HAPPLICATION hApplication, + LPSTR szFileList, + ULONG *pulSize) +{ + return SAR_NOTSUPPORTYETERR; +} + +ULONG DEVAPI SKF_GetFileInfo(HAPPLICATION hApplication, + LPSTR szFileName, + FILEATTRIBUTE *pFileInfo) +{ + return SAR_NOTSUPPORTYETERR; +} + +ULONG DEVAPI SKF_ReadFile(HAPPLICATION hApplication, + LPSTR szFileName, + ULONG ulOffset, + ULONG ulSize, + BYTE *pbOutData, + ULONG *pulOutLen) +{ + return SAR_NOTSUPPORTYETERR; +} + +ULONG DEVAPI SKF_WriteFile(HAPPLICATION hApplication, + LPSTR szFileName, + ULONG ulOffset, + BYTE *pbData, + ULONG ulSize) +{ + return SAR_NOTSUPPORTYETERR; +} + +ULONG DEVAPI SKF_DeleteFile(HAPPLICATION hApplication, + LPSTR szFileName) +{ + return SAR_NOTSUPPORTYETERR; +} + + +ULONG DEVAPI SKF_GenECCKeyPair(HCONTAINER hContainer, + ULONG ulAlgId, + ECCPUBLICKEYBLOB *pBlob) +{ + return SAR_NOTSUPPORTYETERR; +} + +ULONG DEVAPI SKF_ImportECCKeyPair(HCONTAINER hContainer, + ENVELOPEDKEYBLOB *pEnvelopedKeyBlob) +{ + return SAR_NOTSUPPORTYETERR; +} + +ULONG DEVAPI SKF_ECCSignData(HCONTAINER hContainer, + BYTE *pbData, + ULONG ulDataLen, + ECCSIGNATUREBLOB *pSignature) +{ + return SAR_NOTSUPPORTYETERR; +} + +ULONG DEVAPI SKF_GenerateAgreementDataWithECC(HCONTAINER hContainer, + ULONG ulAlgId, + ECCPUBLICKEYBLOB *pTempECCPubKeyBlob, + BYTE *pbID, + ULONG ulIDLen, + HANDLE *phAgreementHandle) +{ + return SAR_NOTSUPPORTYETERR; +} + +ULONG DEVAPI SKF_GenerateAgreementDataAndKeyWithECC(HANDLE hContainer, + ULONG ulAlgId, + ECCPUBLICKEYBLOB *pSponsorECCPubKeyBlob, + ECCPUBLICKEYBLOB *pSponsorTempECCPubKeyBlob, + ECCPUBLICKEYBLOB *pTempECCPubKeyBlob, + BYTE *pbID, + ULONG ulIDLen, + BYTE *pbSponsorID, + ULONG ulSponsorIDLen, + HANDLE *phKeyHandle) +{ + return SAR_NOTSUPPORTYETERR; +} + +ULONG DEVAPI SKF_GenerateKeyWithECC(HANDLE hAgreementHandle, + ECCPUBLICKEYBLOB *pECCPubKeyBlob, + ECCPUBLICKEYBLOB *pTempECCPubKeyBlob, + BYTE *pbID, + ULONG ulIDLen, + HANDLE *phKeyHandle) +{ + return SAR_NOTSUPPORTYETERR; +} + +ULONG DEVAPI SKF_GenRSAKeyPair(HCONTAINER hContainer, + ULONG ulBitsLen, + RSAPUBLICKEYBLOB *pBlob) +{ + return SAR_NOTSUPPORTYETERR; +} + +ULONG DEVAPI SKF_ImportRSAKeyPair(HCONTAINER hContainer, + ULONG ulSymAlgId, + BYTE *pbWrappedKey, + ULONG ulWrappedKeyLen, + BYTE *pbEncryptedData, + ULONG ulEncryptedDataLen) +{ + return SAR_NOTSUPPORTYETERR; +} + +ULONG DEVAPI SKF_RSASignData(HCONTAINER hContainer, + BYTE *pbData, + ULONG ulDataLen, + BYTE *pbSignature, + ULONG *pulSignLen) +{ + return SAR_NOTSUPPORTYETERR; +} + +ULONG DEVAPI SKF_ImportSessionKey(HCONTAINER hContainer, + ULONG ulAlgId, + BYTE *pbWrapedData, + ULONG ulWrapedLen, + HANDLE *phKey) +{ + return SAR_NOTSUPPORTYETERR; +} + +ULONG DEVAPI SKF_RSAExportSessionKey(HCONTAINER hContainer, + ULONG ulAlgId, + RSAPUBLICKEYBLOB *pPubKey, + BYTE *pbData, + ULONG *pulDataLen, + HANDLE *phSessionKey) +{ + return SAR_NOTSUPPORTYETERR; +} + +ULONG DEVAPI SKF_ECCExportSessionKey(HCONTAINER hContainer, + ULONG ulAlgId, + ECCPUBLICKEYBLOB *pPubKey, + ECCCIPHERBLOB *pData, + HANDLE *phSessionKey) +{ + return SAR_NOTSUPPORTYETERR; +} + diff --git a/crypto/sof/build.info b/crypto/sof/build.info new file mode 100644 index 00000000..e458751d --- /dev/null +++ b/crypto/sof/build.info @@ -0,0 +1,4 @@ +LIBS=../../libcrypto +SOURCE[../../libcrypto]=\ + sof_err.c \ + sof_lib.c diff --git a/crypto/sof/sof_err.c b/crypto/sof/sof_err.c new file mode 100644 index 00000000..252beb37 --- /dev/null +++ b/crypto/sof/sof_err.c @@ -0,0 +1,91 @@ +/* + * Generated by util/mkerr.pl DO NOT EDIT + * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include +#include + +/* BEGIN ERROR CODES */ +#ifndef OPENSSL_NO_ERR + +# define ERR_FUNC(func) ERR_PACK(ERR_LIB_SOF,func,0) +# define ERR_REASON(reason) ERR_PACK(ERR_LIB_SOF,0,reason) + +static ERR_STRING_DATA SOF_str_functs[] = { + {ERR_FUNC(SOF_F_SOF_CHANGEPASSWD), "SOF_ChangePassWd"}, + {ERR_FUNC(SOF_F_SOF_CREATETIMESTAMPREQUEST), + "SOF_CreateTimeStampRequest"}, + {ERR_FUNC(SOF_F_SOF_CREATETIMESTAMPRESPONSE), + "SOF_CreateTimeStampResponse"}, + {ERR_FUNC(SOF_F_SOF_DECRYPTDATA), "SOF_DecryptData"}, + {ERR_FUNC(SOF_F_SOF_DECRYPTFILE), "SOF_DecryptFile"}, + {ERR_FUNC(SOF_F_SOF_DELCERTTRUSTLIST), "SOF_DelCertTrustList"}, + {ERR_FUNC(SOF_F_SOF_ENCRYPTDATA), "SOF_EncryptData"}, + {ERR_FUNC(SOF_F_SOF_ENCRYPTFILE), "SOF_EncryptFile"}, + {ERR_FUNC(SOF_F_SOF_EXPORTEXCHANGEUSERCERT), + "SOF_ExportExChangeUserCert"}, + {ERR_FUNC(SOF_F_SOF_EXPORTUSERCERT), "SOF_ExportUserCert"}, + {ERR_FUNC(SOF_F_SOF_GENRANDOM), "SOF_GenRandom"}, + {ERR_FUNC(SOF_F_SOF_GETCERTINFO), "SOF_GetCertInfo"}, + {ERR_FUNC(SOF_F_SOF_GETCERTINFOBYOID), "SOF_GetCertInfoByOid"}, + {ERR_FUNC(SOF_F_SOF_GETCERTTRUSTLIST), "SOF_GetCertTrustList"}, + {ERR_FUNC(SOF_F_SOF_GETCERTTRUSTLISTALTNAMES), + "SOF_GetCertTrustListAltNames"}, + {ERR_FUNC(SOF_F_SOF_GETDEVICEINFO), "SOF_GetDeviceInfo"}, + {ERR_FUNC(SOF_F_SOF_GETENCRYPTMETHOD), "SOF_GetEncryptMethod"}, + {ERR_FUNC(SOF_F_SOF_GETINFOFROMSIGNEDMESSAGE), + "SOF_GetInfoFromSignedMessage"}, + {ERR_FUNC(SOF_F_SOF_GETLASTERROR), "SOF_GetLastError"}, + {ERR_FUNC(SOF_F_SOF_GETPINRETRYCOUNT), "SOF_GetPinRetryCount"}, + {ERR_FUNC(SOF_F_SOF_GETSERVERCERTIFICATE), "SOF_GetServerCertificate"}, + {ERR_FUNC(SOF_F_SOF_GETSIGNMETHOD), "SOF_GetSignMethod"}, + {ERR_FUNC(SOF_F_SOF_GETTIMESTAMPINFO), "SOF_GetTimeStampInfo"}, + {ERR_FUNC(SOF_F_SOF_GETUSERLIST), "SOF_GetUserList"}, + {ERR_FUNC(SOF_F_SOF_GETVERSION), "SOF_GetVersion"}, + {ERR_FUNC(SOF_F_SOF_GETXMLSIGNATUREINFO), "SOF_GetXMLSignatureInfo"}, + {ERR_FUNC(SOF_F_SOF_INITCERTAPPPOLICY), "SOF_InitCertAppPolicy"}, + {ERR_FUNC(SOF_F_SOF_LOGIN), "SOF_Login"}, + {ERR_FUNC(SOF_F_SOF_SETCERTTRUSTLIST), "SOF_SetCertTrustList"}, + {ERR_FUNC(SOF_F_SOF_SETENCRYPTMETHOD), "SOF_SetEncryptMethod"}, + {ERR_FUNC(SOF_F_SOF_SETSIGNMETHOD), "SOF_SetSignMethod"}, + {ERR_FUNC(SOF_F_SOF_SIGNDATA), "SOF_SignData"}, + {ERR_FUNC(SOF_F_SOF_SIGNDATAXML), "SOF_SignDataXML"}, + {ERR_FUNC(SOF_F_SOF_SIGNFILE), "SOF_SignFile"}, + {ERR_FUNC(SOF_F_SOF_SIGNMESSAGE), "SOF_SignMessage"}, + {ERR_FUNC(SOF_F_SOF_SIGNMESSAGEDETACH), "SOF_SignMessageDetach"}, + {ERR_FUNC(SOF_F_SOF_VALIDATECERT), "SOF_ValidateCert"}, + {ERR_FUNC(SOF_F_SOF_VERIFYSIGNEDDATA), "SOF_VerifySignedData"}, + {ERR_FUNC(SOF_F_SOF_VERIFYSIGNEDDATAXML), "SOF_VerifySignedDataXML"}, + {ERR_FUNC(SOF_F_SOF_VERIFYSIGNEDFILE), "SOF_VerifySignedFile"}, + {ERR_FUNC(SOF_F_SOF_VERIFYSIGNEDMESSAGE), "SOF_VerifySignedMessage"}, + {ERR_FUNC(SOF_F_SOF_VERIFYSIGNEDMESSAGEDETACH), + "SOF_VerifySignedMessageDetach"}, + {ERR_FUNC(SOF_F_SOF_VERIFYTIMESTAMP), "SOF_VerifyTimeStamp"}, + {0, NULL} +}; + +static ERR_STRING_DATA SOF_str_reasons[] = { + {ERR_REASON(SOF_R_NOT_IMPLEMENTED), "not implemented"}, + {0, NULL} +}; + +#endif + +int ERR_load_SOF_strings(void) +{ +#ifndef OPENSSL_NO_ERR + + if (ERR_func_error_string(SOF_str_functs[0].error) == NULL) { + ERR_load_strings(0, SOF_str_functs); + ERR_load_strings(0, SOF_str_reasons); + } +#endif + return 1; +} diff --git a/crypto/sof/sof_errstr.c b/crypto/sof/sof_errstr.c new file mode 100644 index 00000000..67eaee5c --- /dev/null +++ b/crypto/sof/sof_errstr.c @@ -0,0 +1,72 @@ +/* ==================================================================== + * Copyright (c) 2016 The GmSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the GmSSL Project. + * (http://gmssl.org/)" + * + * 4. The name "GmSSL Project" must not be used to endorse or promote + * products derived from this software without prior written + * permission. For written permission, please contact + * guanzhi1980@gmail.com. + * + * 5. Products derived from this software may not be called "GmSSL" + * nor may "GmSSL" appear in their names without prior written + * permission of the GmSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the GmSSL Project + * (http://gmssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE GmSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GmSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +#include +#include +#include "../../e_os.h" + +static ERR_STRING_DATA sof_errstr[] = { + { SOR_OK, "Success" }, + { SOR_UnknownErr, "Unknown error" }, + { SOF_FileErr, "File error" }, + { SOR_ProviderTypeErr, "Provider type error" }, + { SOR_LoadProviderErr, "Load provider error" }, +}; + +char *SOF_GetErrorString(int err) +{ + int i; + for (i = 0; i < OSSL_NELEM(sof_errstr); i++) { + if (err == sof_errstr[i].error) { + return sof_errstr[i].string; + } + } + return "(undef)"; +} + diff --git a/crypto/sof/sof_lib.c b/crypto/sof/sof_lib.c new file mode 100644 index 00000000..1d155d27 --- /dev/null +++ b/crypto/sof/sof_lib.c @@ -0,0 +1,314 @@ +/* ==================================================================== + * Copyright (c) 2016 The GmSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the GmSSL Project. + * (http://gmssl.org/)" + * + * 4. The name "GmSSL Project" must not be used to endorse or promote + * products derived from this software without prior written + * permission. For written permission, please contact + * guanzhi1980@gmail.com. + * + * 5. Products derived from this software may not be called "GmSSL" + * nor may "GmSSL" appear in their names without prior written + * permission of the GmSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the GmSSL Project + * (http://gmssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE GmSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GmSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +#include +#include + +BSTR sof_version = "1.0"; +long sof_sign_method = SGD_SM2; +long sof_enc_method = SGD_SM4_CBC; + +BSTR SOF_GetVersion(void) +{ + SOFerr(SOF_F_SOF_GETVERSION, SOF_R_NOT_IMPLEMENTED); + return NULL; +} + +long SOF_SetSignMethod(long SignMethod) +{ + SOFerr(SOF_F_SOF_SETSIGNMETHOD, SOF_R_NOT_IMPLEMENTED); + return 0; +} + +long SOF_GetSignMethod(void) +{ + SOFerr(SOF_F_SOF_GETSIGNMETHOD, SOF_R_NOT_IMPLEMENTED); + return 0; +} + +long SOF_SetEncryptMethod(long EncryptMethod) +{ + SOFerr(SOF_F_SOF_SETENCRYPTMETHOD, SOF_R_NOT_IMPLEMENTED); + return 0; +} + +long SOF_GetEncryptMethod(void) +{ + SOFerr(SOF_F_SOF_GETENCRYPTMETHOD, SOF_R_NOT_IMPLEMENTED); + return 0; +} + +BSTR SOF_GetUserList(void) +{ + SOFerr(SOF_F_SOF_GETUSERLIST, SOF_R_NOT_IMPLEMENTED); + return NULL; +} + +BSTR SOF_ExportUserCert(BSTR ContainerName) +{ + SOFerr(SOF_F_SOF_EXPORTUSERCERT, SOF_R_NOT_IMPLEMENTED); + return NULL; +} + +BOOL SOF_Login(BSTR ContainerName, BSTR PassWd) +{ + SOFerr(SOF_F_SOF_LOGIN, SOF_R_NOT_IMPLEMENTED); + return NULL; +} + +long SOF_GetPinRetryCount(BSTR ContainerName) +{ + SOFerr(SOF_F_SOF_GETPINRETRYCOUNT, SOF_R_NOT_IMPLEMENTED); + return 0; +} + +BOOL SOF_ChangePassWd(BSTR ContainerName, BSTR OldPassWd, BSTR NewPassWd) +{ + SOFerr(SOF_F_SOF_CHANGEPASSWD, SOF_R_NOT_IMPLEMENTED); + return NULL; +} + +BSTR SOF_ExportExChangeUserCert(BSTR ContainerName) +{ + SOFerr(SOF_F_SOF_EXPORTEXCHANGEUSERCERT, SOF_R_NOT_IMPLEMENTED); + return NULL; +} + +BSTR SOF_GetCertInfo(BSTR Base64EncodeCert, short Type) +{ + SOFerr(SOF_F_SOF_GETCERTINFO, SOF_R_NOT_IMPLEMENTED); + return NULL; +} + +BSTR SOF_GetCertInfoByOid(BSTR Base64EncodeCert, BSTR Oid) +{ + SOFerr(SOF_F_SOF_GETCERTINFOBYOID, SOF_R_NOT_IMPLEMENTED); + return NULL; +} + +BSTR SOF_GetDeviceInfo(BSTR ContainerName, long Type) +{ + SOFerr(SOF_F_SOF_GETDEVICEINFO, SOF_R_NOT_IMPLEMENTED); + return NULL; +} + +long SOF_ValidateCert(BSTR Base64EncodeCert) +{ + SOFerr(SOF_F_SOF_VALIDATECERT, SOF_R_NOT_IMPLEMENTED); + return 0; +} + +BSTR SOF_SignData(BSTR ContainerName, BSTR InData) +{ + SOFerr(SOF_F_SOF_SIGNDATA, SOF_R_NOT_IMPLEMENTED); + return NULL; +} + +BOOL SOF_VerifySignedData(BSTR Base64EncodeCert, BSTR InData, BSTR SignValue) +{ + SOFerr(SOF_F_SOF_VERIFYSIGNEDDATA, SOF_R_NOT_IMPLEMENTED); + return 0; +} + +BSTR SOF_SignFile(BSTR ContainerName, BSTR InFile) +{ + SOFerr(SOF_F_SOF_SIGNFILE, SOF_R_NOT_IMPLEMENTED); + return NULL; +} + +BOOL SOF_VerifySignedFile(BSTR Base64EncodeCert, BSTR InFile, BSTR SignValue) +{ + SOFerr(SOF_F_SOF_VERIFYSIGNEDFILE, SOF_R_NOT_IMPLEMENTED); + return 0; +} + +BSTR SOF_EncryptData(BSTR Base64EncodeCert, BSTR InData) +{ + SOFerr(SOF_F_SOF_ENCRYPTDATA, SOF_R_NOT_IMPLEMENTED); + return NULL; +} + +BSTR SOF_DecryptData(BSTR ContainerName, BSTR InData) +{ + SOFerr(SOF_F_SOF_DECRYPTDATA, SOF_R_NOT_IMPLEMENTED); + return NULL; +} + +BOOL SOF_EncryptFile(BSTR Base64EncodeCert, BSTR InFile, BSTR OutFile) +{ + SOFerr(SOF_F_SOF_ENCRYPTFILE, SOF_R_NOT_IMPLEMENTED); + return 0; +} + +BOOL SOF_DecryptFile(BSTR ContainerName, BSTR InFile, BSTR OutFile) +{ + SOFerr(SOF_F_SOF_DECRYPTFILE, SOF_R_NOT_IMPLEMENTED); + return 0; +} + +BSTR SOF_SignMessage(short flag, BSTR ContainerName, BSTR InData) +{ + SOFerr(SOF_F_SOF_SIGNMESSAGE, SOF_R_NOT_IMPLEMENTED); + return NULL; +} + +BOOL SOF_VerifySignedMessage(BSTR MessageData, BSTR InData) +{ + SOFerr(SOF_F_SOF_VERIFYSIGNEDMESSAGE, SOF_R_NOT_IMPLEMENTED); + return 0; +} + +BSTR SOF_GetInfoFromSignedMessage(BSTR SignedMessage, short Type) +{ + SOFerr(SOF_F_SOF_GETINFOFROMSIGNEDMESSAGE, SOF_R_NOT_IMPLEMENTED); + return NULL; +} + +BSTR SOF_SignDataXML(BSTR ContainerName, BSTR InData) +{ + SOFerr(SOF_F_SOF_SIGNDATAXML, SOF_R_NOT_IMPLEMENTED); + return NULL; +} + +BOOL SOF_VerifySignedDataXML(BSTR InData) +{ + SOFerr(SOF_F_SOF_VERIFYSIGNEDDATAXML, SOF_R_NOT_IMPLEMENTED); + return 0; +} + +BSTR SOF_GetXMLSignatureInfo(BSTR XMLSignedData, short Type) +{ + SOFerr(SOF_F_SOF_GETXMLSIGNATUREINFO, SOF_R_NOT_IMPLEMENTED); + return NULL; +} + +BSTR SOF_GenRandom(short RandomLen) +{ + SOFerr(SOF_F_SOF_GENRANDOM, SOF_R_NOT_IMPLEMENTED); + return NULL; +} + +long SOF_GetLastError(void) +{ + SOFerr(SOF_F_SOF_GETLASTERROR, SOF_R_NOT_IMPLEMENTED); + return 0; +} + +long SOF_SetCertTrustList(BSTR CTLAltName, BSTR CTLContent, short CTLContentLen) +{ + SOFerr(SOF_F_SOF_SETCERTTRUSTLIST, SOF_R_NOT_IMPLEMENTED); + return 0; +} + +BSTR SOF_GetCertTrustListAltNames(void) +{ + SOFerr(SOF_F_SOF_GETCERTTRUSTLISTALTNAMES, SOF_R_NOT_IMPLEMENTED); + return NULL; +} + +BSTR SOF_GetCertTrustList(BSTR CTLAltName) +{ + SOFerr(SOF_F_SOF_GETCERTTRUSTLIST, SOF_R_NOT_IMPLEMENTED); + return NULL; +} + +long SOF_DelCertTrustList(BSTR CTLAltName) +{ + SOFerr(SOF_F_SOF_DELCERTTRUSTLIST, SOF_R_NOT_IMPLEMENTED); + return 0; +} + +long SOF_InitCertAppPolicy(BSTR PolicyName) +{ + SOFerr(SOF_F_SOF_INITCERTAPPPOLICY, SOF_R_NOT_IMPLEMENTED); + return 0; +} + +BSTR SOF_GetServerCertificate(short CertUsage) +{ + SOFerr(SOF_F_SOF_GETSERVERCERTIFICATE, SOF_R_NOT_IMPLEMENTED); + return NULL; +} + +BSTR SOF_SignMessageDetach(BSTR InData) +{ + SOFerr(SOF_F_SOF_SIGNMESSAGEDETACH, SOF_R_NOT_IMPLEMENTED); + return NULL; +} + +long SOF_VerifySignedMessageDetach(BSTR InData, BSTR SignedMessage) +{ + SOFerr(SOF_F_SOF_VERIFYSIGNEDMESSAGEDETACH, SOF_R_NOT_IMPLEMENTED); + return 0; +} + +BSTR SOF_CreateTimeStampRequest(BSTR InData) +{ + SOFerr(SOF_F_SOF_CREATETIMESTAMPREQUEST, SOF_R_NOT_IMPLEMENTED); + return NULL; +} + +BSTR SOF_CreateTimeStampResponse(BSTR TimeStampRequest) +{ + SOFerr(SOF_F_SOF_CREATETIMESTAMPRESPONSE, SOF_R_NOT_IMPLEMENTED); + return NULL; +} + +long SOF_VerifyTimeStamp(BSTR InData, BSTR tsResponseData) +{ + SOFerr(SOF_F_SOF_VERIFYTIMESTAMP, SOF_R_NOT_IMPLEMENTED); + return 0; +} + +BSTR SOF_GetTimeStampInfo(BSTR tsResponseData, short type) +{ + SOFerr(SOF_F_SOF_GETTIMESTAMPINFO, SOF_R_NOT_IMPLEMENTED); + return NULL; +} + diff --git a/include/openssl/err.h b/include/openssl/err.h index 0666afe5..3af35a04 100644 --- a/include/openssl/err.h +++ b/include/openssl/err.h @@ -102,6 +102,10 @@ typedef struct err_state_st { # define ERR_LIB_BFIBE 59 # define ERR_LIB_BB1IBE 60 # define ERR_LIB_SM9 61 +# define ERR_LIB_SAF 62 +# define ERR_LIB_SDF 63 +# define ERR_LIB_SKF 64 +# define ERR_LIB_SOF 65 # define ERR_LIB_USER 128 @@ -149,6 +153,10 @@ typedef struct err_state_st { # define BFIBEerr(f,r) ERR_PUT_error(ERR_LIB_BFIBE,(f),(r),OPENSSL_FILE,OPENSSL_LINE) # define BB1IBEerr(f,r) ERR_PUT_error(ERR_LIB_BB1IBE,(f),(r),OPENSSL_FILE,OPENSSL_LINE) # define SM9err(f,r) ERR_PUT_error(ERR_LIB_SM9,(f),(r),OPENSSL_FILE,OPENSSL_LINE) +# define SAFerr(f,r) ERR_PUT_error(ERR_LIB_SAF,(f),(r),OPENSSL_FILE,OPENSSL_LINE) +# define SDFerr(f,r) ERR_PUT_error(ERR_LIB_SDF,(f),(r),OPENSSL_FILE,OPENSSL_LINE) +# define SKFerr(f,r) ERR_PUT_error(ERR_LIB_SKF,(f),(r),OPENSSL_FILE,OPENSSL_LINE) +# define SOFerr(f,r) ERR_PUT_error(ERR_LIB_SOF,(f),(r),OPENSSL_FILE,OPENSSL_LINE) # define ERR_PACK(l,f,r) ( \ (((unsigned int)(l) & 0x0FF) << 24L) | \ @@ -205,6 +213,10 @@ typedef struct err_state_st { # define ERR_R_BFIBE_LIB ERR_LIB_BFIBE/* 59 */ # define ERR_R_BB1IBE_LIB ERR_LIB_BB1IBE/* 60 */ # define ERR_R_SM9_LIB ERR_LIB_SM9/* 61 */ +# define ERR_R_SAF_LIB ERR_LIB_SAF/* 62 */ +# define ERR_R_SDF_LIB ERR_LIB_SDF/* 63 */ +# define ERR_R_SKF_LIB ERR_LIB_SKF/* 64 */ +# define ERR_R_SOF_LIB ERR_LIB_SOF/* 65 */ # define ERR_R_NESTED_ASN1_ERROR 58 diff --git a/include/openssl/gmsaf.h b/include/openssl/gmsaf.h new file mode 100644 index 00000000..9021d58f --- /dev/null +++ b/include/openssl/gmsaf.h @@ -0,0 +1,120 @@ +/* ==================================================================== + * 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 HEADER_GMSAF_H +#define HEADER_GMSAF_H + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + + +int SAF_PrintNameInfo(FILE *fp, SGD_NAME_INFO *nameInfo); +const char *SAF_GetErrorString(int err); + +/* BEGIN ERROR CODES */ +/* + * The following lines are auto generated by the script mkerr.pl. Any changes + * made after this point may be overwritten when the script is next run. + */ + +int ERR_load_SAF_strings(void); + +/* Error codes for the SAF functions. */ + +/* Function codes. */ +# define SAF_F_SAF_BASE64_CREATEBASE64OBJ 100 +# define SAF_F_SAF_BASE64_DECODE 101 +# define SAF_F_SAF_BASE64_DECODEFINAL 102 +# define SAF_F_SAF_BASE64_DECODEUPDATE 103 +# define SAF_F_SAF_BASE64_ENCODE 104 +# define SAF_F_SAF_BASE64_ENCODEFINAL 105 +# define SAF_F_SAF_BASE64_ENCODEUPDATE 106 +# define SAF_F_SAF_CREATESYMMKEYOBJ 107 +# define SAF_F_SAF_ECCPUBLICKEYENC 108 +# define SAF_F_SAF_ECCPUBLICKEYENCBYCERT 109 +# define SAF_F_SAF_ECCSIGN 110 +# define SAF_F_SAF_ECCVERIFYSIGN 111 +# define SAF_F_SAF_ECCVERIFYSIGNBYCERT 112 +# define SAF_F_SAF_GENECCKEYPAIR 113 +# define SAF_F_SAF_GENERATEAGREEMENTDATAWITHECC 114 +# define SAF_F_SAF_GENERATEKEYWITHECC 115 +# define SAF_F_SAF_GETECCPUBLICKEY 116 +# define SAF_F_SAF_MACFINAL 117 +# define SAF_F_SAF_MACUPDATE 118 +# define SAF_F_SAF_PKCS7_DECODEDIGESTEDDATA 119 +# define SAF_F_SAF_PKCS7_ENCODEDIGESTEDDATA 120 +# define SAF_F_SAF_SYMMDECRYPTUPDATE 121 +# define SAF_F_SAF_SYMMENCRYPTUPDATE 122 + +/* Reason codes. */ +# define SAF_R_BUFFER_TOO_SMALL 100 +# define SAF_R_CBCMAC_FAILURE 101 +# define SAF_R_GEN_RANDOM 102 +# define SAF_R_INT_OVERFLOW 103 +# define SAF_R_INVALID_ALGOR 104 +# define SAF_R_INVALID_CONTEXT 105 +# define SAF_R_INVALID_DIGEST_ALGOR 106 +# define SAF_R_INVALID_HANDLE 107 +# define SAF_R_INVALID_INPUT_LENGTH 108 +# define SAF_R_INVALID_KEY_LENGTH 109 +# define SAF_R_INVALID_KEY_USAGE 110 +# define SAF_R_INVALID_LENGTH 111 +# define SAF_R_MAC_FAILURE 112 +# define SAF_R_OPERATION_NOT_INITIALIZED 113 +# define SAF_R_SAF_ERROR 114 + +# ifdef __cplusplus +} +# endif +#endif diff --git a/include/openssl/gmsdf.h b/include/openssl/gmsdf.h new file mode 100644 index 00000000..e5332eed --- /dev/null +++ b/include/openssl/gmsdf.h @@ -0,0 +1,177 @@ +/* ==================================================================== + * 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 HEADER_GMSDF_H +#define HEADER_GMSDF_H + +#include +#include +#include + +#define SDF_MIN_KEY_INDEX 1 /* defined by GM/T 0018 */ +#define SDF_MAX_KEY_INDEX 32 /* defined by GmSSL as vendor */ +#define SDF_MIN_PASSWORD_LENGTH 8 /* defined by GM/T 0018 */ +#define SDF_MAX_PASSWORD_LENGTH 255 /* defined by GmSSL as vendor */ + +#define ECCref_MAX_CIPHER_LEN 255 + + +#ifdef __cplusplus +extern "C" { +#endif + +int SDF_PrintDeviceInfo(FILE *fp, DEVICEINFO *devInfo); +int SDF_PrintRSAPublicKey(FILE *fp, RSArefPublicKey *pk); +int SDF_PrintRSAPrivateKey(FILE *fp, RSArefPrivateKey *pk); +int SDF_PrintECCPublicKey(FILE *fp, ECCrefPublicKey *pk); +int SDF_PrintECCPrivateKey(FILE *fp, ECCrefPrivateKey *pk); +int SDF_PrintECCCipher(FILE *fp, ECCCipher *cipher); +int SDF_PrintECCSignature(FILE *fp, ECCSignature *sig); +const char *SDF_GetErrorString(int err); + +//FIXME: implement this in a standalone file in sdf module +int SDF_ImportKey( + void *hSessionHandle, + unsigned char *pucKey, + unsigned int uiKeyLength, + void **phKeyHandle); + + +/* BEGIN ERROR CODES */ +/* + * The following lines are auto generated by the script mkerr.pl. Any changes + * made after this point may be overwritten when the script is next run. + */ + +int ERR_load_SDF_strings(void); + +/* Error codes for the SDF functions. */ + +/* Function codes. */ +# define SDF_F_SDF_CALCULATEMAC 100 +# define SDF_F_SDF_CLOSEDEVICE 145 +# define SDF_F_SDF_CLOSESESSION 101 +# define SDF_F_SDF_DECODE_EC_SIGNATURE 102 +# define SDF_F_SDF_DECRYPT 103 +# define SDF_F_SDF_ENCODE_EC_SIGNATURE 104 +# define SDF_F_SDF_ENCRYPT 105 +# define SDF_F_SDF_EXPORTENCPUBLICKEY_ECC 106 +# define SDF_F_SDF_EXPORTENCPUBLICKEY_RSA 107 +# define SDF_F_SDF_EXPORTSIGNPUBLICKEY_ECC 108 +# define SDF_F_SDF_EXPORTSIGNPUBLICKEY_RSA 109 +# define SDF_F_SDF_EXTERNALDECRYPT_ECC 110 +# define SDF_F_SDF_EXTERNALENCRYPT_ECC 111 +# define SDF_F_SDF_EXTERNALPRIVATEKEYOPERATION_RSA 112 +# define SDF_F_SDF_EXTERNALPUBLICKEYOPERATION_RSA 113 +# define SDF_F_SDF_EXTERNALSIGN_ECC 114 +# define SDF_F_SDF_EXTERNALVERIFY_ECC 115 +# define SDF_F_SDF_GENERATEKEYPAIR_ECC 116 +# define SDF_F_SDF_GENERATEKEYPAIR_RSA 117 +# define SDF_F_SDF_GENERATEKEYWITHEPK_ECC 118 +# define SDF_F_SDF_GENERATEKEYWITHEPK_RSA 119 +# define SDF_F_SDF_GENERATEKEYWITHIPK_ECC 120 +# define SDF_F_SDF_GENERATEKEYWITHIPK_RSA 121 +# define SDF_F_SDF_GENERATERANDOM 122 +# define SDF_F_SDF_GETDEVICEINFO 123 +# define SDF_F_SDF_GETPRIVATEKEYACCESSRIGHT 124 +# define SDF_F_SDF_GET_CIPHER 125 +# define SDF_F_SDF_GET_DIGEST 126 +# define SDF_F_SDF_HASHFINAL 127 +# define SDF_F_SDF_HASHINIT 128 +# define SDF_F_SDF_HASHUPDATE 129 +# define SDF_F_SDF_IMPORTKEY 130 +# define SDF_F_SDF_IMPORTKEYWITHISK_ECC 131 +# define SDF_F_SDF_IMPORTKEYWITHISK_RSA 132 +# define SDF_F_SDF_INTERNALDECRYPT_ECC 133 +# define SDF_F_SDF_INTERNALENCRYPT_ECC 134 +# define SDF_F_SDF_INTERNALPRIVATEKEYOPERATION_RSA 135 +# define SDF_F_SDF_INTERNALPUBLICKEYOPERATION_RSA 136 +# define SDF_F_SDF_INTERNALSIGN_ECC 137 +# define SDF_F_SDF_INTERNALVERIFY_ECC 138 +# define SDF_F_SDF_LOAD_EC_PRIVATE_KEY 139 +# define SDF_F_SDF_LOAD_EC_PUBLIC_KEY 140 +# define SDF_F_SDF_LOAD_RSA_PRIVATE_KEY 141 +# define SDF_F_SDF_LOAD_RSA_PUBLIC_KEY 142 +# define SDF_F_SDF_OPENDEVICE 143 +# define SDF_F_SDF_OPENSESSION 144 +# define SDF_F_SDF_RELEASEPRIVATEKEYACCESSRIGHT 146 + +/* Reason codes. */ +# define SDF_R_BUFFER_TOO_SMALL 100 +# define SDF_R_BUUTER_TOO_SMALL 101 +# define SDF_R_CBCMAC_FAILURE 102 +# define SDF_R_CMAC_FAILURE 126 +# define SDF_R_COMPUTE_SM2_ID_FAILURE 103 +# define SDF_R_ENGINE_LOAD_KEY_FAILURE 104 +# define SDF_R_GET_PRIVATE_KEY_FAILED 105 +# define SDF_R_GET_PUBLIC_KEY_FAILED 106 +# define SDF_R_INVALID_ALGOR 107 +# define SDF_R_INVALID_DEVICE_HANDLE 122 +# define SDF_R_INVALID_EC_CIPHERTEXT 108 +# define SDF_R_INVALID_EC_PRIVATE_KEY 109 +# define SDF_R_INVALID_EC_PUBLIC_KEY 110 +# define SDF_R_INVALID_INPUT_LENGTH 111 +# define SDF_R_INVALID_KEY_HANDLE 112 +# define SDF_R_INVALID_KEY_INDEX 123 +# define SDF_R_INVALID_KEY_LENGTH 113 +# define SDF_R_INVALID_KEY_USAGE 114 +# define SDF_R_INVALID_LENGTH 115 +# define SDF_R_INVALID_OPERATION_STATE 116 +# define SDF_R_INVALID_PASSWORD_LENGTH 124 +# define SDF_R_INVALID_SESSION 117 +# define SDF_R_INVALID_SESSION_HANDLE 125 +# define SDF_R_KEY_TYPE_NOT_MATCH 118 +# define SDF_R_LOAD_ENGINE_FAILURE 119 +# define SDF_R_RANDOM_FAILURE 120 +# define SDF_R_SDF_SESSION_NO_ENGINE 121 + +# ifdef __cplusplus +} +# endif +#endif diff --git a/include/openssl/gmskf.h b/include/openssl/gmskf.h new file mode 100644 index 00000000..cfadd2bb --- /dev/null +++ b/include/openssl/gmskf.h @@ -0,0 +1,187 @@ +/* ==================================================================== + * 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 HEADER_GMSKF_H +#define HEADER_GMSKF_H + +#include +#include + +#ifndef SKF_NO_GMSSL +#define SKF_NO_PADDING 0 +#define SKF_PKCS5_PADDING 1 +#endif + +#ifndef SKF_NO_GMSSL +#define DEV_ABSENT_STATE 0x00000000 +#define DEV_PRESENT_STATE 0x00000001 +#define DEV_UNKNOW_STATE 0x00000010 +#endif + +#ifndef SKF_NO_GMSSL +#define CONTAINER_TYPE_UNDEF 0 +#define CONTAINER_TYPE_RSA 1 +#define CONTAINER_TYPE_ECC 2 +#endif + +#ifdef __cplusplus +extern "C" { +#endif + + +//FIXME: change name +const char *SKF_get_alg_name(ULONG ulAlgID); + +int SKF_PrintDeviceInfo(FILE *fp, DEVINFO *devInfo); +int SKF_PrintRSAPublicKey(FILE *fp, RSAPUBLICKEYBLOB *pk); +int SKF_PrintRSAPrivateKey(FILE *fp, RSAPRIVATEKEYBLOB *pk); +int SKF_PrintECCPublicKey(FILE *fp, ECCPUBLICKEYBLOB *pk); +int SKF_PrintECCPrivateKey(FILE *fp, ECCPRIVATEKEYBLOB *pk); +int SKF_PrintECCCipher(FILE *fp, ECCCIPHERBLOB *cipher); +int SKF_PrintECCSignature(FILE *fp, ECCSIGNATUREBLOB *sig); +const char *SKF_GetErrorString(ULONG error); + + + +/* BEGIN ERROR CODES */ +/* + * The following lines are auto generated by the script mkerr.pl. Any changes + * made after this point may be overwritten when the script is next run. + */ + +int ERR_load_SKF_strings(void); + +/* Error codes for the SKF functions. */ + +/* Function codes. */ +# define SKF_F_SKF_CLOSEHANDLE 100 +# define SKF_F_SKF_DECRYPT 101 +# define SKF_F_SKF_DECRYPTFINAL 102 +# define SKF_F_SKF_DECRYPTINIT 103 +# define SKF_F_SKF_DECRYPTUPDATE 104 +# define SKF_F_SKF_DIGEST 105 +# define SKF_F_SKF_DIGESTFINAL 106 +# define SKF_F_SKF_DIGESTINIT 107 +# define SKF_F_SKF_DIGESTUPDATE 108 +# define SKF_F_SKF_ENCRYPT 109 +# define SKF_F_SKF_ENCRYPTFINAL 110 +# define SKF_F_SKF_ENCRYPTINIT 111 +# define SKF_F_SKF_ENCRYPTUPDATE 112 +# define SKF_F_SKF_EXTECCDECRYPT 113 +# define SKF_F_SKF_EXTECCENCRYPT 114 +# define SKF_F_SKF_EXTECCSIGN 115 +# define SKF_F_SKF_EXTECCVERIFY 116 +# define SKF_F_SKF_EXTRSAPRIKEYOPERATION 117 +# define SKF_F_SKF_EXTRSAPUBKEYOPERATION 118 +# define SKF_F_SKF_GENEXTECCKEYPAIR 119 +# define SKF_F_SKF_GENEXTRSAKEY 120 +# define SKF_F_SKF_GENRANDOM 121 +# define SKF_F_SKF_GETDEVINFO 122 +# define SKF_F_SKF_GETDEVSTATE 123 +# define SKF_F_SKF_HANDLE_GET_CBCMAC_CTX 124 +# define SKF_F_SKF_HANDLE_GET_CIPHER 125 +# define SKF_F_SKF_HANDLE_GET_CIPHER_CTX 126 +# define SKF_F_SKF_HANDLE_GET_KEY 127 +# define SKF_F_SKF_HANDLE_GET_MD_CTX 128 +# define SKF_F_SKF_MAC 129 +# define SKF_F_SKF_MACFINAL 130 +# define SKF_F_SKF_MACINIT 131 +# define SKF_F_SKF_MACUPDATE 132 +# define SKF_F_SKF_SETSYMMKEY 133 + +/* Reason codes. */ +# define SKF_R_BUFFER_TOO_SMALL 100 +# define SKF_R_CTX_NOT_CREATED 101 +# define SKF_R_DECRYPT_FAILED 102 +# define SKF_R_ENCODE_CIPHERTEXT_FAILED 103 +# define SKF_R_ENCODE_FAILED 104 +# define SKF_R_ENCODE_SIGNATURE_FAILED 105 +# define SKF_R_ENCRYPT_FAILED 106 +# define SKF_R_FAIL 107 +# define SKF_R_GEN_RSA_FAILED 108 +# define SKF_R_GET_PRIVATE_KEY_FAILED 109 +# define SKF_R_GET_PUBLIC_KEY_FAILED 110 +# define SKF_R_INVALID_ALGID 111 +# define SKF_R_INVALID_ALGOR 112 +# define SKF_R_INVALID_ARGUMENTS 113 +# define SKF_R_INVALID_BLOB 114 +# define SKF_R_INVALID_CIPHERTEXT 115 +# define SKF_R_INVALID_CIPHERTEXT_LENGTH 116 +# define SKF_R_INVALID_CIPHER_CTX_HANDLE 117 +# define SKF_R_INVALID_DIGEST_LENGTH 118 +# define SKF_R_INVALID_ECC_PRIVATE_KEY 119 +# define SKF_R_INVALID_ECC_PUBLIC_KEY 120 +# define SKF_R_INVALID_EC_PRIVATE_KEY 121 +# define SKF_R_INVALID_EC_PUBLIC_KEY 122 +# define SKF_R_INVALID_FEED_BIT_LENGTH 123 +# define SKF_R_INVALID_HANDLE 124 +# define SKF_R_INVALID_HANDLE_ALGOR 125 +# define SKF_R_INVALID_HANDLE_MAGIC 126 +# define SKF_R_INVALID_HANDLE_TYPE 127 +# define SKF_R_INVALID_HASH_HANDLE 128 +# define SKF_R_INVALID_ID_LENGTH 129 +# define SKF_R_INVALID_INPUT_LENGTH 130 +# define SKF_R_INVALID_IV_LENGTH 131 +# define SKF_R_INVALID_KEY_HANDLE 132 +# define SKF_R_INVALID_KEY_LENGTH 133 +# define SKF_R_INVALID_MAC_HANDLE 134 +# define SKF_R_INVALID_PLAINTEXT_LENGTH 135 +# define SKF_R_INVALID_RANDOM_LENGTH 136 +# define SKF_R_INVALID_RSA_PUBLIC_KEY 137 +# define SKF_R_INVALID_SIGNATURE 138 +# define SKF_R_MALLOC_FAILED 139 +# define SKF_R_NO_PUBLIC_KEY 140 +# define SKF_R_NULL_ARGUMENT 141 +# define SKF_R_SIGN_FAILED 142 +# define SKF_R_VERIFY_NOT_PASS 143 + +# ifdef __cplusplus +} +# endif +#endif diff --git a/include/openssl/gmsof.h b/include/openssl/gmsof.h new file mode 100644 index 00000000..674e87ea --- /dev/null +++ b/include/openssl/gmsof.h @@ -0,0 +1,143 @@ +/* ==================================================================== + * Copyright (c) 2016 The GmSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the GmSSL Project. + * (http://gmssl.org/)" + * + * 4. The name "GmSSL Project" must not be used to endorse or promote + * products derived from this software without prior written + * permission. For written permission, please contact + * guanzhi1980@gmail.com. + * + * 5. Products derived from this software may not be called "GmSSL" + * nor may "GmSSL" appear in their names without prior written + * permission of the GmSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the GmSSL Project + * (http://gmssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE GmSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE GmSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +#ifndef HEADER_GMSOF_H +#define HEADER_GMSOF_H + +#include +#include +#include + +/* SOF_SignMessage Flag */ +#define SOF_FLAG_SIG_WITH_MESSAGE 0 +#define SOF_FLAG_SIG_WITHOUT_MESSAGE 1 + +/* SOF_GetInfoFromSignedMessage Type */ +#define SOF_SIGNED_MESSAGE_MESSAGE 1 +#define SOF_SIGNED_MESSAGE_CERT 2 +#define SOF_SIGNED_MESSAGE_SIGNATURE 3 + +/* SOF_GetXMLSignatureInfo */ +#define SOF_XML_TYPE_MESSAGE 1 +#define SOF_XML_TYPE_DIGEST 2 +#define SOF_XML_TYPE_SIGNATURE 3 +#define SOF_XML_TYPE_CERTIFICATE 4 +#define SOF_XML_TYPE_DIGEST_ALGOR 5 +#define SOF_XML_TYPE_SIGN_ALGOR 6 + + + +#ifdef __cplusplus +extern "C" { +#endif + + + +/* BEGIN ERROR CODES */ +/* + * The following lines are auto generated by the script mkerr.pl. Any changes + * made after this point may be overwritten when the script is next run. + */ + +int ERR_load_SOF_strings(void); + +/* Error codes for the SOF functions. */ + +/* Function codes. */ +# define SOF_F_SOF_CHANGEPASSWD 100 +# define SOF_F_SOF_CREATETIMESTAMPREQUEST 101 +# define SOF_F_SOF_CREATETIMESTAMPRESPONSE 102 +# define SOF_F_SOF_DECRYPTDATA 103 +# define SOF_F_SOF_DECRYPTFILE 104 +# define SOF_F_SOF_DELCERTTRUSTLIST 105 +# define SOF_F_SOF_ENCRYPTDATA 106 +# define SOF_F_SOF_ENCRYPTFILE 107 +# define SOF_F_SOF_EXPORTEXCHANGEUSERCERT 108 +# define SOF_F_SOF_EXPORTUSERCERT 109 +# define SOF_F_SOF_GENRANDOM 110 +# define SOF_F_SOF_GETCERTINFO 111 +# define SOF_F_SOF_GETCERTINFOBYOID 112 +# define SOF_F_SOF_GETCERTTRUSTLIST 113 +# define SOF_F_SOF_GETCERTTRUSTLISTALTNAMES 114 +# define SOF_F_SOF_GETDEVICEINFO 115 +# define SOF_F_SOF_GETENCRYPTMETHOD 116 +# define SOF_F_SOF_GETINFOFROMSIGNEDMESSAGE 117 +# define SOF_F_SOF_GETLASTERROR 118 +# define SOF_F_SOF_GETPINRETRYCOUNT 119 +# define SOF_F_SOF_GETSERVERCERTIFICATE 120 +# define SOF_F_SOF_GETSIGNMETHOD 121 +# define SOF_F_SOF_GETTIMESTAMPINFO 122 +# define SOF_F_SOF_GETUSERLIST 123 +# define SOF_F_SOF_GETVERSION 124 +# define SOF_F_SOF_GETXMLSIGNATUREINFO 125 +# define SOF_F_SOF_INITCERTAPPPOLICY 126 +# define SOF_F_SOF_LOGIN 127 +# define SOF_F_SOF_SETCERTTRUSTLIST 128 +# define SOF_F_SOF_SETENCRYPTMETHOD 129 +# define SOF_F_SOF_SETSIGNMETHOD 130 +# define SOF_F_SOF_SIGNDATA 131 +# define SOF_F_SOF_SIGNDATAXML 132 +# define SOF_F_SOF_SIGNFILE 133 +# define SOF_F_SOF_SIGNMESSAGE 134 +# define SOF_F_SOF_SIGNMESSAGEDETACH 135 +# define SOF_F_SOF_VALIDATECERT 136 +# define SOF_F_SOF_VERIFYSIGNEDDATA 137 +# define SOF_F_SOF_VERIFYSIGNEDDATAXML 138 +# define SOF_F_SOF_VERIFYSIGNEDFILE 139 +# define SOF_F_SOF_VERIFYSIGNEDMESSAGE 140 +# define SOF_F_SOF_VERIFYSIGNEDMESSAGEDETACH 141 +# define SOF_F_SOF_VERIFYTIMESTAMP 142 + +/* Reason codes. */ +# define SOF_R_NOT_IMPLEMENTED 100 + +# ifdef __cplusplus +} +# endif +#endif diff --git a/util/mkdef.pl b/util/mkdef.pl index 8d1ede68..d1a3c245 100755 --- a/util/mkdef.pl +++ b/util/mkdef.pl @@ -133,7 +133,7 @@ my @known_algorithms = ( "RC2", "RC4", "RC5", "IDEA", "DES", "BF", # APPLINK (win build feature?) "APPLINK", "SM3", "SMS4", "KDF2", "ECIES", "FFX", "PAILLIER", "CPK", "OTP", "GMAPI", "EC2", - "BFIBE", "BB1IBE", "SM9" + "BFIBE", "BB1IBE", "SM9", "SAF", "SDF", "SKF", "SOF" ); my %disabled_algorithms;