OLD | NEW |
| (Empty) |
1 /* | |
2 * datatypes.h | |
3 * | |
4 * data types for bit vectors and finite fields | |
5 * | |
6 * David A. McGrew | |
7 * Cisco Systems, Inc. | |
8 */ | |
9 | |
10 /* | |
11 * | |
12 * Copyright (c) 2001-2006, Cisco Systems, Inc. | |
13 * All rights reserved. | |
14 * | |
15 * Redistribution and use in source and binary forms, with or without | |
16 * modification, are permitted provided that the following conditions | |
17 * are met: | |
18 * | |
19 * Redistributions of source code must retain the above copyright | |
20 * notice, this list of conditions and the following disclaimer. | |
21 * | |
22 * Redistributions in binary form must reproduce the above | |
23 * copyright notice, this list of conditions and the following | |
24 * disclaimer in the documentation and/or other materials provided | |
25 * with the distribution. | |
26 * | |
27 * Neither the name of the Cisco Systems, Inc. nor the names of its | |
28 * contributors may be used to endorse or promote products derived | |
29 * from this software without specific prior written permission. | |
30 * | |
31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |
32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |
33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS | |
34 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE | |
35 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, | |
36 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | |
37 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR | |
38 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
39 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | |
40 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |
41 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED | |
42 * OF THE POSSIBILITY OF SUCH DAMAGE. | |
43 * | |
44 */ | |
45 | |
46 | |
47 #ifndef _DATATYPES_H | |
48 #define _DATATYPES_H | |
49 | |
50 #include "integers.h" /* definitions of uint32_t, et cetera */ | |
51 #include "alloc.h" | |
52 | |
53 #include <stdarg.h> | |
54 | |
55 #ifndef SRTP_KERNEL | |
56 # include <stdio.h> | |
57 # include <string.h> | |
58 # include <time.h> | |
59 # ifdef HAVE_NETINET_IN_H | |
60 # include <netinet/in.h> | |
61 # elif defined HAVE_WINSOCK2_H | |
62 # include <winsock2.h> | |
63 # elif defined HAVE_BYTESWAP_METHODS_H | |
64 # include <stdlib.h> | |
65 # define ntohl(x) _byteswap_ulong (x) | |
66 # define ntohs(x) _byteswap_ushort (x) | |
67 # define htonl(x) _byteswap_ulong (x) | |
68 # define htons(x) _byteswap_ushort (x) | |
69 # endif | |
70 #endif | |
71 | |
72 | |
73 /* if DATATYPES_USE_MACROS is defined, then little functions are macros */ | |
74 #define DATATYPES_USE_MACROS | |
75 | |
76 typedef union { | |
77 uint8_t v8[2]; | |
78 uint16_t value; | |
79 } v16_t; | |
80 | |
81 typedef union { | |
82 uint8_t v8[4]; | |
83 uint16_t v16[2]; | |
84 uint32_t value; | |
85 } v32_t; | |
86 | |
87 typedef union { | |
88 uint8_t v8[8]; | |
89 uint16_t v16[4]; | |
90 uint32_t v32[2]; | |
91 uint64_t value; | |
92 } v64_t; | |
93 | |
94 typedef union { | |
95 uint8_t v8[16]; | |
96 uint16_t v16[8]; | |
97 uint32_t v32[4]; | |
98 uint64_t v64[2]; | |
99 } v128_t; | |
100 | |
101 typedef union { | |
102 uint8_t v8[32]; | |
103 uint16_t v16[16]; | |
104 uint32_t v32[8]; | |
105 uint64_t v64[4]; | |
106 } v256_t; | |
107 | |
108 | |
109 /* some useful and simple math functions */ | |
110 | |
111 #define pow_2(X) ( (unsigned int)1 << (X) ) /* 2^X */ | |
112 | |
113 #define pow_minus_one(X) ( (X) ? -1 : 1 ) /* (-1)^X */ | |
114 | |
115 | |
116 /* | |
117 * octet_get_weight(x) returns the hamming weight (number of bits equal to | |
118 * one) in the octet x | |
119 */ | |
120 | |
121 int | |
122 octet_get_weight(uint8_t octet); | |
123 | |
124 char * | |
125 octet_bit_string(uint8_t x); | |
126 | |
127 #define MAX_PRINT_STRING_LEN 1024 | |
128 | |
129 char * | |
130 octet_string_hex_string(const void *str, int length); | |
131 | |
132 char * | |
133 v128_bit_string(v128_t *x); | |
134 | |
135 char * | |
136 v128_hex_string(v128_t *x); | |
137 | |
138 uint8_t | |
139 nibble_to_hex_char(uint8_t nibble); | |
140 | |
141 char * | |
142 char_to_hex_string(char *x, int num_char); | |
143 | |
144 uint8_t | |
145 hex_string_to_octet(char *s); | |
146 | |
147 /* | |
148 * hex_string_to_octet_string(raw, hex, len) converts the hexadecimal | |
149 * string at *hex (of length len octets) to the equivalent raw data | |
150 * and writes it to *raw. | |
151 * | |
152 * if a character in the hex string that is not a hexadeciaml digit | |
153 * (0123456789abcdefABCDEF) is encountered, the function stops writing | |
154 * data to *raw | |
155 * | |
156 * the number of hex digits copied (which is two times the number of | |
157 * octets in *raw) is returned | |
158 */ | |
159 | |
160 int | |
161 hex_string_to_octet_string(char *raw, char *hex, int len); | |
162 | |
163 v128_t | |
164 hex_string_to_v128(char *s); | |
165 | |
166 void | |
167 v128_copy_octet_string(v128_t *x, const uint8_t s[16]); | |
168 | |
169 void | |
170 v128_left_shift(v128_t *x, int shift_index); | |
171 | |
172 void | |
173 v128_right_shift(v128_t *x, int shift_index); | |
174 | |
175 /* | |
176 * the following macros define the data manipulation functions | |
177 * | |
178 * If DATATYPES_USE_MACROS is defined, then these macros are used | |
179 * directly (and function call overhead is avoided). Otherwise, | |
180 * the macros are used through the functions defined in datatypes.c | |
181 * (and the compiler provides better warnings). | |
182 */ | |
183 | |
184 #define _v128_set_to_zero(x) \ | |
185 ( \ | |
186 (x)->v32[0] = 0, \ | |
187 (x)->v32[1] = 0, \ | |
188 (x)->v32[2] = 0, \ | |
189 (x)->v32[3] = 0 \ | |
190 ) | |
191 | |
192 #define _v128_copy(x, y) \ | |
193 ( \ | |
194 (x)->v32[0] = (y)->v32[0], \ | |
195 (x)->v32[1] = (y)->v32[1], \ | |
196 (x)->v32[2] = (y)->v32[2], \ | |
197 (x)->v32[3] = (y)->v32[3] \ | |
198 ) | |
199 | |
200 #define _v128_xor(z, x, y) \ | |
201 ( \ | |
202 (z)->v32[0] = (x)->v32[0] ^ (y)->v32[0], \ | |
203 (z)->v32[1] = (x)->v32[1] ^ (y)->v32[1], \ | |
204 (z)->v32[2] = (x)->v32[2] ^ (y)->v32[2], \ | |
205 (z)->v32[3] = (x)->v32[3] ^ (y)->v32[3] \ | |
206 ) | |
207 | |
208 #define _v128_and(z, x, y) \ | |
209 ( \ | |
210 (z)->v32[0] = (x)->v32[0] & (y)->v32[0], \ | |
211 (z)->v32[1] = (x)->v32[1] & (y)->v32[1], \ | |
212 (z)->v32[2] = (x)->v32[2] & (y)->v32[2], \ | |
213 (z)->v32[3] = (x)->v32[3] & (y)->v32[3] \ | |
214 ) | |
215 | |
216 #define _v128_or(z, x, y) \ | |
217 ( \ | |
218 (z)->v32[0] = (x)->v32[0] | (y)->v32[0], \ | |
219 (z)->v32[1] = (x)->v32[1] | (y)->v32[1], \ | |
220 (z)->v32[2] = (x)->v32[2] | (y)->v32[2], \ | |
221 (z)->v32[3] = (x)->v32[3] | (y)->v32[3] \ | |
222 ) | |
223 | |
224 #define _v128_complement(x) \ | |
225 ( \ | |
226 (x)->v32[0] = ~(x)->v32[0], \ | |
227 (x)->v32[1] = ~(x)->v32[1], \ | |
228 (x)->v32[2] = ~(x)->v32[2], \ | |
229 (x)->v32[3] = ~(x)->v32[3] \ | |
230 ) | |
231 | |
232 /* ok for NO_64BIT_MATH if it can compare uint64_t's (even as structures) */ | |
233 #define _v128_is_eq(x, y) \ | |
234 (((x)->v64[0] == (y)->v64[0]) && ((x)->v64[1] == (y)->v64[1])) | |
235 | |
236 | |
237 #ifdef NO_64BIT_MATH | |
238 #define _v128_xor_eq(z, x) \ | |
239 ( \ | |
240 (z)->v32[0] ^= (x)->v32[0], \ | |
241 (z)->v32[1] ^= (x)->v32[1], \ | |
242 (z)->v32[2] ^= (x)->v32[2], \ | |
243 (z)->v32[3] ^= (x)->v32[3] \ | |
244 ) | |
245 #else | |
246 #define _v128_xor_eq(z, x) \ | |
247 ( \ | |
248 (z)->v64[0] ^= (x)->v64[0], \ | |
249 (z)->v64[1] ^= (x)->v64[1] \ | |
250 ) | |
251 #endif | |
252 | |
253 /* NOTE! This assumes an odd ordering! */ | |
254 /* This will not be compatible directly with math on some processors */ | |
255 /* bit 0 is first 32-bit word, low order bit. in little-endian, that's | |
256 the first byte of the first 32-bit word. In big-endian, that's | |
257 the 3rd byte of the first 32-bit word */ | |
258 /* The get/set bit code is used by the replay code ONLY, and it doesn't | |
259 really care which bit is which. AES does care which bit is which, but | |
260 doesn't use the 128-bit get/set or 128-bit shifts */ | |
261 | |
262 #define _v128_get_bit(x, bit) \ | |
263 ( \ | |
264 ((((x)->v32[(bit) >> 5]) >> ((bit) & 31)) & 1) \ | |
265 ) | |
266 | |
267 #define _v128_set_bit(x, bit) \ | |
268 ( \ | |
269 (((x)->v32[(bit) >> 5]) |= ((uint32_t)1 << ((bit) & 31))) \ | |
270 ) | |
271 | |
272 #define _v128_clear_bit(x, bit) \ | |
273 ( \ | |
274 (((x)->v32[(bit) >> 5]) &= ~((uint32_t)1 << ((bit) & 31))) \ | |
275 ) | |
276 | |
277 #define _v128_set_bit_to(x, bit, value) \ | |
278 ( \ | |
279 (value) ? _v128_set_bit(x, bit) : \ | |
280 _v128_clear_bit(x, bit) \ | |
281 ) | |
282 | |
283 | |
284 #if 0 | |
285 /* nothing uses this */ | |
286 #ifdef WORDS_BIGENDIAN | |
287 | |
288 #define _v128_add(z, x, y) { \ | |
289 uint64_t tmp; \ | |
290 \ | |
291 tmp = x->v32[3] + y->v32[3]; \ | |
292 z->v32[3] = (uint32_t) tmp; \ | |
293 \ | |
294 tmp = x->v32[2] + y->v32[2] + (tmp >> 32); \ | |
295 z->v32[2] = (uint32_t) tmp; \ | |
296 \ | |
297 tmp = x->v32[1] + y->v32[1] + (tmp >> 32); \ | |
298 z->v32[1] = (uint32_t) tmp; \ | |
299 \ | |
300 tmp = x->v32[0] + y->v32[0] + (tmp >> 32); \ | |
301 z->v32[0] = (uint32_t) tmp; \ | |
302 } | |
303 | |
304 #else /* assume little endian architecture */ | |
305 | |
306 #define _v128_add(z, x, y) { \ | |
307 uint64_t tmp; \ | |
308 \ | |
309 tmp = htonl(x->v32[3]) + htonl(y->v32[3]); \ | |
310 z->v32[3] = ntohl((uint32_t) tmp); \ | |
311 \ | |
312 tmp = htonl(x->v32[2]) + htonl(y->v32[2]) \ | |
313 + htonl(tmp >> 32); \ | |
314 z->v32[2] = ntohl((uint32_t) tmp); \ | |
315 \ | |
316 tmp = htonl(x->v32[1]) + htonl(y->v32[1]) \ | |
317 + htonl(tmp >> 32); \ | |
318 z->v32[1] = ntohl((uint32_t) tmp); \ | |
319 \ | |
320 tmp = htonl(x->v32[0]) + htonl(y->v32[0]) \ | |
321 + htonl(tmp >> 32); \ | |
322 z->v32[0] = ntohl((uint32_t) tmp); \ | |
323 } | |
324 #endif /* WORDS_BIGENDIAN */ | |
325 #endif /* 0 */ | |
326 | |
327 | |
328 #ifdef DATATYPES_USE_MACROS /* little functions are really macros */ | |
329 | |
330 #define v128_set_to_zero(z) _v128_set_to_zero(z) | |
331 #define v128_copy(z, x) _v128_copy(z, x) | |
332 #define v128_xor(z, x, y) _v128_xor(z, x, y) | |
333 #define v128_and(z, x, y) _v128_and(z, x, y) | |
334 #define v128_or(z, x, y) _v128_or(z, x, y) | |
335 #define v128_complement(x) _v128_complement(x) | |
336 #define v128_is_eq(x, y) _v128_is_eq(x, y) | |
337 #define v128_xor_eq(x, y) _v128_xor_eq(x, y) | |
338 #define v128_get_bit(x, i) _v128_get_bit(x, i) | |
339 #define v128_set_bit(x, i) _v128_set_bit(x, i) | |
340 #define v128_clear_bit(x, i) _v128_clear_bit(x, i) | |
341 #define v128_set_bit_to(x, i, y) _v128_set_bit_to(x, i, y) | |
342 | |
343 #else | |
344 | |
345 void | |
346 v128_set_to_zero(v128_t *x); | |
347 | |
348 int | |
349 v128_is_eq(const v128_t *x, const v128_t *y); | |
350 | |
351 void | |
352 v128_copy(v128_t *x, const v128_t *y); | |
353 | |
354 void | |
355 v128_xor(v128_t *z, v128_t *x, v128_t *y); | |
356 | |
357 void | |
358 v128_and(v128_t *z, v128_t *x, v128_t *y); | |
359 | |
360 void | |
361 v128_or(v128_t *z, v128_t *x, v128_t *y); | |
362 | |
363 void | |
364 v128_complement(v128_t *x); | |
365 | |
366 int | |
367 v128_get_bit(const v128_t *x, int i); | |
368 | |
369 void | |
370 v128_set_bit(v128_t *x, int i) ; | |
371 | |
372 void | |
373 v128_clear_bit(v128_t *x, int i); | |
374 | |
375 void | |
376 v128_set_bit_to(v128_t *x, int i, int y); | |
377 | |
378 #endif /* DATATYPES_USE_MACROS */ | |
379 | |
380 /* | |
381 * octet_string_is_eq(a,b, len) returns 1 if the length len strings a | |
382 * and b are not equal, returns 0 otherwise | |
383 */ | |
384 | |
385 int | |
386 octet_string_is_eq(uint8_t *a, uint8_t *b, int len); | |
387 | |
388 void | |
389 octet_string_set_to_zero(uint8_t *s, int len); | |
390 | |
391 | |
392 #if !defined(SRTP_KERNEL_LINUX) && defined(HAVE_CONFIG_H) | |
393 | |
394 /* | |
395 * Convert big endian integers to CPU byte order. | |
396 */ | |
397 #ifdef WORDS_BIGENDIAN | |
398 /* Nothing to do. */ | |
399 # define be32_to_cpu(x) (x) | |
400 # define be64_to_cpu(x) (x) | |
401 #elif defined(HAVE_BYTESWAP_H) | |
402 /* We have (hopefully) optimized versions in byteswap.h */ | |
403 # include <byteswap.h> | |
404 # define be32_to_cpu(x) bswap_32((x)) | |
405 # define be64_to_cpu(x) bswap_64((x)) | |
406 #else | |
407 | |
408 #if defined(__GNUC__) && defined(HAVE_X86) | |
409 /* Fall back. */ | |
410 static inline uint32_t be32_to_cpu(uint32_t v) { | |
411 /* optimized for x86. */ | |
412 asm("bswap %0" : "=r" (v) : "0" (v)); | |
413 return v; | |
414 } | |
415 # else /* HAVE_X86 */ | |
416 # ifdef HAVE_NETINET_IN_H | |
417 # include <netinet/in.h> | |
418 # elif defined HAVE_WINSOCK2_H | |
419 # include <winsock2.h> | |
420 # endif | |
421 # define be32_to_cpu(x) ntohl((x)) | |
422 # endif /* HAVE_X86 */ | |
423 | |
424 static inline uint64_t be64_to_cpu(uint64_t v) { | |
425 # ifdef NO_64BIT_MATH | |
426 /* use the make64 functions to do 64-bit math */ | |
427 v = make64(htonl(low32(v)),htonl(high32(v))); | |
428 # else | |
429 /* use the native 64-bit math */ | |
430 v= (uint64_t)((be32_to_cpu((uint32_t)(v >> 32))) | (((uint64_t)be32_to_cpu((u
int32_t)v)) << 32)); | |
431 # endif | |
432 return v; | |
433 } | |
434 | |
435 #endif /* ! SRTP_KERNEL_LINUX */ | |
436 | |
437 #endif /* WORDS_BIGENDIAN */ | |
438 | |
439 /* | |
440 * functions manipulating bitvector_t | |
441 * | |
442 * A bitvector_t consists of an array of words and an integer | |
443 * representing the number of significant bits stored in the array. | |
444 * The bits are packed as follows: the least significant bit is that | |
445 * of word[0], while the most significant bit is the nth most | |
446 * significant bit of word[m], where length = bits_per_word * m + n. | |
447 * | |
448 */ | |
449 | |
450 #define bits_per_word 32 | |
451 #define bytes_per_word 4 | |
452 | |
453 typedef struct { | |
454 uint32_t length; | |
455 uint32_t *word; | |
456 } bitvector_t; | |
457 | |
458 | |
459 #define _bitvector_get_bit(v, bit_index) \ | |
460 ( \ | |
461 ((((v)->word[((bit_index) >> 5)]) >> ((bit_index) & 31)) & 1) \ | |
462 ) | |
463 | |
464 | |
465 #define _bitvector_set_bit(v, bit_index) \ | |
466 ( \ | |
467 (((v)->word[((bit_index) >> 5)] |= ((uint32_t)1 << ((bit_index) & 31)))) \ | |
468 ) | |
469 | |
470 #define _bitvector_clear_bit(v, bit_index) \ | |
471 ( \ | |
472 (((v)->word[((bit_index) >> 5)] &= ~((uint32_t)1 << ((bit_index) & 31)))) \ | |
473 ) | |
474 | |
475 #define _bitvector_get_length(v) \ | |
476 ( \ | |
477 ((v)->length) \ | |
478 ) | |
479 | |
480 #ifdef DATATYPES_USE_MACROS /* little functions are really macros */ | |
481 | |
482 #define bitvector_get_bit(v, bit_index) _bitvector_get_bit(v, bit_index) | |
483 #define bitvector_set_bit(v, bit_index) _bitvector_set_bit(v, bit_index) | |
484 #define bitvector_clear_bit(v, bit_index) _bitvector_clear_bit(v, bit_index) | |
485 #define bitvector_get_length(v) _bitvector_get_length(v) | |
486 | |
487 #else | |
488 | |
489 int | |
490 bitvector_get_bit(const bitvector_t *v, int bit_index); | |
491 | |
492 void | |
493 bitvector_set_bit(bitvector_t *v, int bit_index); | |
494 | |
495 void | |
496 bitvector_clear_bit(bitvector_t *v, int bit_index); | |
497 | |
498 unsigned long | |
499 bitvector_get_length(const bitvector_t *v); | |
500 | |
501 #endif | |
502 | |
503 int | |
504 bitvector_alloc(bitvector_t *v, unsigned long length); | |
505 | |
506 void | |
507 bitvector_dealloc(bitvector_t *v); | |
508 | |
509 void | |
510 bitvector_set_to_zero(bitvector_t *x); | |
511 | |
512 void | |
513 bitvector_left_shift(bitvector_t *x, int index); | |
514 | |
515 char * | |
516 bitvector_bit_string(bitvector_t *x, char* buf, int len); | |
517 | |
518 #ifdef TESTAPP_SOURCE | |
519 int base64_string_to_octet_string(char *raw, int *pad, char *base64, int len); | |
520 #endif | |
521 | |
522 #endif /* _DATATYPES_H */ | |
OLD | NEW |