Security Guidelines¶
Security best practices for the Nexus Embedded Platform.
Overview¶
Security is critical in embedded systems. This guide covers:
Input Validation: Prevent injection attacks
Memory Safety: Prevent buffer overflows
Cryptography: Secure data and communications
Access Control: Protect sensitive resources
Secure Boot: Verify firmware integrity
Update Security: Secure firmware updates
Secure Coding Practices¶
Input Validation¶
Always Validate Inputs
/* Bad: No validation */
void process_data(uint8_t* buffer, size_t length) {
memcpy(internal_buffer, buffer, length); /* Overflow! */
}
/* Good: Validate inputs */
hal_status_t process_data(const uint8_t* buffer, size_t length) {
if (buffer == NULL) {
return HAL_ERROR_PARAM;
}
if (length == 0 || length > MAX_BUFFER_SIZE) {
return HAL_ERROR_PARAM;
}
memcpy(internal_buffer, buffer, length);
return HAL_OK;
}
Range Checking
/* Validate array indices */
hal_status_t set_value(size_t index, uint32_t value) {
if (index >= ARRAY_SIZE) {
return HAL_ERROR_PARAM;
}
array[index] = value;
return HAL_OK;
}
Integer Overflow Checks
/* Check for overflow before allocation */
void* safe_alloc(size_t count, size_t size) {
if (count > 0 && size > SIZE_MAX / count) {
return NULL; /* Would overflow */
}
return malloc(count * size);
}
Buffer Overflow Prevention¶
Use Safe String Functions
/* Bad: Unsafe string copy */
void copy_string_unsafe(char* dest, const char* src) {
strcpy(dest, src); /* Buffer overflow risk! */
}
/* Good: Safe string copy */
void copy_string_safe(char* dest, size_t dest_size, const char* src) {
if (dest == NULL || src == NULL || dest_size == 0) {
return;
}
strncpy(dest, src, dest_size - 1);
dest[dest_size - 1] = '\0';
}
Bounds Checking
/* Always check buffer bounds */
hal_status_t write_buffer(uint8_t* buffer, size_t buffer_size,
const uint8_t* data, size_t data_size) {
if (buffer == NULL || data == NULL) {
return HAL_ERROR_PARAM;
}
if (data_size > buffer_size) {
return HAL_ERROR_NO_MEMORY;
}
memcpy(buffer, data, data_size);
return HAL_OK;
}
Memory Safety¶
Pointer Safety¶
Null Pointer Checks
/* Always check pointers */
hal_status_t process_config(const config_t* config) {
if (config == NULL) {
return HAL_ERROR_PARAM;
}
/* Use config */
return HAL_OK;
}
Avoid Use-After-Free
/* Bad: Use after free */
void bad_example(void) {
uint8_t* buffer = malloc(256);
free(buffer);
buffer[0] = 0; /* Use after free! */
}
/* Good: Clear pointer after free */
void good_example(void) {
uint8_t* buffer = malloc(256);
free(buffer);
buffer = NULL; /* Prevent use after free */
}
Double-Free Prevention
/* Safe free macro */
#define SAFE_FREE(ptr) \
do { \
if (ptr != NULL) { \
free(ptr); \
ptr = NULL; \
} \
} while(0)
Stack Protection¶
Stack Canaries
#define STACK_CANARY 0xDEADBEEF
void protected_function(void) {
uint32_t canary = STACK_CANARY;
/* Function code */
/* Check canary */
if (canary != STACK_CANARY) {
/* Stack overflow detected */
handle_security_violation();
}
}
Cryptography¶
Random Number Generation¶
Use Hardware RNG
/* Use hardware random number generator */
uint32_t get_random(void) {
/* Enable RNG clock */
RCC->AHB2ENR |= RCC_AHB2ENR_RNGEN;
/* Enable RNG */
RNG->CR |= RNG_CR_RNGEN;
/* Wait for random data */
while (!(RNG->SR & RNG_SR_DRDY));
return RNG->DR;
}
Seed PRNG Properly
/* Seed with hardware RNG */
void seed_prng(void) {
uint32_t seed = get_random();
srand(seed);
}
Encryption¶
AES Encryption
/* Encrypt data with AES */
hal_status_t encrypt_data(const uint8_t* plaintext, size_t length,
const uint8_t* key, uint8_t* ciphertext) {
if (plaintext == NULL || key == NULL || ciphertext == NULL) {
return HAL_ERROR_PARAM;
}
/* Initialize AES */
aes_context_t ctx;
aes_init(&ctx, key, AES_KEY_SIZE_256);
/* Encrypt */
aes_encrypt(&ctx, plaintext, ciphertext, length);
/* Clear sensitive data */
memset(&ctx, 0, sizeof(ctx));
return HAL_OK;
}
Secure Storage¶
Key Storage¶
Never Hardcode Keys
/* Bad: Hardcoded key */
const uint8_t encryption_key[] = {
0x01, 0x02, 0x03, /* ... */
};
/* Good: Load from secure storage */
hal_status_t load_encryption_key(uint8_t* key, size_t key_size) {
return secure_storage_read(KEY_ID, key, key_size);
}
Clear Sensitive Data
/* Clear sensitive data after use */
void process_password(const char* password) {
/* Use password */
authenticate(password);
/* Clear from memory */
memset((void*)password, 0, strlen(password));
}
Secure Boot¶
Firmware Verification¶
Verify Signature
/* Verify firmware signature */
bool verify_firmware(const uint8_t* firmware, size_t length,
const uint8_t* signature) {
uint8_t hash[32];
/* Calculate firmware hash */
sha256(firmware, length, hash);
/* Verify signature */
return rsa_verify(hash, sizeof(hash), signature, public_key);
}
Secure Boot Flow
void secure_boot(void) {
/* Read firmware */
uint8_t* firmware = (uint8_t*)FIRMWARE_ADDRESS;
size_t length = get_firmware_length();
/* Read signature */
uint8_t* signature = (uint8_t*)SIGNATURE_ADDRESS;
/* Verify firmware */
if (!verify_firmware(firmware, length, signature)) {
/* Verification failed */
enter_recovery_mode();
return;
}
/* Jump to application */
jump_to_application(FIRMWARE_ADDRESS);
}
Secure Communication¶
TLS/SSL¶
Use TLS for Network Communication
/* Establish secure connection */
hal_status_t connect_secure(const char* host, uint16_t port) {
tls_context_t ctx;
/* Initialize TLS */
tls_init(&ctx);
/* Set CA certificate */
tls_set_ca_cert(&ctx, ca_cert, ca_cert_len);
/* Connect */
if (tls_connect(&ctx, host, port) != TLS_OK) {
return HAL_ERROR;
}
return HAL_OK;
}
Access Control¶
Privilege Separation¶
Use MPU for Memory Protection
/* Configure MPU region */
void configure_mpu(void) {
/* Disable MPU */
MPU->CTRL = 0;
/* Configure region 0: Flash (read-only) */
MPU->RBAR = FLASH_BASE | MPU_RBAR_VALID_Msk | 0;
MPU->RASR = MPU_RASR_ENABLE_Msk |
MPU_RASR_SIZE_512KB |
MPU_RASR_AP_RO_RO;
/* Configure region 1: RAM (read-write) */
MPU->RBAR = RAM_BASE | MPU_RBAR_VALID_Msk | 1;
MPU->RASR = MPU_RASR_ENABLE_Msk |
MPU_RASR_SIZE_128KB |
MPU_RASR_AP_RW_RW;
/* Enable MPU */
MPU->CTRL = MPU_CTRL_ENABLE_Msk;
}
Security Checklist¶
Development Checklist¶
☐ All inputs validated ☐ Buffer bounds checked ☐ No hardcoded secrets ☐ Sensitive data cleared after use ☐ Secure random number generation ☐ Encryption for sensitive data ☐ Firmware signature verification ☐ TLS for network communication ☐ Memory protection enabled ☐ Stack protection enabled
Code Review Checklist¶
☐ No buffer overflows ☐ No integer overflows ☐ No format string vulnerabilities ☐ No SQL injection (if applicable) ☐ No command injection ☐ Proper error handling ☐ No information leakage ☐ Secure defaults
See Also¶
Coding Standards - Coding standards
Code Review Guidelines - Code review
Testing - Security testing
Summary¶
Key security practices:
Validate all inputs
Prevent buffer overflows
Use cryptography correctly
Protect sensitive data
Verify firmware integrity
Use secure communication
Implement access control
Security must be considered throughout the development lifecycle.