93 lines
3.1 KiB
C
93 lines
3.1 KiB
C
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <stdint.h>
|
|
#include "main.h"
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
// MESSAGE PADDING IMPLEMENTATION
|
|
// ISO/IEC 9797-1 Method 2 (Padmé Padding)
|
|
// with Exponential Bucketing for Traffic Analysis Resistance
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// Calculate required chunk size using exponential bucketing
|
|
// Starting at 256 bytes, doubling each time
|
|
// Provides strong protection against length analysis attacks
|
|
size_t calculate_chunk_size(size_t msg_len) {
|
|
size_t chunk = 256; // Minimum chunk size: 256 bytes
|
|
|
|
// Need space for message + 0x80 byte (minimum 1 byte padding)
|
|
while (chunk < msg_len + 1) {
|
|
chunk *= 2;
|
|
}
|
|
|
|
return chunk;
|
|
}
|
|
|
|
// Apply ISO/IEC 9797-1 Method 2 (Padmé) padding
|
|
// Appends 0x80 byte followed by 0x00 bytes to reach chunk boundary
|
|
// Returns 0 on success, non-zero on error
|
|
int apply_padme_padding(unsigned char* buffer, size_t msg_len, size_t chunk_size) {
|
|
if (!buffer) {
|
|
return 1; // Error: null pointer
|
|
}
|
|
|
|
if (chunk_size < msg_len + 1) {
|
|
return 2; // Error: chunk size too small for message + padding
|
|
}
|
|
|
|
// Apply padding: 0x80 followed by 0x00 bytes
|
|
buffer[msg_len] = 0x80;
|
|
|
|
// Fill remaining bytes with 0x00
|
|
if (chunk_size > msg_len + 1) {
|
|
memset(buffer + msg_len + 1, 0x00, chunk_size - msg_len - 1);
|
|
}
|
|
|
|
return 0; // Success
|
|
}
|
|
|
|
// Remove ISO/IEC 9797-1 Method 2 (Padmé) padding
|
|
// Scans backwards for 0x80 marker, validates padding
|
|
// Returns 0 on success, non-zero on error
|
|
// Sets msg_len to the actual message length (excluding padding)
|
|
int remove_padme_padding(const unsigned char* buffer, size_t chunk_size, size_t* msg_len) {
|
|
if (!buffer || !msg_len) {
|
|
return 1; // Error: null pointer
|
|
}
|
|
|
|
if (chunk_size == 0) {
|
|
return 2; // Error: invalid chunk size
|
|
}
|
|
|
|
// Scan backwards from end to find 0x80 marker
|
|
for (int i = chunk_size - 1; i >= 0; i--) {
|
|
if (buffer[i] == 0x80) {
|
|
// Found the padding marker
|
|
*msg_len = i;
|
|
return 0; // Success
|
|
} else if (buffer[i] != 0x00) {
|
|
// Found non-zero, non-0x80 byte - invalid padding
|
|
return 3; // Error: invalid padding (corrupted or tampered data)
|
|
}
|
|
}
|
|
|
|
// No 0x80 marker found - invalid padding
|
|
return 4; // Error: no padding marker found
|
|
}
|
|
|
|
// Helper function to get human-readable chunk size
|
|
// Useful for debugging and user feedback
|
|
void format_chunk_size(size_t chunk_size, char* buffer, size_t buffer_size) {
|
|
if (!buffer || buffer_size == 0) return;
|
|
|
|
if (chunk_size < 1024) {
|
|
snprintf(buffer, buffer_size, "%zu bytes", chunk_size);
|
|
} else if (chunk_size < 1024 * 1024) {
|
|
snprintf(buffer, buffer_size, "%.1f KB", chunk_size / 1024.0);
|
|
} else if (chunk_size < 1024 * 1024 * 1024) {
|
|
snprintf(buffer, buffer_size, "%.1f MB", chunk_size / (1024.0 * 1024.0));
|
|
} else {
|
|
snprintf(buffer, buffer_size, "%.1f GB", chunk_size / (1024.0 * 1024.0 * 1024.0));
|
|
}
|
|
}
|