"""
SecureByteArray: Secure Memory Management Implementation
Version: 1.0
Author: [Gabriel Cellammare]
Last Modified: [05/01/2025]
This module provides a secure implementation for handling sensitive data in memory with:
- Protected memory management
- Anti-dumping measures
- Secure data wiping
- Automatic cleanup mechanisms
Security Features:
1. Memory Protection: Implements secure allocation and wiping
2. Anti-Dumping: Uses multiple overwrite passes
3. Context Management: Automatic cleanup
4. Access Control: Locking mechanism
5. Secure Random: Uses secrets module for cryptographic operations
Dependencies:
- array (for byte array management)
- ctypes (for low-level memory operations)
- secrets (for cryptographic random generation)
- logging (for security event tracking)
"""
import array
import ctypes
import secrets
from typing import Optional, Union
import logging
[docs]
class MemorySecurityError(Exception):
"""
Custom exception for memory security operations.
Used to distinguish memory security issues from standard exceptions.
Provides specific error context for security-related failures.
"""
pass
[docs]
class SecureByteArray:
"""
Secure Memory Management Implementation
Provides protected memory operations for sensitive data handling:
- Secure memory allocation and deallocation
- Protection against memory dumps
- Multi-pass secure data wiping
- Automatic memory cleanup
- Memory access controls
Security Features:
- Uses cryptographic random for overwriting
- Implements multiple wipe passes
- Verifies memory allocation
- Provides memory locking
- Implements secure copying
Usage:
# Using as context manager (recommended)
with SecureByteArray(sensitive_data) as secure_data:
processed_data = secure_data.to_bytes()
# Direct usage (requires manual cleanup)
secure_data = SecureByteArray(sensitive_data)
try:
processed_data = secure_data.to_bytes()
finally:
secure_data.secure_zero()
"""
# Configure logging for security events
logger = logging.getLogger(__name__)
logging.basicConfig(level=logging.INFO)
# Security configuration constants
SECURE_WIPE_PASSES = 3 # Minimum passes for secure wiping
MIN_RANDOM_BYTES = 32 # Minimum random bytes for secure overwriting
[docs]
def __init__(self, data: Optional[Union[bytes, bytearray, array.array]] = None):
"""
Initialize secure byte array with optional data.
Args:
data: Initial sensitive data (optional)
Raises:
MemorySecurityError: On memory allocation failure
TypeError: On invalid input data type
Security:
- Validates input types
- Verifies memory allocation
- Initializes security state
"""
try:
if data is not None:
if not isinstance(data, (bytes, bytearray, array.array)):
raise TypeError(
"Data must be bytes, bytearray, or array")
self._data = array.array('B', data)
self._address = self._data.buffer_info()[0]
self._length = len(self._data)
else:
self._data = array.array('B')
self._address = self._data.buffer_info()[0]
self._length = 0
self._is_locked = False
self._verify_memory_allocation()
except Exception as e:
self.logger.error(
f"Error initializing SecureByteArray: {e}")
raise MemorySecurityError(
"Unable to initialize secure memory") from e
def _verify_memory_allocation(self) -> None:
"""
Verify memory allocation security.
Raises:
MemorySecurityError: If allocation verification fails
Security:
- Checks memory address validity
- Validates allocation size
- Verifies address space
"""
if self._length > 0 and (self._address is None or self._address == 0):
raise MemorySecurityError("Memory allocation failed")
[docs]
def secure_zero(self) -> None:
"""
Securely wipe memory contents.
Security Implementation:
- Multiple overwrite passes
- Cryptographic random data
- Final zero overwrite
- Memory fence operations
Raises:
MemorySecurityError: If secure wiping fails
"""
if self._length == 0:
return
try:
for _ in range(self.SECURE_WIPE_PASSES):
# Cryptographic random overwrite
random_data = secrets.token_bytes(
max(self._length, self.MIN_RANDOM_BYTES))
ctypes.memmove(self._address, random_data, self._length)
# Final secure zero pass
ctypes.memset(self._address, 0, self._length)
except Exception as e:
self.logger.error(
f"Error during secure memory wiping: {e}")
raise MemorySecurityError(
"Unable to securely wipe memory") from e
[docs]
def to_bytes(self) -> bytes:
"""
Create secure copy of data.
Returns:
bytes: Copy of protected data
Raises:
MemorySecurityError: If array is locked
Security:
- Validates lock state
- Creates secure copy
- Maintains original protection
"""
if self._is_locked:
raise MemorySecurityError(
"Cannot access data while array is locked")
return bytes(self._data)