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-2017 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 #ifdef OPENSSL
51 #include <openssl/crypto.h>
52 #endif
53
54 #include "datatypes.h"
55
56 static const int8_t octet_weight[256] = {
57 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, 1, 2, 2, 3, 2, 3, 3, 4,
58 2, 3, 3, 4, 3, 4, 4, 5, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
59 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 1, 2, 2, 3, 2, 3, 3, 4,
60 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
61 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6,
62 4, 5, 5, 6, 5, 6, 6, 7, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
63 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 2, 3, 3, 4, 3, 4, 4, 5,
64 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
65 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6,
66 4, 5, 5, 6, 5, 6, 6, 7, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
67 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8
68 };
69
octet_get_weight(uint8_t octet)70 int octet_get_weight(uint8_t octet)
71 {
72 return (int)octet_weight[octet];
73 }
74
75 /*
76 * bit_string is a buffer that is used to hold output strings, e.g.
77 * for printing.
78 */
79
80 /* the value MAX_PRINT_STRING_LEN is defined in datatypes.h */
81
82 char bit_string[MAX_PRINT_STRING_LEN];
83
srtp_nibble_to_hex_char(uint8_t nibble)84 uint8_t srtp_nibble_to_hex_char(uint8_t nibble)
85 {
86 char buf[16] = { '0', '1', '2', '3', '4', '5', '6', '7',
87 '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
88 return buf[nibble & 0xF];
89 }
90
srtp_octet_string_hex_string(const void * s,int length)91 char *srtp_octet_string_hex_string(const void *s, int length)
92 {
93 const uint8_t *str = (const uint8_t *)s;
94 int i;
95
96 /* double length, since one octet takes two hex characters */
97 length *= 2;
98
99 /* truncate string if it would be too long */
100 if (length > MAX_PRINT_STRING_LEN)
101 length = MAX_PRINT_STRING_LEN - 2;
102
103 for (i = 0; i < length; i += 2) {
104 bit_string[i] = srtp_nibble_to_hex_char(*str >> 4);
105 bit_string[i + 1] = srtp_nibble_to_hex_char(*str++ & 0xF);
106 }
107 bit_string[i] = 0; /* null terminate string */
108 return bit_string;
109 }
110
v128_hex_string(v128_t * x)111 char *v128_hex_string(v128_t *x)
112 {
113 int i, j;
114
115 for (i = j = 0; i < 16; i++) {
116 bit_string[j++] = srtp_nibble_to_hex_char(x->v8[i] >> 4);
117 bit_string[j++] = srtp_nibble_to_hex_char(x->v8[i] & 0xF);
118 }
119
120 bit_string[j] = 0; /* null terminate string */
121 return bit_string;
122 }
123
v128_bit_string(v128_t * x)124 char *v128_bit_string(v128_t *x)
125 {
126 int j, i;
127 uint32_t mask;
128
129 for (j = i = 0; j < 4; j++) {
130 for (mask = 0x80000000; mask > 0; mask >>= 1) {
131 if (x->v32[j] & mask)
132 bit_string[i] = '1';
133 else
134 bit_string[i] = '0';
135 ++i;
136 }
137 }
138 bit_string[128] = 0; /* null terminate string */
139
140 return bit_string;
141 }
142
v128_copy_octet_string(v128_t * x,const uint8_t s[16])143 void v128_copy_octet_string(v128_t *x, const uint8_t s[16])
144 {
145 #ifdef ALIGNMENT_32BIT_REQUIRED
146 if ((((uint32_t)&s[0]) & 0x3) != 0)
147 #endif
148 {
149 x->v8[0] = s[0];
150 x->v8[1] = s[1];
151 x->v8[2] = s[2];
152 x->v8[3] = s[3];
153 x->v8[4] = s[4];
154 x->v8[5] = s[5];
155 x->v8[6] = s[6];
156 x->v8[7] = s[7];
157 x->v8[8] = s[8];
158 x->v8[9] = s[9];
159 x->v8[10] = s[10];
160 x->v8[11] = s[11];
161 x->v8[12] = s[12];
162 x->v8[13] = s[13];
163 x->v8[14] = s[14];
164 x->v8[15] = s[15];
165 }
166 #ifdef ALIGNMENT_32BIT_REQUIRED
167 else {
168 v128_t *v = (v128_t *)&s[0];
169
170 v128_copy(x, v);
171 }
172 #endif
173 }
174
175 #ifndef DATATYPES_USE_MACROS /* little functions are not macros */
176
v128_set_to_zero(v128_t * x)177 void v128_set_to_zero(v128_t *x)
178 {
179 _v128_set_to_zero(x);
180 }
181
v128_copy(v128_t * x,const v128_t * y)182 void v128_copy(v128_t *x, const v128_t *y)
183 {
184 _v128_copy(x, y);
185 }
186
v128_xor(v128_t * z,v128_t * x,v128_t * y)187 void v128_xor(v128_t *z, v128_t *x, v128_t *y)
188 {
189 _v128_xor(z, x, y);
190 }
191
v128_and(v128_t * z,v128_t * x,v128_t * y)192 void v128_and(v128_t *z, v128_t *x, v128_t *y)
193 {
194 _v128_and(z, x, y);
195 }
196
v128_or(v128_t * z,v128_t * x,v128_t * y)197 void v128_or(v128_t *z, v128_t *x, v128_t *y)
198 {
199 _v128_or(z, x, y);
200 }
201
v128_complement(v128_t * x)202 void v128_complement(v128_t *x)
203 {
204 _v128_complement(x);
205 }
206
v128_is_eq(const v128_t * x,const v128_t * y)207 int v128_is_eq(const v128_t *x, const v128_t *y)
208 {
209 return _v128_is_eq(x, y);
210 }
211
v128_xor_eq(v128_t * x,const v128_t * y)212 int v128_xor_eq(v128_t *x, const v128_t *y)
213 {
214 return _v128_xor_eq(x, y);
215 }
216
v128_get_bit(const v128_t * x,int i)217 int v128_get_bit(const v128_t *x, int i)
218 {
219 return _v128_get_bit(x, i);
220 }
221
v128_set_bit(v128_t * x,int i)222 void v128_set_bit(v128_t *x, int i)
223 {
224 _v128_set_bit(x, i);
225 }
226
v128_clear_bit(v128_t * x,int i)227 void v128_clear_bit(v128_t *x, int i)
228 {
229 _v128_clear_bit(x, i);
230 }
231
v128_set_bit_to(v128_t * x,int i,int y)232 void v128_set_bit_to(v128_t *x, int i, int y)
233 {
234 _v128_set_bit_to(x, i, y);
235 }
236
237 #endif /* DATATYPES_USE_MACROS */
238
v128_right_shift(v128_t * x,int shift)239 void v128_right_shift(v128_t *x, int shift)
240 {
241 const int base_index = shift >> 5;
242 const int bit_index = shift & 31;
243 int i, from;
244 uint32_t b;
245
246 if (shift > 127) {
247 v128_set_to_zero(x);
248 return;
249 }
250
251 if (bit_index == 0) {
252 /* copy each word from left size to right side */
253 x->v32[4 - 1] = x->v32[4 - 1 - base_index];
254 for (i = 4 - 1; i > base_index; i--)
255 x->v32[i - 1] = x->v32[i - 1 - base_index];
256
257 } else {
258 /* set each word to the "or" of the two bit-shifted words */
259 for (i = 4; i > base_index; i--) {
260 from = i - 1 - base_index;
261 b = x->v32[from] << bit_index;
262 if (from > 0)
263 b |= x->v32[from - 1] >> (32 - bit_index);
264 x->v32[i - 1] = b;
265 }
266 }
267
268 /* now wrap up the final portion */
269 for (i = 0; i < base_index; i++)
270 x->v32[i] = 0;
271 }
272
v128_left_shift(v128_t * x,int shift)273 void v128_left_shift(v128_t *x, int shift)
274 {
275 int i;
276 const int base_index = shift >> 5;
277 const int bit_index = shift & 31;
278
279 if (shift > 127) {
280 v128_set_to_zero(x);
281 return;
282 }
283
284 if (bit_index == 0) {
285 for (i = 0; i < 4 - base_index; i++)
286 x->v32[i] = x->v32[i + base_index];
287 } else {
288 for (i = 0; i < 4 - base_index - 1; i++)
289 x->v32[i] = (x->v32[i + base_index] >> bit_index) ^
290 (x->v32[i + base_index + 1] << (32 - bit_index));
291 x->v32[4 - base_index - 1] = x->v32[4 - 1] >> bit_index;
292 }
293
294 /* now wrap up the final portion */
295 for (i = 4 - base_index; i < 4; i++)
296 x->v32[i] = 0;
297 }
298
299 /* functions manipulating bitvector_t */
300
301 #ifndef DATATYPES_USE_MACROS /* little functions are not macros */
302
bitvector_get_bit(const bitvector_t * v,int bit_index)303 int bitvector_get_bit(const bitvector_t *v, int bit_index)
304 {
305 return _bitvector_get_bit(v, bit_index);
306 }
307
bitvector_set_bit(bitvector_t * v,int bit_index)308 void bitvector_set_bit(bitvector_t *v, int bit_index)
309 {
310 _bitvector_set_bit(v, bit_index);
311 }
312
bitvector_clear_bit(bitvector_t * v,int bit_index)313 void bitvector_clear_bit(bitvector_t *v, int bit_index)
314 {
315 _bitvector_clear_bit(v, bit_index);
316 }
317
318 #endif /* DATATYPES_USE_MACROS */
319
bitvector_alloc(bitvector_t * v,unsigned long length)320 int bitvector_alloc(bitvector_t *v, unsigned long length)
321 {
322 unsigned long l;
323
324 /* Round length up to a multiple of bits_per_word */
325 length =
326 (length + bits_per_word - 1) & ~(unsigned long)((bits_per_word - 1));
327
328 l = length / bits_per_word * bytes_per_word;
329
330 /* allocate memory, then set parameters */
331 if (l == 0) {
332 v->word = NULL;
333 v->length = 0;
334 return -1;
335 } else {
336 v->word = (uint32_t *)srtp_crypto_alloc(l);
337 if (v->word == NULL) {
338 v->length = 0;
339 return -1;
340 }
341 }
342 v->length = length;
343
344 /* initialize bitvector to zero */
345 bitvector_set_to_zero(v);
346
347 return 0;
348 }
349
bitvector_dealloc(bitvector_t * v)350 void bitvector_dealloc(bitvector_t *v)
351 {
352 if (v->word != NULL)
353 srtp_crypto_free(v->word);
354 v->word = NULL;
355 v->length = 0;
356 }
357
bitvector_set_to_zero(bitvector_t * x)358 void bitvector_set_to_zero(bitvector_t *x)
359 {
360 /* C99 guarantees that memset(0) will set the value 0 for uint32_t */
361 memset(x->word, 0, x->length >> 3);
362 }
363
bitvector_bit_string(bitvector_t * x,char * buf,int len)364 char *bitvector_bit_string(bitvector_t *x, char *buf, int len)
365 {
366 int j, i;
367 uint32_t mask;
368
369 for (j = i = 0; j < (int)(x->length >> 5) && i < len - 1; j++) {
370 for (mask = 0x80000000; mask > 0; mask >>= 1) {
371 if (x->word[j] & mask)
372 buf[i] = '1';
373 else
374 buf[i] = '0';
375 ++i;
376 if (i >= len - 1)
377 break;
378 }
379 }
380 buf[i] = 0; /* null terminate string */
381
382 return buf;
383 }
384
bitvector_left_shift(bitvector_t * x,int shift)385 void bitvector_left_shift(bitvector_t *x, int shift)
386 {
387 int i;
388 const int base_index = shift >> 5;
389 const int bit_index = shift & 31;
390 const int word_length = x->length >> 5;
391
392 if (shift >= (int)x->length) {
393 bitvector_set_to_zero(x);
394 return;
395 }
396
397 if (bit_index == 0) {
398 for (i = 0; i < word_length - base_index; i++)
399 x->word[i] = x->word[i + base_index];
400 } else {
401 for (i = 0; i < word_length - base_index - 1; i++)
402 x->word[i] = (x->word[i + base_index] >> bit_index) ^
403 (x->word[i + base_index + 1] << (32 - bit_index));
404 x->word[word_length - base_index - 1] =
405 x->word[word_length - 1] >> bit_index;
406 }
407
408 /* now wrap up the final portion */
409 for (i = word_length - base_index; i < word_length; i++)
410 x->word[i] = 0;
411 }
412
srtp_octet_string_is_eq(uint8_t * a,uint8_t * b,int len)413 int srtp_octet_string_is_eq(uint8_t *a, uint8_t *b, int len)
414 {
415 uint8_t *end = b + len;
416 uint8_t accumulator = 0;
417
418 /*
419 * We use this somewhat obscure implementation to try to ensure the running
420 * time only depends on len, even accounting for compiler optimizations.
421 * The accumulator ends up zero iff the strings are equal.
422 */
423 while (b < end)
424 accumulator |= (*a++ ^ *b++);
425
426 /* Return 1 if *not* equal. */
427 return accumulator != 0;
428 }
429
srtp_cleanse(void * s,size_t len)430 void srtp_cleanse(void *s, size_t len)
431 {
432 volatile unsigned char *p = (volatile unsigned char *)s;
433 while (len--)
434 *p++ = 0;
435 }
436
octet_string_set_to_zero(void * s,size_t len)437 void octet_string_set_to_zero(void *s, size_t len)
438 {
439 #if defined(OPENSSL) && !defined(OPENSSL_CLEANSE_BROKEN)
440 OPENSSL_cleanse(s, len);
441 #else
442 srtp_cleanse(s, len);
443 #endif
444 }
445
446 #ifdef TESTAPP_SOURCE
447
448 static const char b64chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
449 "abcdefghijklmnopqrstuvwxyz0123456789+/";
450
base64_block_to_octet_triple(char * out,char * in)451 static int base64_block_to_octet_triple(char *out, char *in)
452 {
453 unsigned char sextets[4] = { 0 };
454 int j = 0;
455 int i;
456
457 for (i = 0; i < 4; i++) {
458 char *p = strchr(b64chars, in[i]);
459 if (p != NULL)
460 sextets[i] = p - b64chars;
461 else
462 j++;
463 }
464
465 out[0] = (sextets[0] << 2) | (sextets[1] >> 4);
466 if (j < 2)
467 out[1] = (sextets[1] << 4) | (sextets[2] >> 2);
468 if (j < 1)
469 out[2] = (sextets[2] << 6) | sextets[3];
470 return j;
471 }
472
base64_string_to_octet_string(char * out,int * pad,char * in,int len)473 int base64_string_to_octet_string(char *out, int *pad, char *in, int len)
474 {
475 int k = 0;
476 int i = 0;
477 int j = 0;
478 if (len % 4 != 0)
479 return 0;
480
481 while (i < len && j == 0) {
482 j = base64_block_to_octet_triple(out + k, in + i);
483 k += 3;
484 i += 4;
485 }
486 *pad = j;
487 return i;
488 }
489
490 #endif
491