]>
git.ipfire.org Git - people/ms/strongswan.git/blob - src/libstrongswan/utils/chunk.h
2 * Copyright (C) 2008-2013 Tobias Brunner
3 * Copyright (C) 2005-2008 Martin Willi
4 * Copyright (C) 2005 Jan Hutter
5 * Hochschule fuer Technik Rapperswil
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>.
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
19 * @defgroup chunk chunk
28 #include <sys/types.h>
33 typedef struct chunk_t chunk_t
;
36 * General purpose pointer/length abstraction.
39 /** Pointer to start of data */
41 /** Length of data in bytes */
48 * A { NULL, 0 }-chunk handy for initialization.
50 extern chunk_t chunk_empty
;
53 * Create a new chunk pointing to "ptr" with length "len"
55 static inline chunk_t
chunk_create(u_char
*ptr
, size_t len
)
57 chunk_t chunk
= {ptr
, len
};
62 * Create a clone of a chunk pointing to "ptr"
64 chunk_t
chunk_create_clone(u_char
*ptr
, chunk_t chunk
);
67 * Calculate length of multiple chunks
69 size_t chunk_length(const char *mode
, ...);
72 * Concatenate chunks into a chunk pointing to "ptr".
74 * The mode string specifies the number of chunks, and how to handle each of
75 * them with a single character: 'c' for copy (allocate new chunk), 'm' for move
76 * (free given chunk) or 's' for sensitive-move (clear given chunk, then free).
78 chunk_t
chunk_create_cat(u_char
*ptr
, const char* mode
, ...);
81 * Split up a chunk into parts, "mode" is a string of "a" (alloc),
82 * "c" (copy) and "m" (move). Each letter say for the corresponding chunk if
83 * it should get allocated on heap, copied into existing chunk, or the chunk
84 * should point into "chunk". The length of each part is an argument before
85 * each target chunk. E.g.:
86 * chunk_split(chunk, "mcac", 3, &a, 7, &b, 5, &c, d.len, &d);
88 void chunk_split(chunk_t chunk
, const char *mode
, ...);
91 * Write the binary contents of a chunk_t to a file
93 * @param chunk contents to write to file
94 * @param path path where file is written to
95 * @param label label specifying file type
96 * @param mask file mode creation mask
97 * @param force overwrite existing file by force
98 * @return TRUE if write operation was successful
100 bool chunk_write(chunk_t chunk
, char *path
, char *label
, mode_t mask
, bool force
);
103 * Convert a chunk of data to hex encoding.
105 * The resulting string is '\\0' terminated, but the chunk does not include
106 * the '\\0'. If buf is supplied, it must hold at least (chunk.len * 2 + 1).
108 * @param chunk data to convert to hex encoding
109 * @param buf buffer to write to, NULL to malloc
110 * @param uppercase TRUE to use uppercase letters
111 * @return chunk of encoded data
113 chunk_t
chunk_to_hex(chunk_t chunk
, char *buf
, bool uppercase
);
116 * Convert a hex encoded in a binary chunk.
118 * If buf is supplied, it must hold at least (hex.len / 2) + (hex.len % 2)
119 * bytes. It is filled by the right to give correct values for short inputs.
121 * @param hex hex encoded input data
122 * @param buf buffer to write decoded data, NULL to malloc
123 * @return converted data
125 chunk_t
chunk_from_hex(chunk_t hex
, char *buf
);
128 * Convert a chunk of data to its base64 encoding.
130 * The resulting string is '\\0' terminated, but the chunk does not include
131 * the '\\0'. If buf is supplied, it must hold at least (chunk.len * 4 / 3 + 1).
133 * @param chunk data to convert
134 * @param buf buffer to write to, NULL to malloc
135 * @return chunk of encoded data
137 chunk_t
chunk_to_base64(chunk_t chunk
, char *buf
);
140 * Convert a base64 in a binary chunk.
142 * If buf is supplied, it must hold at least (base64.len / 4 * 3).
144 * @param base64 base64 encoded input data
145 * @param buf buffer to write decoded data, NULL to malloc
146 * @return converted data
148 chunk_t
chunk_from_base64(chunk_t base64
, char *buf
);
151 * Convert a chunk of data to its base32 encoding.
153 * The resulting string is '\\0' terminated, but the chunk does not include
154 * the '\\0'. If buf is supplied, it must hold (chunk.len * 8 / 5 + 1) bytes.
156 * @param chunk data to convert
157 * @param buf buffer to write to, NULL to malloc
158 * @return chunk of encoded data
160 chunk_t
chunk_to_base32(chunk_t chunk
, char *buf
);
163 * Free contents of a chunk
165 static inline void chunk_free(chunk_t
*chunk
)
168 *chunk
= chunk_empty
;
172 * Overwrite the contents of a chunk and free it
174 static inline void chunk_clear(chunk_t
*chunk
)
178 memwipe(chunk
->ptr
, chunk
->len
);
184 * Initialize a chunk using a char array
186 #define chunk_from_chars(...) ((chunk_t){(char[]){__VA_ARGS__}, sizeof((char[]){__VA_ARGS__})})
189 * Initialize a chunk to point to a thing
191 #define chunk_from_thing(thing) chunk_create((char*)&(thing), sizeof(thing))
194 * Initialize a chunk from a static string, not containing 0-terminator
196 #define chunk_from_str(str) chunk_create(str, strlen(str))
199 * Allocate a chunk on the heap
201 #define chunk_alloc(bytes) ({size_t x = (bytes); chunk_create(x ? malloc(x) : NULL, x);})
204 * Allocate a chunk on the stack
206 #define chunk_alloca(bytes) ({size_t x = (bytes); chunk_create(x ? alloca(x) : NULL, x);})
209 * Clone a chunk on heap
211 #define chunk_clone(chunk) ({chunk_t x = (chunk); chunk_create_clone(x.len ? malloc(x.len) : NULL, x);})
214 * Clone a chunk on stack
216 #define chunk_clonea(chunk) ({chunk_t x = (chunk); chunk_create_clone(x.len ? alloca(x.len) : NULL, x);})
219 * Concatenate chunks into a chunk on heap
221 #define chunk_cat(mode, ...) chunk_create_cat(malloc(chunk_length(mode, __VA_ARGS__)), mode, __VA_ARGS__)
224 * Concatenate chunks into a chunk on stack
226 #define chunk_cata(mode, ...) chunk_create_cat(alloca(chunk_length(mode, __VA_ARGS__)), mode, __VA_ARGS__)
229 * Skip n bytes in chunk (forward pointer, shorten length)
231 static inline chunk_t
chunk_skip(chunk_t chunk
, size_t bytes
)
233 if (chunk
.len
> bytes
)
243 * Skip a leading zero-valued byte
245 static inline chunk_t
chunk_skip_zero(chunk_t chunk
)
247 if (chunk
.len
> 1 && *chunk
.ptr
== 0x00)
257 * Compare two chunks, returns zero if a equals b
258 * or negative/positive if a is small/greater than b
260 int chunk_compare(chunk_t a
, chunk_t b
);
263 * Compare two chunks for equality,
264 * NULL chunks are never equal.
266 static inline bool chunk_equals(chunk_t a
, chunk_t b
)
268 return a
.ptr
!= NULL
&& b
.ptr
!= NULL
&&
269 a
.len
== b
.len
&& memeq(a
.ptr
, b
.ptr
, a
.len
);
273 * Compare two chunks (given as pointers) for equality (useful as callback),
274 * NULL chunks are never equal.
276 static inline bool chunk_equals_ptr(chunk_t
*a
, chunk_t
*b
)
278 return a
!= NULL
&& b
!= NULL
&& chunk_equals(*a
, *b
);
282 * Increment a chunk, as it would reprensent a network order integer.
284 * @param chunk chunk to increment
285 * @return TRUE if an overflow occurred
287 bool chunk_increment(chunk_t chunk
);
290 * Check if a chunk has printable characters only.
292 * If sane is given, chunk is cloned into sane and all non printable characters
293 * get replaced by "replace".
295 * @param chunk chunk to check for printability
296 * @param sane pointer where sane version is allocated, or NULL
297 * @param replace character to use for replaceing unprintable characters
298 * @return TRUE if all characters in chunk are printable
300 bool chunk_printable(chunk_t chunk
, chunk_t
*sane
, char replace
);
303 * Computes a 32 bit hash of the given chunk.
304 * @note This hash is only intended for hash tables not for cryptographic purposes.
306 u_int32_t
chunk_hash(chunk_t chunk
);
309 * Incremental version of chunk_hash. Use this to hash two or more chunks.
311 u_int32_t
chunk_hash_inc(chunk_t chunk
, u_int32_t hash
);
314 * Computes a quick MAC from the given chunk and key using SipHash.
316 * The key must have a length of 128-bit (16 bytes).
318 * @note While SipHash has strong features using it for cryptographic purposes
319 * is not recommended (in particular because of the rather short output size).
321 * @param chunk data to process
322 * @param key key to use
323 * @return MAC for given input and key
325 u_int64_t
chunk_mac(chunk_t chunk
, u_char
*key
);
328 * printf hook function for chunk_t.
332 * Use #-modifier to print a compact version
334 int chunk_printf_hook(printf_hook_data_t
*data
, printf_hook_spec_t
*spec
,
335 const void *const *args
);
337 #endif /** CHUNK_H_ @}*/