1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/netwerk/srtp/src/crypto/math/math.c Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,802 @@ 1.4 +/* 1.5 + * math.c 1.6 + * 1.7 + * crypto math operations and data types 1.8 + * 1.9 + * David A. McGrew 1.10 + * Cisco Systems, Inc. 1.11 + */ 1.12 +/* 1.13 + * 1.14 + * Copyright (c) 2001-2006 Cisco Systems, Inc. 1.15 + * All rights reserved. 1.16 + * 1.17 + * Redistribution and use in source and binary forms, with or without 1.18 + * modification, are permitted provided that the following conditions 1.19 + * are met: 1.20 + * 1.21 + * Redistributions of source code must retain the above copyright 1.22 + * notice, this list of conditions and the following disclaimer. 1.23 + * 1.24 + * Redistributions in binary form must reproduce the above 1.25 + * copyright notice, this list of conditions and the following 1.26 + * disclaimer in the documentation and/or other materials provided 1.27 + * with the distribution. 1.28 + * 1.29 + * Neither the name of the Cisco Systems, Inc. nor the names of its 1.30 + * contributors may be used to endorse or promote products derived 1.31 + * from this software without specific prior written permission. 1.32 + * 1.33 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1.34 + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 1.35 + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 1.36 + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 1.37 + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 1.38 + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 1.39 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 1.40 + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 1.41 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 1.42 + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 1.43 + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 1.44 + * OF THE POSSIBILITY OF SUCH DAMAGE. 1.45 + * 1.46 + */ 1.47 + 1.48 +#include "crypto_math.h" 1.49 + 1.50 +int 1.51 +octet_weight[256] = { 1.52 + 0, 1, 1, 2, 1, 2, 2, 3, 1.53 + 1, 2, 2, 3, 2, 3, 3, 4, 1.54 + 1, 2, 2, 3, 2, 3, 3, 4, 1.55 + 2, 3, 3, 4, 3, 4, 4, 5, 1.56 + 1, 2, 2, 3, 2, 3, 3, 4, 1.57 + 2, 3, 3, 4, 3, 4, 4, 5, 1.58 + 2, 3, 3, 4, 3, 4, 4, 5, 1.59 + 3, 4, 4, 5, 4, 5, 5, 6, 1.60 + 1, 2, 2, 3, 2, 3, 3, 4, 1.61 + 2, 3, 3, 4, 3, 4, 4, 5, 1.62 + 2, 3, 3, 4, 3, 4, 4, 5, 1.63 + 3, 4, 4, 5, 4, 5, 5, 6, 1.64 + 2, 3, 3, 4, 3, 4, 4, 5, 1.65 + 3, 4, 4, 5, 4, 5, 5, 6, 1.66 + 3, 4, 4, 5, 4, 5, 5, 6, 1.67 + 4, 5, 5, 6, 5, 6, 6, 7, 1.68 + 1, 2, 2, 3, 2, 3, 3, 4, 1.69 + 2, 3, 3, 4, 3, 4, 4, 5, 1.70 + 2, 3, 3, 4, 3, 4, 4, 5, 1.71 + 3, 4, 4, 5, 4, 5, 5, 6, 1.72 + 2, 3, 3, 4, 3, 4, 4, 5, 1.73 + 3, 4, 4, 5, 4, 5, 5, 6, 1.74 + 3, 4, 4, 5, 4, 5, 5, 6, 1.75 + 4, 5, 5, 6, 5, 6, 6, 7, 1.76 + 2, 3, 3, 4, 3, 4, 4, 5, 1.77 + 3, 4, 4, 5, 4, 5, 5, 6, 1.78 + 3, 4, 4, 5, 4, 5, 5, 6, 1.79 + 4, 5, 5, 6, 5, 6, 6, 7, 1.80 + 3, 4, 4, 5, 4, 5, 5, 6, 1.81 + 4, 5, 5, 6, 5, 6, 6, 7, 1.82 + 4, 5, 5, 6, 5, 6, 6, 7, 1.83 + 5, 6, 6, 7, 6, 7, 7, 8 1.84 +}; 1.85 + 1.86 +int 1.87 +low_bit[256] = { 1.88 + -1, 0, 1, 0, 2, 0, 1, 0, 1.89 + 3, 0, 1, 0, 2, 0, 1, 0, 1.90 + 4, 0, 1, 0, 2, 0, 1, 0, 1.91 + 3, 0, 1, 0, 2, 0, 1, 0, 1.92 + 5, 0, 1, 0, 2, 0, 1, 0, 1.93 + 3, 0, 1, 0, 2, 0, 1, 0, 1.94 + 4, 0, 1, 0, 2, 0, 1, 0, 1.95 + 3, 0, 1, 0, 2, 0, 1, 0, 1.96 + 6, 0, 1, 0, 2, 0, 1, 0, 1.97 + 3, 0, 1, 0, 2, 0, 1, 0, 1.98 + 4, 0, 1, 0, 2, 0, 1, 0, 1.99 + 3, 0, 1, 0, 2, 0, 1, 0, 1.100 + 5, 0, 1, 0, 2, 0, 1, 0, 1.101 + 3, 0, 1, 0, 2, 0, 1, 0, 1.102 + 4, 0, 1, 0, 2, 0, 1, 0, 1.103 + 3, 0, 1, 0, 2, 0, 1, 0, 1.104 + 7, 0, 1, 0, 2, 0, 1, 0, 1.105 + 3, 0, 1, 0, 2, 0, 1, 0, 1.106 + 4, 0, 1, 0, 2, 0, 1, 0, 1.107 + 3, 0, 1, 0, 2, 0, 1, 0, 1.108 + 5, 0, 1, 0, 2, 0, 1, 0, 1.109 + 3, 0, 1, 0, 2, 0, 1, 0, 1.110 + 4, 0, 1, 0, 2, 0, 1, 0, 1.111 + 3, 0, 1, 0, 2, 0, 1, 0, 1.112 + 6, 0, 1, 0, 2, 0, 1, 0, 1.113 + 3, 0, 1, 0, 2, 0, 1, 0, 1.114 + 4, 0, 1, 0, 2, 0, 1, 0, 1.115 + 3, 0, 1, 0, 2, 0, 1, 0, 1.116 + 5, 0, 1, 0, 2, 0, 1, 0, 1.117 + 3, 0, 1, 0, 2, 0, 1, 0, 1.118 + 4, 0, 1, 0, 2, 0, 1, 0, 1.119 + 3, 0, 1, 0, 2, 0, 1, 0 1.120 +}; 1.121 + 1.122 + 1.123 +int 1.124 +high_bit[256] = { 1.125 + -1, 0, 1, 1, 2, 2, 2, 2, 1.126 + 3, 3, 3, 3, 3, 3, 3, 3, 1.127 + 4, 4, 4, 4, 4, 4, 4, 4, 1.128 + 4, 4, 4, 4, 4, 4, 4, 4, 1.129 + 5, 5, 5, 5, 5, 5, 5, 5, 1.130 + 5, 5, 5, 5, 5, 5, 5, 5, 1.131 + 5, 5, 5, 5, 5, 5, 5, 5, 1.132 + 5, 5, 5, 5, 5, 5, 5, 5, 1.133 + 6, 6, 6, 6, 6, 6, 6, 6, 1.134 + 6, 6, 6, 6, 6, 6, 6, 6, 1.135 + 6, 6, 6, 6, 6, 6, 6, 6, 1.136 + 6, 6, 6, 6, 6, 6, 6, 6, 1.137 + 6, 6, 6, 6, 6, 6, 6, 6, 1.138 + 6, 6, 6, 6, 6, 6, 6, 6, 1.139 + 6, 6, 6, 6, 6, 6, 6, 6, 1.140 + 6, 6, 6, 6, 6, 6, 6, 6, 1.141 + 7, 7, 7, 7, 7, 7, 7, 7, 1.142 + 7, 7, 7, 7, 7, 7, 7, 7, 1.143 + 7, 7, 7, 7, 7, 7, 7, 7, 1.144 + 7, 7, 7, 7, 7, 7, 7, 7, 1.145 + 7, 7, 7, 7, 7, 7, 7, 7, 1.146 + 7, 7, 7, 7, 7, 7, 7, 7, 1.147 + 7, 7, 7, 7, 7, 7, 7, 7, 1.148 + 7, 7, 7, 7, 7, 7, 7, 7, 1.149 + 7, 7, 7, 7, 7, 7, 7, 7, 1.150 + 7, 7, 7, 7, 7, 7, 7, 7, 1.151 + 7, 7, 7, 7, 7, 7, 7, 7, 1.152 + 7, 7, 7, 7, 7, 7, 7, 7, 1.153 + 7, 7, 7, 7, 7, 7, 7, 7, 1.154 + 7, 7, 7, 7, 7, 7, 7, 7, 1.155 + 7, 7, 7, 7, 7, 7, 7, 7, 1.156 + 7, 7, 7, 7, 7, 7, 7, 7 1.157 +}; 1.158 + 1.159 +int 1.160 +octet_get_weight(uint8_t octet) { 1.161 + extern int octet_weight[256]; 1.162 + 1.163 + return octet_weight[octet]; 1.164 +} 1.165 + 1.166 +unsigned char 1.167 +v32_weight(v32_t a) { 1.168 + unsigned int wt = 0; 1.169 + 1.170 + wt += octet_weight[a.v8[0]]; /* note: endian-ness makes no difference */ 1.171 + wt += octet_weight[a.v8[1]]; 1.172 + wt += octet_weight[a.v8[2]]; 1.173 + wt += octet_weight[a.v8[3]]; 1.174 + 1.175 + return wt; 1.176 +} 1.177 + 1.178 +unsigned char 1.179 +v32_distance(v32_t x, v32_t y) { 1.180 + x.value ^= y.value; 1.181 + return v32_weight(x); 1.182 +} 1.183 + 1.184 +unsigned int 1.185 +v32_dot_product(v32_t a, v32_t b) { 1.186 + a.value &= b.value; 1.187 + return v32_weight(a) & 1; 1.188 +} 1.189 + 1.190 +/* 1.191 + * _bit_string returns a NULL-terminated character string suitable for 1.192 + * printing 1.193 + */ 1.194 + 1.195 +#define MAX_STRING_LENGTH 1024 1.196 + 1.197 +char bit_string[MAX_STRING_LENGTH]; 1.198 + 1.199 +char * 1.200 +octet_bit_string(uint8_t x) { 1.201 + int mask, index; 1.202 + 1.203 + for (mask = 1, index = 0; mask < 256; mask <<= 1) 1.204 + if ((x & mask) == 0) 1.205 + bit_string[index++] = '0'; 1.206 + else 1.207 + bit_string[index++] = '1'; 1.208 + 1.209 + bit_string[index++] = 0; /* NULL terminate string */ 1.210 + 1.211 + return bit_string; 1.212 +} 1.213 + 1.214 +char * 1.215 +v16_bit_string(v16_t x) { 1.216 + int i, mask, index; 1.217 + 1.218 + for (i = index = 0; i < 2; i++) { 1.219 + for (mask = 1; mask < 256; mask <<= 1) 1.220 + if ((x.v8[i] & mask) == 0) 1.221 + bit_string[index++] = '0'; 1.222 + else 1.223 + bit_string[index++] = '1'; 1.224 + } 1.225 + bit_string[index++] = 0; /* NULL terminate string */ 1.226 + return bit_string; 1.227 +} 1.228 + 1.229 +char * 1.230 +v32_bit_string(v32_t x) { 1.231 + int i, mask, index; 1.232 + 1.233 + for (i = index = 0; i < 4; i++) { 1.234 + for (mask = 128; mask > 0; mask >>= 1) 1.235 + if ((x.v8[i] & mask) == 0) 1.236 + bit_string[index++] = '0'; 1.237 + else 1.238 + bit_string[index++] = '1'; 1.239 + } 1.240 + bit_string[index++] = 0; /* NULL terminate string */ 1.241 + return bit_string; 1.242 +} 1.243 + 1.244 +char * 1.245 +v64_bit_string(const v64_t *x) { 1.246 + int i, mask, index; 1.247 + 1.248 + for (i = index = 0; i < 8; i++) { 1.249 + for (mask = 1; mask < 256; mask <<= 1) 1.250 + if ((x->v8[i] & mask) == 0) 1.251 + bit_string[index++] = '0'; 1.252 + else 1.253 + bit_string[index++] = '1'; 1.254 + } 1.255 + bit_string[index++] = 0; /* NULL terminate string */ 1.256 + return bit_string; 1.257 +} 1.258 + 1.259 +char * 1.260 +v128_bit_string(v128_t *x) { 1.261 + int j, index; 1.262 + uint32_t mask; 1.263 + 1.264 + for (j=index=0; j < 4; j++) { 1.265 + for (mask=0x80000000; mask > 0; mask >>= 1) { 1.266 + if (x->v32[j] & mask) 1.267 + bit_string[index] = '1'; 1.268 + else 1.269 + bit_string[index] = '0'; 1.270 + ++index; 1.271 + } 1.272 + } 1.273 + bit_string[128] = 0; /* null terminate string */ 1.274 + 1.275 + return bit_string; 1.276 +} 1.277 + 1.278 +uint8_t 1.279 +nibble_to_hex_char(uint8_t nibble) { 1.280 + char buf[16] = {'0', '1', '2', '3', '4', '5', '6', '7', 1.281 + '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; 1.282 + return buf[nibble & 0xF]; 1.283 +} 1.284 + 1.285 +char * 1.286 +octet_hex_string(uint8_t x) { 1.287 + 1.288 + bit_string[0] = nibble_to_hex_char(x >> 4); 1.289 + bit_string[1] = nibble_to_hex_char(x & 0xF); 1.290 + 1.291 + bit_string[2] = 0; /* null terminate string */ 1.292 + return bit_string; 1.293 +} 1.294 + 1.295 +char * 1.296 +octet_string_hex_string(const void *str, int length) { 1.297 + const uint8_t *s = str; 1.298 + int i; 1.299 + 1.300 + /* double length, since one octet takes two hex characters */ 1.301 + length *= 2; 1.302 + 1.303 + /* truncate string if it would be too long */ 1.304 + if (length > MAX_STRING_LENGTH) 1.305 + length = MAX_STRING_LENGTH-1; 1.306 + 1.307 + for (i=0; i < length; i+=2) { 1.308 + bit_string[i] = nibble_to_hex_char(*s >> 4); 1.309 + bit_string[i+1] = nibble_to_hex_char(*s++ & 0xF); 1.310 + } 1.311 + bit_string[i] = 0; /* null terminate string */ 1.312 + return bit_string; 1.313 +} 1.314 + 1.315 +char * 1.316 +v16_hex_string(v16_t x) { 1.317 + int i, j; 1.318 + 1.319 + for (i=j=0; i < 2; i++) { 1.320 + bit_string[j++] = nibble_to_hex_char(x.v8[i] >> 4); 1.321 + bit_string[j++] = nibble_to_hex_char(x.v8[i] & 0xF); 1.322 + } 1.323 + 1.324 + bit_string[j] = 0; /* null terminate string */ 1.325 + return bit_string; 1.326 +} 1.327 + 1.328 +char * 1.329 +v32_hex_string(v32_t x) { 1.330 + int i, j; 1.331 + 1.332 + for (i=j=0; i < 4; i++) { 1.333 + bit_string[j++] = nibble_to_hex_char(x.v8[i] >> 4); 1.334 + bit_string[j++] = nibble_to_hex_char(x.v8[i] & 0xF); 1.335 + } 1.336 + 1.337 + bit_string[j] = 0; /* null terminate string */ 1.338 + return bit_string; 1.339 +} 1.340 + 1.341 +char * 1.342 +v64_hex_string(const v64_t *x) { 1.343 + int i, j; 1.344 + 1.345 + for (i=j=0; i < 8; i++) { 1.346 + bit_string[j++] = nibble_to_hex_char(x->v8[i] >> 4); 1.347 + bit_string[j++] = nibble_to_hex_char(x->v8[i] & 0xF); 1.348 + } 1.349 + 1.350 + bit_string[j] = 0; /* null terminate string */ 1.351 + return bit_string; 1.352 +} 1.353 + 1.354 +char * 1.355 +v128_hex_string(v128_t *x) { 1.356 + int i, j; 1.357 + 1.358 + for (i=j=0; i < 16; i++) { 1.359 + bit_string[j++] = nibble_to_hex_char(x->v8[i] >> 4); 1.360 + bit_string[j++] = nibble_to_hex_char(x->v8[i] & 0xF); 1.361 + } 1.362 + 1.363 + bit_string[j] = 0; /* null terminate string */ 1.364 + return bit_string; 1.365 +} 1.366 + 1.367 +char * 1.368 +char_to_hex_string(char *x, int num_char) { 1.369 + int i, j; 1.370 + 1.371 + if (num_char >= 16) 1.372 + num_char = 16; 1.373 + for (i=j=0; i < num_char; i++) { 1.374 + bit_string[j++] = nibble_to_hex_char(x[i] >> 4); 1.375 + bit_string[j++] = nibble_to_hex_char(x[i] & 0xF); 1.376 + } 1.377 + 1.378 + bit_string[j] = 0; /* null terminate string */ 1.379 + return bit_string; 1.380 +} 1.381 + 1.382 +int 1.383 +hex_char_to_nibble(uint8_t c) { 1.384 + switch(c) { 1.385 + case ('0'): return 0x0; 1.386 + case ('1'): return 0x1; 1.387 + case ('2'): return 0x2; 1.388 + case ('3'): return 0x3; 1.389 + case ('4'): return 0x4; 1.390 + case ('5'): return 0x5; 1.391 + case ('6'): return 0x6; 1.392 + case ('7'): return 0x7; 1.393 + case ('8'): return 0x8; 1.394 + case ('9'): return 0x9; 1.395 + case ('a'): return 0xa; 1.396 + case ('A'): return 0xa; 1.397 + case ('b'): return 0xb; 1.398 + case ('B'): return 0xb; 1.399 + case ('c'): return 0xc; 1.400 + case ('C'): return 0xc; 1.401 + case ('d'): return 0xd; 1.402 + case ('D'): return 0xd; 1.403 + case ('e'): return 0xe; 1.404 + case ('E'): return 0xe; 1.405 + case ('f'): return 0xf; 1.406 + case ('F'): return 0xf; 1.407 + default: return -1; /* this flags an error */ 1.408 + } 1.409 + /* NOTREACHED */ 1.410 + return -1; /* this keeps compilers from complaining */ 1.411 +} 1.412 + 1.413 +int 1.414 +is_hex_string(char *s) { 1.415 + while(*s != 0) 1.416 + if (hex_char_to_nibble(*s++) == -1) 1.417 + return 0; 1.418 + return 1; 1.419 +} 1.420 + 1.421 +uint8_t 1.422 +hex_string_to_octet(char *s) { 1.423 + uint8_t x; 1.424 + 1.425 + x = (hex_char_to_nibble(s[0]) << 4) 1.426 + | hex_char_to_nibble(s[1] & 0xFF); 1.427 + 1.428 + return x; 1.429 +} 1.430 + 1.431 +/* 1.432 + * hex_string_to_octet_string converts a hexadecimal string 1.433 + * of length 2 * len to a raw octet string of length len 1.434 + */ 1.435 + 1.436 +int 1.437 +hex_string_to_octet_string(char *raw, char *hex, int len) { 1.438 + uint8_t x; 1.439 + int tmp; 1.440 + int hex_len; 1.441 + 1.442 + hex_len = 0; 1.443 + while (hex_len < len) { 1.444 + tmp = hex_char_to_nibble(hex[0]); 1.445 + if (tmp == -1) 1.446 + return hex_len; 1.447 + x = (tmp << 4); 1.448 + hex_len++; 1.449 + tmp = hex_char_to_nibble(hex[1]); 1.450 + if (tmp == -1) 1.451 + return hex_len; 1.452 + x |= (tmp & 0xff); 1.453 + hex_len++; 1.454 + *raw++ = x; 1.455 + hex += 2; 1.456 + } 1.457 + return hex_len; 1.458 +} 1.459 + 1.460 +v16_t 1.461 +hex_string_to_v16(char *s) { 1.462 + v16_t x; 1.463 + int i, j; 1.464 + 1.465 + for (i=j=0; i < 4; i += 2, j++) { 1.466 + x.v8[j] = (hex_char_to_nibble(s[i]) << 4) 1.467 + | hex_char_to_nibble(s[i+1] & 0xFF); 1.468 + } 1.469 + return x; 1.470 +} 1.471 + 1.472 +v32_t 1.473 +hex_string_to_v32(char *s) { 1.474 + v32_t x; 1.475 + int i, j; 1.476 + 1.477 + for (i=j=0; i < 8; i += 2, j++) { 1.478 + x.v8[j] = (hex_char_to_nibble(s[i]) << 4) 1.479 + | hex_char_to_nibble(s[i+1] & 0xFF); 1.480 + } 1.481 + return x; 1.482 +} 1.483 + 1.484 +v64_t 1.485 +hex_string_to_v64(char *s) { 1.486 + v64_t x; 1.487 + int i, j; 1.488 + 1.489 + for (i=j=0; i < 16; i += 2, j++) { 1.490 + x.v8[j] = (hex_char_to_nibble(s[i]) << 4) 1.491 + | hex_char_to_nibble(s[i+1] & 0xFF); 1.492 + } 1.493 + return x; 1.494 +} 1.495 + 1.496 +v128_t 1.497 +hex_string_to_v128(char *s) { 1.498 + v128_t x; 1.499 + int i, j; 1.500 + 1.501 + for (i=j=0; i < 32; i += 2, j++) { 1.502 + x.v8[j] = (hex_char_to_nibble(s[i]) << 4) 1.503 + | hex_char_to_nibble(s[i+1] & 0xFF); 1.504 + } 1.505 + return x; 1.506 +} 1.507 + 1.508 + 1.509 + 1.510 +/* 1.511 + * the matrix A[] is stored in column format, i.e., A[i] is the ith 1.512 + * column of the matrix 1.513 + */ 1.514 + 1.515 +uint8_t 1.516 +A_times_x_plus_b(uint8_t A[8], uint8_t x, uint8_t b) { 1.517 + int index = 0; 1.518 + unsigned mask; 1.519 + 1.520 + for (mask=1; mask < 256; mask *= 2) { 1.521 + if (x & mask) 1.522 + b^= A[index]; 1.523 + ++index; 1.524 + } 1.525 + 1.526 + return b; 1.527 +} 1.528 + 1.529 +void 1.530 +v16_copy_octet_string(v16_t *x, const uint8_t s[2]) { 1.531 + x->v8[0] = s[0]; 1.532 + x->v8[1] = s[1]; 1.533 +} 1.534 + 1.535 +void 1.536 +v32_copy_octet_string(v32_t *x, const uint8_t s[4]) { 1.537 + x->v8[0] = s[0]; 1.538 + x->v8[1] = s[1]; 1.539 + x->v8[2] = s[2]; 1.540 + x->v8[3] = s[3]; 1.541 +} 1.542 + 1.543 +void 1.544 +v64_copy_octet_string(v64_t *x, const uint8_t s[8]) { 1.545 + x->v8[0] = s[0]; 1.546 + x->v8[1] = s[1]; 1.547 + x->v8[2] = s[2]; 1.548 + x->v8[3] = s[3]; 1.549 + x->v8[4] = s[4]; 1.550 + x->v8[5] = s[5]; 1.551 + x->v8[6] = s[6]; 1.552 + x->v8[7] = s[7]; 1.553 +} 1.554 + 1.555 +void 1.556 +v128_copy_octet_string(v128_t *x, const uint8_t s[16]) { 1.557 + x->v8[0] = s[0]; 1.558 + x->v8[1] = s[1]; 1.559 + x->v8[2] = s[2]; 1.560 + x->v8[3] = s[3]; 1.561 + x->v8[4] = s[4]; 1.562 + x->v8[5] = s[5]; 1.563 + x->v8[6] = s[6]; 1.564 + x->v8[7] = s[7]; 1.565 + x->v8[8] = s[8]; 1.566 + x->v8[9] = s[9]; 1.567 + x->v8[10] = s[10]; 1.568 + x->v8[11] = s[11]; 1.569 + x->v8[12] = s[12]; 1.570 + x->v8[13] = s[13]; 1.571 + x->v8[14] = s[14]; 1.572 + x->v8[15] = s[15]; 1.573 + 1.574 +} 1.575 + 1.576 +#ifndef DATATYPES_USE_MACROS /* little functions are not macros */ 1.577 + 1.578 +void 1.579 +v128_set_to_zero(v128_t *x) { 1.580 + _v128_set_to_zero(x); 1.581 +} 1.582 + 1.583 +void 1.584 +v128_copy(v128_t *x, const v128_t *y) { 1.585 + _v128_copy(x, y); 1.586 +} 1.587 + 1.588 +void 1.589 +v128_xor(v128_t *z, v128_t *x, v128_t *y) { 1.590 + _v128_xor(z, x, y); 1.591 +} 1.592 + 1.593 +void 1.594 +v128_and(v128_t *z, v128_t *x, v128_t *y) { 1.595 + _v128_and(z, x, y); 1.596 +} 1.597 + 1.598 +void 1.599 +v128_or(v128_t *z, v128_t *x, v128_t *y) { 1.600 + _v128_or(z, x, y); 1.601 +} 1.602 + 1.603 +void 1.604 +v128_complement(v128_t *x) { 1.605 + _v128_complement(x); 1.606 +} 1.607 + 1.608 +int 1.609 +v128_is_eq(const v128_t *x, const v128_t *y) { 1.610 + return _v128_is_eq(x, y); 1.611 +} 1.612 + 1.613 +int 1.614 +v128_get_bit(const v128_t *x, int i) { 1.615 + return _v128_get_bit(x, i); 1.616 +} 1.617 + 1.618 +void 1.619 +v128_set_bit(v128_t *x, int i) { 1.620 + _v128_set_bit(x, i); 1.621 +} 1.622 + 1.623 +void 1.624 +v128_clear_bit(v128_t *x, int i){ 1.625 + _v128_clear_bit(x, i); 1.626 +} 1.627 + 1.628 +void 1.629 +v128_set_bit_to(v128_t *x, int i, int y){ 1.630 + _v128_set_bit_to(x, i, y); 1.631 +} 1.632 + 1.633 + 1.634 +#endif /* DATATYPES_USE_MACROS */ 1.635 + 1.636 + 1.637 +static inline void 1.638 +v128_left_shift2(v128_t *x, int num_bits) { 1.639 + int i; 1.640 + int word_shift = num_bits >> 5; 1.641 + int bit_shift = num_bits & 31; 1.642 + 1.643 + for (i=0; i < (4-word_shift); i++) { 1.644 + x->v32[i] = x->v32[i+word_shift] << bit_shift; 1.645 + } 1.646 + 1.647 + for ( ; i < word_shift; i++) { 1.648 + x->v32[i] = 0; 1.649 + } 1.650 + 1.651 +} 1.652 + 1.653 +void 1.654 +v128_right_shift(v128_t *x, int index) { 1.655 + const int base_index = index >> 5; 1.656 + const int bit_index = index & 31; 1.657 + int i, from; 1.658 + uint32_t b; 1.659 + 1.660 + if (index > 127) { 1.661 + v128_set_to_zero(x); 1.662 + return; 1.663 + } 1.664 + 1.665 + if (bit_index == 0) { 1.666 + 1.667 + /* copy each word from left size to right side */ 1.668 + x->v32[4-1] = x->v32[4-1-base_index]; 1.669 + for (i=4-1; i > base_index; i--) 1.670 + x->v32[i-1] = x->v32[i-1-base_index]; 1.671 + 1.672 + } else { 1.673 + 1.674 + /* set each word to the "or" of the two bit-shifted words */ 1.675 + for (i = 4; i > base_index; i--) { 1.676 + from = i-1 - base_index; 1.677 + b = x->v32[from] << bit_index; 1.678 + if (from > 0) 1.679 + b |= x->v32[from-1] >> (32-bit_index); 1.680 + x->v32[i-1] = b; 1.681 + } 1.682 + 1.683 + } 1.684 + 1.685 + /* now wrap up the final portion */ 1.686 + for (i=0; i < base_index; i++) 1.687 + x->v32[i] = 0; 1.688 + 1.689 +} 1.690 + 1.691 +void 1.692 +v128_left_shift(v128_t *x, int index) { 1.693 + int i; 1.694 + const int base_index = index >> 5; 1.695 + const int bit_index = index & 31; 1.696 + 1.697 + if (index > 127) { 1.698 + v128_set_to_zero(x); 1.699 + return; 1.700 + } 1.701 + 1.702 + if (bit_index == 0) { 1.703 + for (i=0; i < 4 - base_index; i++) 1.704 + x->v32[i] = x->v32[i+base_index]; 1.705 + } else { 1.706 + for (i=0; i < 4 - base_index - 1; i++) 1.707 + x->v32[i] = (x->v32[i+base_index] << bit_index) ^ 1.708 + (x->v32[i+base_index+1] >> (32 - bit_index)); 1.709 + x->v32[4 - base_index-1] = x->v32[4-1] << bit_index; 1.710 + } 1.711 + 1.712 + /* now wrap up the final portion */ 1.713 + for (i = 4 - base_index; i < 4; i++) 1.714 + x->v32[i] = 0; 1.715 + 1.716 +} 1.717 + 1.718 + 1.719 +#if 0 1.720 +void 1.721 +v128_add(v128_t *z, v128_t *x, v128_t *y) { 1.722 + /* integer addition modulo 2^128 */ 1.723 + 1.724 +#ifdef WORDS_BIGENDIAN 1.725 + uint64_t tmp; 1.726 + 1.727 + tmp = x->v32[3] + y->v32[3]; 1.728 + z->v32[3] = (uint32_t) tmp; 1.729 + 1.730 + tmp = x->v32[2] + y->v32[2] + (tmp >> 32); 1.731 + z->v32[2] = (uint32_t) tmp; 1.732 + 1.733 + tmp = x->v32[1] + y->v32[1] + (tmp >> 32); 1.734 + z->v32[1] = (uint32_t) tmp; 1.735 + 1.736 + tmp = x->v32[0] + y->v32[0] + (tmp >> 32); 1.737 + z->v32[0] = (uint32_t) tmp; 1.738 + 1.739 +#else /* assume little endian architecture */ 1.740 + uint64_t tmp; 1.741 + 1.742 + tmp = htonl(x->v32[3]) + htonl(y->v32[3]); 1.743 + z->v32[3] = ntohl((uint32_t) tmp); 1.744 + 1.745 + tmp = htonl(x->v32[2]) + htonl(y->v32[2]) + htonl(tmp >> 32); 1.746 + z->v32[2] = ntohl((uint32_t) tmp); 1.747 + 1.748 + tmp = htonl(x->v32[1]) + htonl(y->v32[1]) + htonl(tmp >> 32); 1.749 + z->v32[1] = ntohl((uint32_t) tmp); 1.750 + 1.751 + tmp = htonl(x->v32[0]) + htonl(y->v32[0]) + htonl(tmp >> 32); 1.752 + z->v32[0] = ntohl((uint32_t) tmp); 1.753 + 1.754 +#endif /* WORDS_BIGENDIAN */ 1.755 + 1.756 +} 1.757 +#endif 1.758 + 1.759 +int 1.760 +octet_string_is_eq(uint8_t *a, uint8_t *b, int len) { 1.761 + uint8_t *end = b + len; 1.762 + while (b < end) 1.763 + if (*a++ != *b++) 1.764 + return 1; 1.765 + return 0; 1.766 +} 1.767 + 1.768 +void 1.769 +octet_string_set_to_zero(uint8_t *s, int len) { 1.770 + uint8_t *end = s + len; 1.771 + 1.772 + do { 1.773 + *s = 0; 1.774 + } while (++s < end); 1.775 + 1.776 +} 1.777 + 1.778 + 1.779 +/* functions below not yet tested! */ 1.780 + 1.781 +int 1.782 +v32_low_bit(v32_t *w) { 1.783 + int value; 1.784 + 1.785 + value = low_bit[w->v8[0]]; 1.786 + if (value != -1) 1.787 + return value; 1.788 + value = low_bit[w->v8[1]]; 1.789 + if (value != -1) 1.790 + return value + 8; 1.791 + value = low_bit[w->v8[2]]; 1.792 + if (value != -1) 1.793 + return value + 16; 1.794 + value = low_bit[w->v8[3]]; 1.795 + if (value == -1) 1.796 + return -1; 1.797 + return value + 24; 1.798 +} 1.799 + 1.800 +/* high_bit not done yet */ 1.801 + 1.802 + 1.803 + 1.804 + 1.805 +