gpt4 book ai didi

c - memcpy:第二次调用后出现段错误

转载 作者:太空宇宙 更新时间:2023-11-04 08:48:25 25 4
gpt4 key购买 nike

我正在为 Karl Malbrain 的 AES implementation 编写包装器处理大于 16 字节的输入文件。因此,我编写了一个函数 aes_encrypt_block,它将输入缓冲区 (message) 分成 16 个字节的 block (chunk/chunk_cipher), 调用加密/解密函数并将加密/解密的16字节放回结果缓冲区。

这行得通。但是,我需要在加密之前填充消息。因此,我加密的最后 16 个字节(在 for 循环之外)是填充字节。将这些字节复制到输出缓冲区 (cipher) 时,出现段错误。我真的看不出出了什么问题。

你看到错误了吗?

问候

#include "aes.h"
#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>

#define DEBUG 1

void aes_encrypt_block(uint8_t **message, uint8_t **cipher, uint8_t blocks, uint8_t pad_bytes);
void aes_decrypt_block(uint8_t **msg_decrypted, uint8_t **cipher, uint8_t blocks, uint8_t pad_bytes);
unsigned long readFile(char *fileName, uint8_t **buffer);
//unsigned long readFile1(char *fileName, uint8_t *buffer);

uint8_t secret[16] = {0x44, 0x43, 0x45, 0x33, 0x44, 0x03, 0x34, 0x44, 0x43, 0x45, 0x33, 0x44, 0x03, 0x34, 0x03, 0x34};
uint8_t *chunk = NULL;
uint8_t *chunk_cipher = NULL;
uint8_t expanded[176] = {0x00};
uint8_t *buffer = NULL;
uint8_t *cipher = NULL;
uint8_t *msg_decrypted = NULL;
uint8_t mode = -1;


int main(int argc, char *argv[]) {
uint32_t i = 0;
uint8_t blocks = -1, pad_bytes = -1;
unsigned long fileLen;
char* ch = NULL;

if(argc<3) {
printf("Wrong arguments supplied.\n\n%s {0/1} OUT\n\n\t0 - encrypt\n\t1 - decrypt\n\tOUT - file to read from / to write to.\n\n", argv[0]);
return 0;
} else {
mode = atoi(argv[1]);
if(mode<0 || mode>1) {
printf("Wrong arguments supplied.\n\n%s {0/1} OUT\n\n\t0 - encrypt\n\t1 - decrypt\n\tOUT - file to read from / to write to.\n\n", argv[0]);
return 0;
}
}
puts("");

// Read file
fileLen = readFile(argv[2], &buffer);
// Setting up parameters and memory
if(fileLen%16!=0) {
printf("- ");
blocks = fileLen/16+1;
pad_bytes = (blocks*16)-fileLen;
} else {
printf("+ ");
blocks = fileLen/16+1;
pad_bytes = 16;
}
cipher = malloc((blocks*16)*sizeof(int));
if(cipher==NULL) printf("malloc() error!\n");
aes_expand_key(secret, expanded);
if(DEBUG) printf("size: %u, size/16: %d, blocks: %d, padding: %d\n\n", fileLen, fileLen/16, blocks, pad_bytes);

if(!mode) { // We will encrypt
aes_encrypt_block(&buffer, &cipher, blocks, pad_bytes);
free(buffer);

FILE *file_enc;
file_enc = fopen("bla.enc", "wb");
fileLen = fwrite(&cipher, sizeof(uint8_t), 32, file_enc);
printf("\nWrote %ld bytes to %s\n", fileLen, argv[2]);
fclose(file_enc);
} else { // We will decrypt
msg_decrypted = malloc((16*blocks)*sizeof(uint8_t));

// Decrypting blocks
aes_decrypt_block(msg_decrypted, cipher, blocks, pad_bytes);

puts("\nDecrypted message:");
printf("%s\n", msg_decrypted);
puts("");
free(msg_decrypted);
}

return 0;
}


unsigned long readFile(char *fileName, uint8_t **buffer) {
unsigned long fileLen = 0;
uint8_t i;
char* ch = NULL;

FILE *file;
file = fopen (fileName, "rb"); /* open the file for reading */

if(file==NULL) {
perror(fileName);
return 0;
}
fseek(file, 0, SEEK_END);
fileLen=ftell(file);
fseek(file, 0, SEEK_SET);
*buffer=malloc(fileLen+1);

if (!buffer) {
fprintf(stderr, "Memory error!");
fclose(file);
return;
}
fread(*buffer, 1, fileLen, file);
printf( "Source message in hex(%s, %ld bytes):\n", fileName, fileLen );
for (ch = *buffer ; ch < *buffer + fileLen; ++ch) {
printf( "%02X", *ch );
}
puts("\nASCII:\n---------");
for (ch = *buffer ; ch < *buffer + fileLen; ++ch) {
printf( "%c", *ch );
}
puts("");
fclose(file);

return fileLen;
}


void aes_encrypt_block(uint8_t **message, uint8_t **cipher, uint8_t blocks, uint8_t pad_bytes) {
uint8_t i;

chunk = malloc(16*sizeof(uint8_t));
if(chunk==NULL) printf("malloc() error!\n");
chunk_cipher = malloc(16*sizeof(uint8_t));
if(chunk_cipher == NULL) printf("malloc() error!\n");

for(i=0; i<(blocks-1); i++) {
memcpy(chunk, message[i*16], 16*sizeof(uint8_t));
aes_encrypt(chunk, expanded, chunk_cipher);
memcpy(cipher[i*16], chunk_cipher, 16*sizeof(uint8_t));
}

// Padding
memcpy(chunk, message[(blocks-1)*16], (16-pad_bytes)*sizeof(uint8_t));
uint8_t j;
for(j=0; j<=pad_bytes; j++) {
chunk[15-j] = pad_bytes;
}
aes_encrypt(chunk, expanded, chunk_cipher);
memcpy(cipher[i*16], chunk, 16*sizeof(uint8_t));
}

编辑:

Valgrind输出(test.c中第149行对应:memcpy(cipher[i*16], chunk, 16*sizeof(uint8_t));)

Valgrind outputs:
InvalidWrite: Invalid write of size 4
Call stack:
/usr/lib/valgrind/vgpreload_memcheck-x86-linux.so 0x402E08A: memcpy
/home/dev/aes/test.c|149|0x804A604: aes_encrypt_block
/home/dev/aes/test.c|59|0x8049AFE: main
Address 0x0 is not stack'd, malloc'd or (recently) free'd
Valgrind found 1 errors!

最佳答案

如果 pad_bytes == 16 那么这个循环:

for(j=0; j<=pad_bytes; j++) {
chunk[15-j] = pad_bytes;
}

将写入 chunk 开始之前的无效位置,可能会破坏您的堆。

大概应该是:

for(j=0; j<pad_bytes; j++) {
chunk[15-j] = pad_bytes;
}

另请注意,您似乎也有一些 memory leaks通过 malloc 分配的内存不是 freed,例如aes_encrypt_block() 中的 chunkchunk_cipher

关于c - memcpy:第二次调用后出现段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20681867/

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