307 lines
		
	
	
		
			7.6 KiB
		
	
	
	
		
			C
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			307 lines
		
	
	
		
			7.6 KiB
		
	
	
	
		
			C
		
	
	
		
			Executable File
		
	
	
	
	
| /*
 | |
|  * Broadcom Secure Standard Library.
 | |
|  *
 | |
|  * Copyright (C) 1999-2019, Broadcom.
 | |
|  *
 | |
|  *      Unless you and Broadcom execute a separate written software license
 | |
|  * agreement governing use of this software, this software is licensed to you
 | |
|  * under the terms of the GNU General Public License version 2 (the "GPL"),
 | |
|  * available at http://www.broadcom.com/licenses/GPLv2.php, with the
 | |
|  * following added to such license:
 | |
|  *
 | |
|  *      As a special exception, the copyright holders of this software give you
 | |
|  * permission to link this software with independent modules, and to copy and
 | |
|  * distribute the resulting executable under terms of your choice, provided that
 | |
|  * you also meet, for each linked independent module, the terms and conditions of
 | |
|  * the license of that module.  An independent module is a module which is not
 | |
|  * derived from this software.  The special exception does not apply to any
 | |
|  * modifications of the software.
 | |
|  *
 | |
|  *      Notwithstanding the above, under no circumstances may you combine this
 | |
|  * software in any way with any other Broadcom software provided under a license
 | |
|  * other than the GPL, without Broadcom's express prior written consent.
 | |
|  *
 | |
|  *
 | |
|  * <<Broadcom-WL-IPTag/Open:>>
 | |
|  *
 | |
|  * $Id $
 | |
|  */
 | |
| 
 | |
| #include <bcm_cfg.h>
 | |
| #include <typedefs.h>
 | |
| #include <bcmdefs.h>
 | |
| #ifdef BCMDRIVER
 | |
| #include <osl.h>
 | |
| #else /* BCMDRIVER */
 | |
| #include <stddef.h>
 | |
| #include <string.h>
 | |
| #endif /* else BCMDRIVER */
 | |
| 
 | |
| #include <bcmstdlib_s.h>
 | |
| #include <bcmutils.h>
 | |
| 
 | |
| /*
 | |
|  * __SIZE_MAX__ value is depending on platform:
 | |
|  * Firmware Dongle: RAMSIZE (Dongle Specific Limit).
 | |
|  * LINUX NIC/Windows/MACOSX/Application: OS Native or
 | |
|  * 0xFFFFFFFFu if not defined.
 | |
|  */
 | |
| #ifndef SIZE_MAX
 | |
| #ifndef __SIZE_MAX__
 | |
| #define __SIZE_MAX__ 0xFFFFFFFFu
 | |
| #endif /* __SIZE_MAX__ */
 | |
| #define SIZE_MAX __SIZE_MAX__
 | |
| #endif /* SIZE_MAX */
 | |
| #define RSIZE_MAX (SIZE_MAX >> 1u)
 | |
| 
 | |
| #if !defined(__STDC_WANT_SECURE_LIB__) && !(defined(__STDC_LIB_EXT1__) && \
 | |
| 	defined(__STDC_WANT_LIB_EXT1__))
 | |
| /*
 | |
|  * memmove_s - secure memmove
 | |
|  * dest : pointer to the object to copy to
 | |
|  * destsz : size of the destination buffer
 | |
|  * src : pointer to the object to copy from
 | |
|  * n : number of bytes to copy
 | |
|  * Return Value : zero on success and non-zero on error
 | |
|  * Also on error, if dest is not a null pointer and destsz not greater
 | |
|  * than RSIZE_MAX, writes destsz zero bytes into the dest object.
 | |
|  */
 | |
| int
 | |
| memmove_s(void *dest, size_t destsz, const void *src, size_t n)
 | |
| {
 | |
| 	int err = BCME_OK;
 | |
| 
 | |
| 	if ((!dest) || (((char *)dest + destsz) < (char *)dest)) {
 | |
| 		err = BCME_BADARG;
 | |
| 		goto exit;
 | |
| 	}
 | |
| 
 | |
| 	if (destsz > RSIZE_MAX) {
 | |
| 		err = BCME_BADLEN;
 | |
| 		goto exit;
 | |
| 	}
 | |
| 
 | |
| 	if (destsz < n) {
 | |
| 		memset(dest, 0, destsz);
 | |
| 		err = BCME_BADLEN;
 | |
| 		goto exit;
 | |
| 	}
 | |
| 
 | |
| 	if ((!src) || (((const char *)src + n) < (const char *)src)) {
 | |
| 		memset(dest, 0, destsz);
 | |
| 		err = BCME_BADARG;
 | |
| 		goto exit;
 | |
| 	}
 | |
| 
 | |
| 	memmove(dest, src, n);
 | |
| exit:
 | |
| 	return err;
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * memcpy_s - secure memcpy
 | |
|  * dest : pointer to the object to copy to
 | |
|  * destsz : size of the destination buffer
 | |
|  * src : pointer to the object to copy from
 | |
|  * n : number of bytes to copy
 | |
|  * Return Value : zero on success and non-zero on error
 | |
|  * Also on error, if dest is not a null pointer and destsz not greater
 | |
|  * than RSIZE_MAX, writes destsz zero bytes into the dest object.
 | |
|  */
 | |
| int
 | |
| memcpy_s(void *dest, size_t destsz, const void *src, size_t n)
 | |
| {
 | |
| 	int err = BCME_OK;
 | |
| 	char *d = dest;
 | |
| 	const char *s = src;
 | |
| 
 | |
| 	if ((!d) || ((d + destsz) < d)) {
 | |
| 		err = BCME_BADARG;
 | |
| 		goto exit;
 | |
| 	}
 | |
| 
 | |
| 	if (destsz > RSIZE_MAX) {
 | |
| 		err = BCME_BADLEN;
 | |
| 		goto exit;
 | |
| 	}
 | |
| 
 | |
| 	if (destsz < n) {
 | |
| 		memset(dest, 0, destsz);
 | |
| 		err = BCME_BADLEN;
 | |
| 		goto exit;
 | |
| 	}
 | |
| 
 | |
| 	if ((!s) || ((s + n) < s)) {
 | |
| 		memset(dest, 0, destsz);
 | |
| 		err = BCME_BADARG;
 | |
| 		goto exit;
 | |
| 	}
 | |
| 
 | |
| 	/* overlap checking between dest and src */
 | |
| 	if (!(((d + destsz) <= s) || (d >= (s + n)))) {
 | |
| 		memset(dest, 0, destsz);
 | |
| 		err = BCME_BADARG;
 | |
| 		goto exit;
 | |
| 	}
 | |
| 
 | |
| 	(void)memcpy(dest, src, n);
 | |
| exit:
 | |
| 	return err;
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * memset_s - secure memset
 | |
|  * dest : pointer to the object to be set
 | |
|  * destsz : size of the destination buffer
 | |
|  * c : byte value
 | |
|  * n : number of bytes to be set
 | |
|  * Return Value : zero on success and non-zero on error
 | |
|  * Also on error, if dest is not a null pointer and destsz not greater
 | |
|  * than RSIZE_MAX, writes destsz bytes with value c into the dest object.
 | |
|  */
 | |
| int
 | |
| memset_s(void *dest, size_t destsz, int c, size_t n)
 | |
| {
 | |
| 	int err = BCME_OK;
 | |
| 	if ((!dest) || (((char *)dest + destsz) < (char *)dest)) {
 | |
| 		err = BCME_BADARG;
 | |
| 		goto exit;
 | |
| 	}
 | |
| 
 | |
| 	if (destsz > RSIZE_MAX) {
 | |
| 		err = BCME_BADLEN;
 | |
| 		goto exit;
 | |
| 	}
 | |
| 
 | |
| 	if (destsz < n) {
 | |
| 		(void)memset(dest, c, destsz);
 | |
| 		err = BCME_BADLEN;
 | |
| 		goto exit;
 | |
| 	}
 | |
| 
 | |
| 	(void)memset(dest, c, n);
 | |
| exit:
 | |
| 	return err;
 | |
| }
 | |
| #endif /* !__STDC_WANT_SECURE_LIB__ && !(__STDC_LIB_EXT1__ && __STDC_WANT_LIB_EXT1__) */
 | |
| 
 | |
| #if 0
 | |
| /**
 | |
|  * strlcpy - Copy a %NUL terminated string into a sized buffer
 | |
|  * @dest: Where to copy the string to
 | |
|  * @src: Where to copy the string from
 | |
|  * @size: size of destination buffer 0 if input parameters are NOK
 | |
|  * return: string leng of src (assume src is NUL terminated)
 | |
|  *
 | |
|  * Compatible with *BSD: the result is always a valid
 | |
|  * NUL-terminated string that fits in the buffer (unless,
 | |
|  * of course, the buffer size is zero). It does not pad
 | |
|  * out the result like strncpy() does.
 | |
|  */
 | |
| size_t strlcpy(char *dest, const char *src, size_t size)
 | |
| {
 | |
| 	const char *s = src;
 | |
| 	size_t n;
 | |
| 
 | |
| 	if (dest == NULL) {
 | |
| 		return 0;
 | |
| 	}
 | |
| 
 | |
| 	/* terminate dest if src is NULL and return 0 as only NULL was added */
 | |
| 	if (s == NULL) {
 | |
| 		*dest = '\0';
 | |
| 		return 0;
 | |
| 	}
 | |
| 
 | |
| 	/* allows us to handle size 0 */
 | |
| 	if (size == 0) {
 | |
| 		n = 0;
 | |
| 	} else {
 | |
| 		n = size - 1u;
 | |
| 	}
 | |
| 
 | |
| 	/* perform copy */
 | |
| 	while (*s && n != 0) {
 | |
| 		*dest++ = *s++;
 | |
| 		n--;
 | |
| 	}
 | |
| 
 | |
| 	*dest = '\0';
 | |
| 
 | |
| 	/* count to end of s or compensate for NULL */
 | |
| 	if (n == 0) {
 | |
| 		while (*s++)
 | |
| 			;
 | |
| 	} else {
 | |
| 		s++;
 | |
| 	}
 | |
| 
 | |
| 	/* return bytes copied not accounting NUL */
 | |
| 	return (s - src - 1u);
 | |
| }
 | |
| #endif // endif
 | |
| 
 | |
| /**
 | |
|  * strlcat_s - Concatenate a %NUL terminated string with a sized buffer
 | |
|  * @dest: Where to concatenate the string to
 | |
|  * @src: Where to copy the string from
 | |
|  * @size: size of destination buffer
 | |
|  * return: string length of created string (i.e. the initial length of dest plus the length of src)
 | |
|  *         not including the NUL char, up until size
 | |
|  *
 | |
|  * Unlike strncat(), strlcat() take the full size of the buffer (not just the number of bytes to
 | |
|  * copy) and guarantee to NUL-terminate the result (even when there's nothing to concat).
 | |
|  * If the length of dest string concatinated with the src string >= size, truncation occurs.
 | |
|  *
 | |
|  * Compatible with *BSD: the result is always a valid NUL-terminated string that fits in the buffer
 | |
|  * (unless, of course, the buffer size is zero).
 | |
|  *
 | |
|  * If either src or dest is not NUL-terminated, dest[size-1] will be set to NUL.
 | |
|  * If size < strlen(dest) + strlen(src), dest[size-1] will be set to NUL.
 | |
|  * If size == 0, dest[0] will be set to NUL.
 | |
|  */
 | |
| size_t
 | |
| strlcat_s(char *dest, const char *src, size_t size)
 | |
| {
 | |
| 	char *d = dest;
 | |
| 	const char *s = src;	/* point to the start of the src string */
 | |
| 	size_t n = size;
 | |
| 	size_t dlen;
 | |
| 	size_t bytes_to_copy = 0;
 | |
| 
 | |
| 	if (dest == NULL) {
 | |
| 		return 0;
 | |
| 	}
 | |
| 
 | |
| 	/* set d to point to the end of dest string (up to size) */
 | |
| 	while (n != 0 && *d != '\0') {
 | |
| 		d++;
 | |
| 		n--;
 | |
| 	}
 | |
| 	dlen = (size_t)(d - dest);
 | |
| 
 | |
| 	if (s != NULL) {
 | |
| 		size_t slen = 0;
 | |
| 
 | |
| 		/* calculate src len in case it's not null-terminated */
 | |
| 		n = size;
 | |
| 		while (n-- != 0 && *(s + slen) != '\0') {
 | |
| 			++slen;
 | |
| 		}
 | |
| 
 | |
| 		n = size - dlen;	/* maximum num of chars to copy */
 | |
| 		if (n != 0) {
 | |
| 			/* copy relevant chars (until end of src buf or given size is reached) */
 | |
| 			bytes_to_copy = MIN(slen - (size_t)(s - src), n - 1);
 | |
| 			(void)memcpy(d, s, bytes_to_copy);
 | |
| 			d += bytes_to_copy;
 | |
| 		}
 | |
| 	}
 | |
| 	if (n == 0 && dlen != 0) {
 | |
| 		--d;	/* nothing to copy, but NUL-terminate dest anyway */
 | |
| 	}
 | |
| 	*d = '\0';	/* NUL-terminate dest */
 | |
| 
 | |
| 	return (dlen + bytes_to_copy);
 | |
| }
 | 
