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 |