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 | # endif |
64 | #endif |
65 | |
66 | |
67 | /* if DATATYPES_USE_MACROS is defined, then little functions are macros */ |
68 | #define DATATYPES_USE_MACROS |
69 | |
70 | typedef union { |
71 | uint8_t v8[2]; |
72 | uint16_t value; |
73 | } v16_t; |
74 | |
75 | typedef union { |
76 | uint8_t v8[4]; |
77 | uint16_t v16[2]; |
78 | uint32_t value; |
79 | } v32_t; |
80 | |
81 | typedef union { |
82 | uint8_t v8[8]; |
83 | uint16_t v16[4]; |
84 | uint32_t v32[2]; |
85 | uint64_t value; |
86 | } v64_t; |
87 | |
88 | typedef union { |
89 | uint8_t v8[16]; |
90 | uint16_t v16[8]; |
91 | uint32_t v32[4]; |
92 | uint64_t v64[2]; |
93 | } v128_t; |
94 | |
95 | |
96 | |
97 | /* some useful and simple math functions */ |
98 | |
99 | #define pow_2(X) ( (unsigned int)1 << (X) ) /* 2^X */ |
100 | |
101 | #define pow_minus_one(X) ( (X) ? -1 : 1 ) /* (-1)^X */ |
102 | |
103 | |
104 | /* |
105 | * octet_get_weight(x) returns the hamming weight (number of bits equal to |
106 | * one) in the octet x |
107 | */ |
108 | |
109 | int |
110 | octet_get_weight(uint8_t octet); |
111 | |
112 | char * |
113 | octet_bit_string(uint8_t x); |
114 | |
115 | #define MAX_PRINT_STRING_LEN 1024 |
116 | |
117 | char * |
118 | octet_string_hex_string(const void *str, int length); |
119 | |
120 | char * |
121 | v128_bit_string(v128_t *x); |
122 | |
123 | char * |
124 | v128_hex_string(v128_t *x); |
125 | |
126 | uint8_t |
127 | nibble_to_hex_char(uint8_t nibble); |
128 | |
129 | char * |
130 | char_to_hex_string(char *x, int num_char); |
131 | |
132 | uint8_t |
133 | hex_string_to_octet(char *s); |
134 | |
135 | /* |
136 | * hex_string_to_octet_string(raw, hex, len) converts the hexadecimal |
137 | * string at *hex (of length len octets) to the equivalent raw data |
138 | * and writes it to *raw. |
139 | * |
140 | * if a character in the hex string that is not a hexadeciaml digit |
141 | * (0123456789abcdefABCDEF) is encountered, the function stops writing |
142 | * data to *raw |
143 | * |
144 | * the number of hex digits copied (which is two times the number of |
145 | * octets in *raw) is returned |
146 | */ |
147 | |
148 | int |
149 | hex_string_to_octet_string(char *raw, char *hex, int len); |
150 | |
151 | v128_t |
152 | hex_string_to_v128(char *s); |
153 | |
154 | void |
155 | v128_copy_octet_string(v128_t *x, const uint8_t s[16]); |
156 | |
157 | void |
158 | v128_left_shift(v128_t *x, int shift_index); |
159 | |
160 | void |
161 | v128_right_shift(v128_t *x, int shift_index); |
162 | |
163 | /* |
164 | * the following macros define the data manipulation functions |
165 | * |
166 | * If DATATYPES_USE_MACROS is defined, then these macros are used |
167 | * directly (and function call overhead is avoided). Otherwise, |
168 | * the macros are used through the functions defined in datatypes.c |
169 | * (and the compiler provides better warnings). |
170 | */ |
171 | |
172 | #define _v128_set_to_zero(x) \ |
173 | ( \ |
174 | (x)->v32[0] = 0, \ |
175 | (x)->v32[1] = 0, \ |
176 | (x)->v32[2] = 0, \ |
177 | (x)->v32[3] = 0 \ |
178 | ) |
179 | |
180 | #define _v128_copy(x, y) \ |
181 | ( \ |
182 | (x)->v32[0] = (y)->v32[0], \ |
183 | (x)->v32[1] = (y)->v32[1], \ |
184 | (x)->v32[2] = (y)->v32[2], \ |
185 | (x)->v32[3] = (y)->v32[3] \ |
186 | ) |
187 | |
188 | #define _v128_xor(z, x, y) \ |
189 | ( \ |
190 | (z)->v32[0] = (x)->v32[0] ^ (y)->v32[0], \ |
191 | (z)->v32[1] = (x)->v32[1] ^ (y)->v32[1], \ |
192 | (z)->v32[2] = (x)->v32[2] ^ (y)->v32[2], \ |
193 | (z)->v32[3] = (x)->v32[3] ^ (y)->v32[3] \ |
194 | ) |
195 | |
196 | #define _v128_and(z, x, y) \ |
197 | ( \ |
198 | (z)->v32[0] = (x)->v32[0] & (y)->v32[0], \ |
199 | (z)->v32[1] = (x)->v32[1] & (y)->v32[1], \ |
200 | (z)->v32[2] = (x)->v32[2] & (y)->v32[2], \ |
201 | (z)->v32[3] = (x)->v32[3] & (y)->v32[3] \ |
202 | ) |
203 | |
204 | #define _v128_or(z, x, y) \ |
205 | ( \ |
206 | (z)->v32[0] = (x)->v32[0] | (y)->v32[0], \ |
207 | (z)->v32[1] = (x)->v32[1] | (y)->v32[1], \ |
208 | (z)->v32[2] = (x)->v32[2] | (y)->v32[2], \ |
209 | (z)->v32[3] = (x)->v32[3] | (y)->v32[3] \ |
210 | ) |
211 | |
212 | #define _v128_complement(x) \ |
213 | ( \ |
214 | (x)->v32[0] = ~(x)->v32[0], \ |
215 | (x)->v32[1] = ~(x)->v32[1], \ |
216 | (x)->v32[2] = ~(x)->v32[2], \ |
217 | (x)->v32[3] = ~(x)->v32[3] \ |
218 | ) |
219 | |
220 | /* ok for NO_64BIT_MATH if it can compare uint64_t's (even as structures) */ |
221 | #define _v128_is_eq(x, y) \ |
222 | (((x)->v64[0] == (y)->v64[0]) && ((x)->v64[1] == (y)->v64[1])) |
223 | |
224 | |
225 | #ifdef NO_64BIT_MATH |
226 | #define _v128_xor_eq(z, x) \ |
227 | ( \ |
228 | (z)->v32[0] ^= (x)->v32[0], \ |
229 | (z)->v32[1] ^= (x)->v32[1], \ |
230 | (z)->v32[2] ^= (x)->v32[2], \ |
231 | (z)->v32[3] ^= (x)->v32[3] \ |
232 | ) |
233 | #else |
234 | #define _v128_xor_eq(z, x) \ |
235 | ( \ |
236 | (z)->v64[0] ^= (x)->v64[0], \ |
237 | (z)->v64[1] ^= (x)->v64[1] \ |
238 | ) |
239 | #endif |
240 | |
241 | /* NOTE! This assumes an odd ordering! */ |
242 | /* This will not be compatible directly with math on some processors */ |
243 | /* bit 0 is first 32-bit word, low order bit. in little-endian, that's |
244 | the first byte of the first 32-bit word. In big-endian, that's |
245 | the 3rd byte of the first 32-bit word */ |
246 | /* The get/set bit code is used by the replay code ONLY, and it doesn't |
247 | really care which bit is which. AES does care which bit is which, but |
248 | doesn't use the 128-bit get/set or 128-bit shifts */ |
249 | |
250 | #define _v128_get_bit(x, bit) \ |
251 | ( \ |
252 | ((((x)->v32[(bit) >> 5]) >> ((bit) & 31)) & 1) \ |
253 | ) |
254 | |
255 | #define _v128_set_bit(x, bit) \ |
256 | ( \ |
257 | (((x)->v32[(bit) >> 5]) |= ((uint32_t)1 << ((bit) & 31))) \ |
258 | ) |
259 | |
260 | #define _v128_clear_bit(x, bit) \ |
261 | ( \ |
262 | (((x)->v32[(bit) >> 5]) &= ~((uint32_t)1 << ((bit) & 31))) \ |
263 | ) |
264 | |
265 | #define _v128_set_bit_to(x, bit, value) \ |
266 | ( \ |
267 | (value) ? _v128_set_bit(x, bit) : \ |
268 | _v128_clear_bit(x, bit) \ |
269 | ) |
270 | |
271 | |
272 | #if 0 |
273 | /* nothing uses this */ |
274 | #ifdef WORDS_BIGENDIAN |
275 | |
276 | #define _v128_add(z, x, y) { \ |
277 | uint64_t tmp; \ |
278 | \ |
279 | tmp = x->v32[3] + y->v32[3]; \ |
280 | z->v32[3] = (uint32_t) tmp; \ |
281 | \ |
282 | tmp = x->v32[2] + y->v32[2] + (tmp >> 32); \ |
283 | z->v32[2] = (uint32_t) tmp; \ |
284 | \ |
285 | tmp = x->v32[1] + y->v32[1] + (tmp >> 32); \ |
286 | z->v32[1] = (uint32_t) tmp; \ |
287 | \ |
288 | tmp = x->v32[0] + y->v32[0] + (tmp >> 32); \ |
289 | z->v32[0] = (uint32_t) tmp; \ |
290 | } |
291 | |
292 | #else /* assume little endian architecture */ |
293 | |
294 | #define _v128_add(z, x, y) { \ |
295 | uint64_t tmp; \ |
296 | \ |
297 | tmp = htonl(x->v32[3]) + htonl(y->v32[3]); \ |
298 | z->v32[3] = ntohl((uint32_t) tmp); \ |
299 | \ |
300 | tmp = htonl(x->v32[2]) + htonl(y->v32[2]) \ |
301 | + htonl(tmp >> 32); \ |
302 | z->v32[2] = ntohl((uint32_t) tmp); \ |
303 | \ |
304 | tmp = htonl(x->v32[1]) + htonl(y->v32[1]) \ |
305 | + htonl(tmp >> 32); \ |
306 | z->v32[1] = ntohl((uint32_t) tmp); \ |
307 | \ |
308 | tmp = htonl(x->v32[0]) + htonl(y->v32[0]) \ |
309 | + htonl(tmp >> 32); \ |
310 | z->v32[0] = ntohl((uint32_t) tmp); \ |
311 | } |
312 | #endif /* WORDS_BIGENDIAN */ |
313 | #endif /* 0 */ |
314 | |
315 | |
316 | #ifdef DATATYPES_USE_MACROS /* little functions are really macros */ |
317 | |
318 | #define v128_set_to_zero(z) _v128_set_to_zero(z) |
319 | #define v128_copy(z, x) _v128_copy(z, x) |
320 | #define v128_xor(z, x, y) _v128_xor(z, x, y) |
321 | #define v128_and(z, x, y) _v128_and(z, x, y) |
322 | #define v128_or(z, x, y) _v128_or(z, x, y) |
323 | #define v128_complement(x) _v128_complement(x) |
324 | #define v128_is_eq(x, y) _v128_is_eq(x, y) |
325 | #define v128_xor_eq(x, y) _v128_xor_eq(x, y) |
326 | #define v128_get_bit(x, i) _v128_get_bit(x, i) |
327 | #define v128_set_bit(x, i) _v128_set_bit(x, i) |
328 | #define v128_clear_bit(x, i) _v128_clear_bit(x, i) |
329 | #define v128_set_bit_to(x, i, y) _v128_set_bit_to(x, i, y) |
330 | |
331 | #else |
332 | |
333 | void |
334 | v128_set_to_zero(v128_t *x); |
335 | |
336 | int |
337 | v128_is_eq(const v128_t *x, const v128_t *y); |
338 | |
339 | void |
340 | v128_copy(v128_t *x, const v128_t *y); |
341 | |
342 | void |
343 | v128_xor(v128_t *z, v128_t *x, v128_t *y); |
344 | |
345 | void |
346 | v128_and(v128_t *z, v128_t *x, v128_t *y); |
347 | |
348 | void |
349 | v128_or(v128_t *z, v128_t *x, v128_t *y); |
350 | |
351 | void |
352 | v128_complement(v128_t *x); |
353 | |
354 | int |
355 | v128_get_bit(const v128_t *x, int i); |
356 | |
357 | void |
358 | v128_set_bit(v128_t *x, int i) ; |
359 | |
360 | void |
361 | v128_clear_bit(v128_t *x, int i); |
362 | |
363 | void |
364 | v128_set_bit_to(v128_t *x, int i, int y); |
365 | |
366 | #endif /* DATATYPES_USE_MACROS */ |
367 | |
368 | /* |
369 | * octet_string_is_eq(a,b, len) returns 1 if the length len strings a |
370 | * and b are not equal, returns 0 otherwise |
371 | */ |
372 | |
373 | int |
374 | octet_string_is_eq(uint8_t *a, uint8_t *b, int len); |
375 | |
376 | void |
377 | octet_string_set_to_zero(uint8_t *s, int len); |
378 | |
379 | |
380 | #ifndef SRTP_KERNEL_LINUX |
381 | |
382 | /* |
383 | * Convert big endian integers to CPU byte order. |
384 | */ |
385 | #ifdef WORDS_BIGENDIAN |
386 | /* Nothing to do. */ |
387 | # define be32_to_cpu(x) (x) |
388 | # define be64_to_cpu(x) (x) |
389 | #elif defined(HAVE_BYTESWAP_H) |
390 | /* We have (hopefully) optimized versions in byteswap.h */ |
391 | # include <byteswap.h> |
392 | # define be32_to_cpu(x) bswap_32((x)) |
393 | # define be64_to_cpu(x) bswap_64((x)) |
394 | #else |
395 | |
396 | #if defined(__GNUC__) && defined(HAVE_X86) |
397 | /* Fall back. */ |
398 | static inline uint32_t be32_to_cpu(uint32_t v) { |
399 | /* optimized for x86. */ |
400 | asm("bswap %0" : "=r" (v) : "0" (v)); |
401 | return v; |
402 | } |
403 | # else /* HAVE_X86 */ |
404 | # ifdef HAVE_NETINET_IN_H |
405 | # include <netinet/in.h> |
406 | # elif defined HAVE_WINSOCK2_H |
407 | # include <winsock2.h> |
408 | # endif |
409 | # define be32_to_cpu(x) ntohl((x)) |
410 | # endif /* HAVE_X86 */ |
411 | |
412 | static inline uint64_t be64_to_cpu(uint64_t v) { |
413 | # ifdef NO_64BIT_MATH |
414 | /* use the make64 functions to do 64-bit math */ |
415 | v = make64(htonl(low32(v)),htonl(high32(v))); |
416 | # else |
417 | /* use the native 64-bit math */ |
418 | v= (uint64_t)((be32_to_cpu((uint32_t)(v >> 32))) | (((uint64_t)be32_to_cpu((uint32_t)v)) << 32)); |
419 | # endif |
420 | return v; |
421 | } |
422 | |
423 | #endif /* ! SRTP_KERNEL_LINUX */ |
424 | |
425 | #endif /* WORDS_BIGENDIAN */ |
426 | |
427 | /* |
428 | * functions manipulating bitvector_t |
429 | * |
430 | * A bitvector_t consists of an array of words and an integer |
431 | * representing the number of significant bits stored in the array. |
432 | * The bits are packed as follows: the least significant bit is that |
433 | * of word[0], while the most significant bit is the nth most |
434 | * significant bit of word[m], where length = bits_per_word * m + n. |
435 | * |
436 | */ |
437 | |
438 | #define bits_per_word 32 |
439 | #define bytes_per_word 4 |
440 | |
441 | typedef struct { |
442 | uint32_t length; |
443 | uint32_t *word; |
444 | } bitvector_t; |
445 | |
446 | |
447 | #define _bitvector_get_bit(v, bit_index) \ |
448 | ( \ |
449 | ((((v)->word[((bit_index) >> 5)]) >> ((bit_index) & 31)) & 1) \ |
450 | ) |
451 | |
452 | |
453 | #define _bitvector_set_bit(v, bit_index) \ |
454 | ( \ |
455 | (((v)->word[((bit_index) >> 5)] |= ((uint32_t)1 << ((bit_index) & 31)))) \ |
456 | ) |
457 | |
458 | #define _bitvector_clear_bit(v, bit_index) \ |
459 | ( \ |
460 | (((v)->word[((bit_index) >> 5)] &= ~((uint32_t)1 << ((bit_index) & 31)))) \ |
461 | ) |
462 | |
463 | #define _bitvector_get_length(v) \ |
464 | ( \ |
465 | ((v)->length) \ |
466 | ) |
467 | |
468 | #ifdef DATATYPES_USE_MACROS /* little functions are really macros */ |
469 | |
470 | #define bitvector_get_bit(v, bit_index) _bitvector_get_bit(v, bit_index) |
471 | #define bitvector_set_bit(v, bit_index) _bitvector_set_bit(v, bit_index) |
472 | #define bitvector_clear_bit(v, bit_index) _bitvector_clear_bit(v, bit_index) |
473 | #define bitvector_get_length(v) _bitvector_get_length(v) |
474 | |
475 | #else |
476 | |
477 | int |
478 | bitvector_get_bit(const bitvector_t *v, int bit_index); |
479 | |
480 | void |
481 | bitvector_set_bit(bitvector_t *v, int bit_index); |
482 | |
483 | void |
484 | bitvector_clear_bit(bitvector_t *v, int bit_index); |
485 | |
486 | unsigned long |
487 | bitvector_get_length(const bitvector_t *v); |
488 | |
489 | #endif |
490 | |
491 | int |
492 | bitvector_alloc(bitvector_t *v, unsigned long length); |
493 | |
494 | void |
495 | bitvector_dealloc(bitvector_t *v); |
496 | |
497 | void |
498 | bitvector_set_to_zero(bitvector_t *x); |
499 | |
500 | void |
501 | bitvector_left_shift(bitvector_t *x, int index); |
502 | |
503 | char * |
504 | bitvector_bit_string(bitvector_t *x, char* buf, int len); |
505 | |
506 | #endif /* _DATATYPES_H */ |
507 | |