I'm trying to implement reading the BMP file in c.
I came across basic bmp reading module from google as the below.
#include <stdio.h>
#include <malloc.h>
#include <memory.h>
#include <io.h>
#include <fcntl.h>
#include "ReadBMP.h"
char ReadBMPFile(const char *file_name, BMPDATA *ret_bmp_data)
{
int fh;
long file_length;
void *bmp_file_data;
fh = _open(file_name, _O_RDONLY, _O_BINARY);
if (fh == -1)
{
return -1;
}
_lseek(fh, 0, SEEK_END);
file_length = _tell(fh);
_lseek(fh, 0, SEEK_SET);
bmp_file_data = malloc(file_length);
_read(fh, bmp_file_data, file_length);
_close(fh);
ReadBMPData(bmp_file_data, ret_bmp_data);
free(bmp_file_data);
return 0;
}
But I feel hard to use above function in my code.
#include <windows.h>
#include "ReadBMP.h"
#define WIDTHBYTES(bits) (((bits)+31)/32*4)
#define BYTE unsigned char
int main(int argc, char *argv[])
{
FILE *fp;
int i, j, k,n;
int width = 16;
int height = 16;
int bpp = 24;
FILE *fp_new;
char *filename_new;
char ch;
BMPDATA *ret_bmp_data;
int val[1000];
char filename[100];
//char *filename = "test.bmp";
// Check if a filename has been specified in the command
if (argc < 2)
{
printf("Missing Filename\n");
return(1);
}
else
{
filename_new = argv[1];
printf("Filename : %s\n", filename_new);
}
ReadBMPFile(filename_new, ret_bmp_data);
When I do implement like this I've got a error message as the below
error C4700: uninitialized local variable 'ret_bmp_data' used
How do I initialize the local variable?
update
I've updated ReadBMP.c file at all.
#include <stdio.h>
#include <malloc.h>
#include <memory.h>
#include <io.h>
#include <fcntl.h>
#include "ReadBMP.h"
void DecodeData(const char *byte_data, int offset, BMPDATA *ret_bmp_data);
void DecodeInfomation(const char *byte_data, int offset, BMPDATA *ret_bmp_data);
char ReadBMPFile(const char *file_name, BMPDATA *ret_bmp_data)
{
int fh;
long file_length;
void *bmp_file_data;
fh = _open(file_name, _O_RDONLY, _O_BINARY);
if (fh == -1)
{
return -1;
}
_lseek(fh, 0, SEEK_END);
file_length = _tell(fh);
_lseek(fh, 0, SEEK_SET);
bmp_file_data = malloc(file_length);
_read(fh, bmp_file_data, file_length);
_close(fh);
ReadBMPData(bmp_file_data, ret_bmp_data);
free(bmp_file_data);
return 0;
}
char ReadBMPData(const void *bmp_file_data, BMPDATA *ret_bmp_data)
{
char *byte_data;
int offset;
byte_data = (char *)bmp_file_data;
if ((byte_data[0] != 'B') || (byte_data[1] != 'M'))
{
return -1;
}
memcpy(&offset, &byte_data[10], 4);
DecodeInfomation(byte_data, offset, ret_bmp_data);
DecodeData(byte_data, offset, ret_bmp_data);
return 0;
}
void DecodeInfomation(const char *byte_data, int offset, BMPDATA *ret_bmp_data)
{
if (offset == 26)
{
memcpy(&ret_bmp_data->width, &byte_data[18], 2);
memcpy(&ret_bmp_data->height, &byte_data[20], 2);
memcpy(&ret_bmp_data->bits_per_pixel, &byte_data[24], 2);
}
else
{
memcpy(&ret_bmp_data->width, &byte_data[18], 4);
memcpy(&ret_bmp_data->height, &byte_data[22], 4);
memcpy(&ret_bmp_data->bits_per_pixel, &byte_data[28], 2);
}
}
void DecodeData(const char *byte_data, int offset, BMPDATA *ret_bmp_data)
{
int data_size;
if (ret_bmp_data->bits_per_pixel == 24)
{
data_size = ret_bmp_data->width * ret_bmp_data->height * 3;
ret_bmp_data->data = malloc(data_size);
memcpy(ret_bmp_data->data, &byte_data[offset], data_size);
}
}
this is ReadBMP.h
#ifndef READBMP_H
#define READBMP_H
typedef struct BMPDATA
{
short bits_per_pixel;
int width;
int height;
unsigned char *data;
}BMPDATA;
#ifdef __cplusplus
extern "C"
{
#endif
char ReadBMPFile(const char *file_name, BMPDATA *ret_bmp_data);
char ReadBMPData(const void *bmp_file_data, BMPDATA *ret_bmp_data);
#ifdef __cplusplus
}
#endif
#endif
and
this is Source.cpp
#include <stdio.h>
#include <stdlib.h> /* system, NULL, EXIT_FAILURE */
#include <windows.h>
#include "ReadBMP.h"
#define WIDTHBYTES(bits) (((bits)+31)/32*4)
#define BYTE unsigned char
int main(int argc, char *argv[])
{
FILE *fp;
int i, j, k,n;
int width = 16;
int height = 16;
int bpp = 24;
////////////////// add BMP read 2018-03-20 ///////////////
FILE *fp_new;
char *filename_new;
char ch;
BMPDATA *ret_bmp_data;
int val[1000];
char filename[100];
//char *filename = "test.bmp";
// Check if a filename has been specified in the command
if (argc < 2)
{
printf("Missing Filename\n");
return(1);
}
else
{
filename_new = argv[1];
printf("Filename : %s\n", filename_new);
}
ReadBMPFile(filename_new, ret_bmp_data);
fclose(fp);
fclose(fp_new);
}
Due to the error message, it seems that the BMPDATA variable in main isn't supposed to be a BMPDATA pointer but a BMPDATA object.
Like:
int main(int argc, char *argv[])
{
....
BMPDATA ret_bmp_data;
....
ReadBMPFile(filename_new, &ret_bmp_data);
....
}
Related
I'm trying to encrypt/decrypt an AES key/iv using RSA encryption algorithm using openssl in C.
The decryption is working before storing the encrypted data into the file . But the decryption threw an error while decrypting the same encrypted data stored on the file.
Here is my code:
#include <stdio.h>
#include <stdbool.h>
#include <openssl/pem.h>
#include <openssl/ssl.h>
#include <openssl/rsa.h>
#include <openssl/evp.h>
#include <openssl/bio.h>
#include <openssl/err.h>
#include <string.h>
int padding = RSA_PKCS1_PADDING;
#define RSA_KEY_Size 384;
#define AES_256_KEY_SIZE 32;
// testing encryption/decryption
int func(const char* pubkeyfile, unsigned char *key, unsigned char *iv)
{
unsigned char *encryptedkey = (unsigned char*)malloc(RSA_KEY_Size);
unsigned char *encryptediv = (unsigned char*)malloc(RSA_KEY_Size);
unsigned char *decryptedkey = (unsigned char*)malloc(AES_256_KEY_SIZE);
unsigned char *decryptediv = (unsigned char*)malloc(AES_256_KEY_SIZE);
int result1 = rsaEncrypt(key, pubkeyfile, encryptedkey);
int result2 = rsaEncrypt(iv, pubkeyfile, encryptediv);
serialize(encryptedkey, encryptediv);
///////tested here, this part working fine
int r1 = rsaDecrypt(encryptedkey, privkeyfile, decryptedkey);
int r2 = rsaDecrypt(encryptediv, privkeyfile, decryptediv);
///////////////////////////////
unsigned char *getkey = (unsigned char*)malloc(RSA_KEY_Size);;
unsigned char *getiv = (unsigned char*)malloc(RSA_KEY_Size);;
deserialize(getkey, getiv);
unsigned char *ikey = (unsigned char*)malloc(AES_256_KEY_SIZE);
unsigned char *iiv = (unsigned char*)malloc(AES_256_KEY_SIZE);
//////////tested here, failed to decrypt after taking encrypted data from a file/////////////////
int r22 = rsaDecrypt(getiv, privkeyfile, iiv);
int r21 = rsaDecrypt(getkey, privkeyfile, ikey);
//////////////////////////////////////////////////
return 0;
}
typedef struct item {
uint8_t keyivlen;
char keyiv[RSA_KEY_Size];
struct item *next;
} list;
int serialize(unsigned char* key, unsigned char* iv)
{
list *ptr;
char *buffer;
int listLength;
list first, second;
ptr = &first;
FILE *filePtr;
memcpy(first.keyiv, key, strlen(key));
first.keyivlen = strlen(first.keyiv);
first.next = &second;
memcpy(second.keyiv, iv, strlen(iv));
second.keyivlen = strlen(second.keyiv);
second.next = 0;
listLength = listSize(ptr);
buffer = (char *)malloc(listLength);
serializeList(ptr, buffer);
filePtr = fopen("example.data", "wb+");
fwrite(buffer, listLength, 1, filePtr);
fclose(filePtr);
free(buffer);
return 0;
}
int deserialize(unsigned char* key, unsigned char* iv)
{
FILE *filePtr;
int listLength = 0;
int done = 0;
uint8_t arrayLen;
unsigned char *buffer;
int i = 0;
listLength = fileSize("example.data");
filePtr = fopen("example.data", "rb");
while (done < listLength) {
fread(&arrayLen, 1, 1, filePtr);
buffer = (unsigned char *)malloc(arrayLen + 1);
fread(buffer, arrayLen, 1, filePtr);
buffer[arrayLen] = '\0';
if (i == 0)
{
memcpy(key, buffer, arrayLen + 1);
}
else
{
memcpy(iv, buffer, arrayLen + 1);
}
//addToList(arrayLen, buffer);
done += arrayLen + 1;
i++;
free(buffer);
}
//printList(start);
return 0;
}
Here is the error:
error:0407109F:rsa routines:RSA_padding_check_PKCS1_type_2:pkcs decoding error
error:04065072:rsa routines:rsa_ossl_private_decrypt:padding check failed
And it fails in:
int r22 = rsaDecrypt(getiv, privkeyfile, iiv);
int r21 = rsaDecrypt(getkey, privkeyfile, ikey);
What could be the reason for this error?
arrayLen is only uint8_t which fits at most 255 , so your deserialised data is too short. You need RSA_KEY_Size bytes.
I have three binary files: cipher01.bin, cipher02.bin and cipher03.bin.
Additionally I have a sign.bin and a pubkey.pem file. The task is to hash all three ciphers and compare it to the signature. Therefore I used RSA to decrypt the sign.bin with the public key from pubkey.pem.
The result looks good but none of the cipher-hashes belongs to the signature. But I know, that there is at least one cipher which belongs to the signature because it is a task from our university. Maybe I forgot something but I can't figure out what.
Here is my code so far:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <openssl/sha.h>
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/pem.h>
#include <openssl/ssl.h>
#include <openssl/rsa.h>
#include <openssl/bio.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
/** converts unsigned character to readble string*/
char *pt(unsigned char *md) {
int i;
char *buf = (char*)malloc(sizeof(char)*80);
for(int i = 0; i < SHA_DIGEST_LENGTH;i++) {
sprintf(&(buf[i*2]),"%02x",md[i]);
}
return (buf);
}
/** returns error */
void err_exit(void) {
printf("%s\n",ERR_error_string(ERR_get_error(),NULL));
ERR_free_strings();
exit(EXIT_FAILURE);
}
/** reads a file */
char * readFile(char * filename,long int * filesize) {
FILE *fin;
char *buf;
if((fin=fopen(filename,"r"))==NULL) {
printf("Error opening %s.\n",filename);
exit(EXIT_FAILURE);
}
fseek(fin,0L,SEEK_END);
*filesize = ftell(fin);
rewind(fin);
if(!(buf=malloc(*filesize))) {
printf("Memory exhausted. Stop.\n");
exit(EXIT_FAILURE);
}
fread(buf,*filesize,1,fin);
fclose(fin);
return buf;
}
/** hash a file with sha1 */
char * hashBinaryFile(char * filename) {
long int filesize = 0;
EVP_MD_CTX c;
unsigned char md[SHA_DIGEST_LENGTH];
ERR_load_crypto_strings();
EVP_MD_CTX_init(&c);
/** reads files into buf */
char * buf = readFile(filename,&filesize);
if((EVP_DigestInit(&c,EVP_sha1()))==0) {
err_exit();
}
if((EVP_DigestUpdate(&c,buf,filesize))==0) {
err_exit();
}
if((EVP_DigestFinal(&c,md,NULL))==0) {
err_exit();
}
//printf("%s\n",pt(md));
EVP_MD_CTX_cleanup(&c);
free(buf);
ERR_free_strings();
return pt(md);
}
int padding = RSA_PKCS1_PADDING;
/** loads public key and creates rsa */
RSA * createRSAWithFilename(char * filename,int public) {
FILE * fp = fopen(filename,"rb");
if(fp == NULL) {
printf("Unable to open file %s \n",filename);
return NULL;
}
RSA *rsa= RSA_new() ;
if(public) {
rsa = PEM_read_RSA_PUBKEY(fp, &rsa,NULL, NULL);
} else {
rsa = PEM_read_RSAPrivateKey(fp, &rsa,NULL, NULL);
}
return rsa;
}
/** decrypt signature */
char * public_decrypt(unsigned char * enc_data,int data_len, unsigned char *decrypted) {
RSA * rsa = createRSAWithFilename("archieve/pubkey.pem",1);
int result = RSA_public_decrypt(data_len,enc_data,decrypted,rsa,padding);
return pt(decrypted);
}
int main(int argc,char *argv[]) {
/** decrypt signature */
long int encrypted_length;
long int decrypted_length;
unsigned char decrypted[4098]={};
char * encrypted = readFile("archieve/s72897-sig.bin",&encrypted_length);
char * sign = public_decrypt(encrypted,encrypted_length, decrypted);
char * cipher01 = hashBinaryFile("archieve/s72897-cipher01.bin");
char * cipher02 = hashBinaryFile("archieve/s72897-cipher02.bin");
char * cipher03 = hashBinaryFile("archieve/s72897-cipher03.bin");
if(strcmp(sign,cipher01)==0) {
printf("cipher01\n");
} else if(strcmp(sign,cipher02)==0) {
printf("cipher02\n");
} else if(strcmp(sign,cipher03)==0) {
printf("cipher03\n");
} else {
printf("No cipher matches the signature\n");
}
return 0;
}
Thanks for any kind of help.
Edit: fixed some code
Edit2: link to the *.zip https://ufile.io/tqwoh
You transform your files in human readable format twice:
char * public_decrypt(...)
{
return pt(decrypted);
// ^
}
int main(int argc,char *argv[])
{
char * sign = pt(public_decrypt(encrypted,encrypted_length, decrypted));
// ^
Additionally, you actually have some memory leaks: You do not free the rsa instance in public_decrypt neither do you free the strings returned (encrypted, sign, cypher0x)...
Further recommendation in for pt:
char *buf = (char*)malloc(sizeof(char) * 2 * SHA_DIGEST_LENGTH);
If you have an appropriate constant already, use it... sizeof(char) always is 1 by definition, so you could drop it...
C program that reads a disk image specified as a command
line argument and prints the paths for all files and directories in the
image.If the entry is a directory, print a forward slash at the end
of the path....This is my question in program and i done code as below....
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<fcntl.h>
#define K 1024
typedef struct dir {
unsigned int my_node;
unsigned short my_length;
unsigned char my_namelen;
}DIRPATH;
unsigned int getint(int fd, int block, int byte);
unsigned short int getshort(int fd, int block, int byte);
int main (int argc , char *argv[])
{
int i;
int nameleng;
char name[K];
DIRPATH dh;
int argument;
int fd;
argument = (argc > 1) ? atoi(argv[1]) : 0;
fd=open(argv[1],O_RDONLY);
fprintf(stderr,"fd=%d\n",fd);
if(lseek(fd,K,SEEK_SET)<0)
{
fprintf(stderr,"unable to seek");
exit(0);
}
int itab = getint(fd,2,8);
unsigned int first_block = getint(fd,itab,inode_size + 40);
int length=0;
for(i=0;i<6;i++)
{
lseek(fd,first_block * K + length,SEEK_SET);
read(fd,&dh,sizeof(DIRPATH));
length += dh.my_length;
printf("",dh.my_namelen);
read(fd,name,dh.my_namelen);
name[dh.my_namelen] = 0;
printf("%s\n",name);
}
close(fd);
}
unsigned int getint(int fd, int block, int byte)
{
unsigned int x;
int check;
lseek(fd,block * K + byte, SEEK_SET);
check = read(fd, &x, 4);
if(check != 4){
fprintf(stderr,"error to read %d %d \n",block, byte);
exit(0);
}
return(x);
}
unsigned short int getshort(int fd, int block, int byte)
{
unsigned short int x;
int check;
lseek(fd,block * K + byte, SEEK_SET);
check = read(fd, &x, 4);
if(check != 2){
fprintf(stderr,"error to read %d %d \n",block, byte);
exit(0);
}
return(x);
}
I am getting the output but in output it is giving . and ... I have to remove those dots and add / to directories not files.
Can someone explain to me how this retarget.c works?
I am trying to send integers to and from the uart of a microcontroller, i have been successful with using fgets to get a char (16 bits) and returning an integer using the atoi function in the Uart Interupt service routine but I am trying to get an integer using scanf, i am thinking i need to change the retarget file outlined below?
#include <stdio.h>
#include <time.h>
#include <rt_misc.h>
#define AHB_LED_BASE 0x50000000
#define AHB_UART_BASE 0x51000000
#pragma import(__use_no_semihosting)
struct __FILE {
unsigned char * ptr;
};
FILE __stdout = {(unsigned char *) AHB_UART_BASE};
FILE __stdin = {(unsigned char *) AHB_UART_BASE};
int fputc(int ch, FILE *f)
{
return(uart_out(ch));
}
int fgetc(FILE *f)
{
return(uart_in());
}
int ferror(FILE *f)
{
return 0;
}
int uart_out(int ch)
{
int* UARTPtr;
UARTPtr = (int*)AHB_UART_BASE;
*UARTPtr = (int)ch;
return(ch);
}
int uart_in()
{
int ch;
int* UARTPtr;
UARTPtr = (int*)AHB_UART_BASE;
ch = *UARTPtr;
uart_out(ch);
return((int)ch);
}
void _ttywrch(int ch)
{
fputc(ch,&__stdout);
}
void _sys_exit(void) {
while(1);
}
//------------------------------------------------------------------------------
// Cortex-M0
//------------------------------------------------------------------------------
#include <stdio.h>
#include <time.h>
#include <rt_misc.h>
#include <stdlib.h>
#define AHB_LED_BASE 0x50000000
#define AHB_UART_BASE 0x51000000
void UART_ISR(void)
{
int sample;
printf("the value entered is %d\n", sample);
}
//////////////////////////////////////////////////////////////////
// Main Function
//////////////////////////////////////////////////////////////////
int main() {
{
int sample;
scanf ("%d",&sample);
}
}
The scanf function will need ungetc because it must scan ahead in the buffer to see when fields end. E.g., when looking for a number, it needs to pull one character after the number to see where the number ends. When it sees the non-number character, it needs to put it back into the stream so the next call to getc will get it.
Something like this:
struct __FILE
{
unsigned char * ptr;
int unchar; /* place to keep the character put back in the stream */
};
FILE __stdout = {(unsigned char *) AHB_UART_BASE, -1};
FILE __stdin = {(unsigned char *) AHB_UART_BASE, -1};
int fgetc(FILE *f)
{
int c;
if (f->unchar == -1)
{
c = uart_in(); /* just read a character */
}
else
{
c = f->unchar; /* reuse the character put back by ungetc */
f->unchar = -1; /* mark it as used */
}
return c;
}
int fungetc(int c, FILE *f)
{
unsigned char uc = c; /* POSIX says that it is converted first to unsigned char */
f->unchar = (int )uc; /* put back the character */
return (int )uc;
}
am trying to implement an application that uses an MD5 hash underneath, i have acquired the MD5 hash program from the internet, but i don't know how to pass the string from my program ( my program written in C) to the program that calculate the MD5 hash.
this is the main of the program that calculate the MD5 hash..
//
// MD5 Hashing Example - Using Windows Crypto API
//
// by Napalm # NetCore2K
//
#include <stdio.h>
#include <string.h>
#include "winmd5.h"
HCRYPTPROV hCryptProv;
int main(int argc, char *argv[])
{
int i;
CryptStartup();
if(argc > 1){
MD5Context ctx;
MD5Init(&ctx);
MD5Update(&ctx, (unsigned char *)argv[1], strlen(argv[1]));
MD5Final(&ctx);
for(i = 0; i < 16; i++)
printf("%02x", ctx.digest[i]);
printf("\n");
}else
printf("Usage: %s <string>\n", argv[0]);
CryptCleanup();
return 0;
}
this is the header file content..
//
// MD5 Hashing Example - Using Windows Crypto API
//
// by Napalm # NetCore2K
//
#include <windows.h>
#include <wincrypt.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
extern HCRYPTPROV hCryptProv;
void PrintMD5(const char *);
typedef struct {
unsigned char digest[16];
unsigned long hHash;
} MD5Context;
BOOL CryptStartup()
{
if(CryptAcquireContext(&hCryptProv, NULL, MS_ENHANCED_PROV, PROV_RSA_FULL, CRYPT_NEWKEYSET) == 0){
if(GetLastError() == NTE_EXISTS){
if(CryptAcquireContext(&hCryptProv, NULL, MS_ENHANCED_PROV, PROV_RSA_FULL, 0) == 0){
return FALSE;
}
}
else return FALSE;
}
return TRUE;
}
void CryptCleanup()
{
if(hCryptProv) CryptReleaseContext(hCryptProv, 0);
hCryptProv = NULL;
}
void inline MD5Init(MD5Context *ctx)
{
CryptCreateHash(hCryptProv, CALG_MD5, 0, 0, &ctx->hHash);
}
void inline MD5Update(MD5Context *ctx, unsigned char const *buf, unsigned len)
{
CryptHashData(ctx->hHash, buf, len, 0);
}
void inline MD5Final(MD5Context *ctx)
{
DWORD dwCount = 16;
CryptGetHashParam(ctx->hHash, HP_HASHVAL, ctx->digest, &dwCount, 0);
if(ctx->hHash) CryptDestroyHash(ctx->hHash);
ctx->hHash = 0;
}
void PrintMD5(const char *s)
{
MD5Context ctx;
MD5Init(&ctx);
MD5Update(&ctx, (const unsigned char *)s, strlen(s));
MD5Final(&ctx);
int i;
for (i = 0; i < 16; i++) {
printf("%02x", ctx.hHash[i]);
}
printf("\n");
}
how should i call this Main(), and how to pass the String to it and get the result.?
thanks in advance.
Regards
You don't call main() again. You rather use this program as an example to write a separate function, like this:
void PrintMD5(const char *s)
{
MD5Context ctx;
MD5Init(&ctx);
MD5Update(&ctx, (const unsigned char *)s, strlen(s));
MD5Final(&ctx);
int i;
for (i = 0; i < 16; i++) {
printf("%02x", ctx.digest[i]);
}
printf("\n");
}
Then you can call this from your own program like:
PrintMD5("FooBarHelloWorld42");