1 /* $Id$
2  * --------------------------------------------------------------------------
3  *
4  *           //=====   //===== ===//=== //===//  //       //   //===//
5  *          //        //         //    //    // //       //   //    //
6  *         //====//  //         //    //===//  //       //   //===<<
7  *              //  //         //    //       //       //   //    //
8  *       ======//  //=====    //    //       //=====  //   //===//
9  *
10  * -------------- An SCTP implementation according to RFC 4960 --------------
11  *
12  * Copyright (C) 2000 by Siemens AG, Munich, Germany.
13  * Copyright (C) 2001-2004 Andreas Jungmaier
14  * Copyright (C) 2004-2019 Thomas Dreibholz
15  *
16  * Acknowledgements:
17  * Realized in co-operation between Siemens AG and the University of
18  * Duisburg-Essen, Institute for Experimental Mathematics, Computer
19  * Networking Technology group.
20  * This work was partially funded by the Bundesministerium fuer Bildung und
21  * Forschung (BMBF) of the Federal Republic of Germany
22  * (Förderkennzeichen 01AK045).
23  * The authors alone are responsible for the contents.
24  *
25  * This library is free software: you can redistribute it and/or modify it
26  * under the terms of the GNU Lesser General Public License as published by
27  * the Free Software Foundation, either version 2.1 of the License, or
28  * (at your option) any later version.
29  *
30  * This library is distributed in the hope that it will be useful,
31  * but WITHOUT ANY WARRANTY; without even the implied warranty of
32  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
33  * GNU General Public License for more details.
34  *
35  * You should have received a copy of the GNU Lesser General Public License
36  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
37  *
38  * Contact: sctp-discussion@sctp.de
39  *          dreibh@iem.uni-due.de
40  *          tuexen@fh-muenster.de
41  *          andreas.jungmaier@web.de
42  */
43 
44 #include "auxiliary.h"
45 #include "globals.h"
46 #include "sctp.h"
47 #include "adaptation.h"
48 
49 #include <stdio.h>
50 
51 #define BASE 65521L             /* largest prime smaller than 65536 */
52 #define NMAX 5552
53 #define NMIN 16
54 
55 /* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
56 
57 #define DO1(buf,i)  {s1 += buf[i]; s2 += s1;}
58 #define DO2(buf,i)  DO1(buf,i); DO1(buf,i+1);
59 #define DO4(buf,i)  DO2(buf,i); DO2(buf,i+2);
60 #define DO8(buf,i)  DO4(buf,i); DO4(buf,i+4);
61 #define DO16(buf)   DO8(buf,0); DO8(buf,8);
62 
63 /* Example of the crc table file */
64 
65 #define CRC32C(c,d) (c=(c>>8)^crc_c[(c^(d))&0xFF])
66 
67 uint32_t crc_c[256] =
68 {
69     0x00000000, 0xF26B8303, 0xE13B70F7, 0x1350F3F4,
70     0xC79A971F, 0x35F1141C, 0x26A1E7E8, 0xD4CA64EB,
71     0x8AD958CF, 0x78B2DBCC, 0x6BE22838, 0x9989AB3B,
72     0x4D43CFD0, 0xBF284CD3, 0xAC78BF27, 0x5E133C24,
73     0x105EC76F, 0xE235446C, 0xF165B798, 0x030E349B,
74     0xD7C45070, 0x25AFD373, 0x36FF2087, 0xC494A384,
75     0x9A879FA0, 0x68EC1CA3, 0x7BBCEF57, 0x89D76C54,
76     0x5D1D08BF, 0xAF768BBC, 0xBC267848, 0x4E4DFB4B,
77     0x20BD8EDE, 0xD2D60DDD, 0xC186FE29, 0x33ED7D2A,
78     0xE72719C1, 0x154C9AC2, 0x061C6936, 0xF477EA35,
79     0xAA64D611, 0x580F5512, 0x4B5FA6E6, 0xB93425E5,
80     0x6DFE410E, 0x9F95C20D, 0x8CC531F9, 0x7EAEB2FA,
81     0x30E349B1, 0xC288CAB2, 0xD1D83946, 0x23B3BA45,
82     0xF779DEAE, 0x05125DAD, 0x1642AE59, 0xE4292D5A,
83     0xBA3A117E, 0x4851927D, 0x5B016189, 0xA96AE28A,
84     0x7DA08661, 0x8FCB0562, 0x9C9BF696, 0x6EF07595,
85     0x417B1DBC, 0xB3109EBF, 0xA0406D4B, 0x522BEE48,
86     0x86E18AA3, 0x748A09A0, 0x67DAFA54, 0x95B17957,
87     0xCBA24573, 0x39C9C670, 0x2A993584, 0xD8F2B687,
88     0x0C38D26C, 0xFE53516F, 0xED03A29B, 0x1F682198,
89     0x5125DAD3, 0xA34E59D0, 0xB01EAA24, 0x42752927,
90     0x96BF4DCC, 0x64D4CECF, 0x77843D3B, 0x85EFBE38,
91     0xDBFC821C, 0x2997011F, 0x3AC7F2EB, 0xC8AC71E8,
92     0x1C661503, 0xEE0D9600, 0xFD5D65F4, 0x0F36E6F7,
93     0x61C69362, 0x93AD1061, 0x80FDE395, 0x72966096,
94     0xA65C047D, 0x5437877E, 0x4767748A, 0xB50CF789,
95     0xEB1FCBAD, 0x197448AE, 0x0A24BB5A, 0xF84F3859,
96     0x2C855CB2, 0xDEEEDFB1, 0xCDBE2C45, 0x3FD5AF46,
97     0x7198540D, 0x83F3D70E, 0x90A324FA, 0x62C8A7F9,
98     0xB602C312, 0x44694011, 0x5739B3E5, 0xA55230E6,
99     0xFB410CC2, 0x092A8FC1, 0x1A7A7C35, 0xE811FF36,
100     0x3CDB9BDD, 0xCEB018DE, 0xDDE0EB2A, 0x2F8B6829,
101     0x82F63B78, 0x709DB87B, 0x63CD4B8F, 0x91A6C88C,
102     0x456CAC67, 0xB7072F64, 0xA457DC90, 0x563C5F93,
103     0x082F63B7, 0xFA44E0B4, 0xE9141340, 0x1B7F9043,
104     0xCFB5F4A8, 0x3DDE77AB, 0x2E8E845F, 0xDCE5075C,
105     0x92A8FC17, 0x60C37F14, 0x73938CE0, 0x81F80FE3,
106     0x55326B08, 0xA759E80B, 0xB4091BFF, 0x466298FC,
107     0x1871A4D8, 0xEA1A27DB, 0xF94AD42F, 0x0B21572C,
108     0xDFEB33C7, 0x2D80B0C4, 0x3ED04330, 0xCCBBC033,
109     0xA24BB5A6, 0x502036A5, 0x4370C551, 0xB11B4652,
110     0x65D122B9, 0x97BAA1BA, 0x84EA524E, 0x7681D14D,
111     0x2892ED69, 0xDAF96E6A, 0xC9A99D9E, 0x3BC21E9D,
112     0xEF087A76, 0x1D63F975, 0x0E330A81, 0xFC588982,
113     0xB21572C9, 0x407EF1CA, 0x532E023E, 0xA145813D,
114     0x758FE5D6, 0x87E466D5, 0x94B49521, 0x66DF1622,
115     0x38CC2A06, 0xCAA7A905, 0xD9F75AF1, 0x2B9CD9F2,
116     0xFF56BD19, 0x0D3D3E1A, 0x1E6DCDEE, 0xEC064EED,
117     0xC38D26C4, 0x31E6A5C7, 0x22B65633, 0xD0DDD530,
118     0x0417B1DB, 0xF67C32D8, 0xE52CC12C, 0x1747422F,
119     0x49547E0B, 0xBB3FFD08, 0xA86F0EFC, 0x5A048DFF,
120     0x8ECEE914, 0x7CA56A17, 0x6FF599E3, 0x9D9E1AE0,
121     0xD3D3E1AB, 0x21B862A8, 0x32E8915C, 0xC083125F,
122     0x144976B4, 0xE622F5B7, 0xF5720643, 0x07198540,
123     0x590AB964, 0xAB613A67, 0xB831C993, 0x4A5A4A90,
124     0x9E902E7B, 0x6CFBAD78, 0x7FAB5E8C, 0x8DC0DD8F,
125     0xE330A81A, 0x115B2B19, 0x020BD8ED, 0xF0605BEE,
126     0x24AA3F05, 0xD6C1BC06, 0xC5914FF2, 0x37FACCF1,
127     0x69E9F0D5, 0x9B8273D6, 0x88D28022, 0x7AB90321,
128     0xAE7367CA, 0x5C18E4C9, 0x4F48173D, 0xBD23943E,
129     0xF36E6F75, 0x0105EC76, 0x12551F82, 0xE03E9C81,
130     0x34F4F86A, 0xC69F7B69, 0xD5CF889D, 0x27A40B9E,
131     0x79B737BA, 0x8BDCB4B9, 0x988C474D, 0x6AE7C44E,
132     0xBE2DA0A5, 0x4C4623A6, 0x5F16D052, 0xAD7D5351,
133 };
134 
135 static int insert_adler32(unsigned char *buffer, int length);
136 static int insert_crc32(unsigned char *buffer, int length);
137 static int validate_adler32(unsigned char *header_start, int length);
138 static int validate_crc32(unsigned char *buffer, int length);
139 
140 
141 static int (*insert_checksum) (unsigned char* buffer, int length) = insert_crc32;
142 static int (*validate_checksum) (unsigned char* buffer, int length) = validate_crc32;
143 
144 
145 static uint32_t sctp_adler32(uint32_t adler, const unsigned char *buf, unsigned int len);
146 
147 
set_checksum_algorithm(int algorithm)148 int set_checksum_algorithm(int algorithm){
149     if (algorithm == SCTP_CHECKSUM_ALGORITHM_CRC32C) {
150         insert_checksum =  &insert_crc32;
151         validate_checksum =  &validate_crc32;
152         return SCTP_SUCCESS;
153     } else if (algorithm == SCTP_CHECKSUM_ALGORITHM_ADLER32) {
154         insert_checksum =  &insert_adler32;
155         validate_checksum =  &validate_adler32;
156         return SCTP_SUCCESS;
157     } else
158         return -1;
159 }
160 
161 
key_operation(int operation_code)162 unsigned char* key_operation(int operation_code)
163 {
164     static unsigned char *secret_key = NULL;
165     uint32_t              count = 0, tmp;
166 
167     if (operation_code == KEY_READ) return secret_key;
168     else if (operation_code == KEY_INIT) {
169         if (secret_key != NULL) {
170             error_log(ERROR_MAJOR, "tried to init secret key, but key already created !");
171             return secret_key;
172         }
173         secret_key = (unsigned char*)malloc(SECRET_KEYSIZE);
174         while (count < SECRET_KEYSIZE){
175             /* if you care for security, you need to use a cryptographically secure PRNG */
176             tmp = adl_random();
177             memcpy(&secret_key[count], &tmp, sizeof(uint32_t));
178             count += sizeof(uint32_t);
179         }
180     } else {
181         error_log(ERROR_MAJOR, "unknown key operation code !");
182         return NULL;
183     }
184     return secret_key;
185 }
186 
aux_insert_checksum(unsigned char * buffer,int length)187 int aux_insert_checksum(unsigned char *buffer, int length)
188 {
189     return ((*insert_checksum)(buffer,length));
190 }
191 
192 
insert_adler32(unsigned char * buffer,int length)193 static int insert_adler32(unsigned char *buffer, int length)
194 {
195     SCTP_message *message;
196     uint32_t      a32;
197     /* save crc value from PDU */
198     if (length > NMAX || length < NMIN)
199         return -1;
200     message = (SCTP_message *) buffer;
201     message->common_header.checksum = htonl(0L);
202 
203     /* now compute the thingie */
204     /* FIXME : sanity checks for size etc. */
205     a32 = sctp_adler32(1, buffer, length);
206 
207     /* and insert it into the message */
208     message->common_header.checksum = htonl(a32);
209 
210     event_logi(VERBOSE, "DEBUG Validation : Inserting adler32 == %x", a32);
211 
212     return 1;
213 }
214 
generate_crc32c(unsigned char * buffer,int length)215 static uint32_t generate_crc32c(unsigned char *buffer, int length)
216 {
217     unsigned char byte0, byte1, byte2, byte3, swap;
218     uint32_t      crc32 = ~0L;
219     int           i;
220 
221     for (i = 0; i < length; i++)
222     {
223       CRC32C(crc32, buffer[i]);
224     }
225     crc32 =~ crc32;
226     /* do the swap */
227     byte0 = (unsigned char) crc32 & 0xff;
228     byte1 = (unsigned char) (crc32>>8) & 0xff;
229     byte2 = (unsigned char) (crc32>>16) & 0xff;
230     byte3 = (unsigned char) (crc32>>24) & 0xff;
231     swap = byte0; byte0 = byte3; byte3 = swap;
232     swap = byte1; byte1 = byte2; byte2 = swap;
233     crc32 = ((byte3 << 24)|(byte2 << 16)|(byte1 << 8)| byte0);
234 
235     return crc32;
236 
237 }
238 
insert_crc32(unsigned char * buffer,int length)239 static int insert_crc32(unsigned char *buffer, int length)
240 {
241     SCTP_message *message;
242     uint32_t      crc32c;
243 
244     /* check packet length */
245     if (length > NMAX  || length < NMIN)
246       return -1;
247 
248     message = (SCTP_message *) buffer;
249     message->common_header.checksum = 0L;
250     crc32c =  generate_crc32c(buffer, length);
251     /* and insert it into the message */
252     message->common_header.checksum = htonl(crc32c);
253 
254    return 1;
255 }
256 
257 
validate_size(unsigned char * header_start,int length)258 int validate_size(unsigned char *header_start, int length)
259 {
260     if ((length % 4) != 0L)
261         return 0;
262     if (length > NMAX  || length < NMIN)
263         return 0;
264     return 1;
265 }
266 
267 
268 
validate_adler32(unsigned char * header_start,int length)269 static int validate_adler32(unsigned char *header_start, int length)
270 {
271     SCTP_message *message;
272     uint32_t      old_crc32;
273     uint32_t      a32;
274 
275     /* save crc value from PDU */
276     message = (SCTP_message *) header_start;
277     old_crc32 = ntohl(message->common_header.checksum);
278 
279     event_logi(VVERBOSE, "DEBUG Validation : old adler == %x", old_crc32);
280 
281     message->common_header.checksum = htonl(0L);
282 
283     /* now compute the thingie */
284     a32 = sctp_adler32(1, header_start, length);
285 
286     event_logi(VVERBOSE, "DEBUG Validation : my adler32 == %x", a32);
287     if (a32 == old_crc32)  return 1;
288     return 0;
289 }
290 
validate_crc32(unsigned char * buffer,int length)291 static int validate_crc32(unsigned char *buffer, int length)
292 {
293     SCTP_message *message;
294     uint32_t      original_crc32;
295     uint32_t      crc32 = ~0;
296 
297     /* check packet length */
298 
299     /* save and zero checksum */
300     message = (SCTP_message *) buffer;
301     original_crc32 = ntohl(message->common_header.checksum);
302     event_logi(VVERBOSE, "DEBUG Validation : old crc32c == %x", original_crc32);
303     message->common_header.checksum = 0;
304     crc32 = generate_crc32c(buffer, length);
305     event_logi(VVERBOSE, "DEBUG Validation : my crc32c == %x", crc32);
306 
307     return ((original_crc32 == crc32)? 1 : 0);
308 }
309 
310 
311 
validate_datagram(unsigned char * buffer,int length)312 int validate_datagram(unsigned char *buffer, int length)
313 {
314     /* sanity check for size (min,max, multiple of 32 bits) */
315     if (!validate_size(buffer, length))
316         return 0;
317     if (!(*validate_checksum)(buffer, length))
318         return 0;
319     /* FIXME :  validation is not yet complete */
320     return 1;
321 }
322 
323 /**
324  * adler32.c -- compute the Adler-32 checksum of a data stream
325  * Copyright (C) 1995-1996 Mark Adler
326  * For conditions of distribution and use, see copyright notice in zlib.h
327  * available, e.g. from  http://www.cdrom.com/pub/infozip/zlib/
328  */
sctp_adler32(uint32_t adler,const unsigned char * buf,unsigned int len)329 static uint32_t sctp_adler32(uint32_t adler, const unsigned char *buf, unsigned int len)
330 {
331     uint32_t s1 = adler & 0xffff;
332     uint32_t s2 = (adler >> 16) & 0xffff;
333     int      k;
334 
335     if (buf == NULL)
336         return 1L;
337 
338     while (len > 0) {
339         k = len < NMAX ? len : NMAX;
340         len -= k;
341         while (k >= 16) {
342             DO16(buf);
343             buf += 16;
344             k -= 16;
345         }
346         if (k != 0)
347             do {
348                 s1 += *buf++;
349                 s2 += s1;
350             }
351             while (--k);
352         s1 %= BASE;
353         s2 %= BASE;
354     }
355     return (s2 << 16) | s1;
356 }
357