#include #include #include #include #include #include #include #include #include "lzo/minilzo.h" #include "zstd/zstd.h" #include "ucl/ucl.h" #include "lz4/lz4.h" #include "cipher/aes.h" #include "cipher/des.h" #include "cipher/des3.h" #include "cipher/rc4.h" #include "cipher/rsa.h" #include "cipher/ecc.h" using namespace std; #ifdef __cplusplus extern "C" { #endif #include "lzma/FileIO.h" #include "lzma/TinyLzmaCompress.h" #include "lzma/TinyLzmaDecompress.h" #ifdef __cplusplus } #endif #define HEAP_ALLOC(var, size) \ lzo_align_t __LZO_MMODEL var [ ((size) + (sizeof(lzo_align_t) - 1)) / sizeof(lzo_align_t) ] // 定义各个字段的偏移量 #define SYMMETRIC_ENC_TYP_OFFSET 0 #define ASYMMETRIC_ENC_TYP_OFFSET 1 #define COMP_TYP_OFFSET 2 #define INITIAL_FILE_SIZE_OFFSET 3 #define COMPRESSED_FILE_SIZE_OFFSET 7 #define ENCRYPTED_FILE_SIZE_OFFSET 11 #define ENCRYPTED_KEY_SIZE_OFFSET 15 #define PROTECT_TYPE_OFFSET 19 #define MAC_NUMS_OFFSET 20 #define RUN_ADD_OFFSET 21 /** * * 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 */ static HEAP_ALLOC(wrkmem, LZO1X_1_MEM_COMPRESS); const int MAGIC_LENGTH = 32; static int get_random_bytes(unsigned char *buf, size_t len) { // FILE *f; // f = fopen("/dev/urandom", "r"); // fread(buf, len, 1, f); // fclose(f); srand((unsigned)time(NULL)); for(int i = 0; i < len; i++) { buf[i] = rand() % 255; } return 0; } int hexStringToByteArray(const char *hexString, unsigned char *byteArray, int byteArraySize) { int count = 0; const char *pos = hexString; // 转换16进制字符串为字节数组 while (count < byteArraySize && sscanf(pos, "%2hhx", &byteArray[count]) == 1) { pos += 2; count++; } return count; // 返回转换的字节数 } void replaceWithMiddleEight(unsigned char arr[], int length) { if (length < 8) { printf("数组长度不足8位\n"); return; } // 计算中间8位的起始索引 int start = (length - 8) / 2; // 提取中间的8个元素 int middleEight[8]; for (int i = 0; i < 8; i++) { middleEight[i] = arr[start + i]; } // 用中间的8位替换源数组的内容 for (int i = 0; i < length; i++) { arr[i] = middleEight[i % 8]; // 循环使用中间的8位 } } int main(int argc, char *argv[]) { FILE *input_file; char *input_file_path = argv[1]; uint8_t symmetric_enc_typ = (uint8_t) atoi(argv[2]); uint8_t asymmetric_enc_typ = (uint8_t) atoi(argv[3]); uint8_t comp_typ = (uint8_t) atoi(argv[4]); uint8_t cp_symmetric_enc_typ = symmetric_enc_typ; uint8_t cp_asymmetric_enc_typ = asymmetric_enc_typ; uint8_t cp_comp_typ = comp_typ; char *output_file_path = argv[5]; // 保护模式 uint8_t protect_type = (uint8_t) atoi(argv[6]); char *puf_path = argv[7]; uint8_t mac_enable = (uint8_t) atoi(argv[8]); char *mac_path = argv[9]; // 运行地址 0xb0000000 char *str_run_add = argv[10]; // printf("str_run_add %s\n", str_run_add); unsigned int run_add = strtoull(str_run_add, NULL, 16); printf("input_file_path %s\n", input_file_path); printf("symmetric_enc_typ %u\n", symmetric_enc_typ); printf("asymmetric_enc_typ %u\n", asymmetric_enc_typ); printf("comp_typ %u\n", comp_typ); printf("output_file_path %s\n", output_file_path); printf("protect type %u\n", protect_type); printf("puf_path %s\n", puf_path); printf("mac_enable %u\n", mac_enable); printf("mac_path %s\n", mac_path); input_file = fopen(input_file_path, "rb"); if (input_file == NULL) { printf("unable to open file.\n"); return 1; } // 获取文件大小 fseek(input_file, 0, SEEK_END); uint32_t initial_file_size = ftell(input_file); printf("initial file size:%u\n", initial_file_size); rewind(input_file); /** * DES: 64bit 1 key_length 8 * AES: 128bit 2 key_length 32 * 3DES: 64bit 3 key_length 24 * RC4: 256bit 4 key_length 32 */ int symmetric_map[5] = {0, 4, 1, 3, 2}; symmetric_enc_typ = symmetric_map[symmetric_enc_typ]; uint8_t input_length, key_length; if (symmetric_enc_typ == 1) input_length = 8, key_length = 8; else if (symmetric_enc_typ == 2) input_length = 16, key_length = 32; else if (symmetric_enc_typ == 3) input_length = 8, key_length = 24; else if (symmetric_enc_typ == 4) input_length = 1, key_length = 32; else input_length = 0, key_length = 0; // 分配足够的内存来存储文件内容 uint8_t *byte_array = (uint8_t *) malloc(initial_file_size * sizeof(uint8_t)); if (byte_array == NULL) { printf("unable to allocate memory.\n"); return 0; } // 读取文件内容到字节数组 int num_elements = fread(byte_array, sizeof(uint8_t), initial_file_size, input_file); if (num_elements != initial_file_size) { printf("an error occurred while reading the file.\n"); return 0; } fclose(input_file); const int serial_length = 39; unsigned char puf_key[serial_length]; memset(puf_key, 0, serial_length); unsigned char puf_value[serial_length+2]; memset(puf_value, 0, serial_length); if (protect_type == 1) { printf("[STATE] node:1 ; message:PUF交互\n"); FILE *file = fopen(puf_path, "r"); if (file == NULL) { perror("Failed to open file"); return EXIT_FAILURE; } char line1[256]; char line2[256]; char line3[256]; // 读取第一行 if (fgets(line1, sizeof(line1), file) == NULL) { perror("Failed to read line 1"); fclose(file); return EXIT_FAILURE; } // 读取第二行 if (fgets(line2, sizeof(line2), file) == NULL) { perror("Failed to read line 2"); fclose(file); return EXIT_FAILURE; } // 读取第三行 if (fgets(line3, sizeof(line3), file) == NULL) { perror("Failed to read line 3"); fclose(file); return EXIT_FAILURE; } // 打印读取的内容 printf("Line 1: %s", line1); printf("Line 2: %s", line2); printf("Line 3: %s\n", line3); // 关闭文件 fclose(file); // 转换字符串为字节数组 int convertedCount2 = hexStringToByteArray(line2, puf_key, serial_length); int convertedCount3 = hexStringToByteArray(line3, puf_value, serial_length); for (int i = 0; i < 39; i++) { printf("0x%02x,", puf_value[i]); } printf("\n"); // 检查转换的结果 if (convertedCount2 != serial_length || convertedCount3 != serial_length) { printf("Conversion error\n"); return EXIT_FAILURE; } } printf("[STATE] node:2 ; message:获取密钥\n"); uint8_t module_key[32] = {0}; if (protect_type == 1){ replaceWithMiddleEight(puf_value, 41); memcpy(module_key, puf_value + 4, 32); } else { get_random_bytes(module_key, 32); } printf("module key:\n"); for (int i = 0; i < 32; i++) { printf("%02x ", module_key[i]); } printf("\n"); uint8_t mac_nums = 0; unsigned char mac_array[10][18]; memset(mac_array, 0, 180); if (mac_enable == 1) { // 从本地文件中读取MAC地址 int mac_fd = open(mac_path, O_RDONLY); if (mac_fd <= 0) { printf("mac_fd : %d\n", mac_fd); printf("本地未找到MAC地址列表文件\n"); return -1; } while (mac_nums < 10 && (read(mac_fd, mac_array[mac_nums], 18) > 0)) { mac_nums++; } close(mac_fd); } else { mac_array[0][0] = 'P'; } int comp_map[6] = {0, 3, 1, 2, 4, 5}; comp_typ = comp_map[comp_typ]; unsigned long compressed_file_size; uint8_t *compress_out = (uint8_t *) calloc(initial_file_size, sizeof(uint8_t)); int r = -1; if (comp_typ == 1) { printf("compress with lzo...\n"); r = lzo1x_1_compress(byte_array, initial_file_size, compress_out, reinterpret_cast(&compressed_file_size), wrkmem); } else if (comp_typ == 2) { printf("compress with ucl...\n"); int level = 2; r = ucl_nrv2b_99_compress(byte_array, initial_file_size, compress_out, reinterpret_cast(&compressed_file_size), NULL, level, NULL, NULL); compressed_file_size = reinterpret_cast(compressed_file_size); } else if (comp_typ == 3) { printf("compress with lzma...\n"); compressed_file_size = initial_file_size; r = tinyLzmaCompress(byte_array, initial_file_size, compress_out, reinterpret_cast(&compressed_file_size)); compressed_file_size = reinterpret_cast(compressed_file_size); } else if (comp_typ == 4) { printf("compress with zstd...\n"); compressed_file_size = ZSTD_compressBound(initial_file_size); printf("%d\n", compressed_file_size); compressed_file_size = ZSTD_compress(compress_out, compressed_file_size, byte_array, initial_file_size, 2); } else if (comp_typ == 5) { printf("compress with lz4...\n"); int max_dst_size = LZ4_compressBound(initial_file_size); compressed_file_size = LZ4_compress_default(byte_array, compress_out, initial_file_size, max_dst_size); } if (r == 0 || r == -1) { printf("compressed %u bytes into %u bytes\n", initial_file_size, compressed_file_size); printf("[STATE] node: 6 ; message:整体压缩\n"); } else { /* this should NEVER happen */ printf("internal error - compression failed: %d\n", r); return 2; } /* check for an incompressible block */ if ((unsigned int) compressed_file_size >= initial_file_size) { printf("This block contains incompressible data.\n"); return 0; } uint8_t *new_compress_out = (uint8_t *) realloc(compress_out, compressed_file_size); if (new_compress_out != NULL) { compress_out = new_compress_out; } uint8_t key[key_length]; for (int i = 0; i < key_length; i++) key[i] = module_key[i]; printf("key:\n"); for (int i = 0; i < key_length; i++) { printf("%02x ", key[i]); } printf("\n"); uint32_t encrypted_file_size = (compressed_file_size + input_length - 1) / input_length * input_length; printf("encrypted_file_size %u\n", encrypted_file_size); printf("compress bytes:\n"); for (int i = 0; i < 8; i++) { printf("%02x ", compress_out[i]); } printf("\n"); uint8_t *buff = (uint8_t *) malloc(encrypted_file_size * sizeof(uint8_t)); if (symmetric_enc_typ == 1) { printf("enc_typ = 1\n"); DesContext des_context; desInit(&des_context, key, key_length); for (int i = 0; i < encrypted_file_size; i += input_length) desEncryptBlock(&des_context, compress_out + i, buff + i); } if (symmetric_enc_typ == 2) { printf("enc_typ = 2\n"); AesContext aes_context; aesInit(&aes_context, key, key_length); for (int i = 0; i < encrypted_file_size; i += input_length) aesEncryptBlock(&aes_context, compress_out + i, buff + i); } if (symmetric_enc_typ == 3) { printf("enc_typ = 3\n"); Des3Context des3_context; des3Init(&des3_context, key, key_length); for (int i = 0; i < encrypted_file_size; i += input_length) des3EncryptBlock(&des3_context, compress_out + i, buff + i); } if (symmetric_enc_typ == 4) { printf("enc_typ = 4\n"); rc4_encryption(compress_out, encrypted_file_size, key, key_length); memcpy(buff, compress_out, encrypted_file_size); } printf("final bytes:\n"); for (int i = 0; i < 8; i++) { printf("%02x ", buff[i]); } printf("\n"); for (int i = encrypted_file_size - 8; i < encrypted_file_size; i++) { printf("%02x ", buff[i]); } printf("\n"); printf("[STATE] node: 4 ; message:整体加密\n"); // uint8_t *tmp_encrypted = NULL; uint8_t *encrypted = NULL; // uint32_t encrypted_key_size = sizeof key * sizeof(long long); uint32_t encrypted_key_size = key_length; // 如果是软硬结合,加密的key为PUF激励长度39字节 if (protect_type == 1) encrypted_key_size = 39; /** * rsa key */ struct public_key_class pub[1]; struct private_key_class priv[1]; /** * ecc key */ uint8_t pub_key[ECC_KEYSIZE]; uint8_t prv_key[ECC_KEYSIZE]; if (asymmetric_enc_typ != 0) { if (asymmetric_enc_typ == 5) { rsa_gen_keys(pub, priv); encrypted_key_size *= 8; printf("Private Key:\n Modulus: %lld\n Exponent: %lld\n", (long long) priv->modulus, (long long) priv->exponent); printf("Public Key:\n Modulus: %lld\n Exponent: %lld\n", (long long) pub->modulus, (long long) pub->exponent); // 1是软硬结合,加密的是激励 // 0是软加密,加密的是秘钥 if (protect_type == 1) encrypted = rsa_encrypt(puf_key, 39, pub); else if (protect_type == 0) encrypted = rsa_encrypt(key, key_length, pub); // encrypted = (uint8_t *) tmp_encrypted; if (encrypted == NULL) { fprintf(stderr, "error in encryption!\n"); return 1; } } else if (asymmetric_enc_typ == 6) { printf("enc with ecc\n"); ecc_init_keys(pub_key, prv_key); printf("ecc init end\n"); // 1是软硬结合,加密的是激励,申请的空间是39 // 0是软加密,加密的是秘钥,申请的空间是sizeof key if (protect_type == 0) { encrypted = (uint8_t *) realloc(encrypted, sizeof key); ecc_encrypt(pub_key, key, key_length, encrypted, &encrypted_key_size); } else if (protect_type == 1) { encrypted = (uint8_t *) realloc(encrypted, 39); ecc_encrypt(pub_key, puf_key, 39, encrypted, &encrypted_key_size); } printf("encrypted_key_size is %u with ecc\n", encrypted_key_size); } } printf("enc key\n"); for (int i = 0; i < encrypted_key_size; i++) { printf("0x%02x, ", encrypted[i]); } printf("\n"); /** * enc_typ 1B * comp_typ 1B * initial_file_size 4B * compressed_file_size 4B * encrypted_file_size 4B */ printf("uint8_t symmetric_enc_typ: %u\n", symmetric_enc_typ); printf("uint8_t asymmetric_enc_typ: %u\n", asymmetric_enc_typ); printf("uint8_t comp_typ: %u\n", comp_typ); printf("uint32_t file_size: %u\n", initial_file_size); printf("uint32_t compressed_file_size: %u\n", compressed_file_size); printf("uint32_t encrypted_file_size: %u\n", encrypted_file_size); printf("uint8_t input_length: %u\n", input_length); printf("uint8_t key_length: %u\n", key_length); uint8_t magic[MAGIC_LENGTH]; // 将各个字段的值存入 magic 数组 magic[SYMMETRIC_ENC_TYP_OFFSET] = symmetric_enc_typ; magic[ASYMMETRIC_ENC_TYP_OFFSET] = asymmetric_enc_typ; magic[COMP_TYP_OFFSET] = comp_typ; memcpy(magic + INITIAL_FILE_SIZE_OFFSET, &initial_file_size, sizeof(uint32_t)); memcpy(magic + COMPRESSED_FILE_SIZE_OFFSET, &compressed_file_size, sizeof(uint32_t)); memcpy(magic + ENCRYPTED_FILE_SIZE_OFFSET, &encrypted_file_size, sizeof(uint32_t)); memcpy(magic + ENCRYPTED_KEY_SIZE_OFFSET, &encrypted_key_size, sizeof(uint32_t)); // 保护类型 memcpy(magic + PROTECT_TYPE_OFFSET, &protect_type, sizeof(uint8_t)); // MAC地址绑定的数量 memcpy(magic + MAC_NUMS_OFFSET, &mac_nums, sizeof(uint8_t)); // 运行地址 printf("str_run_add %x\n", run_add); memcpy(magic + RUN_ADD_OFFSET, &run_add, 4); FILE *p = fopen(output_file_path, "wb"); if (p == NULL) { printf("open filed\n"); } fwrite(magic, sizeof(uint8_t), MAGIC_LENGTH, p); fwrite(buff, sizeof(uint8_t), encrypted_file_size, p); fwrite(encrypted, sizeof(uint8_t), encrypted_key_size, p); if (asymmetric_enc_typ == 5) { fwrite(pub, sizeof(struct public_key_class), 1, p); fwrite(priv, sizeof(struct private_key_class), 1, p); } else if (asymmetric_enc_typ == 6) { fwrite(pub_key, sizeof(uint8_t), ECC_KEYSIZE, p); fwrite(prv_key, sizeof(uint8_t), ECC_KEYSIZE, p); } for (int i = 0; i < mac_nums; i++) { for (int j = 0; j < 18; j++) { printf("%02x ", mac_array[i][j]); } printf("\n"); } for (int i = 0; i < mac_nums; i++) fwrite(mac_array[i], sizeof(uint8_t), 18, p); printf("[STATE] node: 7 ; message:加壳\n"); fclose(p); free(byte_array); free(buff); printf("[STATE] node: 8 ; message:成功\n"); printf("成功\n"); return 0; } /** * magic * encrypted_file * enc_key/enc serial_challenge * pub_key * prv_key * mac_info[0-10] */