1 /*
2  * libZRTP SDK library, implements the ZRTP secure VoIP protocol.
3  * Copyright (c) 2006-2009 Philip R. Zimmermann.  All rights reserved.
4  * Contact: http://philzimmermann.com
5  * For licensing and other legal details, see the file zrtp_legal.c.
6  *
7  * Viktor Krykun <v.krikun at zfoneproject.com>
8  */
9 
10 #include "zrtp.h"
11 
12 #if ZRTP_HAVE_STRING_H == 1
13 #	include <string.h>
14 #endif
15 
16 
17 /*----------------------------------------------------------------------------*/
zrtp_zstrcmp(const zrtp_stringn_t * left,const zrtp_stringn_t * right)18 int zrtp_zstrcmp(const zrtp_stringn_t *left, const zrtp_stringn_t *right)
19 {
20     if (left->length == right->length) {
21 		return zrtp_memcmp(left->buffer, right->buffer, left->length);
22 	} else {
23 		return left->length - right->length;
24 	}
25 }
26 
zrtp_zstrcpy(zrtp_stringn_t * dst,const zrtp_stringn_t * src)27 void zrtp_zstrcpy(zrtp_stringn_t *dst, const zrtp_stringn_t *src)
28 {
29 	dst->length = ZRTP_MIN(dst->max_length, src->length);
30 	zrtp_memcpy(dst->buffer, src->buffer, dst->length);
31 	if (dst->length < dst->max_length) {
32 		dst->buffer[dst->length] = 0;
33 	}
34 }
35 
zrtp_zstrcpyc(zrtp_stringn_t * dst,const char * src)36 void zrtp_zstrcpyc(zrtp_stringn_t *dst, const char *src)
37 {
38 	dst->length = ZRTP_MIN(dst->max_length, strlen(src));
39 	zrtp_memcpy(dst->buffer, src, dst->length);
40 	if (dst->length < dst->max_length) {
41 		dst->buffer[dst->length] = 0;
42 	}
43 }
44 
zrtp_zstrncpy(zrtp_stringn_t * dst,const zrtp_stringn_t * src,uint16_t size)45 void zrtp_zstrncpy(zrtp_stringn_t *dst, const zrtp_stringn_t *src, uint16_t size)
46 {
47 	dst->length = ZRTP_MIN(dst->max_length, size);
48 	zrtp_memcpy(dst->buffer, src->buffer, dst->length);
49 	if (dst->length < dst->max_length) {
50 		dst->buffer[dst->length] = 0;
51 	}
52 }
53 
zrtp_zstrncpyc(zrtp_stringn_t * dst,const char * src,uint16_t size)54 void zrtp_zstrncpyc(zrtp_stringn_t *dst, const char *src, uint16_t size)
55 {
56 	dst->length = ZRTP_MIN(dst->max_length, size);
57 	zrtp_memcpy(dst->buffer, src, dst->length);
58 	if (dst->length < dst->max_length) {
59 		dst->buffer[dst->length] = 0;
60 	}
61 }
62 
zrtp_zstrcat(zrtp_stringn_t * dst,const zrtp_stringn_t * src)63 void zrtp_zstrcat(zrtp_stringn_t *dst, const zrtp_stringn_t *src)
64 {
65 	uint16_t count = ZRTP_MIN((dst->max_length - dst->length), src->length);
66 	zrtp_memcpy(dst->buffer + dst->length, src->buffer, count);
67 	dst->length += count;
68 	if (dst->length < dst->max_length) {
69 		dst->buffer[dst->length] = 0;
70 	}
71 }
72 
zrtp_wipe_zstring(zrtp_stringn_t * zstr)73 void zrtp_wipe_zstring(zrtp_stringn_t *zstr)
74 {
75 	if (zstr && zstr->length) {
76 		zrtp_memset(zstr->buffer, 0, zstr->max_length);
77 		zstr->length = 0;
78 	}
79 }
80 
zrtp_memcmp(const void * s1,const void * s2,uint32_t n)81 int zrtp_memcmp(const void* s1, const void* s2, uint32_t n)
82 {
83 	uint32_t i = 0;
84 	uint8_t* s1uc = (uint8_t*) s1;
85 	uint8_t* s2uc = (uint8_t*) s2;
86 
87 	for (i=0; i<n; i++) {
88 		if (s1uc[i] < s2uc[i]) {
89 			return -1;
90 		} else if (s1uc[i] > s2uc[i]) {
91 			return 1;
92 		}
93 	}
94 
95 	return 0;
96 }
97 
98 /*----------------------------------------------------------------------------*/
hex2char(char * dst,unsigned char b)99 static char* hex2char(char *dst, unsigned char b)
100 {
101 	unsigned char v = b >> 4;
102 	*dst++ = (v<=9) ? '0'+v : 'a'+ (v-10);
103 	v = b & 0x0f;
104 	*dst++ = (v<=9) ? '0'+v : 'a'+ (v-10);
105 
106 	return dst;
107 }
108 
hex2str(const char * bin,int bin_size,char * buff,int buff_size)109 const char* hex2str(const char* bin, int bin_size, char* buff, int buff_size)
110 {
111 	char* nptr = buff;
112 
113 	if (NULL == buff) {
114 		return "buffer is NULL";
115 	}
116 	if (buff_size < bin_size*2) {
117 		return "buffer too small";
118 	}
119 
120 	while (bin_size--) {
121 		nptr = hex2char(nptr, *bin++);
122 	}
123 
124 	if (buff_size >= bin_size*2+1)
125 		*nptr = 0;
126 
127 	return buff;
128 }
129 
130 /*----------------------------------------------------------------------------*/
char2hex(char v)131 static int char2hex(char v)
132 {
133 	if (v >= 'a' && v <= 'f') {
134 		return v - 'a' + 10;
135 	}
136 	if (v >= 'A' && v <= 'F') {
137 		return v - 'A' + 10;
138 	}
139 	if (v >= '0' && v <= '9') {
140 		return v - '0';
141 	}
142 	return 0x10;
143 }
144 
str2hex(const char * buff,int buff_size,char * bin,int bin_size)145 char *str2hex(const char* buff, int buff_size, char* bin, int bin_size)
146 {
147 	char tmp = 0;
148 
149 	if (NULL == buff || !buff_size) {
150 		return "buffer is NULL || !buf_size";
151 	}
152 	if (buff_size % 2) {
153 		return "buff_size has to be even";
154 	}
155 	if (buff_size > bin_size*2) {
156 		return "buffer too small";
157 	}
158 
159 	while (buff_size--)
160 	{
161 		int value = char2hex(*buff++);
162 		if (value > 0x0F) {
163 			return "wrong symbol in buffer";
164 		}
165 		if (buff_size % 2) {
166 			tmp = (char)value;
167 		} else {
168 			value |= (char)(tmp << 4);
169 			*bin++ = value;
170 		}
171 	}
172 
173 	return bin;
174 }
175