gpt4 book ai didi

c - Memcpy char** 的 typedef,它指向具有 4 个 uint64_t 类型变量的结构

转载 作者:行者123 更新时间:2023-11-30 19:02:43 27 4
gpt4 key购买 nike

有这个代码:

typedef struct {
struct {
uint64_t key;
uint64_t mac;
uint64_t orig;
uint64_t body;
} length;
} secure_head_t;

typedef char *secure_t;

secure_t *secure_alloc(uint64_t key, uint64_t mac, uint64_t orig, uint64_t body) {
secure_t *cryptex = (secure_t*)malloc(sizeof(secure_head_t) + key + mac + body);
secure_head_t *head = (secure_head_t *)cryptex;
head->length.key = key;
head->length.mac = mac;
head->length.orig = orig;
head->length.body = body;
return cryptex;
}

我想将 secure_t 转换为 char *,类似于:char *str = secure_t *text;

我尝试过这个:

secure_head_t *head = (secure_head_t *)securetext;

char frame[sizeof(secure_head_t)];
memcpy(frame, &head, sizeof(secure_head_t));

但这并不是每次都有效,有时甚至无法复制。请告诉我如何正确复制它。我想要的只是将 secure_t* 转换为 char*,然后从 char* 转换回 secure_t*

更新:

我想将使用 OpenSSL 1.0.2 通过 ECDHA 加密的数据 block 转换为二进制缓冲区以便稍后解密。数据 block 的最小值为 1 KB,最大值为 1 MB。我可以控制整个过程,我用它来学习非对称和对称加密。

详细代码如下:

void Encryption(UnicodeString PlainText)
{
srand(time(NULL));
int tlen;
size_t olen;
EC_KEY *key = NULL;
secure_t *ciphered = NULL;
char *hex_pub = NULL, *hex_priv = NULL;

char *text = NULL;
tlen = PlainText.Length();
text = new char [tlen];

WideCharToMultiByte(CP_ACP, 0, PlainText.c_str(), wcslen(PlainText.c_str())+1, text , sizeof(char)*tlen, NULL, NULL);

// Generate a key for our theoretical user.
if (!(key = ecies_key_create()))
{
printf("Key creation failed.\n");
}

// Since we'll store the keys as hex values in reali life, extract the appropriate hex values and release the original key structure.
if (!(hex_pub = ecies_key_public_get_hex(key)) || !(hex_priv = ecies_key_private_get_hex(key)))
{
printf("Serialization of the key to a pair of hex strings failed.\n");
}
//saving keys
KeyPriv = AnsiString(hex_priv);
KeyPub = AnsiString(hex_pub);

if (!(ciphered = ecies_encrypt(hex_pub, text, tlen)))
{
printf("The encryption process failed!\n");
}

secure_head_t *head = (secure_head_t *)ciphered;

char frame[sizeof(secure_head_t )];
memcpy(frame, &head, sizeof(secure_head_t *));
CipherText = frame;
}

void Decrypt(AnsiString CipherText)
{
size_t olen;
EC_KEY *key = NULL;
secure_t *ciphered = NULL;
char *hex_pub = NULL, *hex_priv = NULL;
unsigned char *text = NULL, *copy = NULL, *original = NULL;


secure_head_t *head = new secure_head_t;
memcpy(&head, CipherText.c_str(), sizeof(char)*CipherText.Length());

secure_t *cryptex = (secure_t*)head;

hex_priv = KeyPriv.c_str();


if(!(original = ecies_decrypt(hex_priv, cryptex, &olen)))
{
printf("The decryption process failed!\n");
}

PlainText = AnsiString((char*)original);
}

上面的代码可以工作,但有时不行,而且我不发送长度<25的字符串。

除 OpenSSL 代码外,其他代码如下所示

ecies.h
------------------------------------------------------------------------------
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
//#include <inttypes.h>
#include<stdint.h>

#include <openssl/ssl.h>
#include <openssl/crypto.h>
#include <openssl/err.h>
#include <openssl/stack.h>

#define ECIES_CURVE NID_secp521r1
#define ECIES_CIPHER EVP_aes_256_cbc()
#define ECIES_HASHER EVP_sha512()

//EC_GROUP *eliptic = NULL;

typedef struct {

struct {
uint64_t key;
uint64_t mac;
uint64_t orig;
uint64_t body;
} length;

} secure_head_t;

typedef char* secure_t;

void secure_free(secure_t *cryptex);
void * secure_key_data(secure_t *cryptex);
void * secure_mac_data(secure_t *cryptex);
void * secure_body_data(secure_t *cryptex);
uint64_t secure_key_length(secure_t *cryptex);
uint64_t secure_mac_length(secure_t *cryptex);
uint64_t secure_body_length(secure_t *cryptex);
uint64_t secure_orig_length(secure_t *cryptex);
uint64_t secure_total_length(secure_t *cryptex);
secure_t * secure_alloc(uint64_t key, uint64_t mac, uint64_t orig, uint64_t body);

void ecies_group_init(void);
void ecies_group_free(void);
EC_GROUP * ecies_group(void);

void ecies_key_free(EC_KEY *key);

EC_KEY * ecies_key_create(void);
EC_KEY * ecies_key_create_public_hex(char *hex);
EC_KEY * ecies_key_create_private_hex(char *hex);
EC_KEY * ecies_key_create_public_octets(unsigned char *octets, size_t length);

char * ecies_key_public_get_hex(EC_KEY *key);
char * ecies_key_private_get_hex(EC_KEY *key);

secure_t * ecies_encrypt(char *key, unsigned char *data, size_t length);
unsigned char * ecies_decrypt(char *key, secure_t *cryptex, size_t *length);
------------------------------------------------------------------------------
**secure.c**
------------------------------------------------------------------------------
#include "ecies.h"

uint64_t secure_key_length(secure_t *cryptex) {
secure_head_t *head = (secure_head_t *)cryptex;
return head->length.key;
}

uint64_t secure_mac_length(secure_t *cryptex) {
secure_head_t *head = (secure_head_t *)cryptex;
return head->length.mac;
}

uint64_t secure_body_length(secure_t *cryptex) {
secure_head_t *head = (secure_head_t *)cryptex;
return head->length.body;
}

uint64_t secure_orig_length(secure_t *cryptex) {
secure_head_t *head = (secure_head_t *)cryptex;
return head->length.orig;
}

uint64_t secure_total_length(secure_t *cryptex) {
secure_head_t *head = (secure_head_t *)cryptex;
return sizeof(secure_head_t) + (head->length.key + head->length.mac +
head->length.body);
}

void * secure_key_data(secure_t *cryptex) {
return (char *)cryptex + sizeof(secure_head_t);
}

void * secure_mac_data(secure_t *cryptex) {
secure_head_t *head = (secure_head_t *)cryptex;
return (char *)cryptex + (sizeof(secure_head_t) + head->length.key);
}

void * secure_body_data(secure_t *cryptex) {
secure_head_t *head = (secure_head_t *)cryptex;
return (char *)cryptex + (sizeof(secure_head_t) + head->length.key +
head->length.mac);
}

secure_t * secure_alloc(uint64_t key, uint64_t mac, uint64_t orig, uint64_t body) {
secure_t *cryptex = (secure_t*)malloc(sizeof(secure_head_t) + key + mac + body);
secure_head_t *head = (secure_head_t *)cryptex;
head->length.key = key;
head->length.mac = mac;
head->length.orig = orig;
head->length.body = body;
return cryptex;
}

void secure_free(secure_t *cryptex) {
free(cryptex);
return;
}

------------------------------------------------------------------------------
ecies.c
-------------------------------------------------------------------------------
#include "ecies.h"
#include <openssl/keys.c>
#include <openssl/secure.c>
/*
void ecies_group_free(void) {

EC_GROUP *group = eliptic;
eliptic = NULL;
if (group) {
EC_GROUP_free(group);
}
return;
} */

void * ecies_key_derivation(const void *input, size_t ilen, void *output,
size_t *olen) {

if (*olen < SHA512_DIGEST_LENGTH) {
return NULL;
}

*olen = SHA512_DIGEST_LENGTH;
return SHA512((unsigned char*)input, ilen, (unsigned char*)output);
}

secure_t * ecies_encrypt(char *key, unsigned char *data, size_t length) {

unsigned char *body;
HMAC_CTX hmac;
int body_length;
secure_t *cryptex;
EVP_CIPHER_CTX cipher;
unsigned int mac_length;
EC_KEY *user, *ephemeral;
size_t envelope_length, block_length, key_length;
unsigned char envelope_key[SHA512_DIGEST_LENGTH], iv[EVP_MAX_IV_LENGTH], block[EVP_MAX_BLOCK_LENGTH];

// Simple sanity check.
if (!key || !data || !length) {
//printf("Invalid parameters passed in.\n");
MessageBox ( NULL,L"Invalid parameters passed in.\n" ,L"Error", MB_OK );
return NULL;
}

// Make sure we are generating enough key material for the symmetric ciphers.
if ((key_length = EVP_CIPHER_key_length(ECIES_CIPHER)) * 2 > SHA512_DIGEST_LENGTH) {
//printf("The key derivation method will not produce enough envelope key material for the chosen ciphers. {envelope = %i / required = %zu}", SHA512_DIGEST_LENGTH / 8,(key_length * 2) / 8);
MessageBox ( NULL,L"The key derivation method will not produce enough envelope key material for the chosen ciphers. " ,L"Error", MB_OK );
return NULL;
}

// Convert the user's public key from hex into a full EC_KEY structure.
if (!(user = ecies_key_create_public_hex(key))) {
//printf("Invalid public key provided.\n");
MessageBox ( NULL,L"Invalid public key provided" ,L"Error", MB_OK );
return NULL;
}

// Create the ephemeral key used specifically for this block of data.
else if (!(ephemeral = ecies_key_create())) {
//printf("An error occurred while trying to generate the ephemeral key.\n");
MessageBox ( NULL,L"An error occurred while trying to generate the ephemeral key" ,L"Error", MB_OK );
EC_KEY_free(user);
return NULL;
}

// Use the intersection of the provided keys to generate the envelope data used by the ciphers below. The ecies_key_derivation() function uses
// SHA 512 to ensure we have a sufficient amount of envelope key material and that the material created is sufficiently secure.
else if (ECDH_compute_key(envelope_key, SHA512_DIGEST_LENGTH, EC_KEY_get0_public_key(user), ephemeral, ecies_key_derivation) !=
SHA512_DIGEST_LENGTH) {
//printf("An error occurred while trying to compute the envelope key. {error = %s}\n", ERR_error_string(ERR_get_error(), NULL));
MessageBox ( NULL,L"An error occurred while trying to compute the envelope key" ,L"Error", MB_OK );
EC_KEY_free(ephemeral);
EC_KEY_free(user);
return NULL;
}

// Determine the envelope and block lengths so we can allocate a buffer for the result.
else if ((block_length = EVP_CIPHER_block_size(ECIES_CIPHER)) == 0 || block_length > EVP_MAX_BLOCK_LENGTH ||
(envelope_length = EC_POINT_point2oct(EC_KEY_get0_group(ephemeral), EC_KEY_get0_public_key(ephemeral),
POINT_CONVERSION_COMPRESSED, NULL, 0, NULL)) == 0) {
//printf("Invalid block or envelope length. {block = %zu /envelope = %zu}\n", block_length, envelope_length);
MessageBox ( NULL,L"Invalid block or envelope length" ,L"Error", MB_OK );
EC_KEY_free(ephemeral);
EC_KEY_free(user);
return NULL;
}

// We use a conditional to pad the length if the input buffer is notevenly divisible by the block size.
else if (!(cryptex = secure_alloc(envelope_length, EVP_MD_size(ECIES_HASHER), length, length + (length % block_length ? (block_length - (length % block_length)) : 0)))) {
//printf("Unable to allocate a secure_t buffer to hold the encrypted result.\n");
MessageBox ( NULL,L"Unable to allocate a secure_t buffer to hold the encrypted result" ,L"Error", MB_OK );
EC_KEY_free(ephemeral);
EC_KEY_free(user);
return NULL;
}

// Store the public key portion of the ephemeral key.
else if (EC_POINT_point2oct(EC_KEY_get0_group(ephemeral), EC_KEY_get0_public_key(ephemeral), POINT_CONVERSION_COMPRESSED, (unsigned char*)secure_key_data(cryptex), envelope_length, NULL) != envelope_length) {
//printf("An error occurred while trying to record the public portion of the envelope key. {error = %s}\n", ERR_error_string(ERR_get_error(), NULL));
MessageBox ( NULL,L"An error occurred while trying to record the public portion of the envelope key" ,L"Error", MB_OK );
EC_KEY_free(ephemeral);
EC_KEY_free(user);
secure_free(cryptex);
return NULL;
}

// The envelope key has been stored so we no longer need to keep the keys around.
EC_KEY_free(ephemeral);
EC_KEY_free(user);

// For now we use an empty initialization vector.
memset(iv, 0, EVP_MAX_IV_LENGTH);

// Setup the cipher context, the body length, and store a pointer to the body buffer location.
EVP_CIPHER_CTX_init(&cipher);
body = (unsigned char*)secure_body_data(cryptex);
body_length = secure_body_length(cryptex);

// Initialize the cipher with the envelope key.
if (EVP_EncryptInit_ex(&cipher, ECIES_CIPHER, NULL, envelope_key, iv) != 1 || EVP_CIPHER_CTX_set_padding(&cipher, 0) != 1 || EVP_EncryptUpdate(&cipher, (unsigned char*)body, &body_length, data, length - (length % block_length)) != 1) {
//printf("An error occurred while trying to secure the data using the chosen symmetric cipher. {error = %s}\n", ERR_error_string(ERR_get_error(), NULL));
MessageBox ( NULL,L"An error occurred while trying to secure the data using the chosen symmetric cipher." ,L"Error", MB_OK );
EVP_CIPHER_CTX_cleanup(&cipher);
secure_free(cryptex);
return NULL;
}

// Check whether all of the data was encrypted. If they don't match up, we either have a partial block remaining, or an error occurred.
else if (body_length != length) {

// Make sure all that remains is a partial block, and their wasn't an error.
if (length - body_length >= block_length) {
//printf("Unable to secure the data using the chosen symmetric cipher. {error = %s}\n", ERR_error_string(ERR_get_error(), NULL));
MessageBox ( NULL,L"Unable to secure the data using the chosen symmetric cipher.." ,L"Error", MB_OK );
EVP_CIPHER_CTX_cleanup(&cipher);
secure_free(cryptex);
return NULL;
}

// Copy the remaining data into our partial block buffer. The memset() call ensures any extra bytes will be zero'ed out.
memset(block, 0, EVP_MAX_BLOCK_LENGTH);
memcpy(block, data + body_length, length - body_length);

// Advance the body pointer to the location of the remaining space, and calculate just how much room is still available.
body += body_length;
if ((body_length = secure_body_length(cryptex) - body_length) < 0) {
//printf("The symmetric cipher overflowed!\n");
MessageBox ( NULL,L"The symmetric cipher overflowed!" ,L"Error", MB_OK );
EVP_CIPHER_CTX_cleanup(&cipher);
secure_free(cryptex);
return NULL;
}

// Pass the final partially filled data block into the cipher as a complete block. The padding will be removed during the decryption process.
else if (EVP_EncryptUpdate(&cipher, body, &body_length, block, block_length) != 1) {
//printf("Unable to secure the data using the chosen symmetric cipher. {error = %s}\n", ERR_error_string(ERR_get_error(), NULL));
MessageBox ( NULL,L"Unable to secure the data using the chosen symmetric cipher." ,L"Error", MB_OK );
EVP_CIPHER_CTX_cleanup(&cipher);
secure_free(cryptex);
return NULL;
}
}

// Advance the pointer, then use pointer arithmetic to calculate how much of the body buffer has been used. The complex logic is needed so that we get
// the correct status regardless of whether there was a partial data block.
body += body_length;
if ((body_length = secure_body_length(cryptex) - (body - (unsigned char*)secure_body_data(cryptex))) < 0) {
//printf("The symmetric cipher overflowed!\n");
MessageBox ( NULL,L"The symmetric cipher overflowed!" ,L"Error", MB_OK );
EVP_CIPHER_CTX_cleanup(&cipher);
secure_free(cryptex);
return NULL;
}

else if (EVP_EncryptFinal_ex(&cipher, body, &body_length) != 1) {
//printf("Unable to secure the data using the chosen symmetric cipher. {error = %s}\n", ERR_error_string(ERR_get_error(), NULL));
MessageBox ( NULL,L"Unable to secure the data using the chosen symmetric cipher" ,L"Error", MB_OK );
EVP_CIPHER_CTX_cleanup(&cipher);
secure_free(cryptex);
return NULL;
}

EVP_CIPHER_CTX_cleanup(&cipher);

// Generate an authenticated hash which can be used to validate the data during decryption.
HMAC_CTX_init(&hmac);
mac_length = secure_mac_length(cryptex);

// At the moment we are generating the hash using encrypted data. At some point we may want to validate the original text instead.
if (HMAC_Init_ex(&hmac, envelope_key + key_length, key_length, ECIES_HASHER, NULL) != 1 || HMAC_Update(&hmac, (unsigned char*)secure_body_data(cryptex), secure_body_length(cryptex))
!= 1 || HMAC_Final(&hmac, (unsigned char*)secure_mac_data(cryptex), &mac_length) != 1) {
//printf("Unable to generate a data authentication code. {error = %s}\n", ERR_error_string(ERR_get_error(), NULL));
MessageBox ( NULL,L"Unable to generate a data authentication code." ,L"Error", MB_OK );
HMAC_CTX_cleanup(&hmac);
secure_free(cryptex);
return NULL;
}

HMAC_CTX_cleanup(&hmac);

return cryptex;
}

unsigned char * ecies_decrypt(char *key, secure_t *cryptex, size_t *length) {

HMAC_CTX hmac;
size_t key_length;
int output_length;
EVP_CIPHER_CTX cipher;
EC_KEY *user, *ephemeral;
unsigned int mac_length = EVP_MAX_MD_SIZE;
unsigned char envelope_key[SHA512_DIGEST_LENGTH], iv[EVP_MAX_IV_LENGTH], md[EVP_MAX_MD_SIZE], *block, *output;

// Simple sanity check.
if (!key || !cryptex || !length) {
//printf("Invalid parameters passed in.\n");
MessageBox ( NULL,L"Invalid parameters passed in." ,L"Error", MB_OK );
return NULL;
}

// Make sure we are generating enough key material for the symmetric ciphers.
else if ((key_length = EVP_CIPHER_key_length(ECIES_CIPHER)) * 2 > SHA512_DIGEST_LENGTH) {
//printf("The key derivation method will not produce enough envelope key material for the chosen ciphers. {envelope = %i / required = %zu}", SHA512_DIGEST_LENGTH / 8, (key_length * 2) / 8);
MessageBox ( NULL,L"The key derivation method will not produce enough envelope key material for the chosen ciphers" ,L"Error", MB_OK );
return NULL;
}

// Convert the user's public key from hex into a full EC_KEY structure.
else if (!(user = ecies_key_create_private_hex(key))) {
//printf("Invalid private key provided.\n");
MessageBox ( NULL,L"Invalid private key provided" ,L"Error", MB_OK );
return NULL;
}

// Create the ephemeral key used specifically for this block of data.
else if (!(ephemeral =
ecies_key_create_public_octets((unsigned char*)secure_key_data(cryptex), secure_key_length(cryptex)))) {
//printf("An error occurred while trying to recreate the ephemeral key.\n");
MessageBox ( NULL,L"An ssssserror occurred while trying to recreate the ephemeral key" ,L"Error", MB_OK );
EC_KEY_free(user);
return NULL;
}

// Use the intersection of the provided keys to generate the envelope data used by the ciphers below. The ecies_key_derivation() function uses
// SHA 512 to ensure we have a sufficient amount of envelope key material and that the material created is sufficiently secure.
else if (ECDH_compute_key(envelope_key, SHA512_DIGEST_LENGTH, EC_KEY_get0_public_key(ephemeral), user, ecies_key_derivation) != SHA512_DIGEST_LENGTH) {
//printf("An error occurred while trying to compute the envelope key. {error = %s}\n", ERR_error_string(ERR_get_error(), NULL));
MessageBox ( NULL,L"An error occurred while trying to compute the envelope key." ,L"Error", MB_OK );
EC_KEY_free(ephemeral);
EC_KEY_free(user);
return NULL;
}

// The envelope key material has been extracted, so we no longer need the user and ephemeral keys.
EC_KEY_free(ephemeral);
EC_KEY_free(user);

// Use the authenticated hash of the ciphered data to ensure it was not modified after being encrypted.
HMAC_CTX_init(&hmac);

// At the moment we are generating the hash using encrypted data. At some point we may want to validate the original text instead.
if (HMAC_Init_ex(&hmac, envelope_key + key_length, key_length, ECIES_HASHER, NULL) != 1 || HMAC_Update(&hmac, (unsigned char*)secure_body_data(cryptex),
secure_body_length(cryptex))
!= 1 || HMAC_Final(&hmac, md, &mac_length) != 1) {
//printf("Unable to generate the authentication code needed for validation. {error = %s}\n", ERR_error_string(ERR_get_error(), NULL));
MessageBox ( NULL,L"Unable to generate the authentication code needed for validation." ,L"Error", MB_OK );
HMAC_CTX_cleanup(&hmac);
return NULL;
}

HMAC_CTX_cleanup(&hmac);

// We can use the generated hash to ensure the encrypted data was not altered after being encrypted.
if (mac_length != secure_mac_length(cryptex) || memcmp(md,
secure_mac_data(cryptex), mac_length)) {
//printf("The authentication code was invalid! The ciphered data has been corrupted!\n");
MessageBox ( NULL,L"The authentication code was invalid! The ciphered data has been corrupted" ,L"Error", MB_OK );
return NULL;
}

// Create a buffer to hold the result.
output_length = secure_body_length(cryptex);
if (!(block = output = (unsigned char*)malloc(output_length + 1))) {
//printf("An error occurred while trying to allocate memory for the decrypted data.\n");
MessageBox ( NULL,L"An error occurred while trying to allocate memory for the decrypted data" ,L"Error", MB_OK );
return NULL;
}

// For now we use an empty initialization vector. We also clear out the result buffer just to be on the safe side.
memset(iv, 0, EVP_MAX_IV_LENGTH);
memset(output, 0, output_length + 1);

EVP_CIPHER_CTX_init(&cipher);

// Decrypt the data using the chosen symmetric cipher.
if (EVP_DecryptInit_ex(&cipher, ECIES_CIPHER, NULL, envelope_key, iv)
!= 1 || EVP_CIPHER_CTX_set_padding(&cipher, 0) != 1 ||
EVP_DecryptUpdate(&cipher, block,
&output_length, (unsigned char*)secure_body_data(cryptex),
secure_body_length(cryptex)) != 1) {
//printf("Unable to decrypt the data using the chosen symmetric cipher. {error = %s}\n", ERR_error_string(ERR_get_error(), NULL));
MessageBox ( NULL,L"Unable to decrypt the data using the chosen symmetric cipher." ,L"Error", MB_OK );
EVP_CIPHER_CTX_cleanup(&cipher);
free(output);
return NULL;
}

block += output_length;
if ((output_length = secure_body_length(cryptex) - output_length) != 0)
{
//printf("The symmetric cipher failed to properly decrypt the correct amount of data!\n");
MessageBox ( NULL,L"The symmetric cipher failed to properly decrypt the correct amount of data" ,L"Error", MB_OK );
EVP_CIPHER_CTX_cleanup(&cipher);
free(output);
return NULL;
}

if (EVP_DecryptFinal_ex(&cipher, block, &output_length) != 1) {
//printf("Unable to decrypt the data using the chosen symmetric cipher. {error = %s}\n", ERR_error_string(ERR_get_error(), NULL));
MessageBox ( NULL,L"Unable to decrypt the data using the chosen symmetric cipher." ,L"Error", MB_OK );
EVP_CIPHER_CTX_cleanup(&cipher);
free(output);
return NULL;
}

EVP_CIPHER_CTX_cleanup(&cipher);

*length = secure_orig_length(cryptex);
return output;
}

最佳答案

结构体secure_head_t只包含整数,没有指针,所以在你停留在同一台机器/编译器+选项的情况下,你可以考虑(强制转换)一个指针将 secure_head_t 作为指向 sizeof(secure_head_t) 字符的指针,反之亦然,没有任何问题。否则,使用 sprintf 或等效函数将 4 个整数保存/编码为其外部形式,并使用 scanf 或等效函数读取/解码它们。

我鼓励您永远不要通过typedef隐藏指针,因此不要定义typedef char* secure_t;而是使用字符*

您的代码分配并初始化,然后返回一个 secure_head_t,因此使用 secure_t * 作为 char ** 没有任何意义,因为它是不是指向指针的指针。也许您会想到,因为 struct 包含一个 struct,但 struct 不包含指向 struct 的指针,所以不存在两级指针。

您也遇到了问题:

malloc(sizeof(secure_head_t) + key + mac + body);

因为你要求分配一 block 内存,所以选择的大小取决于keymacbody em> 这不是您想要的,因为您将无缘无故地分配一大块内存,并且可能无法进行分配,因为需要巨大的大小,只需这样做

secure_head_t * head = malloc(sizeof(secure_head_t));

head->length.key = key;
head->length.mac = mac;
head->length.orig = orig;
head->length.body = body;
return (char *) head;

即使说您返回 char * 而不是 secure_head_t * 也很奇怪,因为失去真实类型从来都不是一件好事

关于c - Memcpy char** 的 typedef,它指向具有 4 个 uint64_t 类型变量的结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55525079/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com