feat(lib): implement memcpy_s in lib
To support memcpy_s for better security purpose
to avoid overflowing the dest while copy from src.
Signed-off-by: Jit Loon Lim <jit.loon.lim@intel.com>
Change-Id: I63c3ea6a3e99c10d69be6bce04843c14b0a28a4d
diff --git a/lib/libc/memcpy_s.c b/lib/libc/memcpy_s.c
new file mode 100644
index 0000000..01e88b0
--- /dev/null
+++ b/lib/libc/memcpy_s.c
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2013-2023, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2023, Intel Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <errno.h>
+#include <stddef.h>
+#include <string.h>
+
+int memcpy_s(void *dst, size_t dsize, void *src, size_t ssize)
+{
+ unsigned int *s = (unsigned int *)src;
+ unsigned int *d = (unsigned int *)dst;
+
+ /*
+ * Check source and destination size is NULL
+ */
+ if ((dst == NULL) || (src == NULL)) {
+ return -ENOMEM;
+ }
+
+ /*
+ * Check source and destination size validity
+ */
+ if ((dsize == 0) || (ssize == 0)) {
+ return -ERANGE;
+ }
+
+ /*
+ * Check both source and destination size range
+ */
+ if ((ssize > dsize) || (dsize > ssize)) {
+ return -EINVAL;
+ }
+
+ /*
+ * Check both source and destination address overlapping
+ * When (s > d < s + ssize)
+ * Or (d > s < d + dsize)
+ */
+
+ if (d > s) {
+ if ((d) < (s + ssize)) {
+ return -EOPNOTSUPP;
+ }
+ }
+
+ if (s > d) {
+ if ((s) < (d + dsize)) {
+ return -EOPNOTSUPP;
+ }
+ }
+
+ /*
+ * Start copy process when there is no error
+ */
+ while (ssize--) {
+ d[ssize] = s[ssize];
+ }
+
+ return 0;
+}