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 index); 159 160 void 161 v128_right_shift(v128_t *x, int 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