| Index: libsrtp/crypto/math/datatypes.c
|
| ===================================================================
|
| --- libsrtp/crypto/math/datatypes.c (revision 0)
|
| +++ libsrtp/crypto/math/datatypes.c (revision 0)
|
| @@ -0,0 +1,718 @@
|
| +/*
|
| + * datatypes.c
|
| + *
|
| + * data types for finite fields and functions for input, output, and
|
| + * manipulation
|
| + *
|
| + * David A. McGrew
|
| + * Cisco Systems, Inc.
|
| + */
|
| +/*
|
| + *
|
| + * Copyright (c) 2001-2006 Cisco Systems, Inc.
|
| + * All rights reserved.
|
| + *
|
| + * Redistribution and use in source and binary forms, with or without
|
| + * modification, are permitted provided that the following conditions
|
| + * are met:
|
| + *
|
| + * Redistributions of source code must retain the above copyright
|
| + * notice, this list of conditions and the following disclaimer.
|
| + *
|
| + * Redistributions in binary form must reproduce the above
|
| + * copyright notice, this list of conditions and the following
|
| + * disclaimer in the documentation and/or other materials provided
|
| + * with the distribution.
|
| + *
|
| + * Neither the name of the Cisco Systems, Inc. nor the names of its
|
| + * contributors may be used to endorse or promote products derived
|
| + * from this software without specific prior written permission.
|
| + *
|
| + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
| + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
| + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
| + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
| + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
| + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
| + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
| + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
| + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
| + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
| + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
| + * OF THE POSSIBILITY OF SUCH DAMAGE.
|
| + *
|
| + */
|
| +
|
| +#include "datatypes.h"
|
| +
|
| +int
|
| +octet_weight[256] = {
|
| + 0, 1, 1, 2, 1, 2, 2, 3,
|
| + 1, 2, 2, 3, 2, 3, 3, 4,
|
| + 1, 2, 2, 3, 2, 3, 3, 4,
|
| + 2, 3, 3, 4, 3, 4, 4, 5,
|
| + 1, 2, 2, 3, 2, 3, 3, 4,
|
| + 2, 3, 3, 4, 3, 4, 4, 5,
|
| + 2, 3, 3, 4, 3, 4, 4, 5,
|
| + 3, 4, 4, 5, 4, 5, 5, 6,
|
| + 1, 2, 2, 3, 2, 3, 3, 4,
|
| + 2, 3, 3, 4, 3, 4, 4, 5,
|
| + 2, 3, 3, 4, 3, 4, 4, 5,
|
| + 3, 4, 4, 5, 4, 5, 5, 6,
|
| + 2, 3, 3, 4, 3, 4, 4, 5,
|
| + 3, 4, 4, 5, 4, 5, 5, 6,
|
| + 3, 4, 4, 5, 4, 5, 5, 6,
|
| + 4, 5, 5, 6, 5, 6, 6, 7,
|
| + 1, 2, 2, 3, 2, 3, 3, 4,
|
| + 2, 3, 3, 4, 3, 4, 4, 5,
|
| + 2, 3, 3, 4, 3, 4, 4, 5,
|
| + 3, 4, 4, 5, 4, 5, 5, 6,
|
| + 2, 3, 3, 4, 3, 4, 4, 5,
|
| + 3, 4, 4, 5, 4, 5, 5, 6,
|
| + 3, 4, 4, 5, 4, 5, 5, 6,
|
| + 4, 5, 5, 6, 5, 6, 6, 7,
|
| + 2, 3, 3, 4, 3, 4, 4, 5,
|
| + 3, 4, 4, 5, 4, 5, 5, 6,
|
| + 3, 4, 4, 5, 4, 5, 5, 6,
|
| + 4, 5, 5, 6, 5, 6, 6, 7,
|
| + 3, 4, 4, 5, 4, 5, 5, 6,
|
| + 4, 5, 5, 6, 5, 6, 6, 7,
|
| + 4, 5, 5, 6, 5, 6, 6, 7,
|
| + 5, 6, 6, 7, 6, 7, 7, 8
|
| +};
|
| +
|
| +int
|
| +octet_get_weight(uint8_t octet) {
|
| + extern int octet_weight[256];
|
| +
|
| + return octet_weight[octet];
|
| +}
|
| +
|
| +/*
|
| + * bit_string is a buffer that is used to hold output strings, e.g.
|
| + * for printing.
|
| + */
|
| +
|
| +/* the value MAX_PRINT_STRING_LEN is defined in datatypes.h */
|
| +
|
| +char bit_string[MAX_PRINT_STRING_LEN];
|
| +
|
| +uint8_t
|
| +nibble_to_hex_char(uint8_t nibble) {
|
| + char buf[16] = {'0', '1', '2', '3', '4', '5', '6', '7',
|
| + '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
|
| + return buf[nibble & 0xF];
|
| +}
|
| +
|
| +char *
|
| +octet_string_hex_string(const void *s, int length) {
|
| + const uint8_t *str = (const uint8_t *)s;
|
| + int i;
|
| +
|
| + /* double length, since one octet takes two hex characters */
|
| + length *= 2;
|
| +
|
| + /* truncate string if it would be too long */
|
| + if (length > MAX_PRINT_STRING_LEN)
|
| + length = MAX_PRINT_STRING_LEN-1;
|
| +
|
| + for (i=0; i < length; i+=2) {
|
| + bit_string[i] = nibble_to_hex_char(*str >> 4);
|
| + bit_string[i+1] = nibble_to_hex_char(*str++ & 0xF);
|
| + }
|
| + bit_string[i] = 0; /* null terminate string */
|
| + return bit_string;
|
| +}
|
| +
|
| +inline int
|
| +hex_char_to_nibble(uint8_t c) {
|
| + switch(c) {
|
| + case ('0'): return 0x0;
|
| + case ('1'): return 0x1;
|
| + case ('2'): return 0x2;
|
| + case ('3'): return 0x3;
|
| + case ('4'): return 0x4;
|
| + case ('5'): return 0x5;
|
| + case ('6'): return 0x6;
|
| + case ('7'): return 0x7;
|
| + case ('8'): return 0x8;
|
| + case ('9'): return 0x9;
|
| + case ('a'): return 0xa;
|
| + case ('A'): return 0xa;
|
| + case ('b'): return 0xb;
|
| + case ('B'): return 0xb;
|
| + case ('c'): return 0xc;
|
| + case ('C'): return 0xc;
|
| + case ('d'): return 0xd;
|
| + case ('D'): return 0xd;
|
| + case ('e'): return 0xe;
|
| + case ('E'): return 0xe;
|
| + case ('f'): return 0xf;
|
| + case ('F'): return 0xf;
|
| + default: return -1; /* this flags an error */
|
| + }
|
| + /* NOTREACHED */
|
| + return -1; /* this keeps compilers from complaining */
|
| +}
|
| +
|
| +int
|
| +is_hex_string(char *s) {
|
| + while(*s != 0)
|
| + if (hex_char_to_nibble(*s++) == -1)
|
| + return 0;
|
| + return 1;
|
| +}
|
| +
|
| +/*
|
| + * hex_string_to_octet_string converts a hexadecimal string
|
| + * of length 2 * len to a raw octet string of length len
|
| + */
|
| +
|
| +int
|
| +hex_string_to_octet_string(char *raw, char *hex, int len) {
|
| + uint8_t x;
|
| + int tmp;
|
| + int hex_len;
|
| +
|
| + hex_len = 0;
|
| + while (hex_len < len) {
|
| + tmp = hex_char_to_nibble(hex[0]);
|
| + if (tmp == -1)
|
| + return hex_len;
|
| + x = (tmp << 4);
|
| + hex_len++;
|
| + tmp = hex_char_to_nibble(hex[1]);
|
| + if (tmp == -1)
|
| + return hex_len;
|
| + x |= (tmp & 0xff);
|
| + hex_len++;
|
| + *raw++ = x;
|
| + hex += 2;
|
| + }
|
| + return hex_len;
|
| +}
|
| +
|
| +char *
|
| +v128_hex_string(v128_t *x) {
|
| + int i, j;
|
| +
|
| + for (i=j=0; i < 16; i++) {
|
| + bit_string[j++] = nibble_to_hex_char(x->v8[i] >> 4);
|
| + bit_string[j++] = nibble_to_hex_char(x->v8[i] & 0xF);
|
| + }
|
| +
|
| + bit_string[j] = 0; /* null terminate string */
|
| + return bit_string;
|
| +}
|
| +
|
| +char *
|
| +v128_bit_string(v128_t *x) {
|
| + int j, i;
|
| + uint32_t mask;
|
| +
|
| + for (j=i=0; j < 4; j++) {
|
| + for (mask=0x80000000; mask > 0; mask >>= 1) {
|
| + if (x->v32[j] & mask)
|
| + bit_string[i] = '1';
|
| + else
|
| + bit_string[i] = '0';
|
| + ++i;
|
| + }
|
| + }
|
| + bit_string[128] = 0; /* null terminate string */
|
| +
|
| + return bit_string;
|
| +}
|
| +
|
| +void
|
| +v128_copy_octet_string(v128_t *x, const uint8_t s[16]) {
|
| +#ifdef ALIGNMENT_32BIT_REQUIRED
|
| + if ((((uint32_t) &s[0]) & 0x3) != 0)
|
| +#endif
|
| + {
|
| + x->v8[0] = s[0];
|
| + x->v8[1] = s[1];
|
| + x->v8[2] = s[2];
|
| + x->v8[3] = s[3];
|
| + x->v8[4] = s[4];
|
| + x->v8[5] = s[5];
|
| + x->v8[6] = s[6];
|
| + x->v8[7] = s[7];
|
| + x->v8[8] = s[8];
|
| + x->v8[9] = s[9];
|
| + x->v8[10] = s[10];
|
| + x->v8[11] = s[11];
|
| + x->v8[12] = s[12];
|
| + x->v8[13] = s[13];
|
| + x->v8[14] = s[14];
|
| + x->v8[15] = s[15];
|
| + }
|
| +#ifdef ALIGNMENT_32BIT_REQUIRED
|
| + else
|
| + {
|
| + v128_t *v = (v128_t *) &s[0];
|
| +
|
| + v128_copy(x,v);
|
| + }
|
| +#endif
|
| +}
|
| +
|
| +#ifndef DATATYPES_USE_MACROS /* little functions are not macros */
|
| +
|
| +void
|
| +v128_set_to_zero(v128_t *x) {
|
| + _v128_set_to_zero(x);
|
| +}
|
| +
|
| +void
|
| +v128_copy(v128_t *x, const v128_t *y) {
|
| + _v128_copy(x, y);
|
| +}
|
| +
|
| +void
|
| +v128_xor(v128_t *z, v128_t *x, v128_t *y) {
|
| + _v128_xor(z, x, y);
|
| +}
|
| +
|
| +void
|
| +v128_and(v128_t *z, v128_t *x, v128_t *y) {
|
| + _v128_and(z, x, y);
|
| +}
|
| +
|
| +void
|
| +v128_or(v128_t *z, v128_t *x, v128_t *y) {
|
| + _v128_or(z, x, y);
|
| +}
|
| +
|
| +void
|
| +v128_complement(v128_t *x) {
|
| + _v128_complement(x);
|
| +}
|
| +
|
| +int
|
| +v128_is_eq(const v128_t *x, const v128_t *y) {
|
| + return _v128_is_eq(x, y);
|
| +}
|
| +
|
| +int
|
| +v128_xor_eq(v128_t *x, const v128_t *y) {
|
| + return _v128_xor_eq(x, y);
|
| +}
|
| +
|
| +int
|
| +v128_get_bit(const v128_t *x, int i) {
|
| + return _v128_get_bit(x, i);
|
| +}
|
| +
|
| +void
|
| +v128_set_bit(v128_t *x, int i) {
|
| + _v128_set_bit(x, i);
|
| +}
|
| +
|
| +void
|
| +v128_clear_bit(v128_t *x, int i){
|
| + _v128_clear_bit(x, i);
|
| +}
|
| +
|
| +void
|
| +v128_set_bit_to(v128_t *x, int i, int y){
|
| + _v128_set_bit_to(x, i, y);
|
| +}
|
| +
|
| +
|
| +#endif /* DATATYPES_USE_MACROS */
|
| +
|
| +void
|
| +v128_right_shift(v128_t *x, int shift) {
|
| + const int base_index = shift >> 5;
|
| + const int bit_index = shift & 31;
|
| + int i, from;
|
| + uint32_t b;
|
| +
|
| + if (shift > 127) {
|
| + v128_set_to_zero(x);
|
| + return;
|
| + }
|
| +
|
| + if (bit_index == 0) {
|
| +
|
| + /* copy each word from left size to right side */
|
| + x->v32[4-1] = x->v32[4-1-base_index];
|
| + for (i=4-1; i > base_index; i--)
|
| + x->v32[i-1] = x->v32[i-1-base_index];
|
| +
|
| + } else {
|
| +
|
| + /* set each word to the "or" of the two bit-shifted words */
|
| + for (i = 4; i > base_index; i--) {
|
| + from = i-1 - base_index;
|
| + b = x->v32[from] << bit_index;
|
| + if (from > 0)
|
| + b |= x->v32[from-1] >> (32-bit_index);
|
| + x->v32[i-1] = b;
|
| + }
|
| +
|
| + }
|
| +
|
| + /* now wrap up the final portion */
|
| + for (i=0; i < base_index; i++)
|
| + x->v32[i] = 0;
|
| +
|
| +}
|
| +
|
| +void
|
| +v128_left_shift(v128_t *x, int shift) {
|
| + int i;
|
| + const int base_index = shift >> 5;
|
| + const int bit_index = shift & 31;
|
| +
|
| + if (shift > 127) {
|
| + v128_set_to_zero(x);
|
| + return;
|
| + }
|
| +
|
| + if (bit_index == 0) {
|
| + for (i=0; i < 4 - base_index; i++)
|
| + x->v32[i] = x->v32[i+base_index];
|
| + } else {
|
| + for (i=0; i < 4 - base_index - 1; i++)
|
| + x->v32[i] = (x->v32[i+base_index] >> bit_index) ^
|
| + (x->v32[i+base_index+1] << (32 - bit_index));
|
| + x->v32[4 - base_index-1] = x->v32[4-1] >> bit_index;
|
| + }
|
| +
|
| + /* now wrap up the final portion */
|
| + for (i = 4 - base_index; i < 4; i++)
|
| + x->v32[i] = 0;
|
| +
|
| +}
|
| +
|
| +/* functions manipulating bitvector_t */
|
| +
|
| +#ifndef DATATYPES_USE_MACROS /* little functions are not macros */
|
| +
|
| +int
|
| +bitvector_get_bit(const bitvector_t *v, int bit_index)
|
| +{
|
| + return _bitvector_get_bit(v, bit_index);
|
| +}
|
| +
|
| +void
|
| +bitvector_set_bit(bitvector_t *v, int bit_index)
|
| +{
|
| + _bitvector_set_bit(v, bit_index);
|
| +}
|
| +
|
| +void
|
| +bitvector_clear_bit(bitvector_t *v, int bit_index)
|
| +{
|
| + _bitvector_clear_bit(v, bit_index);
|
| +}
|
| +
|
| +
|
| +#endif /* DATATYPES_USE_MACROS */
|
| +
|
| +int
|
| +bitvector_alloc(bitvector_t *v, unsigned long length) {
|
| + unsigned long l;
|
| +
|
| + /* Round length up to a multiple of bits_per_word */
|
| + length = (length + bits_per_word - 1) & ~(unsigned long)((bits_per_word - 1));
|
| +
|
| + l = length / bits_per_word * bytes_per_word;
|
| +
|
| + /* allocate memory, then set parameters */
|
| + if (l == 0)
|
| + v->word = NULL;
|
| + else {
|
| + v->word = (uint32_t*)crypto_alloc(l);
|
| + if (v->word == NULL) {
|
| + v->word = NULL;
|
| + v->length = 0;
|
| + return -1;
|
| + }
|
| + }
|
| + v->length = length;
|
| +
|
| + /* initialize bitvector to zero */
|
| + bitvector_set_to_zero(v);
|
| +
|
| + return 0;
|
| +}
|
| +
|
| +
|
| +void
|
| +bitvector_dealloc(bitvector_t *v) {
|
| + if (v->word != NULL)
|
| + crypto_free(v->word);
|
| + v->word = NULL;
|
| + v->length = 0;
|
| +}
|
| +
|
| +void
|
| +bitvector_set_to_zero(bitvector_t *x)
|
| +{
|
| + /* C99 guarantees that memset(0) will set the value 0 for uint32_t */
|
| + memset(x->word, 0, x->length >> 3);
|
| +}
|
| +
|
| +char *
|
| +bitvector_bit_string(bitvector_t *x, char* buf, int len) {
|
| + int j, i;
|
| + uint32_t mask;
|
| +
|
| + for (j=i=0; j < (int)(x->length>>5) && i < len-1; j++) {
|
| + for (mask=0x80000000; mask > 0; mask >>= 1) {
|
| + if (x->word[j] & mask)
|
| + buf[i] = '1';
|
| + else
|
| + buf[i] = '0';
|
| + ++i;
|
| + if (i >= len-1)
|
| + break;
|
| + }
|
| + }
|
| + buf[i] = 0; /* null terminate string */
|
| +
|
| + return buf;
|
| +}
|
| +
|
| +void
|
| +bitvector_left_shift(bitvector_t *x, int shift) {
|
| + int i;
|
| + const int base_index = shift >> 5;
|
| + const int bit_index = shift & 31;
|
| + const int word_length = x->length >> 5;
|
| +
|
| + if (shift >= (int)x->length) {
|
| + bitvector_set_to_zero(x);
|
| + return;
|
| + }
|
| +
|
| + if (bit_index == 0) {
|
| + for (i=0; i < word_length - base_index; i++)
|
| + x->word[i] = x->word[i+base_index];
|
| + } else {
|
| + for (i=0; i < word_length - base_index - 1; i++)
|
| + x->word[i] = (x->word[i+base_index] >> bit_index) ^
|
| + (x->word[i+base_index+1] << (32 - bit_index));
|
| + x->word[word_length - base_index-1] = x->word[word_length-1] >> bit_index;
|
| + }
|
| +
|
| + /* now wrap up the final portion */
|
| + for (i = word_length - base_index; i < word_length; i++)
|
| + x->word[i] = 0;
|
| +
|
| +}
|
| +
|
| +
|
| +int
|
| +octet_string_is_eq(uint8_t *a, uint8_t *b, int len) {
|
| + uint8_t *end = b + len;
|
| + while (b < end)
|
| + if (*a++ != *b++)
|
| + return 1;
|
| + return 0;
|
| +}
|
| +
|
| +void
|
| +octet_string_set_to_zero(uint8_t *s, int len) {
|
| + uint8_t *end = s + len;
|
| +
|
| + do {
|
| + *s = 0;
|
| + } while (++s < end);
|
| +
|
| +}
|
| +
|
| +
|
| +/*
|
| + * From RFC 1521: The Base64 Alphabet
|
| + *
|
| + * Value Encoding Value Encoding Value Encoding Value Encoding
|
| + * 0 A 17 R 34 i 51 z
|
| + * 1 B 18 S 35 j 52 0
|
| + * 2 C 19 T 36 k 53 1
|
| + * 3 D 20 U 37 l 54 2
|
| + * 4 E 21 V 38 m 55 3
|
| + * 5 F 22 W 39 n 56 4
|
| + * 6 G 23 X 40 o 57 5
|
| + * 7 H 24 Y 41 p 58 6
|
| + * 8 I 25 Z 42 q 59 7
|
| + * 9 J 26 a 43 r 60 8
|
| + * 10 K 27 b 44 s 61 9
|
| + * 11 L 28 c 45 t 62 +
|
| + * 12 M 29 d 46 u 63 /
|
| + * 13 N 30 e 47 v
|
| + * 14 O 31 f 48 w (pad) =
|
| + * 15 P 32 g 49 x
|
| + * 16 Q 33 h 50 y
|
| + */
|
| +
|
| +int
|
| +base64_char_to_sextet(uint8_t c) {
|
| + switch(c) {
|
| + case 'A':
|
| + return 0;
|
| + case 'B':
|
| + return 1;
|
| + case 'C':
|
| + return 2;
|
| + case 'D':
|
| + return 3;
|
| + case 'E':
|
| + return 4;
|
| + case 'F':
|
| + return 5;
|
| + case 'G':
|
| + return 6;
|
| + case 'H':
|
| + return 7;
|
| + case 'I':
|
| + return 8;
|
| + case 'J':
|
| + return 9;
|
| + case 'K':
|
| + return 10;
|
| + case 'L':
|
| + return 11;
|
| + case 'M':
|
| + return 12;
|
| + case 'N':
|
| + return 13;
|
| + case 'O':
|
| + return 14;
|
| + case 'P':
|
| + return 15;
|
| + case 'Q':
|
| + return 16;
|
| + case 'R':
|
| + return 17;
|
| + case 'S':
|
| + return 18;
|
| + case 'T':
|
| + return 19;
|
| + case 'U':
|
| + return 20;
|
| + case 'V':
|
| + return 21;
|
| + case 'W':
|
| + return 22;
|
| + case 'X':
|
| + return 23;
|
| + case 'Y':
|
| + return 24;
|
| + case 'Z':
|
| + return 25;
|
| + case 'a':
|
| + return 26;
|
| + case 'b':
|
| + return 27;
|
| + case 'c':
|
| + return 28;
|
| + case 'd':
|
| + return 29;
|
| + case 'e':
|
| + return 30;
|
| + case 'f':
|
| + return 31;
|
| + case 'g':
|
| + return 32;
|
| + case 'h':
|
| + return 33;
|
| + case 'i':
|
| + return 34;
|
| + case 'j':
|
| + return 35;
|
| + case 'k':
|
| + return 36;
|
| + case 'l':
|
| + return 37;
|
| + case 'm':
|
| + return 38;
|
| + case 'n':
|
| + return 39;
|
| + case 'o':
|
| + return 40;
|
| + case 'p':
|
| + return 41;
|
| + case 'q':
|
| + return 42;
|
| + case 'r':
|
| + return 43;
|
| + case 's':
|
| + return 44;
|
| + case 't':
|
| + return 45;
|
| + case 'u':
|
| + return 46;
|
| + case 'v':
|
| + return 47;
|
| + case 'w':
|
| + return 48;
|
| + case 'x':
|
| + return 49;
|
| + case 'y':
|
| + return 50;
|
| + case 'z':
|
| + return 51;
|
| + case '0':
|
| + return 52;
|
| + case '1':
|
| + return 53;
|
| + case '2':
|
| + return 54;
|
| + case '3':
|
| + return 55;
|
| + case '4':
|
| + return 56;
|
| + case '5':
|
| + return 57;
|
| + case '6':
|
| + return 58;
|
| + case '7':
|
| + return 59;
|
| + case '8':
|
| + return 60;
|
| + case '9':
|
| + return 61;
|
| + case '+':
|
| + return 62;
|
| + case '/':
|
| + return 63;
|
| + case '=':
|
| + return 64;
|
| + default:
|
| + break;
|
| + }
|
| + return -1;
|
| +}
|
| +
|
| +/*
|
| + * base64_string_to_octet_string converts a hexadecimal string
|
| + * of length 2 * len to a raw octet string of length len
|
| + */
|
| +
|
| +int
|
| +base64_string_to_octet_string(char *raw, char *base64, int len) {
|
| + uint8_t x;
|
| + int tmp;
|
| + int base64_len;
|
| +
|
| + base64_len = 0;
|
| + while (base64_len < len) {
|
| + tmp = base64_char_to_sextet(base64[0]);
|
| + if (tmp == -1)
|
| + return base64_len;
|
| + x = (tmp << 6);
|
| + base64_len++;
|
| + tmp = base64_char_to_sextet(base64[1]);
|
| + if (tmp == -1)
|
| + return base64_len;
|
| + x |= (tmp & 0xffff);
|
| + base64_len++;
|
| + *raw++ = x;
|
| + base64 += 2;
|
| + }
|
| + return base64_len;
|
| +}
|
|
|
| Property changes on: libsrtp/crypto/math/datatypes.c
|
| ___________________________________________________________________
|
| Added: svn:eol-style
|
| + LF
|
|
|
|
|