| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308 |
- /*
- * Broadcom Secure Standard Library.
- *
- * Portions of this code are copyright (c) 2020 Cypress Semiconductor Corporation
- *
- * Copyright (C) 1999-2020, Broadcom Corporation
- *
- * 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 !defined(FREEBSD) && !defined(BCM_USE_PLATFORM_STRLCPY)
- /**
- * 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);
- }
|