Mstdlib-1.24.0
m_mem.h
1/* The MIT License (MIT)
2 *
3 * Copyright (c) 2015 Monetra Technologies, LLC.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a copy
6 * of this software and associated documentation files (the "Software"), to deal
7 * in the Software without restriction, including without limitation the rights
8 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 * copies of the Software, and to permit persons to whom the Software is
10 * furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be included in
13 * all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 * THE SOFTWARE.
22 */
23
24#ifndef __M_MEM_H__
25#define __M_MEM_H__
26
27/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
28
29#include <mstdlib/base/m_defs.h>
30#include <mstdlib/base/m_fmt.h>
31#include <mstdlib/base/m_str.h>
32#include <mstdlib/base/m_types.h>
33
34/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
35
36__BEGIN_DECLS
37
38M_BEGIN_IGNORE_REDECLARATIONS
39#if M_BLACKLIST_FUNC == 1
40# define WARNING_MALLOC "Memory obtained by malloc can contain sensitive information, if not properly cleared when released, the memory could be obtained by another process or leaked by an incorrect program. use M_malloc/M_calloc,M_free/M_realloc instead."
41# ifdef malloc
42# undef malloc
43# else
44 M_DEPRECATED_MSG(WARNING_MALLOC, void *malloc(size_t))
45# endif
46# ifdef free
47# undef free
48# else
49 M_DEPRECATED_MSG(WARNING_MALLOC, void free(void *))
50# endif
51# ifdef calloc
52# undef calloc
53# else
54 M_DEPRECATED_MSG(WARNING_MALLOC, void *calloc(size_t, size_t))
55# endif
56# ifdef realloc
57# undef realloc
58# else
59 M_DEPRECATED_MSG(WARNING_MALLOC, void *realloc(void *, size_t))
60# endif
61# ifdef memcmp
62# undef memcmp
63# else
64 M_DEPRECATED_MSG("memcmp is vulnerable to timing attacks. use M_mem_eq", int memcmp(const void *, const void *, size_t))
65# endif
66#endif
67M_END_IGNORE_REDECLARATIONS
68
69/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
70
71/*! \addtogroup m_mem Memory
72 * \ingroup mstdlib_base
73 *
74 * Memory manipulation.
75 *
76 * Hardening
77 * =========
78 *
79 * To aid in hardening M_malloc wraps the system malloc and stores the length of allocated memory.
80 * M_free uses this length and zeros the memory before calling the system free. The length is
81 * prepended to the memory segment and the pointer to the memory after the size is returned.
82 * The size is then read by M_free so the full allocated memory segment can be zeroed.
83 *
84 * Zeroing memory is performed to combat memory scan attacks. It's not possible to know what data in memory is
85 * sensitive so all data is considered sensitive. Zeroing limits the amount of time data such as credit card
86 * numbers or encryption keys are available. This way data is available only as long as needed.
87 *
88 * M_malloc and M_free are not replacements for the system provided malloc and free functions. They work
89 * on top of the system functions. This is so a hardened system malloc will not have it's functionality
90 * disrupted. Further, a replacement malloc implementation (such as jemalloc) can still be used.
91 *
92 * Some system mallocs already zero memory but many do not. Mstdlib's M_malloc brings this to systems
93 * that do not implement this security feature. This is a case where security trumps performance.
94 *
95 * Memory allocated using M_malloc must never be passed directly to the system free due to the length
96 * offset prefix, the caller would not be passing the base of the block and therefore cause undefined
97 * behavior (probably a segfault).
98 *
99 * Memory allocated by malloc (not M_malloc) should never be passed to M_free. This will result in
100 * undefined behavior (probably a segfault) as well.
101 *
102 * All mstdlib functions that allocate memory use mstdlib's M_malloc. Thus any memory that needs
103 * to be freed using free that is returned by an mstdlib function must be passed to M_free.
104 *
105 *
106 * Hardening that doesn't work
107 * ===========================
108 *
109 * There are a few "hardening" features that are available on Linux and other Unix platforms that were
110 * evaluated. These were determined to not be usable.
111 *
112 * mlock
113 * -----
114 *
115 * mlock prevents a memory segment from being written to on disk swap space.
116 *
117 * The issue with mlock is limits set by the OS. RLIMIT_MEMLOCK (ulimit -l) limits the amount of memory
118 * that can be locked. munlock must be used (before or after, testing showed it didn't matter) to reduce
119 * the locked memory amount. munmap should implicitly unlock the memory as well but in testing a simple
120 * free did not cause the memory to be unlocked.
121 *
122 * munlock is not enough to avoid hitting the limit. In simple / small applications or test cases, it would
123 * function fine. However, a larger application which uses more memory will fail. Once the lock limit
124 * is reached an out of memory error will be returned.
125 *
126 * On Ubuntu 14.04.2 the default RLIMIT_MEMLOCK is 64K. On some versions of Debian is was found to be 32K.
127 * This limit will quickly be reached by a non-trivial application.
128 *
129 * Configuring the system to have a larger limit or making the limit unlimited may not alleviate
130 * this issue. For example, FreeBSD allows mlock use to be restricted to the user-user only.
131 *
132 * Further, Requiring system configuration to use a general purpose library is unacceptable. Especially when the
133 * configuration is non-obvious. Also if mlock is limited to super-user only then mstdlib would be unusable
134 * as user level application.
135 *
136 * madvise with MADV_DONTDUMP
137 * --------------------------
138 *
139 * This is used to prevent marked memory from being in a core dump.
140 *
141 * On Linux madvise requires the memory to be page-aligned. If the memory is not page-aligned madvise will return
142 * a failure with errno EINVAL. Page-alignment can easily cause the application to run out of address space.
143 *
144 * For example you could use an allocation like:
145 *
146 * void *ptr;
147 * posix_memalign(&ptr, sysconf(_SC_PAGESIZE), size);
148 *
149 * Getting the page size on the command line (which is the size of _SC_PAGESIZE):
150 *
151 * $ getconf PAGESIZE
152 * 4096
153 *
154 * In this (and many) cases we have a 4096 byte boundary. Meaning the address of the allocated data must be the
155 * address of a page boundary. There is 4K between each boundary. A large amount of data can be allocated there but
156 * if a small amount of data is allocated then there is a large amount of unusable space due to the next allocation
157 * needing to also be on a 4K boundary.
158 *
159 * Take the following allocations:
160 *
161 * 1. 8 bytes page-aligned.
162 * 2. 4 bytes page-aligned.
163 *
164 * Assuming One and Two are allocated next to each other. One allocates 8 bytes. Two will be aligned to the
165 * 4K boundary after One. A total of 8K of memory is reserved due to this. Only 12 bytes are actually needed but 8K
166 * is reserved. Since memory is now aligned in 4K blocks the total available memory space is greatly reduced.
167 * Not the amount of memory but the amount of allocations.
168 *
169 * On a 32bit system only ~2GB of memory is available to a process. With 4K page-alignment allocations the amount
170 * usable memory is greatly reduced. This might be okay on a 64 bit system but will still be wasteful.
171 *
172 * Also since Linux, since 3.18, has made madvise optional which severely limits its use.
173 *
174 * Conclusion
175 * ----------
176 *
177 * Neither mlock nor madvise can be used on every malloc. It may be okay to use this selectively but in a
178 * general purpose library there is no way to truly know what is sensitive. For example M_list_str and
179 * M_hash_dict duplicate the strings they are given. There is no way for them to know that a particular string needs
180 * to be securely allocated.
181 *
182 * Additional External Security
183 * ============================
184 *
185 * One option to add additional security is to create an encrypting wrapper around a list or hashtable:
186 * - Use a different key for each hashtable.
187 * - Limit the life of a hashtable in order to rotate the key often.
188 * - Insert, wrapper will take the key and value. Encrypt them and store them in the hashtable.
189 * - Get, wrapper will take the key, encrypt it. Use that to look up the value. Decrypt the value. Return the value.
190 *
191 * This option further limits the amount of time sensitive data is stored in the clear in memory because the
192 * value in the hashtable is encrypted. The plain text data is only exposed as long as it is being actively used.
193 * This will further protect against memory scrapers.
194 *
195 * It also, reduces the concern of swap and core dumps because the data is stored encrypted. Granted the key as
196 * well as the encrypted value could be stored on disk. However, it will still be difficult to determine what data
197 * is the key, and what set of data the key belongs to.
198 *
199 * @{
200 */
201
202/*! Error callback for handling malloc failure.
203 *
204 * Can return M_TRUE to retry malloc.
205 */
206typedef M_bool (*M_malloc_error_cb)(void);
207
208/*! Register a callback to be called when M_malloc()/M_realloc() returns a failure.
209 *
210 * Up to 12 callbacks can be registered. They will be called from newest to
211 * oldest. If a callback returns M_TRUE callback processing will stop and
212 * malloc will be retried. If malloc fails again the callbacks processing will
213 * resume. Each callback will be run until either one returns success or all
214 * have returned failure.
215 *
216 * Typically this will be used for external error reporting, or (more) graceful shutdown scenarios.
217 *
218 * \param[in] cb Callback to be called. This should not ever try to allocate memory as it will most likely fail.
219 *
220 * \return M_TRUE on success, M_FALSE on failure. The only failure reason currently is if the maximum
221 * number of registered callbacks has been reached.
222 */
224
225
226/*! Deregister an allocation error callback
227 *
228 * \param[in] cb The callback to remove.
229 *
230 * \return M_TRUE if the callback was removed otherwise M_FALSE. M_FALSE means the callback is not
231 * currently registered.
232 */
234
235
236/*! Clears all user registered callbacks. The default abort callback is not cleared.
237 */
238M_API void M_malloc_clear_errorcb(void);
239
240
241/*! Allocate size bytes and returns pointer to allocated memory.
242 *
243 * Retains information about the size of the allocation and must be released using M_free().
244 *
245 * On failure registered error callbacks will be called and malloc will be repleted if any
246 * error callback return M_TRUE indicating malloc should be retried. If no callbacks return
247 * retry the application will abort. The callbacks will be run in reverse order they were registered.
248 *
249 * \param[in] size Number of bytes of memory to allocate.
250 *
251 * \return Pointer to the newly allocated memory or NULL if the requested memory is unavailable.
252 * Memory must be released using M_free().
253 *
254 * \see M_free
255 */
256M_API void *M_malloc(size_t size) M_ALLOC_SIZE(1) M_WARN_UNUSED_RESULT M_MALLOC;
257
258
259/*! Allocate size bytes and returns pointer to allocated memory and fills the memory with 0's.
260 *
261 * Retains information about the size of the allocation and must be released using M_free().
262 *
263 * \param[in] size Number of bytes of memory to allocate.
264 *
265 * \return Pointer to the newly allocated memory or NULL if the requested memory is unavailable.
266 * Memory must be released using M_free().
267 *
268 * \see M_free
269 */
270M_API void *M_malloc_zero(size_t size) M_ALLOC_SIZE(1) M_WARN_UNUSED_RESULT M_MALLOC;
271
272
273/*! Release allocated memory.
274 *
275 * Like libc free, but works with memory allocated by M_malloc class of functions to free allocated memory.
276 * Before being released, each byte of ptr is first set to zero.
277 *
278 * \param[in] ptr A pointer to a memory location to release returned by M_malloc like functions.
279 *
280 * \see M_malloc
281 * \see M_malloc_zero
282 * \see M_realloc
283 * \see M_memdup
284 * \see M_memdup_max
285 */
286M_API void M_free(void *ptr) M_FREE(1);
287
288
289/*! Resize an allocated memory block.
290 *
291 * Like libc realloc, but works with memory allocated by M_malloc like functions.
292 * If ptr is unable to be resized, before being released, each byte of ptr is first set to zero.
293 *
294 * \param[in] ptr A pointer to a memory location to release/resize returned by M_malloc.
295 * \param[in] size Number of bytes of memory to allocate.
296 *
297 * \return Pointer to the newly allocated memory or NULL if the requested
298 * memory is zero in size or unavailable. Memory must be released using M_free().
299 *
300 * \see M_free
301 */
302M_API void *M_realloc(void *ptr, size_t size) M_ALLOC_SIZE(2) M_WARN_UNUSED_RESULT;
303
304
305/*! Resize an allocated memory block and fill any extended allocated memory with 0's.
306 *
307 * Like libc realloc, but works with memory allocated by M_malloc like functions.
308 * If ptr is unable to be resized, before being released, each byte of ptr is first set to zero.
309 *
310 * \param[in] ptr A pointer to a memory location to release/resize returned by M_malloc.
311 * \param[in] size Number of bytes of memory to allocate.
312 *
313 * \return Pointer to the newly allocated memory or NULL if the requested
314 * memory is zero in size or unavailable. Memory must be released using M_free().
315 *
316 * \see M_free
317 */
318M_API void *M_realloc_zero(void *ptr, size_t size) M_ALLOC_SIZE(2) M_WARN_UNUSED_RESULT;
319
320
321/*! Allocate and copy size bytes from src to the newly allocated space.
322 *
323 * src should be at least size memory area.
324 *
325 * \param[in] src Memory area to copy.
326 * \param[in] size Number of bytes of memory to allocate and copy from src.
327 *
328 * \return Pointer to the newly allocated memory or NULL if the requested
329 * memory is unavailable. Memory must be released with M_free().
330 *
331 * \see M_free
332 */
333M_API void *M_memdup(const void *src, size_t size) M_ALLOC_SIZE(2) M_WARN_UNUSED_RESULT M_WARN_NONNULL(1) M_MALLOC;
334
335
336/*! Allocate at minimum min_alloc_size bytes, but copy no more than size bytes from ptr to the newly allocated space.
337 *
338 * If size is larger than min_alloc_size, then size bytes will be allocated. src should be at least size memory area
339 * or NULL is returned.
340 *
341 * This function behaves like M_malloc(size) when called M_memdup_max(NULL,0,size).
342 *
343 * \param[in] src Memory area to copy.
344 * \param[in] size Number of bytes of memory to allocate and copy from src.
345 * \param[in] min_alloc_size The minimum size of the returned allocation.
346 *
347 * \return Pointer to the newly allocated memory or NULL if the requested
348 * memory is unavailable or if src is NULL but has positive *
349 * size. Memory must be released with M_free().
350 *
351 * \see M_free
352 */
353M_API void *M_memdup_max(const void *src, size_t size, size_t min_alloc_size) M_ALLOC_SIZE(2) M_WARN_UNUSED_RESULT M_WARN_NONNULL(1) M_MALLOC;
354
355
356/* - - - - - - - - - - - - - - - - - - - - - - - - - */
357
358/*! Set memory.
359 *
360 * \param[in,out] s The memory to set.
361 * \param[in] c The value to set.
362 * \param[in] n The length of the memory segment.
363 *
364 * \return A pointer to s.
365 */
366M_API void *M_mem_set(void *s, int c, size_t n);
367
368
369/*! Copy memory area.
370 *
371 * This function behaves like memcpy, but handles NULL gracefully.
372 *
373 * \param[in,out] dst Memory location to copy to.
374 * \param[in] src Memory location to copy from.
375 * \param[in] size Number of bytes to copy.
376 *
377 * \return A pointer to dst.
378 */
379M_API void *M_mem_move(void *dst, const void *src, size_t size) M_WARN_NONNULL(1) M_WARN_NONNULL(2);
380
381
382/*! Copy memory area.
383 *
384 * This function behaves like memcpy, but handles NULL gracefully.
385 *
386 * \param[in,out] dst Memory location to copy to.
387 * \param[in] src Memory location to copy from.
388 * \param[in] size Number of bytes to copy.
389 *
390 * \return A pointer to dst.
391 */
392M_API void *M_mem_copy(void *dst, const void *src, size_t size) M_WARN_NONNULL(1) M_WARN_NONNULL(2);
393
394
395/*! Compare memory segments.
396 *
397 * This is done in a constant-time manner to prevent against timing related attacks.
398 *
399 * \param[in] m1 Memory address.
400 * \param[in] m2 Memory address.
401 * \param[in] size Length of memory to check.
402 *
403 * \return M_TRUE if equal, M_FALSE if not.
404 */
405M_API M_bool M_mem_eq(const void *m1, const void *m2, size_t size) M_WARN_NONNULL(1) M_WARN_NONNULL(2);
406
407
408/*! A wrapper around memcmp that is NULL safe.
409 *
410 * NOTE: this is not a constant-time comparison and thus should ONLY be used
411 * for sorting such as within qsort()!
412 *
413 * \param[in] m1 Memory address.
414 * \param[in] size1 Size of m1.
415 * \param[in] m2 Memory address.
416 * \param[in] size2 Size of m2.
417 *
418 * \return an integer less than, equal to, or greater than zero if m1 is
419 * less than, equal, or greater than m2 respectively
420 */
421M_API int M_mem_cmpsort(const void *m1, size_t size1, const void *m2, size_t size2) M_WARN_UNUSED_RESULT;
422
423
424/* - - - - - - - - - - - - - - - - - - - - - - - - - */
425
426/*! Find first occurrence of b in s.
427 *
428 * \param[in] s The memory area to search.
429 * \param[in] b The byte to search the memory area for.
430 * \param[in] n The size of the memory area to search.
431 *
432 * \return Pointer to the first occurence of b in s or NULL if not found or s is NULL or is 0.
433 */
434M_API void *M_mem_chr(const void *s, M_uint8 b, size_t n) M_WARN_UNUSED_RESULT M_WARN_NONNULL(1);
435
436
437/*! Determine if needle exists in haystack.
438 *
439 * \param[in] haystack Memory to search in.
440 * \param[in] haystack_len The size in bytes of haystack.
441 * \param[in] needle Memory to search for.
442 * \param[in] needle_len The size in bytes of needle.
443 *
444 * \return M_TRUE if needle exists in haystack or needle_len is 0, M_FALSE otherwise.
445 */
446M_API M_bool M_mem_contains(const void *haystack, size_t haystack_len, const void *needle, size_t needle_len) M_WARN_UNUSED_RESULT M_WARN_NONNULL(1) M_WARN_NONNULL(3);
447
448
449/*! Find first occurring bytes needle of length needle_len in haystack.
450 *
451 * \param[in] haystack Memory to search in.
452 * \param[in] haystack_len The size in bytes of haystack.
453 * \param[in] needle Memory to search for.
454 * \param[in] needle_len The size in bytes of needle.
455 *
456 * \return Pointer to first occurrence of needle in haystack or NULL if not found or haystack is NULL or haystack_len
457 * is 0.
458 */
459M_API void *M_mem_mem(const void *haystack, size_t haystack_len, const void *needle, size_t needle_len) M_WARN_UNUSED_RESULT M_WARN_NONNULL(1) M_WARN_NONNULL(3);
460
461
462/*! Find last occurring bytes needle of length needle_len in haystack.
463 *
464 * \param[in] haystack Memory to search in.
465 * \param[in] haystack_len The size in bytes of haystack.
466 * \param[in] needle Memory to search for.
467 * \param[in] needle_len The size in bytes of needle.
468 *
469 * \return Pointer to beginning of the last occurrence of needle in haystack.
470 * NULL if not found or haystack is NULL or haystack_len is 0.
471 */
472M_API void *M_mem_rmem(const void *haystack, size_t haystack_len, const void *needle, size_t needle_len) M_WARN_UNUSED_RESULT M_WARN_NONNULL(1) M_WARN_NONNULL(3);
473
474
475/*! Find first occurring string needle in haystack.
476 *
477 * \param[in] haystack Memory to search in.
478 * \param[in] haystack_len The size in bytes of haystack.
479 * \param[in] needle Memory to search for.
480 *
481 * \return Pointer to first occurrence of needle in haystack or NULL if not found or haystack is NULL.
482 */
483M_API void *M_mem_str(const void *haystack, size_t haystack_len, const char *needle) M_WARN_UNUSED_RESULT M_WARN_NONNULL(1);
484#define M_mem_str(haystack,haystack_len,needle) \
485 M_mem_mem(haystack,haystack_len,needle,M_str_len(needle) )
486
487
488/*! Find index of first occurring bytes needle of length needle_len in haystack.
489 *
490 * \param[in] haystack Memory to search in.
491 * \param[in] haystack_len The size in bytes of haystack.
492 * \param[in] needle Memory to search for.
493 * \param[in] needle_len The size in bytes of needle.
494 * \param[out] idx The index of first occurrence of needle in haystack. Optional, pass NULL if not needed.
495 *
496 * \return M_TRUE if found, M_FALSE otherwise.
497 */
498M_API M_bool M_mem_mempos(const void *haystack, size_t haystack_len, const void *needle, size_t needle_len, size_t *idx) M_WARN_UNUSED_RESULT M_WARN_NONNULL(1) M_WARN_NONNULL(3);
499#define M_mem_strpos(haystack,haystack_len,needle,idx) \
500 M_mem_mempos(haystack,haystack_len,needle,M_str_len(needle) ,idx)
501
502
503/*! Count the number of occurrences of byte b in memory area s of length s_len
504 *
505 * \param[in] s Pointer to the memory area to search.
506 * \param[in] s_len The size of the memory area s.
507 * \param[in] b The byte value to count occurrences of.
508 */
509M_API size_t M_mem_count(const void *s, size_t s_len, M_uint8 b) M_WARN_UNUSED_RESULT M_WARN_NONNULL(1);
510
511
512/*! Calculate an LRC.
513 *
514 * \param[in] s Pointer to the memory area to search.
515 * \param[in] s_len The size of the memory area s.
516 *
517 * \return LRC
518 */
519M_API unsigned char M_mem_calc_lrc(const void *s, size_t s_len);
520
521
522/*! Calculate a CRC (CRC-8/CCITT).
523 *
524 * This is an 8-bit cyclic redundancy check (CRC), using the CCITT standard
525 * polynomial: <tt>x^8 + x^2 + x + 1</tt>. It's calculated using an initial
526 * value of zero.
527 *
528 * Implementation is based on public-domain code that can be found here: https://www.3dbrew.org/wiki/CRC-8-CCITT
529 *
530 * \param[in] s Pointer to data to perform check on.
531 * \param[in] s_len Size of memory area s.
532 * \return CRC-8/CCITT value.
533 */
534M_API M_uint8 M_mem_calc_crc8_ccitt(const void *s, size_t s_len);
535
536
537/*! Calculate a CRC (CRC-16/CCITT).
538 *
539 * This is a 16-bit cyclic redundancy check (CRC), using the CCITT standard
540 * polynomial: <tt>x^16 + x^12 + x^5 + 1</tt>. It's calculated using an initial
541 * value of 0xFFFF, with no final XOR of the output CRC.
542 *
543 * Implementation is based on public-domain code that can be found here: http://automationwiki.com/index.php/CRC-16-CCITT
544 *
545 * \param[in] s Pointer to data to perform check on.
546 * \param[in] s_len Size of memory area s.
547 * \return CRC-16/CCITT value.
548 */
549M_API M_uint16 M_mem_calc_crc16_ccitt(const void *s, size_t s_len);
550
551
552/*! Calculate a CRC (CRC-32).
553 *
554 * This is a 32-bit cyclic redundancy check (CRC), using the most common specification
555 * for 32-bit CRC's (ISO 3309 / ITU-T V.42). This particular CRC-32 variant is used all
556 * over the place - it's used in PNG, SATA, MPEG-2, Gzip, Bzip2, Posix cksum, and many others.
557 *
558 * This spec uses the following polynomial:
559 * <tt>x^32 + x^26 + x^23 + x^22 + x^16 + x^12 + x^11 + x^10 + x^8 + x^7 + x^5 + x^4 + x^2 + x + 1</tt>
560 *
561 * It's calculated using an initial value of 0xFFFFFFFF, and XOR'ing the CRC value by 0xFFFFFFFF after
562 * the computation is done to invert it.
563 *
564 * \param[in] s Pointer to data to perform check on.
565 * \param[in] s_len Size of memory area s.
566 * \return CRC-32 value.
567 */
568M_API M_uint32 M_mem_calc_crc32(const void *s, size_t s_len);
569
570
571/*! Swap byes between positions.
572 *
573 * \param[in,out] s Buffer with data to swap.
574 * \param[in] s_len size of s.
575 * \param[in] idx1 Index to swap.
576 * \param[in] idx2 Index to swap.
577 *
578 * \return M_TRUE on success. Otherwise M_FALSE.
579 */
580M_API M_bool M_mem_swap_bytes(M_uint8 *s, size_t s_len, size_t idx1, size_t idx2);
581
582/*! @} */
583
584__END_DECLS
585
586#endif /* __M_MEM_H__ */
void * M_mem_chr(const void *s, M_uint8 b, size_t n) M_WARN_UNUSED_RESULT
M_bool M_malloc_deregister_errorcb(M_malloc_error_cb cb)
int M_mem_cmpsort(const void *m1, size_t size1, const void *m2, size_t size2) M_WARN_UNUSED_RESULT
void * M_realloc_zero(void *ptr, size_t size) M_ALLOC_SIZE(2) M_WARN_UNUSED_RESULT
M_bool M_mem_contains(const void *haystack, size_t haystack_len, const void *needle, size_t needle_len) M_WARN_UNUSED_RESULT
void * M_memdup_max(const void *src, size_t size, size_t min_alloc_size) M_ALLOC_SIZE(2) M_WARN_UNUSED_RESULT M_MALLOC
#define M_mem_str(haystack, haystack_len, needle)
Definition: m_mem.h:484
M_uint16 M_mem_calc_crc16_ccitt(const void *s, size_t s_len)
void * M_malloc_zero(size_t size) M_ALLOC_SIZE(1) M_WARN_UNUSED_RESULT M_MALLOC
M_uint8 M_mem_calc_crc8_ccitt(const void *s, size_t s_len)
void * M_mem_copy(void *dst, const void *src, size_t size)
void * M_mem_move(void *dst, const void *src, size_t size)
void * M_memdup(const void *src, size_t size) M_ALLOC_SIZE(2) M_WARN_UNUSED_RESULT M_MALLOC
void * M_mem_mem(const void *haystack, size_t haystack_len, const void *needle, size_t needle_len) M_WARN_UNUSED_RESULT
size_t M_mem_count(const void *s, size_t s_len, M_uint8 b) M_WARN_UNUSED_RESULT
M_bool M_mem_swap_bytes(M_uint8 *s, size_t s_len, size_t idx1, size_t idx2)
unsigned char M_mem_calc_lrc(const void *s, size_t s_len)
M_bool M_mem_eq(const void *m1, const void *m2, size_t size)
M_uint32 M_mem_calc_crc32(const void *s, size_t s_len)
void * M_mem_rmem(const void *haystack, size_t haystack_len, const void *needle, size_t needle_len) M_WARN_UNUSED_RESULT
M_bool M_mem_mempos(const void *haystack, size_t haystack_len, const void *needle, size_t needle_len, size_t *idx) M_WARN_UNUSED_RESULT
void M_free(void *ptr) M_FREE(1)
void * M_mem_set(void *s, int c, size_t n)
void M_malloc_clear_errorcb(void)
void * M_malloc(size_t size) M_ALLOC_SIZE(1) M_WARN_UNUSED_RESULT M_MALLOC
M_bool(* M_malloc_error_cb)(void)
Definition: m_mem.h:206
M_bool M_malloc_register_errorcb(M_malloc_error_cb cb)
void * M_realloc(void *ptr, size_t size) M_ALLOC_SIZE(2) M_WARN_UNUSED_RESULT