Related
I just began to understand the embedded world (after Arduino, RPi, etc) with the STM32F103 and FreeRTOS + Libopencm3. My first challenge is to interface a DS18B20, temperature sensor with my microprocessor. The 1-Wire bus is quite easy to understand but not native supported so I followed your advised and go for 1-wire over UART with DMA.
DS18B20 has DATA on USART2TX (+4k7 pullup + diode) and USART2RX, VCC to 5V and GND.
Initialization of 1-Wire :
static void ow_init(void)
{
// One-Wire
// Already done : rcc_periph_clock_enable(RCC_GPIOA);
gpio_set_mode(GPIOA, GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_ALTFN_PUSHPULL, GPIO_USART2_TX);
gpio_set_mode(GPIOA, GPIO_MODE_INPUT, GPIO_CNF_INPUT_FLOAT, GPIO_USART2_RX);
usart_set_baudrate(USART2, 115200);
usart_set_databits(USART2, 8);
usart_set_stopbits(USART2, USART_STOPBITS_1);
usart_set_mode(USART2, USART_MODE_TX);
usart_set_parity(USART2, USART_PARITY_NONE);
usart_set_flow_control(USART2, USART_FLOWCONTROL_NONE);
usart_enable(USART2);
rcc_periph_clock_enable(RCC_DMA1);
}
1-Wire Reset :
uint8_t ow_reset(void)
{
usart_disable_rx_dma(USART2);
usart_disable_tx_dma(USART2);
usart_set_baudrate(USART2, 9600);
usart_set_databits(USART2, 8);
usart_set_stopbits(USART2, USART_STOPBITS_1);
usart_set_mode(USART2, USART_MODE_TX);
usart_set_parity(USART2, USART_PARITY_NONE);
usart_set_flow_control(USART2, USART_FLOWCONTROL_NONE);
usart_send(USART2, 0xf0);
while(usart_get_flag(USART2, USART_SR_TC));
uint8_t ow_presence;
ow_presence = usart_recv(USART2);
usart_set_baudrate(USART2, 115200);
usart_set_databits(USART2, 8);
usart_set_stopbits(USART2, USART_STOPBITS_1);
usart_set_mode(USART2, USART_MODE_TX_RX);
usart_set_parity(USART2, USART_PARITY_NONE);
usart_set_flow_control(USART2, USART_FLOWCONTROL_NONE);
if(ow_presence != 0xf0)
{
return 1;
}
return 0;
}
Getting the scratchpad with :
void ow_convert_to_scratchpad(void)
{
const uint8_t convert_T[] = {0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, // 0xCC
0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00}; // 0x44
dma_channel_reset(DMA1, DMA_CHANNEL7);
dma_set_peripheral_address(DMA1, DMA_CHANNEL7, (uint32_t)&USART2_DR);
dma_set_memory_address(DMA1, DMA_CHANNEL7, (uint32_t) convert_T);
dma_set_number_of_data(DMA1, DMA_CHANNEL7, sizeof(convert_T));
dma_disable_peripheral_increment_mode(DMA1, DMA_CHANNEL7);
dma_enable_memory_increment_mode(DMA1, DMA_CHANNEL7);
dma_set_peripheral_size(DMA1, DMA_CHANNEL7, DMA_CCR_PSIZE_8BIT);
dma_set_memory_size(DMA1, DMA_CHANNEL7, DMA_CCR_MSIZE_8BIT);
dma_set_priority(DMA1, DMA_CHANNEL7, DMA_CCR_PL_LOW);
dma_enable_channel(DMA1, DMA_CHANNEL7);
usart_enable_tx_dma(USART2);
}
uint16_t ow_get_scratchpad(void)
{
const uint8_t read_scratch[] = {0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, // 0xCC
0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, // 0xBE
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
uint8_t buf[8];
dma_channel_reset(DMA1, DMA_CHANNEL6);
dma_set_peripheral_address(DMA1, DMA_CHANNEL6, (uint32_t)&USART2_DR);
dma_set_memory_address(DMA1, DMA_CHANNEL6, (uint32_t) buf);
dma_set_read_from_peripheral(DMA1, DMA_CHANNEL6);
dma_set_number_of_data(DMA1, DMA_CHANNEL6, sizeof(read_scratch));
dma_disable_peripheral_increment_mode(DMA1, DMA_CHANNEL6);
dma_enable_memory_increment_mode(DMA1, DMA_CHANNEL6);
dma_set_peripheral_size(DMA1, DMA_CHANNEL6, DMA_CCR_PSIZE_8BIT);
dma_set_memory_size(DMA1, DMA_CHANNEL6, DMA_CCR_MSIZE_8BIT);
dma_set_priority(DMA1, DMA_CHANNEL6, DMA_CCR_PL_LOW);
dma_channel_reset(DMA1, DMA_CHANNEL7);
dma_set_peripheral_address(DMA1, DMA_CHANNEL7, (uint32_t)&USART2_DR);
dma_set_memory_address(DMA1, DMA_CHANNEL7, (uint32_t) read_scratch);
dma_set_number_of_data(DMA1, DMA_CHANNEL7, sizeof(read_scratch));
dma_set_read_from_peripheral(DMA1, DMA_CHANNEL6);
dma_disable_peripheral_increment_mode(DMA1, DMA_CHANNEL7);
dma_enable_memory_increment_mode(DMA1, DMA_CHANNEL7);
dma_set_peripheral_size(DMA1, DMA_CHANNEL7, DMA_CCR_PSIZE_8BIT);
dma_set_memory_size(DMA1, DMA_CHANNEL7, DMA_CCR_MSIZE_8BIT);
dma_set_priority(DMA1, DMA_CHANNEL7, DMA_CCR_PL_LOW);
dma_enable_channel(DMA1, DMA_CHANNEL6);
dma_enable_channel(DMA1, DMA_CHANNEL7);
usart_enable_tx_dma(USART2);
usart_enable_rx_dma(USART2);
while(dma_get_interrupt_flag(DMA1, DMA_CHANNEL6, DMA_TCIF));
uint16_t tt = 0;
for(int i=0;i<32; i++)
{
uart1_printf("Bit : %d \n\r", buf[i]);
if(buf[i] == 0xff)
{
tt = (tt >> 1) | 0x8000;
}
else
{
tt = tt >> 1;
}
}
return tt;
}
static void demo_task(void *args)
{
(void)args;
for (;;) {
uart1_printf("Hello\n\r");
uint8_t p = ow_reset();
uart1_printf("presence = %d\n\r", p);
ow_convert_to_scratchpad();
for(int i=0; i<5000000; i++)
{
__asm__("nop");
}
ow_reset();
uint16_t t = ow_get_scratchpad();
uart1_printf("t = %d \n\r", t);
vTaskDelay(pdMS_TO_TICKS(500));
}
}
And finally the task that tries to reach the DS18B20
static void demo_task(void *args)
{
(void)args;
for (;;) {
ow_reset();
ow_convert_to_scratchpad();
vTaskDelay(pdMS_TO_TICKS(500));
ow_reset();
uint16_t t = ow_get_scratchpad();
uart1_printf("t = %d \n\r", t);
vTaskDelay(pdMS_TO_TICKS(500));
}
}
I receive some bits as 0xCC, 0xBE, 0xFF but no more answer.
Ok, so
rcc_periph_clock_enable(RCC_USART2);
was missing so USART2 can't do its job. I can send and receive data now.
The reset function works except this line (it wait indefinitely) :
while(usart_get_flag(USART2, USART_SR_TC));
I don't understand why this flag is not true when the transmission is complete... But I have 0x00 on RX line so I think the sensor is responding (I hope...)
My function ow_convert_to_scratchpad with DMA looks like being blocking. I don"t know why...
I just tried (for fun...) to replace the whole DMA by hardcoding the sent of 0xCC, 0x44, 0xCC, 0xBE and the read but no answer (0x00) from the sensors.
I am kind of late to the party, but... Have you tried something a bit less convoluted first? (Simpler to check I mean)
Like asking a single DS18B20 its address?
Reset bus and check presence.
Send search ROM cmd (write byte 0xF0)
loop 64 times reading address bits from LSB to MSB {
read bit i
read bit i complement
check they are 1 and 0 or the other way around
send bit i back to device so it sends you back the next bit
}
At the end you have the 8 byte of the device address. 1 byte family 0x28 48 bit address 1 byte CRC8 to check the whole thing is correct.
I've been trying to use the AES CTR 128 from tiny-aes-c (https://github.com/kokke/tiny-AES-c) to encrypt a randomly generated token, and it works, but not all the time. In some cases the retrieved string after encrypting and decrypting is cut off at some point. Here's the code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "token_auth.h"
#include "aes.h"
uint8_t * create_token() {
static char charset[] = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
uint8_t *token = malloc(sizeof(uint8_t) * (TOKEN_LENGTH + 1));
int i = 0;
srand ( time(NULL) );
for (i = 0; i < TOKEN_LENGTH; i++) {
int pos = rand() % (int)(strlen(charset) - 1);
token[i] = (int) charset[pos] - 0;
}
token[TOKEN_LENGTH] = 0;
return token;
}
int main() {
uint8_t key[16] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F };
uint8_t iv[16] = { 0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00 };
uint8_t *in = create_token();
printf("\nInput: %s\nSize: %d", (char *) in, strlen((char *) in));
struct AES_ctx ctx;
AES_init_ctx_iv(&ctx, key, iv);
AES_CTR_xcrypt_buffer(&ctx, in, strlen((char *) in));
AES_init_ctx_iv(&ctx, key, iv);
AES_CTR_xcrypt_buffer(&ctx, in, strlen((char *) in));
printf("\nDEC: %s\n", (char *) in);
return 0;
}
TOKEN_LENGTH is 128. As an example of the behavior, the string NM5DlWyYInbeNtEWhBxGCdEjHSv2I6FzTMffJNgudrL2UsYe6zVJMA3wvAyhHeQD18UMXckcF8gBAfPGQNqGqwdW9MgS39w7huVfIgtoqJ212SKSIdBaJP9VErOJAmQT comes out NM5DlWyYInbeNtEWhBxGCdEjHSv2 after being encrypted and decrypted. I'm not really good at C, so it might just well be a problem with something else I've done, but at this point I'm lost. Any ideas? Thanks in advance.
The first call to AES_CTR_xcrypt_buffer encrypts the buffer in place in CTR mode.
The buffer still has the same size (128 in your case), but can contain NUL bytes.
The strlen call in the second call of AES_CTR_xcrypt_buffer for decryption can therefore result in a length < 128 if the buffer contains a NUL byte.
By the way: It works in cases where the encryption does not result in a NUL byte in the buffer.
So if you call it with TOKEN_LENGTH as the length parameter decryption will give the original string again:
AES_CTR_xcrypt_buffer(&ctx, in, TOKEN_LENGTH);
I'm using an online CRC-32 calculator to check that my output is correct however it seems that Wireshark has a different expected FCS for the ethernet packet.
message2 is the ethernet frame minus the FCS as seen in Wireshark
#include <stdio.h>
#include <stdint.h>
unsigned int crc32b(unsigned char *message) {
int i, j;
unsigned int byte, crc, mask;
i = 0;
crc = 0xFFFFFFFF;
while (message[i] != 0) {
//printf("%i %x \n\n", i, message[i]);
byte = message[i];
crc = crc ^ byte;
for (j = 7; j >= 0; j--) {
mask = -(crc & 1);
crc = (crc >> 1) ^ (0xEDB88320 & mask);
}
i = i + 1;
}
return ~crc;
}
int main(void)
{
unsigned char * message = "hello test";
unsigned char * message2 = "aabbccddeeff5cb9017c5a53080000000000000000000000000000";
unsigned int res = crc32b(message2);
printf("%x\n", res);
return 0;
}
I've tried using different Polynomials as defined in [1 - subsection CRC-32 IEEE 802.3], however the result does not match Wireshark.
Output using 0xED Polynomial: 0xd81e4af3
Wireshark FCS expected: 0xa8cd3084
I'd really like to code in the FCS for my ethhdr packet, I guess when creating a software packet, the FCS isn't entered by the NIC...
Sources:
[1] - http://crppit.epfl.ch/documentation/Hash_Function/WiKi/Cyclic_redundancy_check.htm
Your implementation is definitively correct (for NUL terminated C strings). It's a maybe a wrong configuration of the network interface. In default mode Wireshark doesn't get a FCS from the network driver. If you use Linux and the driver supports this, then you must enable this with ethtool to get the FCS.
Unfortunately, on my system this only works for receiving frames:
$ ethtool -K eth0 rx-fcs on
See this for details.
I use a slightly different algorithm in my embedded (for AVR microcontrollers) projects and it works perfectly for me:
#define CRC_POLY 0xEDB88320
uint32_t crc32_calc(uint8_t *data, int len)
{
int i, j;
uint32_t crc;
if (!data)
return 0;
if (len < 1)
return 0;
crc = 0xFFFFFFFF;
for (j = 0; j < len; j++) {
crc ^= data[j];
for (i = 0; i < 8; i++) {
crc = (crc & 1) ? ((crc >> 1) ^ CRC_POLY) : (crc >> 1);
}
}
return (crc ^ 0xFFFFFFFF);
}
A real world example:
The Ethernet frame in Wireshark (with ethtool rx-fcs on):
The test with my used implementation:
uint8_t frame[] = { 0x20, 0xcf, 0x30, 0x1a, 0xce, 0xa1, 0x62, 0x38,
0xe0, 0xc2, 0xbd, 0x30, 0x08, 0x06, 0x00, 0x01,
0x08, 0x00 ,0x06 ,0x04 ,0x00 ,0x01 ,0x62 ,0x38,
0xe0 ,0xc2 ,0xbd ,0x30 ,0x0a, 0x2a, 0x2a, 0x01,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x2a,
0x2a, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00 };
printf("0x%x\n", crc32_calc(frame, sizeof(frame)));
The output:
$ ./fcs-test
0x6026b722
$
You can see, Wireshark reports 0x22bf2660 as correct FCS. Here is only a different output because of the byte-order. But the CRC calculation algorithm is correct.
EDIT:
I have modified your code:
uint32_t crc32b(uint8_t *message, int len) {
int i, j;
uint32_t crc, mask;
uint8_t byte;
crc = 0xFFFFFFFF;
for (j = 0; j < len; j++) {
byte = message[j];
crc = crc ^ byte;
for (i = 7; i >= 0; i--) {
mask = -(crc & 1);
crc = (crc >> 1) ^ (0xEDB88320 & mask);
}
}
return ~crc;
}
I added a length argument, because your implementation only works correct when message is a NUL terminated C string. If your input is a byte array, then you get a incorrect CRC value.
See the differences (Array and C string):
uint8_t msg_arr[] = { 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x5c, 0xb9, 0x01, 0x7c, 0x5a, 0x53, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
char *msg_str = "aabbccddeeff5cb9017c5a53080000000000000000000000000000";
printf("0x%x\n", crc32b(msg_arr, sizeof(msg_arr)));
printf("0x%x\n", crc32b(msg_str, strlen(msg_str)));
Output:
$
0x3422dd71
0xd81e4af3
$
There are a number of problems with your code. There are also plenty of existing implementations you could compare (eg, this one linked from the real Wikipedia page on CRC).
unsigned char * message2 = "aabbccddeeff5cb9017c5a53080000000000000000000000000000";
Are you hoping that this will be the octet sequece 0xAA 0xBB 0xCC ... as you see them in Wireshark? Because that isn't at all what you have.
This string actually contains 0x61 0x61 0x62 0x62 ... (assuming your platform uses ASCII encoding) because it is a character string and not an octet string.
specifically, here: byte = message[i]; you assume the first 8 bits of your message are an octet, and again I assume since you didn't say, that you expected this to be 0xAA. It will actually be 0x61.
If you want this to work correctly, translate each pair of characters into an integer value using strtoul(pair, NULL, 16) or similar.
You have a loop for (j = 7; j >= 0; j--) but never use j inside it. You do use the integer constant 1 in an odd-looking way: is there supposed to be a (1 << j) or something?
I suggest fixing the obvious errors, and then writing some self-contained tests before you try comparing whole frames with Wireshark. The code you posted has some basic errors that should be tested, identified and fixed before you get to this point.
Im not sure about your question, but if you want calculate a checksum of a network packet, you have to deploy the data in it's proper structure.
Please make sure your problem is not related with endianness.
The network byte-order is big-endian, here is the point that the things getting a little bit harder.
Little-Endian mostly used in PCs but may vary by hardware and manufacturer.
2byte integer (16 bit integer) with value 255.
Little Endian: FF00
Big Endian: 00FF
Im not sure what kind of checksum you are trying to match with, but checksum not only for data field, mostly it contains all flags and options, issued at last step thats why the implementation require the corresponding data structure.
About checksums, there are a lot of case when you get an invalid checksum with wireshark, it could cause kernel, virtual adapter, accelerated network, dedicated CPU in your NIC, etc...
Example for TCP header:
/* include/linux/tcp.h */
struct tcphdr {
__u16 source;
__u16 dest;
__u32 seq;
__u32 ack_seq;
#if defined(__LITTLE_ENDIAN_BITFIELD)
__u16 res1:4,
doff:4,
fin:1,
syn:1,
rst:1,
psh:1,
ack:1,
urg:1,
ece:1,
cwr:1;
#elif defined(__BIG_ENDIAN_BITFIELD)
__u16 doff:4,
res1:4,
cwr:1,
ece:1,
urg:1,
ack:1,
psh:1,
rst:1,
syn:1,
fin:1;
#else
#error "Adjust your <asm/byteorder.h> defines"
#endif
__u16 window;
__u16 check;
__u16 urg_ptr;
};
This question already has answers here:
Execute a piece of code from the data-section
(1 answer)
Is it possible to load a binary file into memory and execute it in windows
(2 answers)
How to alloc a executable memory buffer?
(5 answers)
Closed 3 years ago.
I have an array with hexadecimal values representing assembly instructions.
I want to push the HelloWorld array as parameter for printf.
Is (int)&HelloWorld the right way to get the address of my array or is there a better solution?
And how can I call Code[] as a function?
I tried with a function pointer but the program jumps somewhere else in memory and ends up crashing at an invalid instruction.
Here is my code:
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <errno.h>
int main()
{
int HelloWorld[15] =
{
// Hello World
0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x2C, 0x20, 0x57, 0x6F, 0x72, 0x6C, 0x64, 0x00
};
int Code[50] =
{
// PUSH [DWORD PTR] DS:<address of array HelloWorld>
0xFF, 0x35, (int)&HelloWorld,
// CALL <address of function printf>
0xE8, (int)&printf,
// ADD esp, 4
0x83, 0xC4, 0x04,
// RET
0xC3
};
long unsigned int ProtectionCode = 0;
// Change protection to read, write, execute
int ChangeProtect = VirtualProtect(Code, 50, PAGE_EXECUTE_READWRITE,
&ProtectionCode);
if(ChangeProtect == 0)
{
printf("Error: %s\n", strerror(errno));
return 1;
}
void (*CodePtr)() = &Code;
(*CodePtr)();
return 0;
}
Thanks for your help.
This version works fine on my windows:
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <errno.h>
char HelloWorld[15] =
{
// Hello World
0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x2C, 0x20, 0x57, 0x6F, 0x72, 0x6C, 0x64, 0x00
};
void __attribute__((used)) foo(void)
{
int (*p)(const char *, ...) = printf;
p(HelloWorld);
}
int main()
{
unsigned char Code[] ={
0x55,
0x89, 0xe5,
0x83, 0xec, 0x28,
0xc7, 0x45, 0xf4, 0x78, 0x8c, 0x40, 0x00,
0xc7, 0x04, 0x24, 0x04, 0xa0, 0x40, 0x00,
0x8b, 0x45, 0xf4,
0xff, 0xd0,
0x90,
0xc9,
0xc3,
};
long unsigned int ProtectionCode = 0;
// Change protection to read, write, execute
int ChangeProtect = VirtualProtect(Code, 50, PAGE_EXECUTE_READWRITE,
&ProtectionCode);
if(ChangeProtect == 0)
{
printf("Error: %s\n", strerror(errno));
return 1;
}
void (*CodePtr)() = &Code;
(*CodePtr)();
return 0;
}
the foo is just to take the code from :)
I am encrypting 3gpp test data with openssl code in c language in linux platform.
i have taken example from stack over flow and tried.But in the final encryption output zeros's are not displayed.i need to encrypt with 128 bit key.
Thanks in advance.
#include <openssl/aes.h>
#include <openssl/rand.h>
#include <openssl/hmac.h>
#include <openssl/buffer.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#define u32 unsigned int
#define u8 unsigned char
#define bufferSize 16
struct ctr_state
{
unsigned char ivec[AES_BLOCK_SIZE];
unsigned int num;
unsigned char ecount[AES_BLOCK_SIZE];
};
AES_KEY key;
unsigned char indata[AES_BLOCK_SIZE];
unsigned char outdata[AES_BLOCK_SIZE];
unsigned char iv[AES_BLOCK_SIZE];
struct ctr_state state;
int init_ctr(struct ctr_state *state, const unsigned char iv[16])
{
/* aes_ctr128_encrypt requires 'num' and 'ecount' set to zero on the
* first call. */
state->num = 0;
memset(state->ecount, 0, AES_BLOCK_SIZE);
/* Initialise counter in 'ivec' to 0 */
memset(state->ivec + 8, 0, 8);
/* Copy IV into 'ivec' */
memcpy(state->ivec, iv, 8);
}
int main(int argc, char *argv[])
{
u8 key1[16] = {
0xd3,0xc5,0xd5,0x92,0x32,0x7f,0xb1,0x1c,
0x40,0x35,0xc6,0x68,0x0a,0xf8,0xc6,0xd1
};
u8 count[4] ={0x39,0x8a,0x59,0xb4};
u32 tempCount = 0;
u8 bearer = 0x15;
u8 dir =0x01,i;
u32 length = 253 ;
u8 indata[32] = {
0x98, 0x1b, 0xa6, 0x82, 0x4c, 0x1b, 0xfb, 0x1a,
0xb4, 0x85, 0x47, 0x20, 0x29, 0xb7, 0x1d, 0x80,
0x8c, 0xe3, 0x3e, 0x2c, 0xc3, 0xc0, 0xb5, 0xfc,
0x1f, 0x3d, 0xe8, 0xa6, 0xdc, 0x66, 0xb1, 0xf0
};
tempCount = htonl((count[0] | (count[1] << 8) | count[2]<< 16 | count[3] << 24)); /* Jyothi Added */
iv[0] = (tempCount >> 24) & 0xff ;
iv[1] = (tempCount >> 16) & 0xff ;
iv[2] = (tempCount >> 8) & 0xff;
iv[3] = tempCount & 0xff;
iv[4] = htonl((( (bearer << 27) | ((dir & 0x1) << 26))));
iv[5] = iv[6]= iv[7] = 0;
printf("iv=\n");
for(i=0;i<16;i++)
printf("%x",iv[i]);
printf("\n");
printf("key1=\n");
for(i=0;i<16;i++)
printf("%x",key1[i]);
printf("\n");
//Initializing the encryption KEY
if (AES_set_encrypt_key(key1, 128, &key) < 0)
{
fprintf(stderr, "Could not set decryption key.");
exit(1);
}
init_ctr(&state, iv);//Counter call
printf("state.ivec after call=\n");
for(i=0;i<16;i++)
printf("%x",state.ivec[i]);
printf("\n");
printf("indata=\n");
for(i=0;i<32;i++)
printf("%x",indata[i]);
printf("\n");
for(i=1;i<2;i++){
//Encrypting Blocks of 16 bytes
AES_ctr128_encrypt(indata, outdata,253, &key, state.ivec, state.ecount, &state.num);
printf("outdata\n");
for(i=0;i<32;i++)
printf("%x",outdata[i]);
printf("\n");
}
}
i am getting output as below.
iv=
398a59b4ac00000000000
key1=
d3c5d592327fb11c4035c668af8c6d1
state.ivec after call=
398a59b4ac00000000000
indata=
981ba6824c1bfb1ab485472029b71d808ce33e2cc3c0b5fc1f3de8a6dc66b1f0
outdata
e9fed8a63d15534d71df2bf3e82214b2ed7dad2f233dc3c22d7bdeeed8e78
algorithm has to generate key stream as below:
71e57e24 710ea81e 6398b52b da5f3f94 3eede9f6 11328620 231f3f1b 328b3f88
but instead it is generating final encryption output without zero's
final expected output is as below:
e9fed8a6 3d155304 d71df20b f3e82214 b20ed7da d2f233dc 3c22d7bd eeed8e78
Change your printf format string to require that each char is output as two hex digits - currently you're losing leading zeroes.
printf("%02x",outdata[i]);
The zero tells it to pad up to two digits using zeroes, the default would be spaces.