AES 128 with CBC-MAC in C - c

The code showing below is AES with CBC mode implementation. I am very new to the network security aspect. I am wondering how I can add the mac generation function upon the block and makes it as cbc-mac
static void GenerateDecryptionKey(uint8_t *key)
{
CRYCONLbits.CRYON = 0b1; //Turn module on
CRYCONHbits.KEYSRC = 0b000; //Select the key source (CRYKEY)
CRYCONLbits.OPMOD = 0b0010; //Select the operational mode (AES Decryption Key Expansion)
CRYCONLbits.CPHRSEL = 0b1; //Select the cipher (AES)
//(AES decryption key generation)
CRYCONHbits.KEYMOD = 0b00; //Set the key strength (128-bit key)
memcpy((void *)&CRYKEY0, key, 16); //Load the key into CRYKEY
//(128-bit key in this example)
CRYCONLbits.CRYGO = 0b1; //Start the encryption
while (CRYCONLbits.CRYGO == 0b1)
;
}
// For 128-bit key and 128-bit block size
void EncryptBlocks(
CIPHER_MODE mode,
uint8_t *key,
uint8_t *iv,
uint8_t *plaintext,
uint8_t *ciphertext,
int numblocks)
{
CRYCONLbits.CRYON = 1; //Turn module on
CRYCONHbits.KEYSRC = 0b0000; //Select the key source (CRYKEY)
CRYCONLbits.OPMOD = 0b0000; //Select operational mode (Encryption)
CRYCONLbits.CPHRSEL = 1; //Select cipher engine (AES)
CRYCONLbits.CPHRMOD = 0b001 ; //Select encryption mode
CRYCONHbits.KEYMOD = 0; //Set key strength to 128-bit
memcpy((void*)&CRYKEY0, key, 16); //Load the 128-bit key into CRYKEY
memcpy((void*)&CRYTXTB0, iv, 16); //Load the 128-bit initial vector (IV)
int i;
for (i = 0; i < numblocks; i += 16) {
//Load the next plaintext block into CRYTXTA
memcpy((void*)&CRYTXTA0, plaintext+ i, 16);
//Start the encryption
CRYCONLbits.CRYGO = 0b1;
// Wait for completion
while (CRYCONLbits.CRYGO == 0b1)
;
//Read the results out of CRYTXTB
memcpy(ciphertext+i, (void*)&CRYTXTB0, 16);
}
}
// For 128-bit key and 128-bit block size
void DecryptBlocks(
CIPHER_MODE mode,
uint8_t *key,
uint8_t *ciphertext,
uint8_t *plaintext,
int numblocks)
{
GenerateDecryptionKey(key);
CRYCONLbits.CRYON = 1; //Turn module on
CRYCONHbits.KEYSRC = 0b0000; //Select the key source (CRYKEY)
CRYCONLbits.OPMOD = 0b0001; //Select operational mode (Decryption)
CRYCONLbits.CPHRSEL = 1; //Select cipher engine (AES)
CRYCONLbits.CPHRMOD = 0b001; //Select decryption mode (CBC)
CRYCONHbits.KEYMOD = 0; //Set key strength to 128-bit
int i;
for (i = 0; i < numblocks; i+= 16) {
//Load the next plaintext block into CRYTXTA
memcpy((void*)&CRYTXTA0, plaintext+i, 16);
//Start the encryption
CRYCONLbits.CRYGO = 0b1;
// Wait for completion
while (CRYCONLbits.CRYGO == 0b1)
;
//Read the results out of CRYTXTB
memcpy(ciphertext+i, (void*)&CRYTXTB0, 16);
}
}
part of the test code is showing below
EncryptBlocks(mode, AES_KEY, 0, plaintext, ciphertext, numblocks);
//EncryptBlocks(mode, AES_KEY, 0, plaintext, ciphertext, numblocks);//iv=0; for ECB mode
//LED1 = 0;
printf("Encrypted block:");
for (i = 0; i < numblocks; i++) {
base = i*16;
printf("\n");
for (j = base; j < base+16; j++) {
printf(" %02X", ciphertext[j]);
last[0] = ciphertext[j];
}
}
printf("\n\n");
for (i = 0; i < 16; i++) {
iv[i] = 0;
}
for(i=0;i<sizeof(plaintext);i++)
plaintext[i] = 0;
DecryptBlocks(mode, AES_KEY, ciphertext, plaintext, numblocks);
printf("Decrypted block: ");
for (i = 0; i < numblocks; i++)
{
base = i*16;
printf("\n");
for (j = base; j < base+16; j++) {
printf(" %02X", plaintext[j]);
}
}
printf("\n");
}

Related

Motor runs despite not calling it

currently doing a project with a board with several routines:
#include <xc.h>
#include "config.h"
#define TRUE 1
#define FALSE 0
#define SW1 PORTBbits.RB4
#define SW2 PORTBbits.RB5
#define PB3 PORTCbits.RC3 //for testing
#define PB2 PORTDbits.RD1
#define PB7 PORTCbits.RC7
#define PB8 PORTCbits.RC6
#define MOTOR PORTDbits.RD0
void initSysPins(void);
void ReadLight(void);
void ReadTemperature(void);
void ReadSoilMoisture(void);
void MessageDoze(void);
void MessageSleep(void);
void lcdClear(void);
void initLCD(void);
void initSysInt(void);
void initSysTimer(void);
void pwrMgmt(void);
void initPWM(void);
unsigned char detPB3(void); //for testing
unsigned char detPB2(void);
unsigned char detPB7(void);
unsigned char detPB8(void);
void main(void) {
initSysInt();
initSysPins();
initSysTimer();
CPUDOZE = 0;
while(TRUE){
if(SW1 == 1 && SW2 == 0){
ReadTemperature();
}
else if (SW1 == 0 && SW2 == 1){
ReadLight();
}
else if (SW1 == 1 && SW2 == 1){
ReadSoilMoisture();
}
else {
lcdClear();
}
pwrMgmt();
//pwrMgmt1();
}
}
void pwrMgmt(void){
if(PB2 == 0){
lcdClear();
ROI = 1;
MessageSleep();
SLEEP();
__delay_ms(500);
}
else if(PB7 == 0){
lcdClear();
MessageDoze();
DOZEN= 1;
ROI = 1;
}
}
unsigned char detPB3(void)
{
unsigned char detect = 0; //initial status, sw1 not pressed
if(PB3 == 0) //if sw1 is pressed
{
__delay_ms(20); // 20ms delay to skip contact bounce
if(PB3 == 0) //if still pressed
{
detect = 1; //confirm sw1 is pressed n set detect
while(PB3 == 0);//wait for sw1 to be released
}
}
return detect;
}
unsigned char detPB2(void)
{
unsigned char detect = 0; //initial status, sw1 not pressed
if(PB2 == 0) //if sw1 is pressed
{
__delay_ms(20); // 20ms delay to skip contact bounce
if(PB2 == 0) //if still pressed
{
detect = 1; //confirm sw1 is pressed n set detect
while(PB2 == 0);//wait for sw1 to be released
}
}
return detect;
}
unsigned char detPB7(void)
{
unsigned char detect = 0; //initial status, sw1 not pressed
if(PB7 == 0) //if sw1 is pressed
{
__delay_ms(20); // 20ms delay to skip contact bounce
if(PB7 == 0) //if still pressed
{
detect = 1; //confirm sw1 is pressed n set detect
while(PB7 == 0);//wait for sw1 to be released
}
}
return detect;
}
unsigned char detPB8(void)
{
unsigned char detect = 0; //initial status, sw1 not pressed
if(PB8 == 0) //if sw1 is pressed
{
__delay_ms(20); // 20ms delay to skip contact bounce
if(PB8 == 0) //if still pressed
{
detect = 1; //confirm sw1 is pressed n set detect
while(PB8 == 0);//wait for sw1 to be released
}
}
return detect;
}
The only problem is that my DC motor still runs on its own despite only being called inside my soil moisture function. the other functions just use LCD and LED and work fine. I've tried working around this by putting MOTOR = 0; inside my main but that doesn't do anything.
EDIT: Works on its own before integration with the rest of my codes.
ReadSoilMoisture():
#include <xc.h>
#include "config.h"
#define lcd_Clear 0b00000001
#define LCD_DATA PORTD
#define LCD_RS PORTEbits.RE1 //RS signal for LCD
#define LCD_E PORTEbits.RE0 // E signal for LCD
#define MOTOR PORTDbits.RD0
void initSysPins(void);
void lcdWriteData(char);
void lcdWriteCtrl(char);
void lcdWriteMessage(char message[], unsigned char row);
void lcdSetPos(unsigned char row, unsigned char col);
void initPWM(void);
//void Message(void);
void Message1(void);
void Message2(void);
void Message(void);
void initLCD(void);
void initADC(void);
unsigned int readPot1(void);
void ReadSoilMoisture(void) {
unsigned int raw;
unsigned char pwmCycle = 0;
// float fresult;
// char res[20];
initLCD();
initSysPins();
initPWM();
initADC();
PWM6CONbits.EN = 1;
// raw = readPot1();
int i = 0;
for(i = 0; i<=40; i++) {
raw = readPot1();
if (raw == 0 && raw <= 10)
{
PORTA = 0x00;
}
else if (raw == 11 && raw <=100)
{
PORTA = 0b00001001; //RED
MOTOR = 1;
pwmCycle = 4000;
__delay_ms(5000);
PWM6DCH = pwmCycle >> 2;
PWM6DCL = (pwmCycle % 4)<< 6;
Message();
__delay_ms(3000);
lcdWriteCtrl(0b00000001); // Clear display & home position
}
else if (raw == 101 && raw <= 1000)
{
PORTA = 0b00010010; //YELLOW
MOTOR = 1;
pwmCycle = 1500;
__delay_ms(3000);
PWM6DCH = pwmCycle >> 2;
PWM6DCL = (pwmCycle % 4)<< 6;
Message1();
__delay_ms(3000);
lcdWriteCtrl(0b00000001); // Clear display & home position
}
else if (raw == 1001 && raw <= 1023)
{
PORTA = 0b00100100; //GREEN
MOTOR = 1;
pwmCycle = 900;
__delay_ms(800);
PWM6DCH = pwmCycle >> 2;
PWM6DCL = (pwmCycle % 4)<< 6;
Message2();
__delay_ms(3000);
lcdWriteCtrl(0b00000001); // Clear display & home position
}
}
}
void Message(void){
char message[] = "Soil Moisture";
char message1[] = "Is 55%";
unsigned char i;
lcdSetPos(1,1); // Set DD RAM pos to row 1, col 3
for(i = 0; message[i] != 0; i++) {
lcdWriteData(message[i]); // Display one character
}
lcdSetPos(2,1); // Set DD RAM pos to row 2, col 1
for(i = 0; message1[i] != 0; i++) {
lcdWriteData(message1[i]); // Display one character
}
}
void Message1(void){
char message[] = "Soil Moisture";
char message1[] = "Is 75%";
unsigned char i;
lcdSetPos(1,1); // Set DD RAM pos to row 1, col 3
for(i = 0; message[i] != 0; i++) {
lcdWriteData(message[i]); // Display one character
}
lcdSetPos(2,1); // Set DD RAM pos to row 2, col 1
for(i = 0; message1[i] != 0; i++) {
lcdWriteData(message1[i]); // Display one character
}
}
void Message2(void){
char message[] = "Soil Moisture";
char message1[] = "Is 95%";
unsigned char i;
lcdSetPos(1,1); // Set DD RAM pos to row 1, col 3
for(i = 0; message[i] != 0; i++) {
lcdWriteData(message[i]); // Display one character
}
lcdSetPos(2,1); // Set DD RAM pos to row 2, col 1
for(i = 0; message1[i] != 0; i++) {
lcdWriteData(message1[i]); // Display one character
}
}
void initPWM(void)
{
CCPTMRS1 = PORTDbits.RD0;
PWM6CON = 0b00000000;
T2PR = 249;
PWM6DCH = 0b01111101;
PWM6DCL = 0b00000000;
T2CON = 0b11110000;
T2CLKCON = 0b00000001;
RA2PPS = 0x0E;
}
Any guess as to what I can do?

Why doesn't my program recognize the PORTbits.RCx == 0 condition?

void UART_init(void){
ANSELB = 0; //set PORT B to digital port
TRISBbits.TRISB5 = 1; //set RX pin to input
TRISBbits.TRISB7 = 0; //set TX pin as output
SPBRGH = 0;
SPBRGL = 25; //set baud rate to 9600
BRGH = 0;
BRG16 = 0;
SYNC = 0;
SPEN = 1; //enable serial port pins
TX9 = 0; //set 9 bit tranmission
RX9 = 0; //set 9 bit receive
TXEN = 1; //enable transmission
CREN = 1; //enable receiver
}
void UART_write(char data){
while(TRMT == 0);
TXREG = data;
}
void UART_write_string(char *text){
for(int i=0; text[i] != '\0'; i++){
UART_write(text[i]);
}
}
char UART_read(){
while(RCIF == 0);
return RCREG;
}
char URAT_read_string(char *stringprimit, int lungime){
for(int i=0; i < lungime; i++){
stringprimit[i] = UART_read();
}
}
int main(int argc, char** argv) {
OSCCONbits.IRCF = 0b1111; //set operating frequency to 31kHz (0b1111) for 16MHz
//WDTCONbits.WDTPS = 0b01110;
//CLRWDT();
//0b01100; //set WTD interval at 4s
UART_init();
//Activam pull-up
OPTION_REGbits.nWPUEN = 0;
WPUCbits.WPUC2 = 1;
WPUCbits.WPUC6 = 1;
WPUCbits.WPUC7 = 1;
WPUCbits.WPUC0 = 0;
WPUCbits.WPUC1 = 0;
WPUCbits.WPUC3 = 1;
//Led-uri
TRISAbits.TRISA1 = 0; // set as output
TRISAbits.TRISA2 = 0; // set as output
ANSELAbits.ANSA1 = 0; //pin digital
ANSELAbits.ANSA2 = 0; //pin digital
ANSELAbits.ANSA0 = 1; //set to analogic pin
TRISAbits.TRISA0 = 1; //set as input
ANSELCbits.ANSC0 = 0; //set to digital pin
ANSELCbits.ANSC1 = 0; //set to digital pin
TRISCbits.TRISC0 = 0; //set as output
TRISCbits.TRISC1 = 0; //set as output
ANSELCbits.ANSC2 = 0; //set to digital pin
ANSELCbits.ANSC6 = 0; //set to digital pin
ANSELCbits.ANSC7 = 0; //set to digital pin
TRISCbits.TRISC2 = 1; //set as input
TRISCbits.TRISC6 = 1; //set as input
TRISCbits.TRISC7 = 1; //set as input
PORTCbits.RC0 = 1;
PORTCbits.RC1 = 0;
PORTAbits.RA1 = 0;
PORTAbits.RA2 = 1;
char user_input;
UART_write_string("1. rotate right ");
UART_write('\r');
UART_write_string("2. rotate left");
UART_write('\r');
UART_write_string("3. stop");
UART_write('\r');
UART_write_string("4. Deactivate UART");
UART_write('\r');
UART_write_string("select:");
while(1){
//CLRWDT();
user_input = UART_read();
if(PORTCbits.RC7 == 0 ){ //motor rotates right
user_input = '1';
PORTCbits.RC0 = 1;
PORTCbits.RC1 = 0;
PORTAbits.RA1 = 0;
PORTAbits.RA2 = 1;
}
if(PORTCbits.RC6 == 0 ){ //motor rotates left
user_input = '2';
PORTCbits.RC0 = 0;
PORTCbits.RC1 = 1;
PORTAbits.RA1 = 1;
PORTAbits.RA2 = 0;
}
if(PORTCbits.RC2 == 0 ){ //motor stop
user_input = '3';
PORTCbits.RC0 = 0;
PORTCbits.RC1 = 0;
PORTAbits.RA1 = 0;
PORTAbits.RA2 = 0;
}
if(user_input =='1') {//motor rotates right
PORTCbits.RC0 = 1;
PORTCbits.RC1 = 0;
PORTAbits.RA1 = 0;
PORTAbits.RA2 = 1;
}
if( user_input =='2'){ //motor rotates left
PORTCbits.RC0 = 0;
PORTCbits.RC1 = 1;
PORTAbits.RA1 = 1;
PORTAbits.RA2 = 0;
}
if(user_input =='3'){ //motor stop
PORTCbits.RC0 = 0;
PORTCbits.RC1 = 0;
PORTAbits.RA1 = 0;
PORTAbits.RA2 = 0;
}
if(user_input =='4'){ //deactivate UART
CREN = 0;
}
}
return (EXIT_SUCCESS);
}
In this project I tried to control a DC motor with two methods, the first method is UART with user's input and the second with buttons.
The scope: When I press the numer 1 from the keyboard I want the motor rotates to the right, 2- left, 3 - stop. This works properly, but the problem is with the buttons, when I press the RC7 button nothing happens.
RC7 - means the motor rotates right, RC6 - them motor rotates left, RC2 - the motor stop
From what I can tell, my program doesn't even see those conditions, like PORTbits.RC7 == 0.
From the code, I can see that the function:
char UART_read(){
while(RCIF == 0);
return RCREG;
}
is blocking on while(RCIF == 0);
and I think this is the reason your Buttons are not working because at the very beginning of the while(1) you have called UART_read();.
And you mentioned it yourself that the output is as expected for UART data, so this answers your question.
To make it work, you have to write a UART Rx Interrupt so that your program should not be blocking/waiting on UART to Receive data.
Edit:
As per your comment, that you are disabling the UART reception using CREN, then you should also check if the Receiver is enabled prior to reading the Rx Data register, you can modify the UART receive function as below:
char UART_read(){
if(CREN == 0) {
return '\0'; //Return NULL Character
}
while(RCIF == 0);
return RCREG;
}

pass multiple values from a function defined in one file to another file using c

I have a task get multiple values from one function defined in one.c file to other function defined in two.c file.
Please find below code snippet from both the files and kindly help to access the values from one.c file into two.c file.
file one.c:
void GetABFWversion(uint8_t* fwcommand, uint8_t* fwaction, uint16_t* fwvalue)
{
uint16_t FW_slot=SdusAutoDetectSlotForNewFirmware();
char MyCopy[10];
strcpy (MyCopy, BrakeBoardInfo.firmwareVersion);
char MyCopy1[10];
for (int k=0; k<9; k++)
{
int l=1;
MyCopy1[k] = MyCopy[k+l];
}
char FWversion_AB[10] = {0};
int z = 0;
for(int x=6;x<10;x++)
{
FWversion_AB[z] = MyCopy1[x];
z++;
}
char res=0;
uint16_t val = atoi(FWversion_AB);
//res = proto485OnlyWrite(0x09,0x02,0x00,val);
printf("\n");
printf("FW version is sent to Arduino!!! ");
RESULT = 1;
*fwcommand = 0x02;
*fwaction = 0x00;
*fwvalue = val;
}
file two.c:
int16_t driver485Read (uint8_t *buffer, const uint16_t length)
{
char head[20];
const char *format="KL%02x:";
int16_t wait_loop_cnt=0;
static uint32_t totalBytes = 0;
static uint32_t respNo = 0;
GPIO_ClearValue(PMAP_GPIO_PORT_DIR_RS485, PMAP_GPIO_PIN_DIR_RS485);
UartRxFlush(UARW_UART_INDEX_RS485); /
respNo++;
int counter = 0;
do
{
OSTimeDly(2);
int8_t newBytesRcv = UartReceive(UARW_UART_INDEX_RS485,
(uint8_t*)&(buffer[counter]), length-counter);
totalBytes += newBytesRcv;
counter = totalBytes;
}
while (/*wait_loop_cnt++<= MAX_WAIT_LOOP &&*/ counter < length);
totalBytes = 0;
uint8_t i = 0;
format="OK%02x:";
printf("Byte received........");
int FWmsg[9] = {0x09,0x30,0x30,0x32,0x32,0x31,0x31,0x31,0x31};
int arduinodata[9] = {0x09,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30};
for (i=0; i<9;i++)
{
printf("%d ",buffer[i]);
arduinodata[i] = buffer[i];
}
if(compareArray(FWmsg,arduinodata,7)==0)
{
printf("Arrays have same elements.\n");
printArray(FWmsg,9);
char res = 0;
uint8_t fwc, fwa;
uint16_t fwv;
GetABFWversion(&fwc, &fwa, &fwv);
res = proto485OnlyWrite(0x09,fwc,fwa,fwv);
printf("\n");
printf("FW version is sent to Arduino!!! ");
}
else
{
printf("Arrays have different elements.\n");
}
/* 1st byte is the slave address byte which value should be >= RS485_ADDRESS_SLAVE_FIRST &&
<= RS485_ADDRESS_SLAVE_LAST and is already checked in dePadLeft() */
for(int i = 1; i < length && buffer[i] >= RS485_PAYLOAD_VALID_MIN && buffer[i] <= RS485_PAYLOAD_VALID_MAX; i++);
counter = i; // to be OK, i = length = RS485_MSG_LENGTH if response (after eventual dePad..) is OK
printf("driver485Read %d\n",counter);
#ifdef RS485_DEBUG
static uint32_t i = 0;
i++;
#endif
return counter;
GPIO_SetValue(PMAP_GPIO_PORT_DIR_RS485, PMAP_GPIO_PIN_DIR_RS485);
}
file three.c:
uint8_t proto485OnlyWrite(uint8_t address, uint8_t command, uint8_t action, uint16_t value)
{
uint8_t res=ERROR_FOUND;
OSSemPend(pbSemaphore, 0, &res);
if (res == OS_ERR_NONE)
{
rs485_message_t rs485Msg;
if (command ==CMD_POWER_PUMP_PB)
{
printf("CMD_POWER_PUMP_PB");
}
proto485ComposeMsg(&rs485Msg, address, command, action, value);
res = (RS485_MSG_LENGTH == driver485Write((uint8_t *)&rs485Msg, sizeof(rs485Msg))) ?
NO_ERROR:
ERROR_FOUND;
OSSemPost(pbSemaphore);
}
return res;
}
I want to get the values of "fwcommand", "fwaction" and "fwvalue" defined in file one.c into file two.c at the place where I am passing the same to "res = proto485OnlyWrite(0x09,fwc,fwa,fwv);" in the place of "fwc", "fwa" and "fwv" respectively.
Thank you....

How can I parallelize multiple for loop in OpenMP?

I am very new to coding and have manage to put these together from different sources. Code runs in c but I am unable to get to work in OpenMP. I get errors such as getting the correct key once and then the next four (4) or five (5) attempts does not generates the correct key. Any help is very welcome.
This is my code.
#include "omp.h"
#include <openssl/conf.h>
#include <openssl/err.h>
#include <openssl/evp.h>
#include <string.h>
#include <time.h>
void handleErrors(void)
{
ERR_print_errors_fp(stderr);
abort();
}
int encrypt(unsigned char *plaintext, int plaintext_len, unsigned char *key,
unsigned char *iv, unsigned char *ciphertext)
{
EVP_CIPHER_CTX *ctx;
int len;
int ciphertext_len;
if (!(ctx = EVP_CIPHER_CTX_new()))
handleErrors();
if (1 != EVP_EncryptInit_ex(ctx, EVP_aes_128_cbc(), NULL, key, iv))
handleErrors();
if (1 != EVP_EncryptUpdate(ctx, ciphertext, &len, plaintext, plaintext_len))
handleErrors();
ciphertext_len = len;
if (1 != EVP_EncryptFinal_ex(ctx, ciphertext + len, &len))
handleErrors();
ciphertext_len += len;
EVP_CIPHER_CTX_free(ctx);
return ciphertext_len;
}
int main(void)
{
int total_thread, thread_id;
double start_time, end_time;
start_time = omp_get_wtime();
printf("Starting of the program, start_time = %f\n", start_time);
/* A 128 bit key */
unsigned char *key = (unsigned char *)"secret##########";
/* A 128 bit IV */
unsigned char *iv = (unsigned char *)"\x01\x02\x03\x04\x05\x06\x07\x08";
/* Message to be encrypted */
unsigned char *plaintext =
(unsigned char *)"This is a really really top secret!";
/* Buffer for ciphertext. Ensure the buffer is long enough for the
ciphertext which may be longer than the plaintext, dependant on the
* algorithm and mode */
unsigned char ciphertext[128];
unsigned char ciphertextnew[128];
#pragma omp parallel
/* Encrypt the plaintext */
encrypt(plaintext, strlen((char *)plaintext), key, iv, ciphertext);
/* Do something useful with the ciphertext here */
printf("Ciphertext is:\n");
BIO_dump_fp(stdout, (const char *)ciphertext, 16);
/*char pbuffer[1024];*/
char password[17] = "################";
char alphabet[] = "ectres";
// int count;
#pragma omp parallel for
for (int s = 0; s < 6; s++)
{
password[0] = alphabet[s];
for (int t = 0; t < 6; t++)
{
password[1] = alphabet[t];
for (int u = 0; u < 6; u++)
{
password[2] = alphabet[u];
for (int v = 0; v < 6; v++)
{
password[3] = alphabet[v];
for (int w = 0; w < 6; w++)
{
password[4] = alphabet[w];
for (int x = 0; x < 6; x++)
{
password[5] = alphabet[x];
encrypt(plaintext, strlen((char *)plaintext),
password, iv, ciphertextnew);
if (strncmp(ciphertext, ciphertextnew, 16) == 0)
{
printf("\n%s", password);
printf(" Here is the correct key!\n\n");
end_time = omp_get_wtime();
total_thread = omp_get_num_threads();
thread_id = omp_get_thread_num();
printf("\nProgram start = %f\n", start_time);
printf("\nProgram end = %f\n", end_time);
printf("\n\nProgram runtime = %f seconds\n\n",
end_time - start_time);
printf("\nTotal number of threads = %d\n",
total_thread);
exit(0);
}
printf("\n%s", password);
}
}
}
}
}
}
return 0;
}
// add padding to key
void pad(char *s, int length)
{
int l;
l = strlen(s); /* its length */
while (l < length)
{
s[l] = '#'; /* insert a space */
l++;
}
s[l] = '\0'; /* strings needs to be terminated in null */
}
As mentionned by #Matthieu Brucher, you have an issue with password being shared.
Another one is the exit(0); statement. You can only parallelize structured-blocks with a single exit point at the bottom (i.e. more or less a statement block without any exit, return, goto...). So the exit statement would not be legit. It seems logical: if a thread hits the exit, what are the other ones supposed to do? How do they know that they have to exit too?
There are however specific directives to cancel a parallel loop, pretty much what the break; statement would do. The omp cancel directive will signal all threads to break from the parallel loop or parallel region. The omp cancellation point is the point where threads will check if a cancellation has been requested.
You'll have to find where the cancellation point should be put: going there too often has a cost in terms of overhead (putting it in the innermost loop may not be efficient), but not often enough means that a thread may keep running for too long before realizing that it should break from its loop (putting it in the outermost loop means that threads will almost never check for cancellation).
char password_found[17];
int flag_found=0;
#pragma omp parallel shared(password_found,flag_found)
{
char password[17] = "################"; //this is a thread private variable
// These will be done in parallel
#pragma omp for collapse(3)
for (int s = 0; s < 6; s++)
for (int t = 0; t < 6; t++)
for (int u = 0; u < 6; u++)
{
password[0] = alphabet[s];
password[1] = alphabet[t];
password[2] = alphabet[u];
// For every s,t,u, a single thread will loop through these
for (int v = 0; v < 6; v++)
for (int w = 0; w < 6; w++)
for (int x = 0; x < 6; x++)
{
password[3] = alphabet[v];
password[4] = alphabet[w];
password[5] = alphabet[x];
encrypt(plaintext, strlen((char *)plaintext),
password, iv, ciphertextnew);
if (strncmp(ciphertext, ciphertextnew, 16) == 0)
{
printf("\n%s", password);
printf(" Here is the correct key!\n\n");
flag_found=1;
strcpy(password_found,password); // Copy thread-private copy to shared variable
// Now, signal everyone to stop
#pragma omp cancel parallel
}
printf("\n%s is bad", password);
} // end inner group of loops
// Threads will check here is they should stop
#pragma omp cancellation point parallel
} // end of the outer group of loops
} // end of parallel region
// Do something now //
if (flag_found){
printf("\nThe password is %s\n",password_found);
return 0;
}else{
printf("Password not found\n");
return 1;
}

One buttoned bandit slot machine - int function

I'm making one-buttoned bandit slot machine made on 3x 7 segment displays and 3x 74HC595 Shift Registers. Problem is that I want to have some kind of indicator that you won (or you partially won - 2 numbers are the same).
losLiczb(latchPin3, dataPin3, clockPin3, data3, liczba3); // liczba3 = in eg. 4
Serial.println("Wylosowana liczba to"); // "Generated number:"
Serial.println(liczba3); // liczba3 = 0
So, liczba1/liczba2/liczba3 is number which was generated in function losLiczb. Main problem is that liczba1/2/3 have assigned number inside function losLiczb (I can chceck correctness via Serial Read), but outside the number liczba1/2/3 is 0, thus program will always indicate that you won. Here is the whole program if you want (some of comments are in polish and are unnessecary,:
int latchPin1 = 5; //Pin connected to ST_CP of 74HC595
int clockPin1 = 4; //Pin connected to SH_CP of 74HC595
int dataPin1 = 6; //Pin connected to DS of 74HC595
int latchPin2 = 8;
int clockPin2 = 7;
int dataPin2 = 9;
int latchPin3 = 11; //11
int clockPin3 = 12; //12
int dataPin3 = 10; //8
int liczba1;
int liczba2;
int liczba3;
const int buttonPin = 2;
int statusPin = 3;
int buttonState = 0;
//holders for infromation you're going to pass to shifting function
byte data;
byte data1;
byte data2;
byte data3;
byte dataArray[10];
byte animacja[8];
byte dummy[1];
void setup() {
//set pins to output because they are addressed in the main loop
pinMode(latchPin1, OUTPUT);
pinMode(latchPin2, OUTPUT);
pinMode(latchPin3, OUTPUT);
pinMode(statusPin, OUTPUT);
pinMode(buttonPin, INPUT);
Serial.begin(9600);
//Arduino doesn't seem to have a way to write binary straight into the code
//so these values are in HEX. Decimal would have been fine, too.
// 00000000 - trzeba zapisywać w translatorze hex-bin w takiej postaci.
// Kolejno od prawej wartości odpowiadają kropce, a, b , c , d, e , f , g
// dataArray[2] = 0xB6; //11111100 FC
dataArray[0] = 0x7F;
dataArray[1] = 0x0C;
dataArray[2] = 0xB6;
dataArray[3] = 0x9E;
dataArray[4] = 0xCC;
dataArray[5] = 0xDA;
dataArray[6] = 0xFA;
dataArray[7] = 0x0E;
dataArray[8] = 0xFE;
dataArray[9] = 0xDE;
animacja[0] = 0x80; //g
animacja[1] = 0x20; //e
animacja[2] = 0x10; //d
animacja[3] = 0x08; //c
animacja[4] = 0x80; //g
animacja[5] = 0x40; //f
animacja[6] = 0x02; //a
animacja[7] = 0x04; //b
dummy[0] = 0x00;
randomSeed(analogRead(0));
}
void loop() {
buttonState = digitalRead(buttonPin);
if (buttonState == HIGH) {
anim();
} else {
idle();
digitalWrite(statusPin, LOW);
}
}
void idle(){
data = dummy[0];
digitalWrite(latchPin1, 0);
shiftOut(dataPin1, clockPin1, data);
digitalWrite(latchPin1, 1);
digitalWrite(latchPin2, 0);
shiftOut(dataPin2, clockPin2, data);
digitalWrite(latchPin2, 1);
digitalWrite(latchPin3, 0);
shiftOut(dataPin3, clockPin3, data);
digitalWrite(latchPin3, 1);
}
// Funkcja odpowiedzialna za animację
void anim(){
for (int p =0; p < 3; p++){
for (int i = 0; i < 8; i++) {
data = animacja[i];
digitalWrite(latchPin1, 0);
shiftOut(dataPin1, clockPin1, data);
digitalWrite(latchPin2, 0);
shiftOut(dataPin2, clockPin2, data);
digitalWrite(latchPin3, 0);
shiftOut(dataPin3, clockPin3, data);
digitalWrite(latchPin1, 1);
digitalWrite(latchPin2, 1);
digitalWrite(latchPin3, 1);
delay(100);
}
}
losLiczb(latchPin1, dataPin1, clockPin1, data1, liczba1);
Serial.println("Wylosowana liczba to");
Serial.println(liczba1);
for (int p =0; p < 2; p++){
for (int i = 0; i < 8; i++) {
data = animacja[i];
digitalWrite(latchPin2, 0);
shiftOut(dataPin2, clockPin2, data);
digitalWrite(latchPin3, 0);
shiftOut(dataPin3, clockPin3, data);
digitalWrite(latchPin2, 1);
digitalWrite(latchPin3, 1);
delay(100);
}
}
losLiczb(latchPin2, dataPin2, clockPin2, data2, liczba2);
Serial.println("Wylosowana liczba to");
Serial.println(liczba2);
for (int p =0; p < 2; p++){
for (int i = 0; i < 8; i++) {
data = animacja[i];
digitalWrite(latchPin3, 0);
shiftOut(dataPin3, clockPin3, data);
digitalWrite(latchPin3, 1);
delay(100);
}
}
losLiczb(latchPin3, dataPin3, clockPin3, data3, liczba3);
Serial.println("Wylosowana liczba to");
Serial.println(liczba3);
if (data1 == data2){
digitalWrite(statusPin, HIGH);
} else {
digitalWrite(statusPin, LOW);
}
delay(5000);
}
//Funckja odpowiedzialna za wylosowanie liczby
int losLiczb(int myLatchPin, int myDataPin, int myClockPin, int myData, int myLiczba) {
//load the light sequence you want from array
int j = random(0, 9);
myLiczba = j;
myData = dataArray[j];
//ground latchPin and hold low for as long as you are transmitting
digitalWrite(myLatchPin, 0);
//move 'em out
shiftOut(myDataPin, myClockPin, myData);
//return the latch pin high to signal chip that it
//no longer needs to listen for information
digitalWrite(myLatchPin, 1);
Serial.println("Wylosowana liczba to");
Serial.println(myLiczba);
}
// the heart of the program
void shiftOut(int myDataPin, int myClockPin, byte myDataOut) {
// This shifts 8 bits out MSB first,
//on the rising edge of the clock,
//clock idles low
//internal function setup
int i=0;
int pinState;
pinMode(myClockPin, OUTPUT);
pinMode(myDataPin, OUTPUT);
//clear everything out just in case to
//prepare shift register for bit shifting
digitalWrite(myDataPin, 0);
digitalWrite(myClockPin, 0);
//for each bit in the byte myDataOut�
//NOTICE THAT WE ARE COUNTING DOWN in our for loop
//This means that %00000001 or "1" will go through such
//that it will be pin Q0 that lights.
for (i=7; i>=0; i--) {
digitalWrite(myClockPin, 0);
//if the value passed to myDataOut and a bitmask result
// true then... so if we are at i=6 and our value is
// %11010100 it would the code compares it to %01000000
// and proceeds to set pinState to 1.
if ( myDataOut & (1<<i) ) {
pinState= 1;
}
else {
pinState= 0;
}
//Sets the pin to HIGH or LOW depending on pinState
digitalWrite(myDataPin, pinState);
//register shifts bits on upstroke of clock pin
digitalWrite(myClockPin, 1);
//zero the data pin after shift to prevent bleed through
digitalWrite(myDataPin, 0);
}
//stop shifting
digitalWrite(myClockPin, 0);
}
Pass the values you want the function to output by reference or by pointer.
void Wrong(int a) {
a = 10;
}
void Right(int& a) {
a = 20;
}
void Right(int* pA) {
*pA = 30;
}
int a = 0;
Wrong(a); printf("%d ", a);
Right(a); printf("%d ", a);
Right(&a); printf("%d\n", a);
output will be 0 20 30

Resources