• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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