/** @file EDKII Device Security library for SPDM device. It follows the SPDM Specification. Copyright (c) 2024, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #include #include #include #include "hal/base.h" #include "hal/library/memlib.h" /** * Copies bytes from a source buffer to a destination buffer. * * This function copies "src_len" bytes from "src_buf" to "dst_buf". * * Asserts and returns a non-zero value if any of the following are true: * 1) "src_buf" or "dst_buf" are NULL. * 2) "src_len" or "dst_len" is greater than (SIZE_MAX >> 1). * 3) "src_len" is greater than "dst_len". * 4) "src_buf" and "dst_buf" overlap. * * If any of these cases fail, a non-zero value is returned. Additionally if * "dst_buf" points to a non-NULL value and "dst_len" is valid, then "dst_len" * bytes of "dst_buf" are zeroed. * * This function follows the C11 cppreference description of memcpy_s. * https://en.cppreference.com/w/c/string/byte/memcpy * The cppreferece description does NOT allow the source or destination * buffers to be NULL. * * This function differs from the Microsoft and Safeclib memcpy_s implementations * in that the Microsoft and Safeclib implementations allow for NULL source and * destinations pointers when the number of bytes to copy (src_len) is zero. * * In addition the Microsoft and Safeclib memcpy_s functions return different * negative values on error. For best support, clients should generally check * against zero for success or failure. * * @param dst_buf Destination buffer to copy to. * @param dst_len Maximum length in bytes of the destination buffer. * @param src_buf Source buffer to copy from. * @param src_len The number of bytes to copy from the source buffer. * * @return 0 on success. non-zero on error. * **/ void libspdm_copy_mem ( void *dst_buf, size_t dst_len, const void *src_buf, size_t src_len ) { volatile uint8_t *dst; const volatile uint8_t *src; dst = (volatile uint8_t *)dst_buf; src = (const volatile uint8_t *)src_buf; /* Check for case where "dst" or "dst_len" may be invalid. * Do not zero "dst" in this case. */ if ((dst == NULL) || (dst_len > (SIZE_MAX >> 1))) { ASSERT (0); } /* Gaurd against invalid source. Zero "dst" in this case. */ if (src == NULL) { ZeroMem (dst_buf, dst_len); ASSERT (0); } /* Guard against overlap case. Zero "dst" in these cases. */ if (((src < dst) && (src + src_len > dst)) || ((dst < src) && (dst + src_len > src))) { ZeroMem (dst_buf, dst_len); ASSERT (0); } /* Guard against invalid lengths. Zero "dst" in these cases. */ if ((src_len > dst_len) || (src_len > (SIZE_MAX >> 1))) { ZeroMem (dst_buf, dst_len); ASSERT (0); } while (src_len-- != 0) { *(dst++) = *(src++); } } /** * Fills a target buffer with a byte value, and returns the target buffer. * * This function fills length bytes of buffer with value, and returns buffer. * * If length is greater than (MAX_ADDRESS - buffer + 1), then ASSERT(). * * @param buffer The memory to set. * @param length The number of bytes to set. * @param value The value with which to fill length bytes of buffer. * * @return buffer. * **/ void libspdm_set_mem ( void *buffer, size_t length, uint8_t value ) { SetMem (buffer, length, value); } /** * Fills a target buffer with zeros, and returns the target buffer. * * This function fills length bytes of buffer with zeros, and returns buffer. * * If length > 0 and buffer is NULL, then ASSERT(). * If length is greater than (MAX_ADDRESS - buffer + 1), then ASSERT(). * * @param buffer The pointer to the target buffer to fill with zeros. * @param length The number of bytes in buffer to fill with zeros. * * @return buffer. * **/ void libspdm_zero_mem ( void *buffer, size_t length ) { ZeroMem (buffer, length); } /** * Compares the contents of two buffers in const time. * * This function compares length bytes of source_buffer to length bytes of destination_buffer. * If all length bytes of the two buffers are identical, then 0 is returned. Otherwise, the * value returned is the first mismatched byte in source_buffer subtracted from the first * mismatched byte in destination_buffer. * * If length > 0 and destination_buffer is NULL, then ASSERT(). * If length > 0 and source_buffer is NULL, then ASSERT(). * If length is greater than (MAX_ADDRESS - destination_buffer + 1), then ASSERT(). * If length is greater than (MAX_ADDRESS - source_buffer + 1), then ASSERT(). * * @param destination_buffer A pointer to the destination buffer to compare. * @param source_buffer A pointer to the source buffer to compare. * @param length The number of bytes to compare. * * @return 0 All length bytes of the two buffers are identical. * @retval Non-zero There is mismatched between source_buffer and destination_buffer. * **/ bool libspdm_consttime_is_mem_equal ( const void *destination_buffer, const void *source_buffer, size_t length ) { if (CompareMem (destination_buffer, source_buffer, length) == 0) { return true; } else { return false; } }