644b8060fe6ba2df62b8c7a01e54ec3910b72362
[strongswan.git] / src / libstrongswan / utils / chunk.c
1 /*
2 * Copyright (C) 2008-2013 Tobias Brunner
3 * Copyright (C) 2005-2006 Martin Willi
4 * Copyright (C) 2005 Jan Hutter
5 * Hochschule fuer Technik Rapperswil
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 * for more details.
16 */
17
18 #include <stdio.h>
19 #include <sys/types.h>
20 #include <sys/stat.h>
21 #include <fcntl.h>
22 #include <unistd.h>
23 #include <errno.h>
24 #include <pthread.h>
25 #include <ctype.h>
26
27 #include "chunk.h"
28 #include "debug.h"
29
30 /**
31 * Empty chunk.
32 */
33 chunk_t chunk_empty = { NULL, 0 };
34
35 /**
36 * Described in header.
37 */
38 chunk_t chunk_create_clone(u_char *ptr, chunk_t chunk)
39 {
40 chunk_t clone = chunk_empty;
41
42 if (chunk.ptr && chunk.len > 0)
43 {
44 clone.ptr = ptr;
45 clone.len = chunk.len;
46 memcpy(clone.ptr, chunk.ptr, chunk.len);
47 }
48
49 return clone;
50 }
51
52 /**
53 * Described in header.
54 */
55 size_t chunk_length(const char* mode, ...)
56 {
57 va_list chunks;
58 size_t length = 0;
59
60 va_start(chunks, mode);
61 while (TRUE)
62 {
63 switch (*mode++)
64 {
65 case 'm':
66 case 'c':
67 case 's':
68 {
69 chunk_t ch = va_arg(chunks, chunk_t);
70 length += ch.len;
71 continue;
72 }
73 default:
74 break;
75 }
76 break;
77 }
78 va_end(chunks);
79 return length;
80 }
81
82 /**
83 * Described in header.
84 */
85 chunk_t chunk_create_cat(u_char *ptr, const char* mode, ...)
86 {
87 va_list chunks;
88 chunk_t construct = chunk_create(ptr, 0);
89
90 va_start(chunks, mode);
91 while (TRUE)
92 {
93 bool free_chunk = FALSE, clear_chunk = FALSE;
94 chunk_t ch;
95
96 switch (*mode++)
97 {
98 case 's':
99 clear_chunk = TRUE;
100 /* FALL */
101 case 'm':
102 free_chunk = TRUE;
103 /* FALL */
104 case 'c':
105 ch = va_arg(chunks, chunk_t);
106 memcpy(ptr, ch.ptr, ch.len);
107 ptr += ch.len;
108 construct.len += ch.len;
109 if (clear_chunk)
110 {
111 chunk_clear(&ch);
112 }
113 else if (free_chunk)
114 {
115 free(ch.ptr);
116 }
117 continue;
118 default:
119 break;
120 }
121 break;
122 }
123 va_end(chunks);
124
125 return construct;
126 }
127
128 /**
129 * Described in header.
130 */
131 void chunk_split(chunk_t chunk, const char *mode, ...)
132 {
133 va_list chunks;
134 u_int len;
135 chunk_t *ch;
136
137 va_start(chunks, mode);
138 while (TRUE)
139 {
140 if (*mode == '\0')
141 {
142 break;
143 }
144 len = va_arg(chunks, u_int);
145 ch = va_arg(chunks, chunk_t*);
146 /* a null chunk means skip len bytes */
147 if (ch == NULL)
148 {
149 chunk = chunk_skip(chunk, len);
150 continue;
151 }
152 switch (*mode++)
153 {
154 case 'm':
155 {
156 ch->len = min(chunk.len, len);
157 if (ch->len)
158 {
159 ch->ptr = chunk.ptr;
160 }
161 else
162 {
163 ch->ptr = NULL;
164 }
165 chunk = chunk_skip(chunk, ch->len);
166 continue;
167 }
168 case 'a':
169 {
170 ch->len = min(chunk.len, len);
171 if (ch->len)
172 {
173 ch->ptr = malloc(ch->len);
174 memcpy(ch->ptr, chunk.ptr, ch->len);
175 }
176 else
177 {
178 ch->ptr = NULL;
179 }
180 chunk = chunk_skip(chunk, ch->len);
181 continue;
182 }
183 case 'c':
184 {
185 ch->len = min(ch->len, chunk.len);
186 ch->len = min(ch->len, len);
187 if (ch->len)
188 {
189 memcpy(ch->ptr, chunk.ptr, ch->len);
190 }
191 else
192 {
193 ch->ptr = NULL;
194 }
195 chunk = chunk_skip(chunk, ch->len);
196 continue;
197 }
198 default:
199 break;
200 }
201 break;
202 }
203 va_end(chunks);
204 }
205
206 /**
207 * Described in header.
208 */
209 bool chunk_write(chunk_t chunk, char *path, char *label, mode_t mask, bool force)
210 {
211 mode_t oldmask;
212 FILE *fd;
213 bool good = FALSE;
214
215 if (!force && access(path, F_OK) == 0)
216 {
217 DBG1(DBG_LIB, " %s file '%s' already exists", label, path);
218 return FALSE;
219 }
220 oldmask = umask(mask);
221 fd = fopen(path, "w");
222 if (fd)
223 {
224 if (fwrite(chunk.ptr, sizeof(u_char), chunk.len, fd) == chunk.len)
225 {
226 DBG1(DBG_LIB, " written %s file '%s' (%d bytes)",
227 label, path, chunk.len);
228 good = TRUE;
229 }
230 else
231 {
232 DBG1(DBG_LIB, " writing %s file '%s' failed: %s",
233 label, path, strerror(errno));
234 }
235 fclose(fd);
236 }
237 else
238 {
239 DBG1(DBG_LIB, " could not open %s file '%s': %s", label, path,
240 strerror(errno));
241 }
242 umask(oldmask);
243 return good;
244 }
245
246 /**
247 * Described in header.
248 */
249 chunk_t chunk_from_fd(int fd)
250 {
251 char buf[8096];
252 char *pos = buf;
253 ssize_t len, total = 0;
254
255 while (TRUE)
256 {
257 len = read(fd, pos, buf + sizeof(buf) - pos);
258 if (len < 0)
259 {
260 DBG1(DBG_LIB, "reading from file descriptor failed: %s",
261 strerror(errno));
262 return chunk_empty;
263 }
264 if (len == 0)
265 {
266 break;
267 }
268 total += len;
269 if (total == sizeof(buf))
270 {
271 DBG1(DBG_LIB, "buffer too small to read from file descriptor");
272 return chunk_empty;
273 }
274 }
275 return chunk_clone(chunk_create(buf, total));
276 }
277
278
279 /** hex conversion digits */
280 static char hexdig_upper[] = "0123456789ABCDEF";
281 static char hexdig_lower[] = "0123456789abcdef";
282
283 /**
284 * Described in header.
285 */
286 chunk_t chunk_to_hex(chunk_t chunk, char *buf, bool uppercase)
287 {
288 int i, len;
289 char *hexdig = hexdig_lower;
290
291 if (uppercase)
292 {
293 hexdig = hexdig_upper;
294 }
295
296 len = chunk.len * 2;
297 if (!buf)
298 {
299 buf = malloc(len + 1);
300 }
301 buf[len] = '\0';
302
303 for (i = 0; i < chunk.len; i++)
304 {
305 buf[i*2] = hexdig[(chunk.ptr[i] >> 4) & 0xF];
306 buf[i*2+1] = hexdig[(chunk.ptr[i] ) & 0xF];
307 }
308 return chunk_create(buf, len);
309 }
310
311 /**
312 * convert a signle hex character to its binary value
313 */
314 static char hex2bin(char hex)
315 {
316 switch (hex)
317 {
318 case '0' ... '9':
319 return hex - '0';
320 case 'A' ... 'F':
321 return hex - 'A' + 10;
322 case 'a' ... 'f':
323 return hex - 'a' + 10;
324 default:
325 return 0;
326 }
327 }
328
329 /**
330 * Described in header.
331 */
332 chunk_t chunk_from_hex(chunk_t hex, char *buf)
333 {
334 int i, len;
335 u_char *ptr;
336 bool odd = FALSE;
337
338 /* subtract the number of optional ':' separation characters */
339 len = hex.len;
340 ptr = hex.ptr;
341 for (i = 0; i < hex.len; i++)
342 {
343 if (*ptr++ == ':')
344 {
345 len--;
346 }
347 }
348
349 /* compute the number of binary bytes */
350 if (len % 2)
351 {
352 odd = TRUE;
353 len++;
354 }
355 len /= 2;
356
357 /* allocate buffer memory unless provided by caller */
358 if (!buf)
359 {
360 buf = malloc(len);
361 }
362
363 /* buffer is filled from the right */
364 memset(buf, 0, len);
365 hex.ptr += hex.len;
366
367 for (i = len - 1; i >= 0; i--)
368 {
369 /* skip separation characters */
370 if (*(--hex.ptr) == ':')
371 {
372 --hex.ptr;
373 }
374 buf[i] = hex2bin(*hex.ptr);
375 if (i > 0 || !odd)
376 {
377 buf[i] |= hex2bin(*(--hex.ptr)) << 4;
378 }
379 }
380 return chunk_create(buf, len);
381 }
382
383 /** base 64 conversion digits */
384 static char b64digits[] =
385 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
386
387 /**
388 * Described in header.
389 */
390 chunk_t chunk_to_base64(chunk_t chunk, char *buf)
391 {
392 int i, len;
393 char *pos;
394
395 len = chunk.len + ((3 - chunk.len % 3) % 3);
396 if (!buf)
397 {
398 buf = malloc(len * 4 / 3 + 1);
399 }
400 pos = buf;
401 for (i = 0; i < len; i+=3)
402 {
403 *pos++ = b64digits[chunk.ptr[i] >> 2];
404 if (i+1 >= chunk.len)
405 {
406 *pos++ = b64digits[(chunk.ptr[i] & 0x03) << 4];
407 *pos++ = '=';
408 *pos++ = '=';
409 break;
410 }
411 *pos++ = b64digits[((chunk.ptr[i] & 0x03) << 4) | (chunk.ptr[i+1] >> 4)];
412 if (i+2 >= chunk.len)
413 {
414 *pos++ = b64digits[(chunk.ptr[i+1] & 0x0F) << 2];
415 *pos++ = '=';
416 break;
417 }
418 *pos++ = b64digits[((chunk.ptr[i+1] & 0x0F) << 2) | (chunk.ptr[i+2] >> 6)];
419 *pos++ = b64digits[chunk.ptr[i+2] & 0x3F];
420 }
421 *pos = '\0';
422 return chunk_create(buf, len * 4 / 3);
423 }
424
425 /**
426 * convert a base 64 digit to its binary form (inversion of b64digits array)
427 */
428 static int b642bin(char b64)
429 {
430 switch (b64)
431 {
432 case 'A' ... 'Z':
433 return b64 - 'A';
434 case 'a' ... 'z':
435 return ('Z' - 'A' + 1) + b64 - 'a';
436 case '0' ... '9':
437 return ('Z' - 'A' + 1) + ('z' - 'a' + 1) + b64 - '0';
438 case '+':
439 case '-':
440 return 62;
441 case '/':
442 case '_':
443 return 63;
444 case '=':
445 return 0;
446 default:
447 return -1;
448 }
449 }
450
451 /**
452 * Described in header.
453 */
454 chunk_t chunk_from_base64(chunk_t base64, char *buf)
455 {
456 u_char *pos, byte[4];
457 int i, j, len, outlen;
458
459 len = base64.len / 4 * 3;
460 if (!buf)
461 {
462 buf = malloc(len);
463 }
464 pos = base64.ptr;
465 outlen = 0;
466 for (i = 0; i < len; i+=3)
467 {
468 outlen += 3;
469 for (j = 0; j < 4; j++)
470 {
471 if (*pos == '=')
472 {
473 outlen--;
474 }
475 byte[j] = b642bin(*pos++);
476 }
477 buf[i] = (byte[0] << 2) | (byte[1] >> 4);
478 buf[i+1] = (byte[1] << 4) | (byte[2] >> 2);
479 buf[i+2] = (byte[2] << 6) | (byte[3]);
480 }
481 return chunk_create(buf, outlen);
482 }
483
484 /** base 32 conversion digits */
485 static char b32digits[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567";
486
487 /**
488 * Described in header.
489 */
490 chunk_t chunk_to_base32(chunk_t chunk, char *buf)
491 {
492 int i, len;
493 char *pos;
494
495 len = chunk.len + ((5 - chunk.len % 5) % 5);
496 if (!buf)
497 {
498 buf = malloc(len * 8 / 5 + 1);
499 }
500 pos = buf;
501 for (i = 0; i < len; i+=5)
502 {
503 *pos++ = b32digits[chunk.ptr[i] >> 3];
504 if (i+1 >= chunk.len)
505 {
506 *pos++ = b32digits[(chunk.ptr[i] & 0x07) << 2];
507 memset(pos, '=', 6);
508 pos += 6;
509 break;
510 }
511 *pos++ = b32digits[((chunk.ptr[i] & 0x07) << 2) |
512 (chunk.ptr[i+1] >> 6)];
513 *pos++ = b32digits[(chunk.ptr[i+1] & 0x3E) >> 1];
514 if (i+2 >= chunk.len)
515 {
516 *pos++ = b32digits[(chunk.ptr[i+1] & 0x01) << 4];
517 memset(pos, '=', 4);
518 pos += 4;
519 break;
520 }
521 *pos++ = b32digits[((chunk.ptr[i+1] & 0x01) << 4) |
522 (chunk.ptr[i+2] >> 4)];
523 if (i+3 >= chunk.len)
524 {
525 *pos++ = b32digits[(chunk.ptr[i+2] & 0x0F) << 1];
526 memset(pos, '=', 3);
527 pos += 3;
528 break;
529 }
530 *pos++ = b32digits[((chunk.ptr[i+2] & 0x0F) << 1) |
531 (chunk.ptr[i+3] >> 7)];
532 *pos++ = b32digits[(chunk.ptr[i+3] & 0x7F) >> 2];
533 if (i+4 >= chunk.len)
534 {
535 *pos++ = b32digits[(chunk.ptr[i+3] & 0x03) << 3];
536 *pos++ = '=';
537 break;
538 }
539 *pos++ = b32digits[((chunk.ptr[i+3] & 0x03) << 3) |
540 (chunk.ptr[i+4] >> 5)];
541 *pos++ = b32digits[chunk.ptr[i+4] & 0x1F];
542 }
543 *pos = '\0';
544 return chunk_create(buf, len * 8 / 5);
545 }
546
547 /**
548 * Described in header.
549 */
550 int chunk_compare(chunk_t a, chunk_t b)
551 {
552 int compare_len = a.len - b.len;
553 int len = (compare_len < 0)? a.len : b.len;
554
555 if (compare_len != 0 || len == 0)
556 {
557 return compare_len;
558 }
559 return memcmp(a.ptr, b.ptr, len);
560 };
561
562
563 /**
564 * Described in header.
565 */
566 bool chunk_increment(chunk_t chunk)
567 {
568 int i;
569
570 for (i = chunk.len - 1; i >= 0; i--)
571 {
572 if (++chunk.ptr[i] != 0)
573 {
574 return FALSE;
575 }
576 }
577 return TRUE;
578 }
579
580 /**
581 * Remove non-printable characters from a chunk.
582 */
583 bool chunk_printable(chunk_t chunk, chunk_t *sane, char replace)
584 {
585 bool printable = TRUE;
586 int i;
587
588 if (sane)
589 {
590 *sane = chunk_clone(chunk);
591 }
592 for (i = 0; i < chunk.len; i++)
593 {
594 if (!isprint(chunk.ptr[i]))
595 {
596 if (sane)
597 {
598 sane->ptr[i] = replace;
599 }
600 printable = FALSE;
601 }
602 }
603 return printable;
604 }
605
606 /**
607 * Helper functions for chunk_mac()
608 */
609 static inline u_int64_t sipget(u_char *in)
610 {
611 u_int64_t v = 0;
612 int i;
613
614 for (i = 0; i < 64; i += 8, ++in)
615 {
616 v |= ((u_int64_t)*in) << i;
617 }
618 return v;
619 }
620
621 static inline u_int64_t siprotate(u_int64_t v, int shift)
622 {
623 return (v << shift) | (v >> (64 - shift));
624 }
625
626 static inline void sipround(u_int64_t *v0, u_int64_t *v1, u_int64_t *v2,
627 u_int64_t *v3)
628 {
629 *v0 += *v1;
630 *v1 = siprotate(*v1, 13);
631 *v1 ^= *v0;
632 *v0 = siprotate(*v0, 32);
633
634 *v2 += *v3;
635 *v3 = siprotate(*v3, 16);
636 *v3 ^= *v2;
637
638 *v2 += *v1;
639 *v1 = siprotate(*v1, 17);
640 *v1 ^= *v2;
641 *v2 = siprotate(*v2, 32);
642
643 *v0 += *v3;
644 *v3 = siprotate(*v3, 21);
645 *v3 ^= *v0;
646 }
647
648 static inline void sipcompress(u_int64_t *v0, u_int64_t *v1, u_int64_t *v2,
649 u_int64_t *v3, u_int64_t m)
650 {
651 *v3 ^= m;
652 sipround(v0, v1, v2, v3);
653 sipround(v0, v1, v2, v3);
654 *v0 ^= m;
655 }
656
657 static inline u_int64_t siplast(size_t len, u_char *pos)
658 {
659 u_int64_t b;
660 int rem = len & 7;
661
662 b = ((u_int64_t)len) << 56;
663 switch (rem)
664 {
665 case 7:
666 b |= ((u_int64_t)pos[6]) << 48;
667 case 6:
668 b |= ((u_int64_t)pos[5]) << 40;
669 case 5:
670 b |= ((u_int64_t)pos[4]) << 32;
671 case 4:
672 b |= ((u_int64_t)pos[3]) << 24;
673 case 3:
674 b |= ((u_int64_t)pos[2]) << 16;
675 case 2:
676 b |= ((u_int64_t)pos[1]) << 8;
677 case 1:
678 b |= ((u_int64_t)pos[0]);
679 break;
680 case 0:
681 break;
682 }
683 return b;
684 }
685
686 /**
687 * Caculate SipHash-2-4 with an optional first block given as argument.
688 */
689 static u_int64_t chunk_mac_inc(chunk_t chunk, u_char *key, u_int64_t m)
690 {
691 u_int64_t v0, v1, v2, v3, k0, k1;
692 size_t len = chunk.len;
693 u_char *pos = chunk.ptr, *end;
694
695 end = chunk.ptr + len - (len % 8);
696
697 k0 = sipget(key);
698 k1 = sipget(key + 8);
699
700 v0 = k0 ^ 0x736f6d6570736575ULL;
701 v1 = k1 ^ 0x646f72616e646f6dULL;
702 v2 = k0 ^ 0x6c7967656e657261ULL;
703 v3 = k1 ^ 0x7465646279746573ULL;
704
705 if (m)
706 {
707 sipcompress(&v0, &v1, &v2, &v3, m);
708 }
709
710 /* compression with c = 2 */
711 for (; pos != end; pos += 8)
712 {
713 m = sipget(pos);
714 sipcompress(&v0, &v1, &v2, &v3, m);
715 }
716 sipcompress(&v0, &v1, &v2, &v3, siplast(len, pos));
717
718 /* finalization with d = 4 */
719 v2 ^= 0xff;
720 sipround(&v0, &v1, &v2, &v3);
721 sipround(&v0, &v1, &v2, &v3);
722 sipround(&v0, &v1, &v2, &v3);
723 sipround(&v0, &v1, &v2, &v3);
724 return v0 ^ v1 ^ v2 ^ v3;
725 }
726
727 /**
728 * Described in header.
729 */
730 u_int64_t chunk_mac(chunk_t chunk, u_char *key)
731 {
732 return chunk_mac_inc(chunk, key, 0);
733 }
734
735 /**
736 * Secret key allocated randomly during first use.
737 */
738 static u_char key[16];
739
740 /**
741 * Static key used in case predictable hash values are required.
742 */
743 static u_char static_key[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
744 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f};
745
746 /**
747 * Only allocate the key once
748 */
749 static pthread_once_t key_allocated = PTHREAD_ONCE_INIT;
750
751 /**
752 * Allocate a key on first use, we do this manually to avoid dependencies on
753 * plugins.
754 */
755 static void allocate_key()
756 {
757 ssize_t len;
758 size_t done = 0;
759 int fd;
760
761 fd = open("/dev/urandom", O_RDONLY);
762 if (fd >= 0)
763 {
764 while (done < sizeof(key))
765 {
766 len = read(fd, key + done, sizeof(key) - done);
767 if (len < 0)
768 {
769 break;
770 }
771 done += len;
772 }
773 close(fd);
774 }
775 /* on error we use random() to generate the key (better than nothing) */
776 if (done < sizeof(key))
777 {
778 srandom(time(NULL) + getpid());
779 for (; done < sizeof(key); done++)
780 {
781 key[done] = (u_char)random();
782 }
783 }
784 }
785
786 /**
787 * Described in header.
788 */
789 u_int32_t chunk_hash_inc(chunk_t chunk, u_int32_t hash)
790 {
791 pthread_once(&key_allocated, allocate_key);
792 /* we could use a mac of the previous hash, but this is faster */
793 return chunk_mac_inc(chunk, key, ((u_int64_t)hash) << 32 | hash);
794 }
795
796 /**
797 * Described in header.
798 */
799 u_int32_t chunk_hash(chunk_t chunk)
800 {
801 pthread_once(&key_allocated, allocate_key);
802 return chunk_mac(chunk, key);
803 }
804
805 /**
806 * Described in header.
807 */
808 u_int32_t chunk_hash_static_inc(chunk_t chunk, u_int32_t hash)
809 { /* we could use a mac of the previous hash, but this is faster */
810 return chunk_mac_inc(chunk, static_key, ((u_int64_t)hash) << 32 | hash);
811 }
812
813 /**
814 * Described in header.
815 */
816 u_int32_t chunk_hash_static(chunk_t chunk)
817 {
818 return chunk_mac(chunk, static_key);
819 }
820
821 /**
822 * Described in header.
823 */
824 int chunk_printf_hook(printf_hook_data_t *data, printf_hook_spec_t *spec,
825 const void *const *args)
826 {
827 chunk_t *chunk = *((chunk_t**)(args[0]));
828 bool first = TRUE;
829 chunk_t copy = *chunk;
830 int written = 0;
831
832 if (!spec->hash && !spec->plus)
833 {
834 u_int chunk_len = chunk->len;
835 const void *new_args[] = {&chunk->ptr, &chunk_len};
836 return mem_printf_hook(data, spec, new_args);
837 }
838
839 while (copy.len > 0)
840 {
841 if (first)
842 {
843 first = FALSE;
844 }
845 else if (!spec->plus)
846 {
847 written += print_in_hook(data, ":");
848 }
849 written += print_in_hook(data, "%02x", *copy.ptr++);
850 copy.len--;
851 }
852 return written;
853 }