/* SPDX-License-Identifier: GPL-3.0-only */ #include "ssh_memory.h" #include #include "sdkconfig.h" #include "esp_heap_caps.h" #include "esp_idf_version.h" #include "secure_random.h" #if !defined(CONFIG_HEAP_POISONING_DISABLED) || !CONFIG_HEAP_POISONING_DISABLED || \ (defined(CONFIG_HEAP_POISONING_LIGHT) && CONFIG_HEAP_POISONING_LIGHT) || \ (defined(CONFIG_HEAP_POISONING_COMPREHENSIVE) && CONFIG_HEAP_POISONING_COMPREHENSIVE) #error "SSH memory requires heap poisoning disabled" #endif #if ESP_IDF_VERSION != ESP_IDF_VERSION_VAL(5, 5, 3) #error "Reaudit SSH memory usable extent contract for this IDF" #endif void *ssh_memory_malloc(size_t size) { return heap_caps_malloc_prefer(size, 2, MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT, MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT); } void ssh_memory_free(void *pointer) { if (pointer == NULL) { return; } secure_wipe(pointer, heap_caps_get_allocated_size(pointer)); heap_caps_free(pointer); } void *ssh_memory_realloc(void *pointer, size_t size) { if (pointer == NULL) { return ssh_memory_malloc(size); } if (size == 0U) { ssh_memory_free(pointer); return NULL; } /* Audited unpoisoned IDF 5.5.3 reports the owned usable extent, including * rounding. Do not substitute an interior-pointer/block-containing query. */ size_t capacity = heap_caps_get_allocated_size(pointer); if (size <= capacity) { secure_wipe((unsigned char *)pointer + size, capacity - size); return pointer; } void *replacement = ssh_memory_malloc(size); if (replacement == NULL) { return NULL; } memcpy(replacement, pointer, capacity); ssh_memory_free(pointer); return replacement; }