| OLD | NEW |
| (Empty) |
| 1 /* | |
| 2 * datatypes.c | |
| 3 * | |
| 4 * data types for finite fields and functions for input, output, and | |
| 5 * manipulation | |
| 6 * | |
| 7 * David A. McGrew | |
| 8 * Cisco Systems, Inc. | |
| 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 #ifdef HAVE_CONFIG_H | |
| 47 #include <config.h> | |
| 48 #endif | |
| 49 | |
| 50 #include "datatypes.h" | |
| 51 | |
| 52 int | |
| 53 octet_weight[256] = { | |
| 54 0, 1, 1, 2, 1, 2, 2, 3, | |
| 55 1, 2, 2, 3, 2, 3, 3, 4, | |
| 56 1, 2, 2, 3, 2, 3, 3, 4, | |
| 57 2, 3, 3, 4, 3, 4, 4, 5, | |
| 58 1, 2, 2, 3, 2, 3, 3, 4, | |
| 59 2, 3, 3, 4, 3, 4, 4, 5, | |
| 60 2, 3, 3, 4, 3, 4, 4, 5, | |
| 61 3, 4, 4, 5, 4, 5, 5, 6, | |
| 62 1, 2, 2, 3, 2, 3, 3, 4, | |
| 63 2, 3, 3, 4, 3, 4, 4, 5, | |
| 64 2, 3, 3, 4, 3, 4, 4, 5, | |
| 65 3, 4, 4, 5, 4, 5, 5, 6, | |
| 66 2, 3, 3, 4, 3, 4, 4, 5, | |
| 67 3, 4, 4, 5, 4, 5, 5, 6, | |
| 68 3, 4, 4, 5, 4, 5, 5, 6, | |
| 69 4, 5, 5, 6, 5, 6, 6, 7, | |
| 70 1, 2, 2, 3, 2, 3, 3, 4, | |
| 71 2, 3, 3, 4, 3, 4, 4, 5, | |
| 72 2, 3, 3, 4, 3, 4, 4, 5, | |
| 73 3, 4, 4, 5, 4, 5, 5, 6, | |
| 74 2, 3, 3, 4, 3, 4, 4, 5, | |
| 75 3, 4, 4, 5, 4, 5, 5, 6, | |
| 76 3, 4, 4, 5, 4, 5, 5, 6, | |
| 77 4, 5, 5, 6, 5, 6, 6, 7, | |
| 78 2, 3, 3, 4, 3, 4, 4, 5, | |
| 79 3, 4, 4, 5, 4, 5, 5, 6, | |
| 80 3, 4, 4, 5, 4, 5, 5, 6, | |
| 81 4, 5, 5, 6, 5, 6, 6, 7, | |
| 82 3, 4, 4, 5, 4, 5, 5, 6, | |
| 83 4, 5, 5, 6, 5, 6, 6, 7, | |
| 84 4, 5, 5, 6, 5, 6, 6, 7, | |
| 85 5, 6, 6, 7, 6, 7, 7, 8 | |
| 86 }; | |
| 87 | |
| 88 int | |
| 89 octet_get_weight(uint8_t octet) { | |
| 90 extern int octet_weight[256]; | |
| 91 | |
| 92 return octet_weight[octet]; | |
| 93 } | |
| 94 | |
| 95 /* | |
| 96 * bit_string is a buffer that is used to hold output strings, e.g. | |
| 97 * for printing. | |
| 98 */ | |
| 99 | |
| 100 /* the value MAX_PRINT_STRING_LEN is defined in datatypes.h */ | |
| 101 | |
| 102 char bit_string[MAX_PRINT_STRING_LEN]; | |
| 103 | |
| 104 uint8_t | |
| 105 nibble_to_hex_char(uint8_t nibble) { | |
| 106 char buf[16] = {'0', '1', '2', '3', '4', '5', '6', '7', | |
| 107 '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; | |
| 108 return buf[nibble & 0xF]; | |
| 109 } | |
| 110 | |
| 111 char * | |
| 112 octet_string_hex_string(const void *s, int length) { | |
| 113 const uint8_t *str = (const uint8_t *)s; | |
| 114 int i; | |
| 115 | |
| 116 /* double length, since one octet takes two hex characters */ | |
| 117 length *= 2; | |
| 118 | |
| 119 /* truncate string if it would be too long */ | |
| 120 if (length > MAX_PRINT_STRING_LEN) | |
| 121 length = MAX_PRINT_STRING_LEN-1; | |
| 122 | |
| 123 for (i=0; i < length; i+=2) { | |
| 124 bit_string[i] = nibble_to_hex_char(*str >> 4); | |
| 125 bit_string[i+1] = nibble_to_hex_char(*str++ & 0xF); | |
| 126 } | |
| 127 bit_string[i] = 0; /* null terminate string */ | |
| 128 return bit_string; | |
| 129 } | |
| 130 | |
| 131 static inline int | |
| 132 hex_char_to_nibble(uint8_t c) { | |
| 133 switch(c) { | |
| 134 case ('0'): return 0x0; | |
| 135 case ('1'): return 0x1; | |
| 136 case ('2'): return 0x2; | |
| 137 case ('3'): return 0x3; | |
| 138 case ('4'): return 0x4; | |
| 139 case ('5'): return 0x5; | |
| 140 case ('6'): return 0x6; | |
| 141 case ('7'): return 0x7; | |
| 142 case ('8'): return 0x8; | |
| 143 case ('9'): return 0x9; | |
| 144 case ('a'): return 0xa; | |
| 145 case ('A'): return 0xa; | |
| 146 case ('b'): return 0xb; | |
| 147 case ('B'): return 0xb; | |
| 148 case ('c'): return 0xc; | |
| 149 case ('C'): return 0xc; | |
| 150 case ('d'): return 0xd; | |
| 151 case ('D'): return 0xd; | |
| 152 case ('e'): return 0xe; | |
| 153 case ('E'): return 0xe; | |
| 154 case ('f'): return 0xf; | |
| 155 case ('F'): return 0xf; | |
| 156 default: return -1; /* this flags an error */ | |
| 157 } | |
| 158 /* NOTREACHED */ | |
| 159 return -1; /* this keeps compilers from complaining */ | |
| 160 } | |
| 161 | |
| 162 int | |
| 163 is_hex_string(char *s) { | |
| 164 while(*s != 0) | |
| 165 if (hex_char_to_nibble(*s++) == -1) | |
| 166 return 0; | |
| 167 return 1; | |
| 168 } | |
| 169 | |
| 170 /* | |
| 171 * hex_string_to_octet_string converts a hexadecimal string | |
| 172 * of length 2 * len to a raw octet string of length len | |
| 173 */ | |
| 174 | |
| 175 int | |
| 176 hex_string_to_octet_string(char *raw, char *hex, int len) { | |
| 177 uint8_t x; | |
| 178 int tmp; | |
| 179 int hex_len; | |
| 180 | |
| 181 hex_len = 0; | |
| 182 while (hex_len < len) { | |
| 183 tmp = hex_char_to_nibble(hex[0]); | |
| 184 if (tmp == -1) | |
| 185 return hex_len; | |
| 186 x = (tmp << 4); | |
| 187 hex_len++; | |
| 188 tmp = hex_char_to_nibble(hex[1]); | |
| 189 if (tmp == -1) | |
| 190 return hex_len; | |
| 191 x |= (tmp & 0xff); | |
| 192 hex_len++; | |
| 193 *raw++ = x; | |
| 194 hex += 2; | |
| 195 } | |
| 196 return hex_len; | |
| 197 } | |
| 198 | |
| 199 char * | |
| 200 v128_hex_string(v128_t *x) { | |
| 201 int i, j; | |
| 202 | |
| 203 for (i=j=0; i < 16; i++) { | |
| 204 bit_string[j++] = nibble_to_hex_char(x->v8[i] >> 4); | |
| 205 bit_string[j++] = nibble_to_hex_char(x->v8[i] & 0xF); | |
| 206 } | |
| 207 | |
| 208 bit_string[j] = 0; /* null terminate string */ | |
| 209 return bit_string; | |
| 210 } | |
| 211 | |
| 212 char * | |
| 213 v128_bit_string(v128_t *x) { | |
| 214 int j, i; | |
| 215 uint32_t mask; | |
| 216 | |
| 217 for (j=i=0; j < 4; j++) { | |
| 218 for (mask=0x80000000; mask > 0; mask >>= 1) { | |
| 219 if (x->v32[j] & mask) | |
| 220 bit_string[i] = '1'; | |
| 221 else | |
| 222 bit_string[i] = '0'; | |
| 223 ++i; | |
| 224 } | |
| 225 } | |
| 226 bit_string[128] = 0; /* null terminate string */ | |
| 227 | |
| 228 return bit_string; | |
| 229 } | |
| 230 | |
| 231 void | |
| 232 v128_copy_octet_string(v128_t *x, const uint8_t s[16]) { | |
| 233 #ifdef ALIGNMENT_32BIT_REQUIRED | |
| 234 if ((((uint32_t) &s[0]) & 0x3) != 0) | |
| 235 #endif | |
| 236 { | |
| 237 x->v8[0] = s[0]; | |
| 238 x->v8[1] = s[1]; | |
| 239 x->v8[2] = s[2]; | |
| 240 x->v8[3] = s[3]; | |
| 241 x->v8[4] = s[4]; | |
| 242 x->v8[5] = s[5]; | |
| 243 x->v8[6] = s[6]; | |
| 244 x->v8[7] = s[7]; | |
| 245 x->v8[8] = s[8]; | |
| 246 x->v8[9] = s[9]; | |
| 247 x->v8[10] = s[10]; | |
| 248 x->v8[11] = s[11]; | |
| 249 x->v8[12] = s[12]; | |
| 250 x->v8[13] = s[13]; | |
| 251 x->v8[14] = s[14]; | |
| 252 x->v8[15] = s[15]; | |
| 253 } | |
| 254 #ifdef ALIGNMENT_32BIT_REQUIRED | |
| 255 else | |
| 256 { | |
| 257 v128_t *v = (v128_t *) &s[0]; | |
| 258 | |
| 259 v128_copy(x,v); | |
| 260 } | |
| 261 #endif | |
| 262 } | |
| 263 | |
| 264 #ifndef DATATYPES_USE_MACROS /* little functions are not macros */ | |
| 265 | |
| 266 void | |
| 267 v128_set_to_zero(v128_t *x) { | |
| 268 _v128_set_to_zero(x); | |
| 269 } | |
| 270 | |
| 271 void | |
| 272 v128_copy(v128_t *x, const v128_t *y) { | |
| 273 _v128_copy(x, y); | |
| 274 } | |
| 275 | |
| 276 void | |
| 277 v128_xor(v128_t *z, v128_t *x, v128_t *y) { | |
| 278 _v128_xor(z, x, y); | |
| 279 } | |
| 280 | |
| 281 void | |
| 282 v128_and(v128_t *z, v128_t *x, v128_t *y) { | |
| 283 _v128_and(z, x, y); | |
| 284 } | |
| 285 | |
| 286 void | |
| 287 v128_or(v128_t *z, v128_t *x, v128_t *y) { | |
| 288 _v128_or(z, x, y); | |
| 289 } | |
| 290 | |
| 291 void | |
| 292 v128_complement(v128_t *x) { | |
| 293 _v128_complement(x); | |
| 294 } | |
| 295 | |
| 296 int | |
| 297 v128_is_eq(const v128_t *x, const v128_t *y) { | |
| 298 return _v128_is_eq(x, y); | |
| 299 } | |
| 300 | |
| 301 int | |
| 302 v128_xor_eq(v128_t *x, const v128_t *y) { | |
| 303 return _v128_xor_eq(x, y); | |
| 304 } | |
| 305 | |
| 306 int | |
| 307 v128_get_bit(const v128_t *x, int i) { | |
| 308 return _v128_get_bit(x, i); | |
| 309 } | |
| 310 | |
| 311 void | |
| 312 v128_set_bit(v128_t *x, int i) { | |
| 313 _v128_set_bit(x, i); | |
| 314 } | |
| 315 | |
| 316 void | |
| 317 v128_clear_bit(v128_t *x, int i){ | |
| 318 _v128_clear_bit(x, i); | |
| 319 } | |
| 320 | |
| 321 void | |
| 322 v128_set_bit_to(v128_t *x, int i, int y){ | |
| 323 _v128_set_bit_to(x, i, y); | |
| 324 } | |
| 325 | |
| 326 | |
| 327 #endif /* DATATYPES_USE_MACROS */ | |
| 328 | |
| 329 void | |
| 330 v128_right_shift(v128_t *x, int shift) { | |
| 331 const int base_index = shift >> 5; | |
| 332 const int bit_index = shift & 31; | |
| 333 int i, from; | |
| 334 uint32_t b; | |
| 335 | |
| 336 if (shift > 127) { | |
| 337 v128_set_to_zero(x); | |
| 338 return; | |
| 339 } | |
| 340 | |
| 341 if (bit_index == 0) { | |
| 342 | |
| 343 /* copy each word from left size to right side */ | |
| 344 x->v32[4-1] = x->v32[4-1-base_index]; | |
| 345 for (i=4-1; i > base_index; i--) | |
| 346 x->v32[i-1] = x->v32[i-1-base_index]; | |
| 347 | |
| 348 } else { | |
| 349 | |
| 350 /* set each word to the "or" of the two bit-shifted words */ | |
| 351 for (i = 4; i > base_index; i--) { | |
| 352 from = i-1 - base_index; | |
| 353 b = x->v32[from] << bit_index; | |
| 354 if (from > 0) | |
| 355 b |= x->v32[from-1] >> (32-bit_index); | |
| 356 x->v32[i-1] = b; | |
| 357 } | |
| 358 | |
| 359 } | |
| 360 | |
| 361 /* now wrap up the final portion */ | |
| 362 for (i=0; i < base_index; i++) | |
| 363 x->v32[i] = 0; | |
| 364 | |
| 365 } | |
| 366 | |
| 367 void | |
| 368 v128_left_shift(v128_t *x, int shift) { | |
| 369 int i; | |
| 370 const int base_index = shift >> 5; | |
| 371 const int bit_index = shift & 31; | |
| 372 | |
| 373 if (shift > 127) { | |
| 374 v128_set_to_zero(x); | |
| 375 return; | |
| 376 } | |
| 377 | |
| 378 if (bit_index == 0) { | |
| 379 for (i=0; i < 4 - base_index; i++) | |
| 380 x->v32[i] = x->v32[i+base_index]; | |
| 381 } else { | |
| 382 for (i=0; i < 4 - base_index - 1; i++) | |
| 383 x->v32[i] = (x->v32[i+base_index] >> bit_index) ^ | |
| 384 (x->v32[i+base_index+1] << (32 - bit_index)); | |
| 385 x->v32[4 - base_index-1] = x->v32[4-1] >> bit_index; | |
| 386 } | |
| 387 | |
| 388 /* now wrap up the final portion */ | |
| 389 for (i = 4 - base_index; i < 4; i++) | |
| 390 x->v32[i] = 0; | |
| 391 | |
| 392 } | |
| 393 | |
| 394 /* functions manipulating bitvector_t */ | |
| 395 | |
| 396 #ifndef DATATYPES_USE_MACROS /* little functions are not macros */ | |
| 397 | |
| 398 int | |
| 399 bitvector_get_bit(const bitvector_t *v, int bit_index) | |
| 400 { | |
| 401 return _bitvector_get_bit(v, bit_index); | |
| 402 } | |
| 403 | |
| 404 void | |
| 405 bitvector_set_bit(bitvector_t *v, int bit_index) | |
| 406 { | |
| 407 _bitvector_set_bit(v, bit_index); | |
| 408 } | |
| 409 | |
| 410 void | |
| 411 bitvector_clear_bit(bitvector_t *v, int bit_index) | |
| 412 { | |
| 413 _bitvector_clear_bit(v, bit_index); | |
| 414 } | |
| 415 | |
| 416 | |
| 417 #endif /* DATATYPES_USE_MACROS */ | |
| 418 | |
| 419 int | |
| 420 bitvector_alloc(bitvector_t *v, unsigned long length) { | |
| 421 unsigned long l; | |
| 422 | |
| 423 /* Round length up to a multiple of bits_per_word */ | |
| 424 length = (length + bits_per_word - 1) & ~(unsigned long)((bits_per_word - 1)); | |
| 425 | |
| 426 l = length / bits_per_word * bytes_per_word; | |
| 427 | |
| 428 /* allocate memory, then set parameters */ | |
| 429 if (l == 0) | |
| 430 v->word = NULL; | |
| 431 else { | |
| 432 v->word = (uint32_t*)crypto_alloc(l); | |
| 433 if (v->word == NULL) { | |
| 434 v->word = NULL; | |
| 435 v->length = 0; | |
| 436 return -1; | |
| 437 } | |
| 438 } | |
| 439 v->length = length; | |
| 440 | |
| 441 /* initialize bitvector to zero */ | |
| 442 bitvector_set_to_zero(v); | |
| 443 | |
| 444 return 0; | |
| 445 } | |
| 446 | |
| 447 | |
| 448 void | |
| 449 bitvector_dealloc(bitvector_t *v) { | |
| 450 if (v->word != NULL) | |
| 451 crypto_free(v->word); | |
| 452 v->word = NULL; | |
| 453 v->length = 0; | |
| 454 } | |
| 455 | |
| 456 void | |
| 457 bitvector_set_to_zero(bitvector_t *x) | |
| 458 { | |
| 459 /* C99 guarantees that memset(0) will set the value 0 for uint32_t */ | |
| 460 memset(x->word, 0, x->length >> 3); | |
| 461 } | |
| 462 | |
| 463 char * | |
| 464 bitvector_bit_string(bitvector_t *x, char* buf, int len) { | |
| 465 int j, i; | |
| 466 uint32_t mask; | |
| 467 | |
| 468 for (j=i=0; j < (int)(x->length>>5) && i < len-1; j++) { | |
| 469 for (mask=0x80000000; mask > 0; mask >>= 1) { | |
| 470 if (x->word[j] & mask) | |
| 471 buf[i] = '1'; | |
| 472 else | |
| 473 buf[i] = '0'; | |
| 474 ++i; | |
| 475 if (i >= len-1) | |
| 476 break; | |
| 477 } | |
| 478 } | |
| 479 buf[i] = 0; /* null terminate string */ | |
| 480 | |
| 481 return buf; | |
| 482 } | |
| 483 | |
| 484 void | |
| 485 bitvector_left_shift(bitvector_t *x, int shift) { | |
| 486 int i; | |
| 487 const int base_index = shift >> 5; | |
| 488 const int bit_index = shift & 31; | |
| 489 const int word_length = x->length >> 5; | |
| 490 | |
| 491 if (shift >= (int)x->length) { | |
| 492 bitvector_set_to_zero(x); | |
| 493 return; | |
| 494 } | |
| 495 | |
| 496 if (bit_index == 0) { | |
| 497 for (i=0; i < word_length - base_index; i++) | |
| 498 x->word[i] = x->word[i+base_index]; | |
| 499 } else { | |
| 500 for (i=0; i < word_length - base_index - 1; i++) | |
| 501 x->word[i] = (x->word[i+base_index] >> bit_index) ^ | |
| 502 (x->word[i+base_index+1] << (32 - bit_index)); | |
| 503 x->word[word_length - base_index-1] = x->word[word_length-1] >> bit_index; | |
| 504 } | |
| 505 | |
| 506 /* now wrap up the final portion */ | |
| 507 for (i = word_length - base_index; i < word_length; i++) | |
| 508 x->word[i] = 0; | |
| 509 | |
| 510 } | |
| 511 | |
| 512 | |
| 513 int | |
| 514 octet_string_is_eq(uint8_t *a, uint8_t *b, int len) { | |
| 515 uint8_t *end = b + len; | |
| 516 while (b < end) | |
| 517 if (*a++ != *b++) | |
| 518 return 1; | |
| 519 return 0; | |
| 520 } | |
| 521 | |
| 522 void | |
| 523 octet_string_set_to_zero(uint8_t *s, int len) { | |
| 524 uint8_t *end = s + len; | |
| 525 | |
| 526 do { | |
| 527 *s = 0; | |
| 528 } while (++s < end); | |
| 529 | |
| 530 } | |
| 531 | |
| 532 #ifdef TESTAPP_SOURCE | |
| 533 | |
| 534 static const char b64chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" | |
| 535 "abcdefghijklmnopqrstuvwxyz0123456789+/"; | |
| 536 | |
| 537 static int base64_block_to_octet_triple(char *out, char *in) { | |
| 538 unsigned char sextets[4] = {0}; | |
| 539 int j = 0; | |
| 540 int i; | |
| 541 | |
| 542 for (i = 0; i < 4; i++) { | |
| 543 char *p = strchr(b64chars, in[i]); | |
| 544 if (p != NULL) sextets[i] = p - b64chars; | |
| 545 else j++; | |
| 546 } | |
| 547 | |
| 548 out[0] = (sextets[0]<<2)|(sextets[1]>>4); | |
| 549 if (j < 2) out[1] = (sextets[1]<<4)|(sextets[2]>>2); | |
| 550 if (j < 1) out[2] = (sextets[2]<<6)|sextets[3]; | |
| 551 return j; | |
| 552 } | |
| 553 | |
| 554 int base64_string_to_octet_string(char *out, int *pad, char *in, int len) { | |
| 555 int k = 0; | |
| 556 int i = 0; | |
| 557 int j = 0; | |
| 558 if (len % 4 != 0) return 0; | |
| 559 | |
| 560 while (i < len && j == 0) { | |
| 561 j = base64_block_to_octet_triple(out + k, in + i); | |
| 562 k += 3; | |
| 563 i += 4; | |
| 564 } | |
| 565 *pad = j; | |
| 566 return i; | |
| 567 } | |
| 568 | |
| 569 #endif | |
| OLD | NEW |