I’m trying to do some kind of voip application using UDP.I have added RSA algorithm for safety.However its gives and segmentation fault.
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <stdlib.h>
#include <stdio.h>
#include <linux/soundcard.h>
#include <stdlib.h>
#define LENGTH 3 /* how many seconds of speech to store */
#define RATE 8000 /* the sampling rate */
#define FILE_INPUT "/dev/dsp" /* Path to the sound card. */
#define FILE_OUTPUT "/dev/dsp"
/*-RSA-*/
//Her is gcd function
int gcd(int a,int b)
{
while(a!=b){
if(a>b)
a-=b;
else
b-=a;
}
return a;
}
//This is called Extended Euclid’s Algorithm to find d.
int findD(int e,int n)
{
int f=e;
int d=n;
int x1, x2, x3, y1, y2, y3;
x1 = 1; x2 = 0; x3 = f; //p
y1 = 0; y2 = 1; y3 = d; //d
int q = 0, i = 1;
int t1 = 0, t2 = 0, t3 = 0;
do
{
if (i == 1)
{
q = x3 / y3;
t1 = x1 - (q * y1);
t2 = x2 - (q * y2);
t3 = x3 - (q * y3);
}
else
{
x1 = y1; x2 = y2; x3 = y3;
y1 = t1; y2 = t2; y3 = t3;
q = x3 / y3;
t1 = x1 - (q * y1);
t2 = x2 - (q * y2);
t3 = x3 - (q * y3);
}
i++;
if (y3 == 0)
{
break;
}
} while (y3 != 1);
if (y3 == 0)
{
//printf("Sayinin tersi yoktur!!!!");
}
else
{
// printf("\nSayinin tersi : %d" , y2);
}
if(y2<=0)
{
y2=e+y2;
}
return y2;
}
//Instead of using pow function,I have choose to write square and multiply method which is faster and
//more suitable for big integers.Because we have no such a change to find 104^30 such like that
//Here computes pow(a,b)%n
int squareMul(int a,int b,int n)
{
int y = 1;
/* Compute pow(a, b) % n using the binary square and multiply method. */
while (b != 0)
{
/* For each 1 in b, accumulate y. */
if (b & 1)
{
y = (y * a) % n;
}
/* Square a for each bit in b. */
a = (a * a) % n;
/* Prepare for the next bit in b. */
b = b >> 1;
}
return y;
}
//Encyrption function
//Assume our plain-text is M
int *encyrpt(int text[],int e,int n)
{
int t=0;
int *s=(int *)malloc(100);
for(t=0;t<sizeof(text);t++)
{
int gec=(int)text[t];
//Here computes E(M)=M^e mod n;
s[t]=squareMul(gec,e,n);
}
return s;
}
//Here is decyrption
//Assume our chipher-text is C
int *decyrpt(int enc[],int d,int e,int n)
{
int i=0;
int *s=(int *)malloc(100);
for(i=0;i<sizeof(enc);i++)
{
int gelenEnc=(int)enc[i];
//Here computes D(C)=C^d mod n;
s[i]=squareMul(gelenEnc,d,n);
}
return s;
}
//Here is totient function to find prime to m.
int totient(int m)
{
int i;
int ph=1;
for(i=2;i<m;i++){
if(gcd(i,m)==1)
{
ph=i;
break;
}
}
return ph;
}
/*-RSA-*/
int main()
{
int sock,bytes_recv;
struct sockaddr_in server_addr;
struct hostent *host;
char send_data[LENGTH*RATE];
char recv_data[LENGTH*RATE];
int addr_len, bytes_read;
struct client_addr;
/* this buffer holds the digitized audio */
unsigned char buf[LENGTH*RATE];
/*----------RSA-----------------------*/
//Here are some variables that I used for RSA ALGORİTHM
//str is our plain-text
char *plainText;
int *ascii;
int *enc;
int *dec;
int p,q;
int k=0;
int n;
int e;
int c;
int phi;
int d;
plainText="Merhaba";
//Here enter 2 relatively prime number
//I have chose the p=73 and q=151
p=73;
q=151;
printf("\n\ p :%d and q :%d \t \n",p,q);
//Here computes n
n = p*q;
//Here computes phi func simply
phi=(p-1)*(q-1);
printf("\n\ n :\t= %d \n",n);
printf("\n\ Phi :\t= %d \n",phi);
//Here Euilers Totient function.It finds a number 'e' which is relatively prime with phi.
e=totient(phi);
//Here computes d,which is multiplicative inverse of e modula phi.
d=findD(phi,e);
printf("\n\ e :\t= %d \n",e);
printf("\n\ d :\t= %d which is multiplicative inverse of e modula phi \n",d);
//Here is the ascii values for plainText.I have created new array in order to store plainText's ascii for simplicty
ascii=(int *)malloc(sizeof(int)*sizeof(plainText)/sizeof(char));
/*---------------RSA------------*/
int sound_device;
/* open sound device */
//I defined sound card both read and write mode for simplicity
sound_device = open("/dev/dsp", O_RDWR);
if (sound_device < 0) {
perror("Open sound card failed");
exit(1);
}
host= (struct hostent *) gethostbyname((char *)"127.0.0.1");
if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
{
perror("socket");
exit(1);
}
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(5000);
server_addr.sin_addr = *((struct in_addr *)host->h_addr);
bzero(&(server_addr.sin_zero),8);
while(1){
read(sound_device, buf, sizeof(buf)); /* record some sound */
printf("\n Size of buff: %d",sizeof(buf));
ascii=malloc(LENGTH*RATE);
buf=malloc(LENGTH*RATE);
printf("\n Size of ascii: %d",sizeof(ascii));
//Here ascii stores plaintText's ascii number.
for(c=0;c<LENGTH*RATE;c++)
{
int k=(int)buf[c];
ascii[c]=k;
printf("\n\t Ascii's of %c \t= %d \n",buf[c],ascii[c]);
printf("\n\t C: %c \t= %d \n",c);
}
enc=encyrpt(ascii,e,n);
//Send function to server
sendto(sock, enc, LENGTH*RATE, 0,(struct sockaddr *)&server_addr, sizeof(struct sockaddr));
//Listen from server for 3 seconds
ioctl(sound_device, SOUND_PCM_SYNC, 0);
bytes_recv = recvfrom(sock,buf,LENGTH*RATE,0,(struct sockaddr *)&server_addr, &addr_len);
printf("\n Sended:");
if(bytes_recv==LENGTH*RATE){
printf("\nMessage received from server,listen:");
//Here is decyription
dec=decyrpt(buf,d,e,n);
write(sound_device, dec, sizeof(dec));
ioctl(sound_device, SOUND_PCM_SYNC, 0);
}
}
}
Ascii's of � = 131
C: � = 10989
Segmentation fault
However,my RSA algorithm works properly in other char array separetly.Any idea?
Thanks
Segmentation fault is usually caused by trying to access memory that was not allocated for the process. This often comes about when you are indexing into arrays (especially, dynamically created ones).
In your code you have a fixed-size
malloc()in theencypt()anddecrypt()functions, but you access its elements based on the size of the input array, which could be a cause for the seg.fault.To be sure, you will need to use a debugger and see where the over/under indexing occurs. Be sure to check accessed to other arrays as well (whether dynamically alocated or not)
Also,
sizeof(plainText)returns the size of a pointer-to-char, not the length of the string. You will either need to declareplaintextas a stack-based array, or use thestrlen()function.