Swapping endiannes in C - c

I have this string
c1eb044f0708015b267913fc4dff5aabe3dd4a97f10f7ba935cd360000000000
How does one swap it so it becomes
000000000036cd35a97b0ff1974adde3ab5aff4dfc1379265b0108074f04ebc1
Those two are basically examples, but that is what i need to do, but not know how as i have very little knowledge of C.
The above two strings are actually unsigned char[] in the C program
P.S
Don't think i didn't go through google. I did, but i found very little of what i needed so every attempt to do that failed.

for (int i = 0; i < size; i += 2) {
myNewStr[size - i - 2] = myStr[i];
myNewStr[size - i - 1] = myStr[i + 1];
}

Something like this; probably not perfect but gives you the idea. You'll want appropriate error checking, initialization of your buffer, etc.
Edit: I made an assumption I shouldn't have, possibly. I interpreted your string as hex representations of bytes, so I took c1 as an unsigned char and switched it with 00, for example. If your string is actually lowercase c, the number 1, etc., then Micah's answer is what you want, not mine.
void reverse_string(unsigned char *buf, int length)
{
int i;
unsigned char temp;
for (i = 0; i < length / 2; i++)
{
temp = buf[i];
buf[i] = buf[length - i - 1];
buf[length - i - 1] = temp;
}
}

This seems to do what you want, include at least string.h and stdlib.h.
unsigned char *stringrev(const unsigned char *s) {
size_t n = strlen((const char *)s);
unsigned char *r = malloc(n + 1);
if (r != NULL && !(n & 1)) {
const unsigned char *fp = s;
unsigned char *rp = r + n;
for(*rp = '\0'; n > 1; n -= 2) {
*--rp = fp[1];
*--rp = fp[0];
fp += 2;
}
}
return r;
}

Slight alternative to Micah's answer. I assume that the size is precalculated and even, and check that it's greater than 0 because s-2 is potentially UB. I modify the string in-place just for variety.
static inline void swap_uchar(unsigned char *l, unsigned char *r) {
unsigned char tmp = *l;
*l = *r;
*r = tmp;
}
void reverse_pairs(unsigned char *s, size_t size) {
if (size > 0) {
for (unsigned char *l=s, *r=s+size-2; l < r; l += 2, r -= 2) {
swap_uchar(l, r);
swap_uchar(l+1, r+1);
}
}
}

If you have a string: "12ab\0" then the reverse endian of this string would be "\0ba21" .
If you have a numeric: 0x12ab then the reverse endian of this numeric would be 0xab12 .
Which one do you want.
Here is a function for converting between endian, which will handle the passed argument as a block of memory and change the endian.
Code
#include <stdio.h>
typedef struct _test {
unsigned int a, b;
} test;
/* x: base address of the memory
* n: length of the memory
*/
void reverse_endian (void *x, int n)
{
char *arr_conv, *arr, t;
arr = arr_conv = (char *) x;
arr += (n-1);
n/=2;
while (n)
{
t = *arr_conv;
*arr_conv = *arr;
*arr = t;
n--;
arr_conv++;
arr--;
}
}
int main (void)
{
char str1[] = "c1eb044f0708015b267913fc4dff5aabe3dd4a97f10f7ba935cd360000000000";
char str2[] = "hellio";
/* Assigns the str1 as hex values */
unsigned char str3[] = {0xc1, 0xeb, 0x04, 0x4f, 0x07, 0x08, 0x01, 0x5b, 0x26, 0x79, 0x13, 0xfc, 0x4d, 0xff, 0x5a, 0xab, 0xe3, 0xdd, 0x4a, 0x97, 0xf1, 0x0f, 0x7b, 0xa9, 0x35, 0xcd, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00};
test x;
char q = 0x12;
int v = 0x1234abcd;
int i, n;
x.a = 0x12ab34cd;
x.b = 0x98ef76af;
printf ("\nNormal : x.a = %x x.b = %x", x.a, x.b);
reverse_endian (&x, sizeof (x));
printf ("\nReverse: x.a = %x x.b = %x", x.a, x.b);
printf ("\nNormal : q = %x", q);
reverse_endian (&q, sizeof (q));
printf ("\nReverse: q = %x", q);
printf ("\nNormal : q = %x", v);
reverse_endian (&v, sizeof (v));
printf ("\nReverse: q = %x", v);
printf ("\nNormal : str1 = %s", str1);
/* minus 1 to avoid the trailing nul character */
reverse_endian (str1, sizeof (str1) - 1);
printf ("\nReverse: str1 = %s", str1);
printf ("\nNormal : str2 = %s", str2);
/* minus 1 to avoid the trailing nul character */
reverse_endian (str2, sizeof (str2) - 1);
printf ("\nReverse: str2 = %s", str2);
printf ("\nNormal : str3 = ");
n = sizeof (str3);
for (i=0; i < n; i++)
{
printf ("%x", (str3[i]>>4)&0x0f);
printf ("%x", str3[i]&0x0f);
}
reverse_endian (str3, sizeof (str3));
printf ("\nReversed: str3 = ");
for (i=0; i < n; i++)
{
printf ("%x", (str3[i]>>4)&0x0f);
printf ("%x", str3[i]&0x0f);
}
printf ("\n");
return 0;
}
Output
Normal : x.a = 12ab34cd x.b = 98ef76af
Reverse: x.a = af76ef98 x.b = cd34ab12
Normal : q = 12
Reverse: q = 12
Normal : q = 1234abcd
Reverse: q = cdab3412
Normal : str1 = c1eb044f0708015b267913fc4dff5aabe3dd4a97f10f7ba935cd360000000000
Reverse: str1 = 000000000063dc539ab7f01f79a4dd3ebaa5ffd4cf319762b5108070f440be1c
Normal : str2 = hellio
Reverse: str2 = oilleh
Normal : str3 = c1eb044f0708015b267913fc4dff5aabe3dd4a97f10f7ba935cd360000000000
Reversed: str3 = 000000000036cd35a97b0ff1974adde3ab5aff4dfc1379265b0108074f04ebc1
Note that the strings str1, str2 are simply reversed, because each character of the string is one byte. The same character string you have provided is represented as byte string in str3. Its hex values are shown as output. The operations for all the data are identical, as it is only concerned to memory byte ordering.

Related

Cast uint8_t to hex string (2 digits)

I'm currently using the following to print uint8_t to hex:
for(int j = 0; j < len; j++) {
printf("%02X ", bytes[j]);
}
Is it possible to do this without a for-loop and simply assign the result to a variable?
Here's one simple way:
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
bool to_hex(char* dest, size_t dest_len, const uint8_t* values, size_t val_len) {
if(dest_len < (val_len*2+1)) /* check that dest is large enough */
return false;
*dest = '\0'; /* in case val_len==0 */
while(val_len--) {
/* sprintf directly to where dest points */
sprintf(dest, "%02X", *values);
dest += 2;
++values;
}
return true;
}
int main() {
uint8_t values[256];
char buf[sizeof(values)*2+1]; /* one extra for \0 */
for(size_t i=0; i<256; ++i)
values[i] = i;
if(to_hex(buf, sizeof(buf), values, sizeof(values)))
printf("%s\n", buf);
}
Output:
000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F707172737475767778797A7B7C7D7E7F808182838485868788898A8B8C8D8E8F909192939495969798999A9B9C9D9E9FA0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBFC0C1C2C3C4C5C6C7C8C9CACBCCCDCECFD0D1D2D3D4D5D6D7D8D9DADBDCDDDEDFE0E1E2E3E4E5E6E7E8E9EAEBECEDEEEFF0F1F2F3F4F5F6F7F8F9FAFBFCFDFEFF
For completeness, here's a self contained version using a lookup table instead of sprintf:
bool to_hex(char* dest, size_t dest_len, const uint8_t* values, size_t val_len) {
static const char hex_table[] = "0123456789ABCDEF";
if(dest_len < (val_len*2+1)) /* check that dest is large enough */
return false;
while(val_len--) {
/* shift down the top nibble and pick a char from the hex_table */
*dest++ = hex_table[*values >> 4];
/* extract the bottom nibble and pick a char from the hex_table */
*dest++ = hex_table[*values++ & 0xF];
}
*dest = 0;
return true;
}
Personally, I'd go for the sprintf approach, but if you badly do not want to use one of the library api, you could use something like this:
char HexLookUp[] = "0123456789abcdef";
void bytes2hex (unsigned char *src, char *out, int len)
{
while(len--)
{
*out++ = HexLookUp[*src >> 4];
*out++ = HexLookUp[*src & 0x0F];
src++;
}
*out = 0;
}
Test code:
int main(void)
{
unsigned char bytes[] = {0x00, 0x01, 0x02, 0x03, 0xDE, 0xAD, 0xBE, 0xEF, 0xCC};
char buffer[sizeof(bytes)*2 + 1];
bytes2hex(bytes, buffer, sizeof(bytes));
printf("%s\n",buffer);
return 0;
}
Output:
00010203deadbeefcc

triple des cbc encryption in C

How I can decrypt by DES_ENCRYPT in c using openssl library.
I found the following function to decrypt and it worked fine when the lengh of key is 8 byte! But when I use 16 byte key, it results wrong value!
int CBC_3Des_Decrypt(char *data, char *okey)
{
DES_key_schedule ks;
DES_cblock ivec = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
int i = 0;
int len = 0;
int nlen = 0;
unsigned char ch = '\0';
unsigned char *ptr = NULL;
unsigned char src[16] = {0};
unsigned char dst[16] = {0};
unsigned char block[8] = {0};
ptr = hex2bin(okey, strlen(okey), &nlen);
memcpy(block, ptr, 8);
free(ptr);
DES_set_key_unchecked((const_DES_cblock*)block, &ks);
len = strlen((char *)data);
ptr = hex2bin(data, len, &nlen);
len = (nlen / 8 + (nlen % 8 ? 1: 0)) * 8;
memcpy(src, ptr, len);
free(ptr);
ch = 8 - nlen % 8;
memset(src + nlen, ch, 8 - nlen % 8);
for (i = 0; i < len; i++) {
TRACE(("%.2X", *(src + i)));
}
DES_ncbc_encrypt(src, dst, sizeof(src), &ks, &ivec, DES_DECRYPT);
for (i = 0; i < len; i++) {
TRACE(("%.2X", *(dst + i)));
}
return 0;
}
How I can decrypt or encrypt using this library with 16 byte key?
The call you're making (DES_ncbc_encrypt) is the DES algorithm, not 3DES. I suspect you meant to call DES_ede3_cbc_encrypt.
It's important not to confuse DES and 3DES ("triple DES"). They're related algorithms, but not the same. Inside of OpenSSL, 3DES is generally called EDE3. EDE3 is a specific way of implementing Triple DES (and is the one everyone uses, so in practice they're generally synonymous).

Error calculating CRC16 for certain characters in C

I am trying to use this code to compute CRC16 bypass. For regular characters it works but for a hex sequence like 0xA0 0x00 0x01 0x01 it fails, not returning the correct value. Go easy on me, usually I do not write C code.
#include <stdio.h>
#include <string.h>
unsigned short CalculateCRC(unsigned char* a_szBuffuer, short a_sBufferLen){
unsigned short usCRC = 0;
for (short j = 0; j < a_sBufferLen; j++)
{
unsigned char* pucPtr = (unsigned char *)&usCRC;
*(pucPtr + 1) = *(pucPtr + 1) ^ *a_szBuffuer++;
for (short i = 0; i <= 7; i++)
{
if (usCRC & ((unsigned short) 0x8000))
{
usCRC = usCRC << 1;
usCRC = usCRC ^ ((unsigned short) 0x8005);
}
else
usCRC = usCRC << 1;
}
}
return (usCRC);
}
void append(char* s, char c)
{
int len = strlen(s);
s[len] = c;
s[len+1] = '\0';
}
int main() {
char d = (char)0xA0;
char d1 = (char)0x00;
char d2 = (char)0x01;
char d3 = (char)0x01;
char sss[256]="";
append(sss, d);
append(sss, d1);
append(sss, d2);
append(sss, d3);
unsigned char* uCB1 = (unsigned char*)sss;
unsigned short CRC= CalculateCRC(uCB1,4);
printf("CRC = %i\n", CRC);
printf("%s\n", sss);
printf("%x\n", CRC);
}
strlen(s); is for finding the length of a string, not for finding the length of a character array that is used, especially if it that may contain '\0'. #Eugene Sh.
Code needs to keep track of the array size used with another variable.
// void append(char* s, char c) {
void append(char* s, size_t *sz, char c) {
s[*sz] = c;
(*sz)++;
}
...
size_t size = 0;
append(sss, &size, d);
append(sss, &size, d1);
append(sss, &size, d2);
append(sss, &size, d3);
unsigned char* uCB1 = (unsigned char*)sss;
unsigned short CRC= CalculateCRC(uCB1, size);
// printf("%s\n", sss);
write a loop to print each `sss[]`.

Reading char array containing Hex values in C

This is part of a program that I use to decrypt AES in C. The program is supposed to take in an IV from an external file, read it then set as the IV. Unfortunately the IV is declared as a char array in the code (which I cannot change) so what I tried to do is to read the external file as byte[], then convert it to char[].
One of the issues I am currently facing is regarding the AES_IV variable as seen below:
#define AES_BLOCK_SIZE 0x10
char AES_IV[AES_BLOCK_SIZE] = {0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,0xAA,0xBB,0xCC,0xDD,0xEE,0xFF};
When I try to print out the AES_IV using the code
printf("\nAES_IV: ");
for (i3 = 0; i3 < AES_BLOCK_SIZE; i3++) {
printf("%02x", AES_IV[i3]);
}
printf("\n");
The output is:
AES_IV: 0c0a513398f1eda13ed2fc7213b50b10
Which is different from the AES_IV I declared.
I changed the for loop to
for (i3 = 0; i3 < 50; i3++) {
and the resultant output is much longer
AES_IV: 0c0a513398f1eda13ed2fc7213b50b105369a...(100 chars in total)
I checked the length of AES_IV and it is still 16, but why does my for loop returns such a long result? Also why did the value of AES_IV change? I have checked and there are no reference to AES_IV anywhere before this part.
Your help is much appreciated.
Source code for reference:
#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
#include <dlfcn.h>
#include "SmartSDLib.h"
#define SDCARD_PATH "/boot"
#define P1_INDEX 2
#define P2_INDEX 3
#define P3_INDEX 4
#define AES_BLOCK_SIZE 0x10
#define APDU_HEADER_SIZE 5
#define FILELEN 32 // For reading IV from file
void To_Hex(char s8Data[],char hexBuffer[], int offset, int nlen)
{
int j;
int nSize = (nlen - offset);
char finalhash[8192];
char hexval [] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
for(j=0 ; j < nSize; j++)
{
finalhash[j*2] = hexval[(s8Data[j] >> 4) & 0xF];
finalhash[(j*2) + 1] = hexval[s8Data[j] & 0x0F];
}
memset(hexBuffer,0x00,8192);
memcpy(hexBuffer, finalhash, nSize*2);
}
char * AccessAPDU(char command[], int size)
{
unsigned char u8Ret;
int s32Len[1];
char s8Buffer[512], hexBuffer[8192];
To_Hex(command, hexBuffer, 0, size);
//printf ("%s\n%s%s\n", "AccessAPDUCommand:","CMD:" , hexBuffer);
u8Ret = OT_SmartSDCard_AccessAPDUCommand(size, command, s32Len, s8Buffer, 0);
if(u8Ret == 0x00)
{
printResult(s32Len, s8Buffer);
}
else
{
printf ("%s%x\n\n", "Error 0x", u8Ret);
}
return s8Buffer;
}
void printResult (int s32Len[], char s8Buffer[])
{
char hexBuffer[8192];
if(s32Len[0] >= 2)
{
To_Hex(s8Buffer, hexBuffer, 0, s32Len[0]);
// printf ("%s%s\n", "Ret:", hexBuffer);
// printf ("%s%d\n\n", "Len: ", s32Len[0]);
}
else
{
printf ("%s%d\n", "Len: ", s32Len[0]);
}
}
void CopyBuffer(char Dest[], char Source[], unsigned int length){
while(length){
Dest[length - 1] = Source[length - 1];
length--;
}
}
int ascii_to_hex(char c) // For reading IV from file
{
int num = (int) c;
if(num < 58 && num > 47) // Handle numbers (0-9)
{
return num - 48;
}
if(num < 103 && num > 96) // Handle lowercase alphabets (a-f)
{
return num - 87;
}
if(num < 71 && num > 64) // Handle uppercase alphabets (A-F)
{
return num - 55;
}
return num;
}
int main()
{
unsigned char u8Ret;
char SDCard_Path[64];
char line[64];
int s32Len[1];
char s8Buffer[512], hexBuffer[8192];
int exit = 1;
int iChoice;
char * response;
int test;
char testchar[32];
bool flag = true;
char fileName[100];
char encrypted[100];
char decrypted[100];
int i;
int j;
int blockCounter = 0;
int commandCounter = 0;
char imageBuffer[1];
/* APDU commands */
char AES_encrypt_cmd[APDU_HEADER_SIZE + AES_BLOCK_SIZE] = {0x80, 0x2A, 0x01,0x00, AES_BLOCK_SIZE}; //encryption APDU
char AES_decrypt_cmd[APDU_HEADER_SIZE + AES_BLOCK_SIZE] = {0x80, 0x2A, 0x02,0x00, AES_BLOCK_SIZE}; //decryption APDU
char GetResponse_cmd[] = {0x00, 0xC0, 0x00,0x00, 0x00}; //Le to be changed before use
char SelectAESapplet_cmd[] = {0x00, 0xA4, 0x04,0x00, 0x10, 0xA0, 0x00, 0x00, 0x00, 0x77, 0x01, 0x03, 0x03, 0x00, 0x00, 0x00, 0xF1, 0x00, 0x00, 0x00, 0x04};
//char PutKeyAES_cmd[] = {0x80, 0xD8, 0x00,0xF8, 0x20, 0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,0xAA,0xBB,0xCC,0xDD,0xEE,0xFF,0xFF,0xEE,0xDD,0xCC,0xBB,0xAA,0x99,0x88,0x77,0x66,0x55,0x44,0x33,0x22,0x11,0x00};
char PutKeyAES_cmd[] = {0x80, 0xD8, 0x00,0xF8, 0x20, 0xCF,0x10,0xF9,0xBD,0xF6,0xAA,0x15,0xC5,0x0E,0xCD,0x79,0xE6,0x28,0x3D,0xA8,0x0A,0x79,0x7A,0x2D,0x27,0x03,0xAE,0x07,0xD5,0x2F,0x5D,0x8F,0x60,0x1F,0x1E,0xF2,0x6F};
/* AES variables */
int AES_keyIndex = 0;
char AES_IV[AES_BLOCK_SIZE] = {0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,0xAA,0xBB,0xCC,0xDD,0xEE,0xFF};
//char AES_IV[AES_BLOCK_SIZE] = {0x12,0xFB,0x87,0x11,0x62,0x7E,0xBB,0x55,0x71,0x7B,0x2F,0x70,0xA4,0x97,0x55,0x7B};
//char AES_IV[AES_BLOCK_SIZE];
char AES_CBC_vector[AES_BLOCK_SIZE];
char AES_cmdBuffer[APDU_HEADER_SIZE + AES_BLOCK_SIZE];
FILE * rFile;
FILE * wFile;
FILE *fileptr;char *buffer;long filelen;int i2,i3,i4;char IV_temp[AES_BLOCK_SIZE]; // This line for the file --> byte --> Hex
printf ("%s\n", "This program will run 1, 2 followed by 6");
// case 1 :
printf ("%s\n", "Initializing: ");
u8Ret = OT_SmartSDCard_Initialization(SDCARD_PATH);
if(u8Ret == 0x00)
printf ("%s\n\n", "Initialization OK");
else
printf ("%s%x\n\n", "Initialization: Error 0x",u8Ret);
// printf ("%s\n\n", "-------------------------------------");
/* ATR */
u8Ret = OT_SmartSDCard_Reset(s32Len, s8Buffer);
if(u8Ret == 0x00)
{
To_Hex(s8Buffer,hexBuffer, 0, s32Len[0]);
// printf ("%s%s\n", "ATR : ", hexBuffer);
// printf ("%s%d\n\n", "Len : ", s32Len[0]);
}
else
printf ("%s%x\n\n", "Reset: Error 0x",u8Ret);
// printf ("%s\n\n", "-------------------------------------");
/* Select AES applet */
printf("%s\n", "Selecting AES applet...");
response = AccessAPDU(SelectAESapplet_cmd, sizeof(SelectAESapplet_cmd));
if(response[0] == 0x61){
GetResponse_cmd[P3_INDEX] = response[1];
AccessAPDU(GetResponse_cmd, sizeof(GetResponse_cmd));
}
// printf ("%s\n\n", "-------------------------------------");
// case 2 :
printf("Putting key...");
AES_keyIndex = 0;
memset(line, 0x00, sizeof(line));
PutKeyAES_cmd[2] = AES_keyIndex;
printf("putting key on index %d\n", AES_keyIndex);
response = AccessAPDU(PutKeyAES_cmd, sizeof(PutKeyAES_cmd));
AES_encrypt_cmd[P2_INDEX] = AES_keyIndex;
AES_decrypt_cmd[P2_INDEX] = AES_keyIndex;
// printf ("%s\n\n", "-------------------------------------");
// case 6 :
printf ("Decrypting in CBC...");
// printf ("File Name: /home/pi/test_encrypted\n");
// printf ("Encrypted File Name: /home/pi/test_decrypted\n");
rFile = fopen("/home/pi/test_encrypted","rb");
wFile = fopen("/home/pi/test_decrypted","wb");
////////////////////////////////////////////////////////////////
// This part to read rFile and store as a byte [WORKING!]
fseek(rFile, 0, SEEK_END); // Jump to the end of the file
filelen = ftell(rFile); // Get the current byte offset in the file
rewind(rFile); // Jump back to the beginning of the file
buffer = (char *)malloc((filelen+1)*sizeof(char)); // Enough memory for file + \0
fread(buffer, filelen, 1, rFile); // Read in the entire file
// This part to convert buffer to hex value [WORKING!]
for (i2 = 0; i2 < 100; i2++)
{
if (i2 > 0) printf(" ");
printf("%02X", buffer[i2]);
IV_temp[i2] = buffer[i2];
}
// This part to print stuff [AES_IV not printing out correctly]
printf("\nAES_IV: ");
//fwrite(AES_IV, 1, sizeof(AES_IV), stdout);
for (i3 = 0; i3 < 50; i3++) {
printf("%02x", AES_IV[i3]);
}
printf("\n");
/*
printf("IV_temp: ");
for (i4 = 0; i4 < AES_BLOCK_SIZE; i4++) {
printf("%02x", IV_temp[i4]);
}
printf("\n");
*/
for (i3 = 0; i3 < AES_BLOCK_SIZE; i3++) {
AES_IV[i3] = IV_temp[i3];
}
printf("\nLength of AES_IV = %d\n", sizeof(AES_IV));
printf("\nAES_IV: ");
for (i3 = 0; i3 < 50; i3++) {
printf("%02x", AES_IV[i3]);
}
printf("\n");
// Return the file pointer to start of file
rewind(rFile);
////////////////////////////////////////////////////////////////
if (rFile == NULL || wFile == NULL)
perror("Error opening File");
else{
int IsEOF = false;
// Initialize the CBC block with IV
CopyBuffer(AES_CBC_vector, AES_IV, AES_BLOCK_SIZE);
while (IsEOF == false) {
i = 0;
while(i < AES_BLOCK_SIZE){ // i run from 0 to (AES_BLOCK_SIZE - 1)
AES_cmdBuffer[APDU_HEADER_SIZE + i] = fgetc(rFile);
if(feof(rFile)) {
IsEOF = true;
if(i == 0) { // break out of while loop if a new block is not yet in progress
break;
} else { // continue to finish the block and pad with zeros
AES_cmdBuffer[APDU_HEADER_SIZE + i] = 0x00; //padding
}
}
i++;
}
if(i == 0) break; //break out of while loop, nothing to send to card
// Fill in the APDU header
CopyBuffer(AES_cmdBuffer, AES_decrypt_cmd, APDU_HEADER_SIZE);
response = AccessAPDU(AES_cmdBuffer, sizeof(AES_cmdBuffer));
if(response[0] == 0x61){
if(response[1] != AES_BLOCK_SIZE) {
perror("Card returning wrong block size");
}
GetResponse_cmd[P3_INDEX] = AES_BLOCK_SIZE;
response = AccessAPDU(GetResponse_cmd, sizeof(GetResponse_cmd));
/* CBC mode */
for(i = 0; i < AES_BLOCK_SIZE; i++){
response[i] ^= AES_CBC_vector[i];
}
fwrite(response, sizeof(char), AES_BLOCK_SIZE, wFile);
// Take the ciphertext to perform XOR next time
CopyBuffer(AES_CBC_vector, &AES_cmdBuffer[APDU_HEADER_SIZE], AES_BLOCK_SIZE);
} else {
perror("Error decrypting file using the smart card");
}
}
}
fclose (rFile);
fclose (wFile);
// printf ("%s\n\n", "-------------------------------------");
return 0;
}
As one comment already stated you should use unsigned char otherwise each element is treated as a signed char by default. Better yet you might want to use fixed-width uint8_t from #include <stdint.h> instead.
Here is a minimal example that works as expected:
#include <stdint.h>
#include <stdio.h>
#define AES_BLOCK_SIZE 0x10
uint8_t AES_IV[AES_BLOCK_SIZE] = {0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,0xAA,0xBB,0xCC,0xDD,0xEE,0xFF};
int
main( void )
{
int i;
for ( i = 0; i < sizeof(AES_IV); i++ ) {
printf( "%02x", AES_IV[i] );
}
return 0;
}

string concatenation with "\x" hex character escape

How do I create a string that contain multiple '\x41' or with arbitrary '\xnn' by copy from some give string for example:
char * string1 = "4141414141414141";
or char * string2 = "bde54d7ee10a2122";
And I would like my char * string3 become something like:
char * string3 = "\xbd\xe5\x4d\x7e\xe1\x0a\x21\x22";
or char * string3 = "\x41\x41\x41\x41\x41\x41\x41\x41";
Here is the code that I am trying to do, but it doesn't work.
char * string1 = "4141414141414141";
char c;
char * slash_x = "\\x";
int len = strlen(string1);
char * string3 = (char *) malloc(9);
for (i = 0; i < len; i++) {
if (0 == i % 2) {
printf("start\n");
j = i;
strcat(salt_empty, slash_x);
c = string[j];
printf("%c\n", c);
strncat(salt_empty, &c, 1);
j++;
c = string[j];
printf("%c\n", c);
strncat(salt_empty, &c, 1);
}
}
printf("%s\n", string3);
So the output with string3 will be "\x41\x41\x41\x41\x41\x41\x41\x41" instead of "AAAAAAAA" at console.
How could I fix the code in order to get "AAAAAAAA"
If the string1 is "bde54d7ee10a2122", then the string3 output at console would be ��M~
!"
You cannot convert the string by re-interpreting it from its source form. Use this instead (inefficient, but simple):
char *string1 = "4141414141414141";
int i, j, len = strlen(string1) & ~1;
char string3[len / 2 + 1];
for (i = j = 0; i < len; i += 2, j++) {
char buf[3];
memcpy(buf, string1 + i, 2);
buf[2] = '\0';
string3[j] = strtol(buf, NULL, 16);
}
string3[j] = '\0';
printf("%s\n", string3);
You want:
char string1[] = {0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0};
For each pair of characters in the source string, determine the hex value of each character in the pair, combine them to come up with the encoded character, then store the result in your destination string.

Resources