aboutsummaryrefslogtreecommitdiff
path: root/epid/common/src/memory.c
diff options
context:
space:
mode:
Diffstat (limited to 'epid/common/src/memory.c')
-rw-r--r--epid/common/src/memory.c123
1 files changed, 123 insertions, 0 deletions
diff --git a/epid/common/src/memory.c b/epid/common/src/memory.c
new file mode 100644
index 0000000..b37180f
--- /dev/null
+++ b/epid/common/src/memory.c
@@ -0,0 +1,123 @@
+/*############################################################################
+ # Copyright 2016 Intel Corporation
+ #
+ # Licensed under the Apache License, Version 2.0 (the "License");
+ # you may not use this file except in compliance with the License.
+ # You may obtain a copy of the License at
+ #
+ # http://www.apache.org/licenses/LICENSE-2.0
+ #
+ # Unless required by applicable law or agreed to in writing, software
+ # distributed under the License is distributed on an "AS IS" BASIS,
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ # See the License for the specific language governing permissions and
+ # limitations under the License.
+ ############################################################################*/
+
+/*!
+ * \file
+ * \brief Memory access implementation.
+ */
+
+#include "epid/common/src/memory.h"
+
+#include <string.h>
+#include <stdint.h>
+
+/// Maximum size of the destination buffer
+#ifndef RSIZE_MAX
+#define RSIZE_MAX ((SIZE_MAX) >> 1)
+#endif
+
+#ifndef MIN
+/// Evaluate to minimum of two values
+#define MIN(a, b) ((a) < (b) ? (a) : (b))
+#endif // MIN
+
+/// Copies count of character from dest to src
+/*! \note Implementation follows C11 memcpy_s but with checks always enabled
+ */
+int memcpy_S(void* dest, size_t destsz, void const* src, size_t count) {
+ size_t i;
+ if (!dest || destsz > RSIZE_MAX) return -1;
+ if (!src || count > RSIZE_MAX || count > destsz ||
+ count > (dest > src ? ((uintptr_t)dest - (uintptr_t)src)
+ : ((uintptr_t)src - (uintptr_t)dest))) {
+ // zero out dest if error detected
+ memset(dest, 0, destsz);
+ return -1;
+ }
+
+ for (i = 0; i < count; i++) ((uint8_t*)dest)[i] = ((uint8_t*)src)[i];
+ return 0;
+}
+
+void EpidZeroMemory(void* ptr, size_t size) { memset(ptr, 0, size); }
+
+#if defined(EPID_ENABLE_EPID_ZERO_MEMORY_ON_FREE)
+
+#if !defined(EPID_ALLOC_ALIGN)
+/// Alignment constant for EpidAlloc, must be a power of two
+#define EPID_ALLOC_ALIGN sizeof(size_t)
+#endif // !defined(EPID_ALLOC_ALIGN)
+
+#pragma pack(1)
+/// Allocated memory block information
+typedef struct EpidAllocHeader {
+ size_t length; ///< number of bytes memory block is allocated for
+ void* ptr; ///< pointer to whole memory block including EpidAllocHeader
+} EpidAllocHeader;
+#pragma pack()
+
+#endif // defined(EPID_ENABLE_EPID_ZERO_MEMORY_ON_FREE)
+
+void* EpidAlloc(size_t size) {
+#if defined(EPID_ENABLE_EPID_ZERO_MEMORY_ON_FREE)
+ void* ptr = NULL;
+ if (size <= 0) return NULL;
+ // Allocate memory enough to store size bytes and EpidAllocHeader
+ ptr = calloc(1, size + EPID_ALLOC_ALIGN - 1 + sizeof(EpidAllocHeader));
+ if (ptr) {
+ void* aligned_pointer = (void*)(((uintptr_t)ptr + EPID_ALLOC_ALIGN +
+ sizeof(EpidAllocHeader) - 1) &
+ (~(EPID_ALLOC_ALIGN - 1)));
+ ((EpidAllocHeader*)aligned_pointer)[-1].length = size;
+ ((EpidAllocHeader*)aligned_pointer)[-1].ptr = ptr;
+ return aligned_pointer;
+ }
+ return NULL;
+#else // defined(EPID_ENABLE_EPID_ZERO_MEMORY_ON_FREE)
+ return calloc(1, size);
+#endif // defined(EPID_ENABLE_EPID_ZERO_MEMORY_ON_FREE)
+}
+
+void* EpidRealloc(void* ptr, size_t new_size) {
+#if defined(EPID_ENABLE_EPID_ZERO_MEMORY_ON_FREE)
+ void* new_ptr = EpidAlloc(new_size);
+ if (!new_ptr) return NULL;
+ if (ptr) {
+ // Memory copy is used to copy a buffer of variable length
+ if (0 != memcpy_S(new_ptr, ((EpidAllocHeader*)new_ptr)[-1].length, ptr,
+ MIN(((EpidAllocHeader*)ptr)[-1].length,
+ ((EpidAllocHeader*)new_ptr)[-1].length))) {
+ EpidFree(new_ptr);
+ return NULL;
+ }
+ EpidFree(ptr);
+ }
+ return new_ptr;
+#else // defined(EPID_ENABLE_EPID_ZERO_MEMORY_ON_FREE)
+ return realloc(ptr, new_size);
+#endif // defined(EPID_ENABLE_EPID_ZERO_MEMORY_ON_FREE)
+}
+
+void EpidFree(void* ptr) {
+#if defined(EPID_ENABLE_EPID_ZERO_MEMORY_ON_FREE)
+ if (ptr) {
+ EpidZeroMemory(ptr, ((EpidAllocHeader*)ptr)[-1].length);
+ free(((EpidAllocHeader*)ptr)[-1].ptr);
+ }
+#else // defined(EPID_ENABLE_EPID_ZERO_MEMORY_ON_FREE)
+ free(ptr);
+#endif // defined(EPID_ENABLE_EPID_ZERO_MEMORY_ON_FREE)
+}