Source code for security.secure_bye_array

"""
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)