diff --git a/wallfacer/encrypt/enclave/CMakeLists.txt b/wallfacer/encrypt/enclave/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..0f5d3ab8670e138ee9ad56686f7b185dd3e781b9 --- /dev/null +++ b/wallfacer/encrypt/enclave/CMakeLists.txt @@ -0,0 +1,35 @@ +# Copyright (c) Huawei Technologies Co., Ltd. 2020. All rights reserved. +# secGear is licensed under the Mulan PSL v2. +# You can use this software according to the terms and conditions of the Mulan PSL v2. +# You may obtain a copy of Mulan PSL v2 at: +# http://license.coscl.org.cn/MulanPSL2 +# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR +# PURPOSE. +# See the Mulan PSL v2 for more details. + +project(enclave C) + +set(CMAKE_C_STANDARD 99) + +set(CURRENT_ROOT_PATH ${CMAKE_CURRENT_SOURCE_DIR}) + +#set edl name +set(EDL_FILE enclave.edl) + +if(CC_GP) + set(CODETYPE trustzone) + set(CODEGEN codegen_arm64) + execute_process(COMMAND uuidgen -r OUTPUT_VARIABLE UUID) + string(REPLACE "\n" "" UUID ${UUID}) + add_definitions(-DPATH="/data/${UUID}.sec") +endif() + +if(CC_SGX) + set(CODETYPE sgx) + set(CODEGEN codegen_x86_64) + add_definitions(-DPATH="${CMAKE_CURRENT_BINARY_DIR}/enclave/enclave.signed.so") +endif() + +add_subdirectory(${CURRENT_ROOT_PATH}/enclave) +add_subdirectory(${CURRENT_ROOT_PATH}/host) diff --git a/wallfacer/encrypt/enclave/enclave.edl b/wallfacer/encrypt/enclave/enclave.edl new file mode 100644 index 0000000000000000000000000000000000000000..77bc7c748c7cee8a6a93a80d03ceaa5e31a9891f --- /dev/null +++ b/wallfacer/encrypt/enclave/enclave.edl @@ -0,0 +1,28 @@ +/*S + * Copyright (c) Huawei Technologies Co., Ltd. 2020. All rights reserved. + * secGear is licensed under the Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR + * PURPOSE. + * See the Mulan PSL v2 for more details. + */ + +enclave { + include "secgear_urts.h" + from "secgear_tstdc.edl" import *; + trusted { + public int get_int(); + public int get_string([out, size=80]unsigned char *buf); + public void transname([in,size=20]char *name); + public void transpsw([in,size=56]char *psw); + public void transinfo([in,size=31]char *info); + public void transcipher([in,size=64]char *cipher); + public void sm3(); + public void sm4crypt(int len); + public void desm4crypt(); + + }; +}; diff --git a/wallfacer/encrypt/enclave/enclave/CMakeLists.txt b/wallfacer/encrypt/enclave/enclave/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..89af399ba19ee6651b7919620754a5c8924219d3 --- /dev/null +++ b/wallfacer/encrypt/enclave/enclave/CMakeLists.txt @@ -0,0 +1,160 @@ +# Copyright (c) Huawei Technologies Co., Ltd. 2020. All rights reserved. +# secGear is licensed under the Mulan PSL v2. +# You can use this software according to the terms and conditions of the Mulan PSL v2. +# You may obtain a copy of Mulan PSL v2 at: +# http://license.coscl.org.cn/MulanPSL2 +# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR +# PURPOSE. +# See the Mulan PSL v2 for more details. + +#set auto code prefix +set(PREFIX enclave) + +#set sign key +set(PEM Enclave_private.pem) + +#set sign tool +set(SIGN_TOOL ${LOCAL_ROOT_PATH}/tools/sign_tool/sign_tool.sh) + +#set enclave src code +set(SOURCE_FILES ${CMAKE_CURRENT_SOURCE_DIR}/hello.c) + +#set log level +set(PRINT_LEVEL 3) +add_definitions(-DPRINT_LEVEL=${PRINT_LEVEL}) + +if(CC_GP) + #set signed output + set(OUTPUT ${UUID}.sec) + #set itrustee device key + set(DEVICEPEM ${CMAKE_CURRENT_SOURCE_DIR}/rsa_public_key_cloud.pem) + #set whilelist. default: /vendor/bin/teec_hello + set(WHITE_LIST_0 /vendor/bin/enclave) + set(WHITE_LIST_OWNER root) + set(WHITE_LIST_1 /vendor/bin/secgear_enclave) + set(WHITELIST WHITE_LIST_0 WHITE_LIST_1) + + set(AUTO_FILES ${CMAKE_CURRENT_BINARY_DIR}/${PREFIX}_t.h ${CMAKE_CURRENT_BINARY_DIR}/${PREFIX}_t.c ${CMAKE_CURRENT_BINARY_DIR}/${PREFIX}_args.h) + add_custom_command(OUTPUT ${AUTO_FILES} + DEPENDS ${CURRENT_ROOT_PATH}/${EDL_FILE} + COMMAND ${CODEGEN} --${CODETYPE} --trusted ${CURRENT_ROOT_PATH}/${EDL_FILE} --search-path ${LOCAL_ROOT_PATH}/inc/host_inc/gp) +endif() + +if(CC_SGX) + set(OUTPUT enclave.signed.so) + set(AUTO_FILES ${CMAKE_CURRENT_BINARY_DIR}/${PREFIX}_t.h ${CMAKE_CURRENT_BINARY_DIR}/${PREFIX}_t.c) + add_custom_command(OUTPUT ${AUTO_FILES} + DEPENDS ${CURRENT_ROOT_PATH}/${EDL_FILE} + COMMAND ${CODEGEN} --${CODETYPE} --trusted ${CURRENT_ROOT_PATH}/${EDL_FILE} --search-path ${LOCAL_ROOT_PATH}/inc/host_inc/sgx --search-path ${SGXSDK}/include) +endif() + +set(COMMON_C_FLAGS "-W -Wall -Werror -fno-short-enums -fno-omit-frame-pointer -fstack-protector \ + -Wstack-protector --param ssp-buffer-size=4 -frecord-gcc-switches -Wextra -nostdinc -nodefaultlibs \ + -fno-peephole -fno-peephole2 -Wno-main -Wno-error=unused-parameter \ + -Wno-error=unused-but-set-variable -Wno-error=format-truncation=") + +set(COMMON_C_LINK_FLAGS "-Wl,-z,now -Wl,-z,relro -Wl,-z,noexecstack -Wl,-nostdlib -nodefaultlibs -nostartfiles") + +if(CC_GP) + configure_file("${CMAKE_CURRENT_SOURCE_DIR}/manifest.txt.in" "${CMAKE_CURRENT_SOURCE_DIR}/manifest.txt") + + set(CMAKE_C_FLAGS "${COMMON_C_FLAGS} -march=armv8-a ") + set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS} -s -fPIC") + set(CMAKE_SHARED_LINKER_FLAGS "${COMMON_C_LINK_FLAGS} -Wl,-s") + + set(ITRUSTEE_TEEDIR ${iTrusteeSDK}/) + set(ITRUSTEE_LIBC ${iTrusteeSDK}/thirdparty/open_source/musl/libc) + + if(${CMAKE_VERSION} VERSION_LESS "3.13.0") + link_directories(${CMAKE_BINARY_DIR}/lib/) + endif() + + add_library(${PREFIX} SHARED ${SOURCE_FILES} ${AUTO_FILES}) + + target_include_directories( ${PREFIX} PRIVATE + ${CMAKE_CURRENT_BINARY_DIR} + ${LOCAL_ROOT_PATH}/inc/host_inc + ${LOCAL_ROOT_PATH}/inc/host_inc/gp + ${LOCAL_ROOT_PATH}/inc/enclave_inc + ${LOCAL_ROOT_PATH}/inc/enclave_inc/gp + ${ITRUSTEE_TEEDIR}/include/TA + ${ITRUSTEE_TEEDIR}/include/TA/huawei_ext + ${ITRUSTEE_LIBC}/arch/aarch64 + ${ITRUSTEE_LIBC}/ + ${ITRUSTEE_LIBC}/arch/arm/bits + ${ITRUSTEE_LIBC}/arch/generic + ${ITRUSTEE_LIBC}/arch/arm + ${LOCAL_ROOT_PATH}/inc/enclave_inc/gp/itrustee) + + if(${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.13.0") + target_link_directories(${PREFIX} PRIVATE + ${CMAKE_BINARY_DIR}/lib/) + endif() + + foreach(WHITE_LIST ${WHITELIST}) + add_definitions(-D${WHITE_LIST}="${${WHITE_LIST}}") + endforeach(WHITE_LIST) + add_definitions(-DWHITE_LIST_OWNER="${WHITE_LIST_OWNER}") + + target_link_libraries(${PREFIX} -lsecgear_tee) + + add_custom_command(TARGET ${PREFIX} + POST_BUILD + COMMAND bash ${SIGN_TOOL} -d sign -x trustzone -i ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/lib${PREFIX}.so -m ${CMAKE_CURRENT_SOURCE_DIR}/manifest.txt + -e ${DEVICEPEM} -o ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/${OUTPUT}) + + install(FILES ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/${OUTPUT} + DESTINATION /data + PERMISSIONS OWNER_EXECUTE OWNER_WRITE OWNER_READ GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE) + +endif() + +if(CC_SGX) + set(SGX_DIR ${SGXSDK}) + set(CMAKE_C_FLAGS "${COMMON_C_FLAGS} -m64 -fvisibility=hidden") + set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS} -s") + set(LINK_LIBRARY_PATH ${SGX_DIR}/lib64) + + if(CC_SIM) + set(Trts_Library_Name sgx_trts_sim) + set(Service_Library_Name sgx_tservice_sim) + else() + set(Trts_Library_Name sgx_trts) + set(Service_Library_Name sgx_tservice) + endif() + + set(Crypto_Library_Name sgx_tcrypto) + + set(CMAKE_SHARED_LINKER_FLAGS "${COMMON_C_LINK_FLAGS} -Wl,-z,defs -Wl,-pie -Bstatic -Bsymbolic -eenclave_entry \ + -Wl,--export-dynamic -Wl,--defsym,__ImageBase=0 -Wl,--gc-sections -Wl,--version-script=${CMAKE_CURRENT_SOURCE_DIR}/Enclave.lds") + + if(${CMAKE_VERSION} VERSION_LESS "3.13.0") + link_directories(${LINK_LIBRARY_PATH}) + endif() + + add_library(${PREFIX} SHARED ${SOURCE_FILES} ${AUTO_FILES}) + + target_include_directories(${PREFIX} PRIVATE + ${CMAKE_CURRENT_BINARY_DIR} + ${SGX_DIR}/include/tlibc + ${SGX_DIR}/include/libcxx + ${SGX_DIR}/include + ${LOCAL_ROOT_PATH}/inc/host_inc + ${LOCAL_ROOT_PATH}/inc/host_inc/sgx) + + if(${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.13.0") + target_link_directories(${PREFIX} PRIVATE + ${LINK_LIBRARY_PATH}) + endif() + + target_link_libraries(${PREFIX} -Wl,--whole-archive ${Trts_Library_Name} -Wl,--no-whole-archive + -Wl,--start-group -lsgx_tstdc -lsgx_tcxx -l${Crypto_Library_Name} -l${Service_Library_Name} -Wl,--end-group) + add_custom_command(TARGET ${PREFIX} + POST_BUILD + COMMAND umask 0177 + COMMAND openssl genrsa -3 -out ${PEM} 3072 + COMMAND bash ${SIGN_TOOL} -d sign -x sgx -i ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/lib${PREFIX}.so -k ${PEM} -o ${OUTPUT} -c ${CMAKE_CURRENT_SOURCE_DIR}/Enclave.config.xml) +endif() + +set_target_properties(${PREFIX} PROPERTIES SKIP_BUILD_RPATH TRUE) diff --git a/wallfacer/encrypt/enclave/enclave/Enclave.config.xml b/wallfacer/encrypt/enclave/enclave/Enclave.config.xml new file mode 100644 index 0000000000000000000000000000000000000000..e94c9bc50a61ebb552322ca5975510ac4b806c79 --- /dev/null +++ b/wallfacer/encrypt/enclave/enclave/Enclave.config.xml @@ -0,0 +1,12 @@ + + 0 + 0 + 0x40000 + 0x100000 + 10 + 1 + + 0 + 0 + 0xFFFFFFFF + diff --git a/wallfacer/encrypt/enclave/enclave/Enclave.lds b/wallfacer/encrypt/enclave/enclave/Enclave.lds new file mode 100644 index 0000000000000000000000000000000000000000..ab77e6478ef3c3448356e80b9884a8a533dd32c6 --- /dev/null +++ b/wallfacer/encrypt/enclave/enclave/Enclave.lds @@ -0,0 +1,11 @@ +enclave.so +{ + global: + g_global_data_sim; + g_global_data; + enclave_entry; + g_peak_heap_used; + local: + *; +}; + diff --git a/wallfacer/encrypt/enclave/enclave/common_utils.h b/wallfacer/encrypt/enclave/enclave/common_utils.h new file mode 100644 index 0000000000000000000000000000000000000000..bd8c64718824a91fa32f11390f76a9b9cec8b36b --- /dev/null +++ b/wallfacer/encrypt/enclave/enclave/common_utils.h @@ -0,0 +1,58 @@ +#ifndef SECGEAR_SM_COMMON_UTILS +#define SECGEAR_SM_COMMON_UTILS + +#include + +typedef __uint8_t uint8; +typedef __uint16_t uint16; +typedef __uint32_t uint32; +typedef __uint64_t uint64; + +#define CONCAT_8x4(x0, x1, x2, x3) ((((uint32)(x0) << 8 | (x1)) << 8 | (x2)) << 8 | (x3)) // X = (x0 || x1 || x2 || x3) +#define CONCAT_16x2(x0, x1) ((uint32)(x0) << 16 | (x1)) // X = (x0 || x1) +#define EXTRACT_8_32(X, i) (((X) >> (((i) ^ 3) << 3)) & 0xFF) // X = (x0 || x1 || x2 || x3) +#define EXTRACT_16_32(X, i) (((X) >> (((i) ^ 1) << 4)) & 0xFFFF) // X = (x0 || x1) +#define EXTRACT_16H_31(X) (((X) >> 15) & 0xFFFF) // Higher 16-bit from 31-bit +#define EXTRACT_16L_31(X) ((X) & 0xFFFF) // Lower 16-bit from 31-bit + +#define ROTATE(a, n) (((a) << (n)) | (((a) & 0xFFFFFFFF) >> (32 - (n)))) +#define ROTATE_31(a, n) ((((a) << (n)) & 0x7FFFFFFF) | (((a) & 0x7FFFFFFF) >> (31 - (n)))) + +#define GET_BIT_VALUE_32(x, i) (((x) >> (31 - (i))) & 1) + +const uint32 PREFIX_MASK_32[32] = { + 0x00000000, + 0x80000000, + 0xC0000000, + 0xE0000000, + 0xF0000000, + 0xF8000000, + 0xFC000000, + 0xFE000000, + 0xFF000000, + 0xFF800000, + 0xFFC00000, + 0xFFE00000, + 0xFFF00000, + 0xFFF80000, + 0xFFFC0000, + 0xFFFE0000, + 0xFFFF0000, + 0xFFFF8000, + 0xFFFFC000, + 0xFFFFE000, + 0xFFFFF000, + 0xFFFFF800, + 0xFFFFFC00, + 0xFFFFFE00, + 0xFFFFFF00, + 0xFFFFFF80, + 0xFFFFFFC0, + 0xFFFFFFE0, + 0xFFFFFFF0, + 0xFFFFFFF8, + 0xFFFFFFFC, + 0xFFFFFFFE +}; + +#endif \ No newline at end of file diff --git a/wallfacer/encrypt/enclave/enclave/hello.c b/wallfacer/encrypt/enclave/enclave/hello.c new file mode 100644 index 0000000000000000000000000000000000000000..d2fa5f4447b3246ca13185cfe6c6535f95323483 --- /dev/null +++ b/wallfacer/encrypt/enclave/enclave/hello.c @@ -0,0 +1,915 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2020. All rights reserved. + * secGear is licensed under the Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR + * PURPOSE. + * See the Mulan PSL v2 for more details. + */ + +#include +#include +#include +#include +#include "enclave_t.h" + +#define BUF_MAX 32 +#define Mkey "admin" //主密钥,用于生成存储密钥 +char uname[20];//用户名 +char upsw[56];//用户密码 +char buff[80];//用户名与密码相连字符串 +char uinfo[31];//用户机密信息,字符串 +char ucipher[64];//用户十六进制密文字符串 +char c[32];//用户十六进制转字符串 +unsigned char cipt[40];//sm3加密后生成的存储密钥 +int num=0; +char key[16];//sm4加密密钥 +char acipt[40];//sm4加密后生成的信息密文 +char temp[32]; +int nnn; + + + +void transname(char *name)//获得用户名 +{ + strncpy(uname,name, strlen(name)); +} +void transpsw(char *psw)//获得用户密码 +{ + strncpy(upsw,psw, strlen(psw)); +} +void transinfo(char *info)//获得用户机密信息 +{ + strncpy(uinfo,info, strlen(info)); +} +void transcipher(char *cipher)//获得用户机密信息 +{ + strncpy(ucipher,cipher, strlen(cipher)); +} + +//SM3 + +#include "sm3.h" + +void sm3() +{ + strncpy(buff, uname, strlen(uname));//获得用户名 + strncat(buff, upsw, strlen(upsw));//连接用户密码 + strncat(buff, Mkey, strlen(Mkey));//连接用户密码 + SM3_CTX c; + sm3_init(&c); + sm3_update(&c, buff, strlen(buff)); + sm3_final(&c, cipt); +} + +//SM4加密算法 + +#include "sm4.h" + +/** + * S盒 + */ +static const int S[16][16] = +{ + { + 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, + 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76 + }, + { + 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, + 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0 + }, + { + 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, + 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15 + }, + { + 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, + 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75 + }, + { + 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, + 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84 + }, + { + 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, + 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf + }, + { + 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, + 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8 + }, + { + 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, + 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2 + }, + { + 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, + 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73 + }, + { + 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, + 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb + }, + { + 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, + 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79 + }, + { + 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, + 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08 + }, + { + 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, + 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a + }, + { + 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, + 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e + }, + { + 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, + 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf + }, + { + 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, + 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16 + } +}; +/** + * 逆S盒 + */ +static const int S2[16][16] = +{ + { + 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, + 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb + }, + { + 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, + 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb + }, + { + 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, + 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e + }, + { + 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, + 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25 + }, + { + 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, + 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92 + }, + { + 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, + 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84 + }, + { + 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, + 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06 + }, + { + 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, + 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b + }, + { + 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, + 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73 + }, + { + 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, + 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e + }, + { + 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, + 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b + }, + { + 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, + 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4 + }, + { + 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, + 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f + }, + { + 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, + 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef + }, + { + 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, + 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61 + }, + { + 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, + 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d + } +}; +/** + * 获取整形数据的低8位的左4个位 + */ +static int getLeft4Bit(int num) +{ + int left = num & 0x000000f0; + return left >> 4; +} +/** + * 获取整形数据的低8位的右4个位 + */ +static int getRight4Bit(int num) +{ + return num & 0x0000000f; +} +/** + * 根据索引,从S盒中获得元素 + */ +static int getNumFromSBox(int index) +{ + int row = getLeft4Bit(index); + int col = getRight4Bit(index); + return S[row][col]; +} +/** + * 把一个字符转变成整型 + */ +static int getIntFromChar(char c) +{ + int result = (int) c; + return result & 0x000000ff; +} +/** + * 把16个字符转变成4X4的数组, + * 该矩阵中字节的排列顺序为从上到下, + * 从左到右依次排列。 + */ +static void convertToIntArray(char *str, int pa[4][4]) +{ + int k = 0; + for(int i = 0; i < 4; i++) + for(int j = 0; j < 4; j++) { + pa[j][i] = getIntFromChar(str[k]); + k++; + } +} +/** + * 把连续的4个字符合并成一个4字节的整型 + */ +static int getWordFromStr(char *str) +{ + int one = getIntFromChar(str[0]); + one = one << 24; + int two = getIntFromChar(str[1]); + two = two << 16; + int three = getIntFromChar(str[2]); + three = three << 8; + int four = getIntFromChar(str[3]); + return one | two | three | four; +} +/** + * 把一个4字节的数的第一、二、三、四个字节取出, + * 入进一个4个元素的整型数组里面。 + */ +static void splitIntToArray(int num, int array[4]) +{ + int one = num >> 24; + array[0] = one & 0x000000ff; + int two = num >> 16; + array[1] = two & 0x000000ff; + int three = num >> 8; + array[2] = three & 0x000000ff; + array[3] = num & 0x000000ff; +} +/** + * 将数组中的元素循环左移step位 + */ +static void leftLoop4int(int array[4], int step) +{ + int temp[4]; + for(int i = 0; i < 4; i++) + { + temp[i] = array[i]; + } + int index = step % 4 == 0 ? 0 : step % 4; + for(int i = 0; i < 4; i++) + { + array[i] = temp[index]; + index++; + index = index % 4; + } +} +/** + * 把数组中的第一、二、三和四元素分别作为 + * 4字节整型的第一、二、三和四字节,合并成一个4字节整型 + */ +static int mergeArrayToInt(int array[4]) +{ + int one = array[0] << 24; + int two = array[1] << 16; + int three = array[2] << 8; + int four = array[3]; + return one | two | three | four; +} +/** + * 常量轮值表 + */ +static const int Rcon[10] = +{ + 0x01000000, 0x02000000, + 0x04000000, 0x08000000, + 0x10000000, 0x20000000, + 0x40000000, 0x80000000, + 0x1b000000, 0x36000000 +}; +/** + * 密钥扩展中的T函数 + */ +static int T(int num, int round) +{ + int numArray[4]; + splitIntToArray(num, numArray); + leftLoop4int(numArray, 1);//字循环 + //字节代换 + for(int i = 0; i < 4; i++) + { + numArray[i] = getNumFromSBox(numArray[i]); + } + int result = mergeArrayToInt(numArray); + return result ^ Rcon[round]; +} +//密钥对应的扩展数组 +static int w[44]; +/** + * 扩展密钥,结果是把w[44]中的每个元素初始化 + */ +static void extendKey(char *key) +{ + for(int i = 0; i < 4; i++) + { + w[i] = getWordFromStr(key + i * 4); + } + for(int i = 4, j = 0; i < 44; i++) + { + if( i % 4 == 0) + { + w[i] = w[i - 4] ^ T(w[i - 1], j); + j++;//下一轮 + } + else + { + w[i] = w[i - 4] ^ w[i - 1]; + } + } +} +/** + * 轮密钥加 + */ +static void addRoundKey(int array[4][4], int round) +{ + int warray[4]; + for(int i = 0; i < 4; i++) + { + splitIntToArray(w[ round * 4 + i], warray); + for(int j = 0; j < 4; j++) + { + array[j][i] = array[j][i] ^ warray[j]; + } + } +} +/** + * 字节代换 + */ +static void subBytes(int array[4][4]) +{ + for(int i = 0; i < 4; i++) + { + for(int j = 0; j < 4; j++) + { + array[i][j] = getNumFromSBox(array[i][j]); + } + } +} +/** + * 行移位 + */ +static void shiftRows(int array[4][4]) +{ + int rowTwo[4], rowThree[4], rowFour[4]; + //复制状态矩阵的第2,3,4行 + for(int i = 0; i < 4; i++) + { + rowTwo[i] = array[1][i]; + rowThree[i] = array[2][i]; + rowFour[i] = array[3][i]; + } + //循环左移相应的位数 + leftLoop4int(rowTwo, 1); + leftLoop4int(rowThree, 2); + leftLoop4int(rowFour, 3); + //把左移后的行复制回状态矩阵中 + for(int i = 0; i < 4; i++) + { + array[1][i] = rowTwo[i]; + array[2][i] = rowThree[i]; + array[3][i] = rowFour[i]; + } +} +/** + * 列混合要用到的矩阵 + */ +static const int colM[4][4] = +{ + {2, 3, 1, 1}, + {1, 2, 3, 1}, + {1, 1, 2, 3}, + {3, 1, 1, 2} +}; +static int GFMul2(int s) +{ + int result = s << 1; + int a7 = result & 0x00000100; + if(a7 != 0) + { + result = result & 0x000000ff; + result = result ^ 0x1b; + } + return result; +} +static int GFMul3(int s) +{ + return GFMul2(s) ^ s; +} +static int GFMul4(int s) +{ + return GFMul2(GFMul2(s)); +} +static int GFMul8(int s) +{ + return GFMul2(GFMul4(s)); +} +static int GFMul9(int s) +{ + return GFMul8(s) ^ s; +} +static int GFMul11(int s) +{ + return GFMul9(s) ^ GFMul2(s); +} +static int GFMul12(int s) +{ + return GFMul8(s) ^ GFMul4(s); +} +static int GFMul13(int s) +{ + return GFMul12(s) ^ s; +} +static int GFMul14(int s) +{ + return GFMul12(s) ^ GFMul2(s); +} +/** + * GF上的二元运算 + */ +static int GFMul(int n, int s) +{ + int result; + if(n == 1) + { + result = s; + } + else if(n == 2) + { + result = GFMul2(s); + } + else if(n == 3) + { + result = GFMul3(s); + } + else if(n == 0x9) + { + result = GFMul9(s); + } + else if(n == 0xb)//11 + { + result = GFMul11(s); + } + else if(n == 0xd)//13 + { + result = GFMul13(s); + } + else if(n == 0xe)//14 + { + result = GFMul14(s); + } + return result; +} +/** + * 列混合 + */ +static void mixColumns(int array[4][4]) +{ + int tempArray[4][4]; + for(int i = 0; i < 4; i++) + { + for(int j = 0; j < 4; j++) + { + tempArray[i][j] = array[i][j]; + } + } + for(int i = 0; i < 4; i++) + { + for(int j = 0; j < 4; j++) + { + array[i][j] = GFMul(colM[i][0],tempArray[0][j]) ^ + GFMul(colM[i][1],tempArray[1][j]) + ^ GFMul(colM[i][2],tempArray[2][j]) + ^ GFMul(colM[i][3], tempArray[3][j]); + } + } +} +/** + * 把4X4数组转回字符串 + */ +static void convertArrayToStr(int array[4][4], char *str) { + for(int i = 0; i < 4; i++) + { + for(int j = 0; j < 4; j++) + { + *str++ = (char)array[j][i]; + } + } +} +/** + * 参数 p: 明文的字符串数组。 + * 参数 plen: 明文的长度。 + * 参数 key: 密钥的字符串数组。 + */ +void sm4(char *p, int plen, char *key) +{ + extendKey(key);//扩展密钥 + int pArray[4][4]; + for(int k = 0; k < plen; k += 16) + { + convertToIntArray(p + k, pArray); + addRoundKey(pArray, 0);//一开始的轮密钥加 + for(int i = 1; i < 10; i++) + {//前9轮 + subBytes(pArray);//字节代换 + shiftRows(pArray);//行移位 + mixColumns(pArray);//列混合 + addRoundKey(pArray, i); + } + //第10轮 + subBytes(pArray);//字节代换 + shiftRows(pArray);//行移位 + addRoundKey(pArray, 10); + convertArrayToStr(pArray, p + k); + } +} +/** + * 根据索引从逆S盒中获取值 + */ +static int getNumFromS1Box(int index) +{ + int row = getLeft4Bit(index); + int col = getRight4Bit(index); + return S2[row][col]; +} +/** + * 逆字节变换 + */ +static void deSubBytes(int array[4][4]) +{ + for(int i = 0; i < 4; i++) + { + for(int j = 0; j < 4; j++) + { + array[i][j] = getNumFromS1Box(array[i][j]); + } + } +} +/** + * 把4个元素的数组循环右移step位 + */ +static void rightLoop4int(int array[4], int step) +{ + int temp[4]; + for(int i = 0; i < 4; i++) + { + temp[i] = array[i]; + } + int index = step % 4 == 0 ? 0 : step % 4; + index = 3 - index; + for(int i = 3; i >= 0; i--) + { + array[i] = temp[index]; + index--; + index = index == -1 ? 3 : index; + } +} +/** + * 逆行移位 + */ +static void deShiftRows(int array[4][4]) +{ + int rowTwo[4], rowThree[4], rowFour[4]; + for(int i = 0; i < 4; i++) + { + rowTwo[i] = array[1][i]; + rowThree[i] = array[2][i]; + rowFour[i] = array[3][i]; + } + rightLoop4int(rowTwo, 1); + rightLoop4int(rowThree, 2); + rightLoop4int(rowFour, 3); + for(int i = 0; i < 4; i++) + { + array[1][i] = rowTwo[i]; + array[2][i] = rowThree[i]; + array[3][i] = rowFour[i]; + } +} +/** + * 逆列混合用到的矩阵 + */ +static const int deColM[4][4] = +{ + {0xe, 0xb, 0xd, 0x9}, + {0x9, 0xe, 0xb, 0xd}, + {0xd, 0x9, 0xe, 0xb}, + {0xb, 0xd, 0x9, 0xe} +}; +/** + * 逆列混合 + */ +static void deMixColumns(int array[4][4]) +{ + int tempArray[4][4]; + for(int i = 0; i < 4; i++) + { + for(int j = 0; j < 4; j++) + { + tempArray[i][j] = array[i][j]; + } + } + for(int i = 0; i < 4; i++) + { + for(int j = 0; j < 4; j++) + { + array[i][j] = GFMul(deColM[i][0],tempArray[0][j]) ^ + GFMul(deColM[i][1],tempArray[1][j]) ^ + GFMul(deColM[i][2],tempArray[2][j]) ^ + GFMul(deColM[i][3], tempArray[3][j]); + } + } +} +/** + * 把两个4X4数组进行异或 + */ +static void addRoundTowArray(int aArray[4][4],int bArray[4][4]) +{ + for(int i = 0; i < 4; i++) + { + for(int j = 0; j < 4; j++) + { + aArray[i][j] = aArray[i][j] ^ bArray[i][j]; + } + } +} +/** + * 从4个32位的密钥字中获得4X4数组, + * 用于进行逆列混合 + */ +static void getArrayFrom4W(int i, int array[4][4]) +{ + int index = i * 4; + int colOne[4], colTwo[4], colThree[4], colFour[4]; + splitIntToArray(w[index], colOne); + splitIntToArray(w[index + 1], colTwo); + splitIntToArray(w[index + 2], colThree); + splitIntToArray(w[index + 3], colFour); + for(int i = 0; i < 4; i++) + { + array[i][0] = colOne[i]; + array[i][1] = colTwo[i]; + array[i][2] = colThree[i]; + array[i][3] = colFour[i]; + } +} +/** + * 参数 c: 密文的字符串数组。 + * 参数 clen: 密文的长度。 + * 参数 key: 密钥的字符串数组。 + */ +void desm4(char *c, int clen, char *key) +{ + extendKey(key);//扩展密钥 + int cArray[4][4]; + for(int k = 0; k < clen; k += 16) + { + convertToIntArray(c + k, cArray); + addRoundKey(cArray, 10); + int wArray[4][4]; + for(int i = 9; i >= 1; i--) + { + deSubBytes(cArray); + deShiftRows(cArray); + deMixColumns(cArray); + getArrayFrom4W(i, wArray); + deMixColumns(wArray); + addRoundTowArray(cArray, wArray); + } + deSubBytes(cArray); + deShiftRows(cArray); + addRoundKey(cArray, 0); + convertArrayToStr(cArray, c + k); + } +} + +#define MAXLEN 1024 + +void printASCII(char *str, int len) {//字符串转16进制 + for(int i = 0; i < len; i++) { + acipt[i] = (int)*str++; + acipt[i] = acipt[i] & 0x000000ff; + } +} + +void hex32_str(char *data,char *input)//将16进制串转字符串 +{ + int i=0,sum; + char t; + for(i=0;i<32;i=i+2) + { + sum=0; + t=data[i]; + if(t<='9') + { + sum=((int)t-48)*16; + } + else + { + switch(t) + { + case 'a':sum=10*16;break; + case 'b':sum=11*16;break; + case 'c':sum=12*16;break; + case 'd':sum=13*16;break; + case 'e':sum=14*16;break; + case 'f':sum=15*16;break; + } + } + t=data[i+1]; + if(t<='9') + { + sum=sum+((int)t-48); + } + else + { + switch(t) + { + case 'a':sum=sum+10;break; + case 'b':sum=sum+11;break; + case 'c':sum=sum+12;break; + case 'd':sum=sum+13;break; + case 'e':sum=sum+14;break; + case 'f':sum=sum+15;break; + } + } + input[i/2]=(char)sum; + } +} + +void hex16_str(char *data,char *output,int len)//将16进制转字符串 +{ + for(int i = 0; i < len; i++) { + output[i] = (char)data[i];//data中每个元素为字符对应的十进制数 + } +} + + +/** + * 使用PKCS#7 填充字符串 + p:要填充的明文字符串 + len:明文字符串长度 + */ +int PKCS7Padding(char *p, int len) +{ + //ascii码转16进制,temp中每个元素为字符对应的十进制数,方便填充 + for(int i = 0; i < len; i++) { + temp[i] = (int)*p++; + temp[i] = temp[i] & 0x000000ff;//temp中为字符转数字,即a=97 + } + + int i; + int block = len/16;//数据分组的组数 + int start = len;//开始补码的地址 + int end=(block+1)*16;//补码后总长度 + int t=16-len%16;//要补的位数,也即要补的字符 + if(t<10) + { + for(i = start; i < end; i++) + { + temp[i] = t; + }; + } + else if(t<=15) + { + for(i = start; i < end; i++) + { + temp[i] = t; + } + } + else if(t==16)//error + { + for(i = start; i < end; i++) + { + temp[i] = 16; + } + } + + hex16_str(temp,uinfo,end);//将temp中的每个元素对应的十进制数转为字符,方便后续对字符串加密 + nnn=end; + return end; +} + +/** + * 删除PKCS#7 填充字符串 + c:要删除填充的解密后的字符串 + len:解密后字符串长度 + padlen:删除填充后字符串长度 + */ +int dePKCS7Padding(char *c, int len) +{ +//送进来的为字符串,每个元素为字符,需要先获取最后一个字符,将字符转int,如0a=10,再从len-10开始置0到最后,返回重置后的字符串 + int padlen=(int)c[len-1]; + nnn=len-padlen; + for(int i=len-padlen;i +#include "common_utils.h" + +#define SM3_DIGEST_LENGTH 32 +#define SM3_WORD uint32 + +#define SM3_CBLOCK 64 +#define SM3_LBLOCK (SM3_CBLOCK/4) + +typedef struct SM3state_st { + SM3_WORD A, B, C, D, E, F, G, H; + SM3_WORD Nl, Nh; + SM3_WORD data[SM3_LBLOCK]; + unsigned int num; +} SM3_CTX; + +#define ROTATE(a, n) (((a) << (n)) | (((a) & 0xFFFFFFFF) >> (32 - (n)))) + +# define HOST_c2l(c,l) (l =(((unsigned long)(*((c)++)))<<24), \ + l|=(((unsigned long)(*((c)++)))<<16), \ + l|=(((unsigned long)(*((c)++)))<< 8), \ + l|=(((unsigned long)(*((c)++))) ) ) +# define HOST_l2c(l,c) (*((c)++)=(unsigned char)(((l)>>24)&0xff), \ + *((c)++)=(unsigned char)(((l)>>16)&0xff), \ + *((c)++)=(unsigned char)(((l)>> 8)&0xff), \ + *((c)++)=(unsigned char)(((l) )&0xff), \ + l) + +#define P0(X) (X ^ ROTATE(X, 9) ^ ROTATE(X, 17)) +#define P1(X) (X ^ ROTATE(X, 15) ^ ROTATE(X, 23)) + +#define FF(J,X,Y,Z) (J<16 ? (X ^ Y ^ Z) : ((X & Y) | (X & Z) | (Y & Z))) +#define GG(J,X,Y,Z) (J<16 ? (X ^ Y ^ Z) : ((X & Y) | ((~X) & Z))) + +#define T(J) (J<16 ? 0x79cc4519 : 0x7a879d8a) + +#define EXPAND(W0,W7,W13,W3,W10) \ + (P1(W0 ^ W7 ^ ROTATE(W13, 15)) ^ ROTATE(W3, 7) ^ W10) + +#define SM3_A 0x7380166fUL +#define SM3_B 0x4914b2b9UL +#define SM3_C 0x172442d7UL +#define SM3_D 0xda8a0600UL +#define SM3_E 0xa96f30bcUL +#define SM3_F 0x163138aaUL +#define SM3_G 0xe38dee4dUL +#define SM3_H 0xb0fb0e4eUL + +#define SM3_MAKE_STRING(c, s) \ + do { \ + unsigned long ll; \ + ll=(c)->A; (void)HOST_l2c(ll, (s)); \ + ll=(c)->B; (void)HOST_l2c(ll, (s)); \ + ll=(c)->C; (void)HOST_l2c(ll, (s)); \ + ll=(c)->D; (void)HOST_l2c(ll, (s)); \ + ll=(c)->E; (void)HOST_l2c(ll, (s)); \ + ll=(c)->F; (void)HOST_l2c(ll, (s)); \ + ll=(c)->G; (void)HOST_l2c(ll, (s)); \ + ll=(c)->H; (void)HOST_l2c(ll, (s)); \ + } while (0) + +void sm3_block_data_order(SM3_CTX *ctx, const void *p, size_t num) { + const unsigned char *data = p; + SM3_WORD A, B, C, D, E, F, G, H; + SM3_WORD w[68]={}, ww[64]={}; + while (num--) { + A = ctx->A; + B = ctx->B; + C = ctx->C; + D = ctx->D; + E = ctx->E; + F = ctx->F; + G = ctx->G; + H = ctx->H; + for (int j = 0; j < 16; ++j) { + HOST_c2l(data, w[j]); + } + for (int j = 16; j < 68; ++j) { + w[j] = EXPAND(w[j-16], w[j-9], w[j-3], w[j-13], w[j-6]); + } + for (int j = 0; j < 64; ++j) { + ww[j] = w[j] ^ w[j+4]; + } + for (int j = 0; j < 64; j++) { + SM3_WORD SS1, SS2, TT1, TT2; + SS1 = ROTATE(ROTATE(A, 12) + E + ROTATE(T(j), j&31), 7); + SS2 = SS1 ^ ROTATE(A, 12); + TT1 = FF(j, A, B, C) + D + SS2 + ww[j]; + TT2 = GG(j, E, F, G) + H + SS1 + w[j]; + D = C; + C = ROTATE(B,9); + B = A; + A = TT1; + H = G; + G = ROTATE(F, 19); + F = E; + E = P0(TT2); + } + ctx->A ^= A; + ctx->B ^= B; + ctx->C ^= C; + ctx->D ^= D; + ctx->E ^= E; + ctx->F ^= F; + ctx->G ^= G; + ctx->H ^= H; + } +} + +int sm3_init(SM3_CTX *c) { + memset(c, 0, sizeof(*c)); + c->A = SM3_A; + c->B = SM3_B; + c->C = SM3_C; + c->D = SM3_D; + c->E = SM3_E; + c->F = SM3_F; + c->G = SM3_G; + c->H = SM3_H; + return 1; +} + +int sm3_update(SM3_CTX *c, const void *data_, size_t len) { + const unsigned char *data = data_; + unsigned char *p; + SM3_WORD l; + size_t n; + if (len == 0) return 1; + l = (c->Nl + (((SM3_WORD) len) << 3)) & 0xffffffffUL; + if (l < c->Nl) c->Nh++; + c->Nh += (SM3_WORD) (len >> 29); + c->Nl = l; + n = c->num; + if (n != 0) { + p = (unsigned char *)c->data; + if (len >= SM3_CBLOCK || len + n >= SM3_CBLOCK) { + memcpy(p + n, data, SM3_CBLOCK - n); + sm3_block_data_order(c, p, 1); + n = SM3_CBLOCK - n; + data += n; + len -= n; + c->num = 0; + memset(p, 0, SM3_CBLOCK); + } + else { + memcpy(p + n, data, len); + c->num += (unsigned int)len; + return 1; + } + } + n = len / SM3_CBLOCK; + if (n > 0) { + sm3_block_data_order(c, data, n); + n *= SM3_CBLOCK; + data += n; + len -= n; + } + if (len != 0) { + p = (unsigned char *)c->data; + c->num = (unsigned int)len; + memcpy(p, data, len); + } + return 1; +} + +int sm3_final(unsigned char *md, SM3_CTX *c) { + unsigned char *p = (unsigned char *)c->data; + size_t n = c->num; + p[n] = 0x80; + n++; + if (n > (SM3_CBLOCK - 8)) { + memset(p + n, 0, SM3_CBLOCK - n); + n = 0; + sm3_block_data_order(c, p, 1); + } + memset(p + n, 0, SM3_CBLOCK - 8 - n); + p += SM3_CBLOCK - 8; + (void)HOST_l2c(c->Nh, p); + (void)HOST_l2c(c->Nl, p); + p -= SM3_CBLOCK; + sm3_block_data_order(c, p, 1); + c->num = 0; + SM3_MAKE_STRING(c, md); + return 1; +} + +#endif \ No newline at end of file diff --git a/wallfacer/encrypt/enclave/enclave/sm4.h b/wallfacer/encrypt/enclave/enclave/sm4.h new file mode 100644 index 0000000000000000000000000000000000000000..39ec1e277cc9240b8d7fa20ba83b7a149393b833 --- /dev/null +++ b/wallfacer/encrypt/enclave/enclave/sm4.h @@ -0,0 +1,102 @@ +#ifndef SECGEAR_SM4_H +#define SECGEAR_SM4_H + +#include +#include "common_utils.h" + +#define ENCRYPT 0 +#define DECRYPT 1 +const uint8 Sbox[256] = { + 0xD6, 0x90, 0xE9, 0xFE, 0xCC, 0xE1, 0x3D, 0xB7, 0x16, 0xB6, 0x14, 0xC2, 0x28, 0xFB, 0x2C, 0x05, + 0x2B, 0x67, 0x9A, 0x76, 0x2A, 0xBE, 0x04, 0xC3, 0xAA, 0x44, 0x13, 0x26, 0x49, 0x86, 0x06, 0x99, + 0x9C, 0x42, 0x50, 0xF4, 0x91, 0xEF, 0x98, 0x7A, 0x33, 0x54, 0x0B, 0x43, 0xED, 0xCF, 0xAC, 0x62, + 0xE4, 0xB3, 0x1C, 0xA9, 0xC9, 0x08, 0xE8, 0x95, 0x80, 0xDF, 0x94, 0xFA, 0x75, 0x8F, 0x3F, 0xA6, + 0x47, 0x07, 0xA7, 0xFC, 0xF3, 0x73, 0x17, 0xBA, 0x83, 0x59, 0x3C, 0x19, 0xE6, 0x85, 0x4F, 0xA8, + 0x68, 0x6B, 0x81, 0xB2, 0x71, 0x64, 0xDA, 0x8B, 0xF8, 0xEB, 0x0F, 0x4B, 0x70, 0x56, 0x9D, 0x35, + 0x1E, 0x24, 0x0E, 0x5E, 0x63, 0x58, 0xD1, 0xA2, 0x25, 0x22, 0x7C, 0x3B, 0x01, 0x21, 0x78, 0x87, + 0xD4, 0x00, 0x46, 0x57, 0x9F, 0xD3, 0x27, 0x52, 0x4C, 0x36, 0x02, 0xE7, 0xA0, 0xC4, 0xC8, 0x9E, + 0xEA, 0xBF, 0x8A, 0xD2, 0x40, 0xC7, 0x38, 0xB5, 0xA3, 0xF7, 0xF2, 0xCE, 0xF9, 0x61, 0x15, 0xA1, + 0xE0, 0xAE, 0x5D, 0xA4, 0x9B, 0x34, 0x1A, 0x55, 0xAD, 0x93, 0x32, 0x30, 0xF5, 0x8C, 0xB1, 0xE3, + 0x1D, 0xF6, 0xE2, 0x2E, 0x82, 0x66, 0xCA, 0x60, 0xC0, 0x29, 0x23, 0xAB, 0x0D, 0x53, 0x4E, 0x6F, + 0xD5, 0xDB, 0x37, 0x45, 0xDE, 0xFD, 0x8E, 0x2F, 0x03, 0xFF, 0x6A, 0x72, 0x6D, 0x6C, 0x5B, 0x51, + 0x8D, 0x1B, 0xAF, 0x92, 0xBB, 0xDD, 0xBC, 0x7F, 0x11, 0xD9, 0x5C, 0x41, 0x1F, 0x10, 0x5A, 0xD8, + 0x0A, 0xC1, 0x31, 0x88, 0xA5, 0xCD, 0x7B, 0xBD, 0x2D, 0x74, 0xD0, 0x12, 0xB8, 0xE5, 0xB4, 0xB0, + 0x89, 0x69, 0x97, 0x4A, 0x0C, 0x96, 0x77, 0x7E, 0x65, 0xB9, 0xF1, 0x09, 0xC5, 0x6E, 0xC6, 0x84, + 0x18, 0xF0, 0x7D, 0xEC, 0x3A, 0xDC, 0x4D, 0x20, 0x79, 0xEE, 0x5F, 0x3E, 0xD7, 0xCB, 0x39, 0x48, +}; +const uint32 FK[4] = { + 0xA3B1BAC6, 0x56AA3350, 0x677D9197, 0xB27022DC, +}; +const uint32 CK[32] = { + 0x00070E15, 0x1C232A31, 0x383F464D, 0x545B6269, + 0x70777E85, 0x8C939AA1, 0xA8AFB6BD, 0xC4CBD2D9, + 0xE0E7EEF5, 0xFC030A11, 0x181F262D, 0x343B4249, + 0x50575E65, 0x6C737A81, 0x888F969D, 0xA4ABB2B9, + 0xC0C7CED5, 0xDCE3EAF1, 0xF8FF060D, 0x141B2229, + 0x30373E45, 0x4C535A61, 0x686F767D, 0x848B9299, + 0xA0A7AEB5, 0xBCC3CAD1, 0xD8DFE6ED, 0xF4FB0209, + 0x10171E25, 0x2C333A41, 0x484F565D, 0x646B7279, +}; +#define L(B) ((B) ^ (ROTATE((B), 2)) ^ (ROTATE((B), 10)) ^ (ROTATE((B), 18)) ^ (ROTATE((B), 24))) +#define LP(B) ((B) ^ (ROTATE((B), 13)) ^ (ROTATE((B), 23))) +#define S(X) (((uint32)Sbox[((X) >> 24) & 0xFF] << 24) | \ + ((uint32)Sbox[((X) >> 16) & 0xFF] << 16) | \ + ((uint32)Sbox[((X) >> 8) & 0xFF] << 8) | \ + ((uint32)Sbox[(X) & 0xFF])) +#define T(X) L(S(X)) +#define TP(X) LP(S(X)) +#define F(X0, X1, X2, X3, rk) ((X0) ^ T((X1) ^ (X2) ^ (X3) ^ (rk))) + +typedef struct sm4_ctx_st { + uint32 M[4]; + uint32 rk[32]; +} SM4_CTX; + +int sm4_init(SM4_CTX *ctx, const uint32 *M, const uint32 *MK) { + memset(ctx, 0, sizeof(*ctx)); + uint32 K[36]; + memset(K, 0, sizeof(K)); + int i; + for (i = 0; i < 4; ++i) { + K[i] = MK[i] ^ FK[i]; + ctx->M[i] = M[i]; + } + for (i = 0; i < 32; ++i) { + ctx->rk[i] = K[i+4] = K[i] ^ TP(K[i+1] ^ K[i+2] ^ K[i+3] ^ CK[i]); + } + return 1; +} + +int sm4_round(SM4_CTX *ctx, int crypt_flag) { + int offset = (crypt_flag ? 31 : 0), i; + uint32 X[36]; + memset(X, 0, sizeof(X)); + for (i = 0; i < 4; ++i) { + X[i] = ctx->M[i]; + } + for (i = 0; i < 32; ++i) { + X[i+4] = F(X[i], X[i+1], X[i+2], X[i+3], ctx->rk[i^offset]); + } + ctx->M[0] = X[35]; + ctx->M[1] = X[34]; + ctx->M[2] = X[33]; + ctx->M[3] = X[32]; + return 1; +} + +int sm4_encrypt(SM4_CTX *ctx) { + return sm4_round(ctx, ENCRYPT); +} + +int sm4_decrypt(SM4_CTX *ctx) { + return sm4_round(ctx, DECRYPT); +} + +int sm4_final(uint32 *out, SM4_CTX *ctx) { + if (!memcpy(out, ctx->M, sizeof(ctx->M))) { + return 0; + } + return 1; +} + +#endif \ No newline at end of file diff --git a/wallfacer/encrypt/enclave/host/CMakeLists.txt b/wallfacer/encrypt/enclave/host/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..2ba74ff8749796020d5442c8ae0981363656b77b --- /dev/null +++ b/wallfacer/encrypt/enclave/host/CMakeLists.txt @@ -0,0 +1,85 @@ +# Copyright (c) Huawei Technologies Co., Ltd. 2020. All rights reserved. +# secGear is licensed under the Mulan PSL v2. +# You can use this software according to the terms and conditions of the Mulan PSL v2. +# You may obtain a copy of Mulan PSL v2 at: +# http://license.coscl.org.cn/MulanPSL2 +# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR +# PURPOSE. +# See the Mulan PSL v2 for more details. + +#set auto code prefix +set(PREFIX enclave) +#set host exec name +set(OUTPUT secgear_enclave) +#set host src code +set(SOURCE_FILE ${CMAKE_CURRENT_SOURCE_DIR}/main.c) + +#set auto code +if(CC_GP) + set(AUTO_FILES ${CMAKE_CURRENT_BINARY_DIR}/${PREFIX}_u.h ${CMAKE_CURRENT_BINARY_DIR}/${PREFIX}_u.c ${CMAKE_CURRENT_BINARY_DIR}/${PREFIX}_args.h) + add_custom_command(OUTPUT ${AUTO_FILES} + DEPENDS ${CURRENT_ROOT_PATH}/${EDL_FILE} + COMMAND ${CODEGEN} --${CODETYPE} --untrusted ${CURRENT_ROOT_PATH}/${EDL_FILE} --search-path ${LOCAL_ROOT_PATH}/inc/host_inc/gp) +endif() + +if(CC_SGX) + set(AUTO_FILES ${CMAKE_CURRENT_BINARY_DIR}/${PREFIX}_u.h ${CMAKE_CURRENT_BINARY_DIR}/${PREFIX}_u.c) + add_custom_command(OUTPUT ${AUTO_FILES} + DEPENDS ${CURRENT_ROOT_PATH}/${EDL_FILE} + COMMAND ${CODEGEN} --${CODETYPE} --untrusted ${CURRENT_ROOT_PATH}/${EDL_FILE} --search-path ${LOCAL_ROOT_PATH}/inc/host_inc/sgx --search-path ${SGXSDK}/include) +endif() + +set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-error -fPIE") +set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS} -s") + +if(CC_GP) + if(${CMAKE_VERSION} VERSION_LESS "3.13.0") + link_directories(${CMAKE_LIBRARY_OUTPUT_DIRECTORY}) + endif() + add_executable(${OUTPUT} ${SOURCE_FILE} ${AUTO_FILES}) + target_include_directories(${OUTPUT} PRIVATE + ${LOCAL_ROOT_PATH}/inc/host_inc + ${LOCAL_ROOT_PATH}/inc/host_inc/gp + ${CMAKE_CURRENT_BINARY_DIR}) + if(${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.13.0") + target_link_directories(${OUTPUT} PRIVATE ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}) + endif() +endif() + +if(CC_SGX) + if(${CMAKE_VERSION} VERSION_LESS "3.13.0") + link_directories(${CMAKE_LIBRARY_OUTPUT_DIRECTORY}) + endif() + add_executable(${OUTPUT} ${SOURCE_FILE} ${AUTO_FILES}) + target_include_directories(${OUTPUT} PRIVATE + ${LOCAL_ROOT_PATH}/inc/host_inc + ${LOCAL_ROOT_PATH}/inc/host_inc/sgx + ${CMAKE_CURRENT_BINARY_DIR}) + if(${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.13.0") + target_link_directories(${OUTPUT} PRIVATE ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}) + endif() +endif() + +if(CC_SIM) + target_link_libraries(${OUTPUT} secgearsim) +else() + target_link_libraries(${OUTPUT} secgear) +endif() +set_target_properties(${OUTPUT} PROPERTIES SKIP_BUILD_RPATH TRUE) + +if(CC_GP) + #itrustee install whitelist /vender/bin/teec_hello + install(TARGETS ${OUTPUT} + RUNTIME + DESTINATION /vendor/bin/ + PERMISSIONS OWNER_EXECUTE OWNER_WRITE OWNER_READ) +endif() + +if(CC_SGX) + install(TARGETS ${OUTPUT} + RUNTIME + DESTINATION ${CMAKE_BINARY_DIR}/bin/ + PERMISSIONS OWNER_EXECUTE OWNER_WRITE OWNER_READ) +endif() + diff --git a/wallfacer/encrypt/enclave/host/db.sh b/wallfacer/encrypt/enclave/host/db.sh new file mode 100644 index 0000000000000000000000000000000000000000..30f650ae22ba5b6ba2a69817aff6fdcb5ad8d5e3 --- /dev/null +++ b/wallfacer/encrypt/enclave/host/db.sh @@ -0,0 +1,29 @@ +#! /bin/bash +#test +echo "read start" +echo "" + +docker -v +echo "docker start" +echo "========================================================" +systemctl start docker +docker ps -a +echo "container start" +echo "========================================================" +docker start opengauss +docker ps -a +docker exec -it opengauss sh +echo "container stop" +echo "========================================================" +docker stop opengauss +docker ps -a + + +echo "grinfo copy to host and wait to settle" +sudo cp /var/lib/docker/volumes/dbvol/_data/omm/grinfo /opt/secGear/debug/examples/helloworld/host +sudo chmod 777 /opt/secGear/debug/examples/helloworld/host/grinfo + + +echo "" +echo "read stop" + diff --git a/wallfacer/encrypt/enclave/host/dbend.sh b/wallfacer/encrypt/enclave/host/dbend.sh new file mode 100644 index 0000000000000000000000000000000000000000..8c11f0ace31040f5e1b3a7a6bc3691bccce9d032 --- /dev/null +++ b/wallfacer/encrypt/enclave/host/dbend.sh @@ -0,0 +1,23 @@ +#! /bin/bash +#test +echo "write start" +echo "" + +echo "grinfo copy to docker and wait to wirte" +sudo docker cp grinfo opengauss:/home/omm +echo "container start" +echo "========================================================" +docker start opengauss +docker ps -a +docker exec -it opengauss sh + +echo "container stop" +echo "========================================================" +docker stop opengauss +docker ps -a +echo "docker stop" +echo "========================================================" +systemctl stop docker + +echo "" +echo "write stop" diff --git a/wallfacer/encrypt/enclave/host/main.c b/wallfacer/encrypt/enclave/host/main.c new file mode 100644 index 0000000000000000000000000000000000000000..47c142b3c7b45ef7a816dd2f87839d937723e79e --- /dev/null +++ b/wallfacer/encrypt/enclave/host/main.c @@ -0,0 +1,230 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2020. All rights reserved. + * secGear is licensed under the Mulan PSL v2. + * You can use this software according to the terms and conditions of the Mulan PSL v2. + * You may obtain a copy of Mulan PSL v2 at: + * http://license.coscl.org.cn/MulanPSL2 + * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR + * PURPOSE. + * See the Mulan PSL v2 for more details. + */ + +#include +#include +#include +#include +#include "enclave.h" +#include "enclave_u.h" +#define MAXLEN 64 +#define idoffset 41 +#define phoneoffset 74 + + + +/** +* 从文件中读取字符串,加密字符串小于32B,解密字符串(16进制)小于64B +*/ +int readStrFromFile(char *filename, char *str,int offset) { + FILE *fp = fopen(filename, "r"); + if(fp == NULL) { + printf("打开文件出错,请确认文件存在当前目录下!\n"); + exit(0); + } + + int val=1; + char sym[4]={'C','O','P','Y'}; + char temp[150]; + memset(temp,'0',sizeof(temp)); + while(1) + { + fgets(temp,150,fp); + val=strncmp(sym,temp,4); + if(val==0) + break; + } + memset(temp,'0',sizeof(temp)); + fgets(temp,150,fp); + char t[32]; + for(int i=offset;i<(offset+32);i++)//id:41~73,phone:74~106 + { + if(temp[i]==' ') break; + t[i-offset]=temp[i]; + } + + strncpy(str,t,strlen(t)); + fclose(fp); + return 0; +} + +/** + * 把字符串写进文件 + */ +void writeStrToFile(unsigned char *str, char *filename,int offset) { + FILE *fp; + fp = fopen(filename, "r+"); + char temp[100]; + for(int i=0;i<1;) + { + while(fgetc(fp)!='\n') + i++; + } + fprintf(fp,"\ndrop table grinfo; \n");//写回数据时对原有数据表清除,防止表内数据不唯一出现差错 + + int val=1; + char sym[4]={'C','O','P','Y'}; + memset(temp,'0',sizeof(temp)); + while(1) + { + fgets(temp,100,fp); + val=strncmp(sym,temp,4); + if(val==0) + break; + } + int size=ftell (fp);//返回文件指针相对于起始位置的偏移量 + memset(temp,'0',sizeof(temp)); + fgets(temp,100,fp); + size=size+offset;//id:offset 40,phone:offset 73 + fseek(fp,size,SEEK_SET);//根据文件指针的位置和偏移量来定位文件指针 + + + for(int i = 0; i < 16; i++) + { + fprintf(fp,"%02x",str[i]); + } + fclose(fp); +} + + +int main() +{ + int retval = 0; + char *path = PATH; + unsigned char buf[80]; + int rvalue; + char name[20]; + char psw[56]; + char fname[17];//文件名 + char info[31];//文件中要加密信息 + char cipher[64];//文件中要解密信息 + int tag; + cc_enclave_t *context = NULL; + cc_enclave_result_t res; + cc_enclave_result_t rres; + + printf("Create secgear enclave\n"); + + + res = cc_enclave_create(path, AUTO_ENCLAVE_TYPE, 0, SECGEAR_DEBUG_FLAG, NULL, 0, &context); + if (res != CC_SUCCESS) { + printf("Create enclave error\n"); + return res; + } + + //清空原内存中数据 + /*memset(fname,'0',sizeof(fname)); + memset(info,'0',sizeof(info)); + memset(cipher,'0',sizeof(cipher));*/ + + + //SM3生成存储密钥 + printf("请输入用户名:\n");//获得用户名 + gets(name); + transname(context,name); + printf("请输入密码 :\n");//获得用户密码 + gets(psw); + transpsw(context,psw); + sm3(context); + printf("加密成功!密文如下:\n"); + res = get_string(context, &retval, buf); + if (res != CC_SUCCESS || retval != (int)CC_SUCCESS) { + printf("Ecall enclave error\n"); + } + else { + for(int i=0;i<16;i++) + { + printf("%02x",buf[i]); + } + printf("\n"); + } + + system("./db.sh");//通过脚本登陆数据库获取个人信息进行复制提取工作 + + + //SM4对文件加解密 + printf("选择加密输入1,选择解密输入2:"); + scanf("%d",&tag); + char gg=getchar();//取走缓存区的回车符 + int offset,len; + if(tag==1){ + printf("请输入要加密的文件名:(该文件必须和本程序在同一目录)\n");//传输要加密的用户信息 + gets(fname); + printf("\n"); + for(int i=0;i<2;i++) + { + if(i==0) + offset=idoffset; + else + offset=phoneoffset; + readStrFromFile(fname,info,offset);//取出要加密字符串 + printf("将要加密的信息:\n"); + puts(info); + len=strlen(info);//识别要机密字符串长度 + transinfo(context,info);//传送到安全区进行加密 + sm4crypt(context,len); + printf("加密成功!密文如下:\n"); + res = get_string(context, &retval, buf); + if (res != CC_SUCCESS || retval != (int)CC_SUCCESS) { + printf("Ecall enclave error\n"); + } else { + for(int i=0;i