-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathReceiverFunctions.java
More file actions
224 lines (176 loc) · 10.5 KB
/
ReceiverFunctions.java
File metadata and controls
224 lines (176 loc) · 10.5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
package udpReceive;
import java.util.Random;
public class ReceiverFunctions {
private static int byteCount=0; // Keeps the counts of the number of bytes received
private static int expectedBytes=351; // Length of data bytes to be received
private static byte[] nonce=new byte[8]; // Randomly generated bytes padded into IACK packet for
//generation of 128 bits key at Sender's side
private static byte[] cipher=new byte[40]; // Variable to store encrypted payload
private static byte[] variable=new byte[2]; // Variable used to store the integrity check values
private static final byte[] S=new byte[256]; // State vector
private static final byte[] T=new byte[256]; // Temporary vector
private static byte[] sendBuffer=new byte[14]; // Byte buffer holding the IACK packet to be sent
private static byte[] sendDataBuffer=new byte[6]; // Byte buffer holding the DACK packet to be sent
private static byte[] integrityCheckValue=new byte[2]; // Byte array to hold the value of Integrity check field
private static byte[] receivedBytes=new byte[((expectedBytes/40)+1)*40]; // Byte array to hold the received 351-bytes of data
// Setting up IACK packet
public static byte[] iackPacketBuffer(byte[] arrReceiveBuffer){
Random randomObj=new Random(); // Object of random class
sendBuffer[0]=0x00;
sendBuffer[1]=0x01; // Setting "PACKET TYPE" as IACK
sendBuffer[2]=arrReceiveBuffer[2];
sendBuffer[3]=arrReceiveBuffer[3]; // Setting the "INITIAL SEQUENCE NUMBER" as in the received INIT packet
randomObj.nextBytes(nonce); // Generating random nonce bytes
for(int j=0;j<8;j++)
sendBuffer[j+4]=nonce[j];
integrityCheckValue=ReceiverFunctions.integrityCheckValue(sendBuffer); // Calling function to receive integrity check value for IACK packet
for(int k=0;k<2;k++)
sendBuffer[k+12]=integrityCheckValue[k]; // Appending received integrity check value at the end of IACK packet
return sendBuffer;
}
// Setting up DACK packet
public static byte[] dackPacketBuffer(byte[] arrReceiveDataBuffer){
System.out.println("------------------------------------------------------------------------------------\n");
sendDataBuffer[0]=0x00;
sendDataBuffer[1]=0x04; // Setting "PACKET TYPE" for DACK
sendDataBuffer[2]=arrReceiveDataBuffer[2];
sendDataBuffer[3]=arrReceiveDataBuffer[3]; // Copying the SEQUENCE NUMBER from the received DATA packet into the DACK
integrityCheckValue=ReceiverFunctions.integrityCheckValueData(sendDataBuffer); // Calling function to receive integrity check value for DACK packet
for(int k=0;k<2;k++)
sendDataBuffer[k+4]=integrityCheckValue[k]; // Calling function to receive integrity check value for IACK packet
return sendDataBuffer; // Returning the prepared DACK to the caller of the function
}
// Integrity check on received INIT Packet
public static boolean integrityCheckReceived(byte[] arrReceiveBuffer){
variable[0]=0x00;
variable[1]=0x00; // Initializing variable to 0
for(int i=0;i<2;i++){
variable[i]=(byte) (variable[i] ^ arrReceiveBuffer[i]); // Bit-wise X-OR on received INIT packet with the 16-bits "variable"
variable[i]=(byte) (variable[i] ^ arrReceiveBuffer[i+2]);
variable[i]=(byte) (variable[i] ^ arrReceiveBuffer[i+4]); // includes the INTEGRITY CHECK VALUE FIELD
}
if(variable[0]==0x00 && variable[1]==0x00)
return true; // Return true if integrity check value=0 (INTEGRITY CHECK=PASS)
else
return false; // Return False if integrity check value!=0 (INTEGRITY CHECK=FAIL)
}
// Integrity check value for IACK Packet
public static byte[] integrityCheckValue(byte[] arrSendBuffer){
variable[0]=0x00;
variable[1]=0x00; // Initializing variable to 0
for(int i=0;i<2;i++){ // Bit-wise X-OR of IACK to be sent with the 16-bits "variable"
variable[i]=(byte) (variable[i]^arrSendBuffer[i]);
for(int j=2;j<11;j+=2)
variable[i]^=arrSendBuffer[i+j]; // Doesn't include the INTEGRITY CHECK VALUE FIELD
}
return variable; // Returns the INTEGRITY CHECK VALUE to be appended in the IACK packet to be sent
}
// Integrity check on DATA packet
public static boolean integrityCheckData(byte[] arrReceiveDataBuffer){
variable[0]=0x00;
variable[1]=0x00; // Initializing variable to 0
for(int i=0;i<2;i++){
variable[i]=(byte) (variable[i] ^ arrReceiveDataBuffer[i]); // Bit-wise X-OR on received DATA with the 16-bits "variable"
variable[i]=(byte) (variable[i] ^ arrReceiveDataBuffer[i+2]);
variable[i]^=arrReceiveDataBuffer[i+4];
for(int j=0;j<40;j+=2)
variable[i]=(byte) (variable[i]^arrReceiveDataBuffer[i+j+6]); // includes Encrypted payload
variable[i]^=arrReceiveDataBuffer[i+46]; // includes the INTEGRITY CHECK VALUE FIELD
}
if(variable[0]==0x00 && variable[1]==0x00)
return true; // Return true if integrity check value=0 (INTEGRITY CHECK=PASS)
return false; // Return true if integrity check value=0 (INTEGRITY CHECK=FAIL)
}
// Integrity check value for DACK packet
public static byte[] integrityCheckValueData(byte[] arrSendDataBuffer){
variable[0]=0x00;
variable[1]=0x00; // Initializing variable to 0
for(int i=0;i<2;i++){ // Bit-wise X-OR of IACK to be sent with the 16-bits "variable"
variable[i]=(byte)(variable[i]^ arrSendDataBuffer[i]);
variable[i]=(byte)(variable[i] ^ arrSendDataBuffer[i+2]);
} // Doesn't include the INTEGRITY CHECK VALUE FIELD
return variable; // Returns the INTEGRITY CHECK VALUE to be appended in the IACK packet to be sent
}
// S byte state vector initialization
public static void RC4Initialization(byte[] arrKeys){
// Initialization of the S State and T vector
for(int s=0;s<256;s++){
S[s]=(byte)s; // Byte is signed type!
T[s] = arrKeys[s % arrKeys.length];
}
int j = 0;
byte temp; // Temporary variable used for swapping
if (arrKeys.length >0 && arrKeys.length < 257){ // Checking the length of the key
for (int i = 0; i < 256; i++) {
j = (j +positive(S[i]) + positive(T[i]))% 256;
temp=S[i]; // Swapping S[i] with another byte in S according to a scheme
S[i]=S[j]; // dictated by the current configuration of S
S[j]=temp;
}
}
else{
System.out.println("Invalid Length for key"); // Print Error Message and throw exception as below
throw new IllegalArgumentException("Key length should be greater than 0 and less than 256 bytes");
}
}
//Function for the Decryption of the received data packets
public static void RC4decryption(byte[] arrCipherTexts){
byte[] plainTexts = new byte[arrCipherTexts.length]; // Creating an array of bytes for Cipher Text
int i = 0, j = 0, k, t;
byte temp;
System.out.println("\n");
for (int z = 0; z < arrCipherTexts.length; z++) {
i = (i + 1) % 256;
j = (j + positive(S[i])) % 256;
temp=S[i];
S[i]=S[j];
S[j]=temp;
t = (positive(S[i]) + positive(S[j])) % 256; // Taking modulus i.e obtaining positive values
k = S[t];
plainTexts[z] = (byte) (arrCipherTexts[z] ^ k); // Cipher text XOR k= Plain text
receivedBytes[byteCount]=plainTexts[z];
byteCount++;
System.out.print("DecryptedByte "+(z+1)+"= "+plainTexts[z]+" "); // Print the Decrypted payload
}
}
//Function for getting absolute value of the byte number
public static int positive(byte temp){
if(temp>=0)
return temp;
else
return 256+temp; // Returns a positive value that results from the addition if the number is negative
}
//Function to display the received bytes
public static void display(int length){
System.out.println("\nReceived Data:");
for(int len=0;len<length;len++)
System.out.println("Byte["+(len+1)+"] ="+receivedBytes[len]); // Display the received data Bytes
System.out.println("____________PROGRAM END_______________");
}
// Function to get the no of data packet count
public static int getPacketCount(){
return(receivedBytes.length/40); // Returns the no of expected packets
}
public static byte[] getSendDataBuffer(){
return sendDataBuffer;
}
// Function to check the integrity of the received data packet
public static boolean dataPacketCheck(byte[] arrSequenceNumber,byte[] arrPacketType,int arrPacketCount,byte[] arrReceiveDataBuffer){
// Checking DATA packet for correct "PACKET TYPE", "SEQUENCE NUMBER"
if(arrReceiveDataBuffer[0]==arrPacketType[0] && arrReceiveDataBuffer[1]==arrPacketType[1] && arrReceiveDataBuffer[2]==arrSequenceNumber[0] && arrReceiveDataBuffer[3]==arrSequenceNumber[1]){
System.out.println("DATA Packet "+(arrPacketCount+1)+" Received"+"\n");
for(int i=0;i<arrReceiveDataBuffer.length;i++)
System.out.print("EncryptedByte "+(i+1)+"= "+arrReceiveDataBuffer[i]+" "); // Printing the received DATA packet i.e Encrypted transmitted data
for(int j=0;j<40;j++)
cipher[j]=arrReceiveDataBuffer[j+6];
ReceiverFunctions.RC4decryption(cipher); // Function call for Decrypting the Encrypted payload
System.out.println("\n");
System.out.println("Sending Acknowledgement for "+(arrPacketCount+1)+" Data packet");
sendDataBuffer=dackPacketBuffer(arrReceiveDataBuffer); // Keeps the received copy of DATA packet in SendDataBuffer for
// for acknowledging received DATA i.e Sending DACK
return true;
}
else
return false;
}
}