// File: Lightweight_HMAC.ino
#include <Arduino.h>
// Constants
#define BLOCK_SIZE 64 // Block size in bytes for the hash algorithm (e.g., 64 bytes for SHA-1)
#define OUTPUT_SIZE 20 // Output size in bytes for SHA-1 (adjust for other hash algorithms)
// Mock SHA-1 Implementation (Replace with an actual lightweight implementation for production use)
void SHA1(const uint8_t *data, size_t len, uint8_t *digest) {
// Simple mock hash: XOR data with a constant for demonstration purposes
for (size_t i = 0; i < OUTPUT_SIZE; i++) {
digest[i] = (uint8_t)(data[i % len] ^ 0x5A);
}
}
// XOR buffer with a specific byte
void XORBuffer(uint8_t *buffer, uint8_t value, size_t len) {
for (size_t i = 0; i < len; i++) {
buffer[i] ^= value;
}
}
// HMAC Implementation
void HMAC(const uint8_t *key, size_t key_len, const uint8_t *message, size_t message_len, uint8_t *hmac) {
uint8_t key_block[BLOCK_SIZE] = {0}; // Padded key
uint8_t inner_hash[OUTPUT_SIZE];
uint8_t inner_data[BLOCK_SIZE + message_len];
uint8_t outer_data[BLOCK_SIZE + OUTPUT_SIZE];
// Step 1: Prepare the key block
if (key_len > BLOCK_SIZE) {
SHA1(key, key_len, key_block); // Hash long key to fit block size
} else {
memcpy(key_block, key, key_len); // Copy key into block
}
// Step 2: Create inner padded key (key XOR with 0x36)
memcpy(inner_data, key_block, BLOCK_SIZE);
XORBuffer(inner_data, 0x36, BLOCK_SIZE);
memcpy(inner_data + BLOCK_SIZE, message, message_len);
// Step 3: Perform inner hash
SHA1(inner_data, BLOCK_SIZE + message_len, inner_hash);
// Step 4: Create outer padded key (key XOR with 0x5C)
memcpy(outer_data, key_block, BLOCK_SIZE);
XORBuffer(outer_data, 0x5C, BLOCK_SIZE);
memcpy(outer_data + BLOCK_SIZE, inner_hash, OUTPUT_SIZE);
// Step 5: Perform outer hash
SHA1(outer_data, BLOCK_SIZE + OUTPUT_SIZE, hmac);
}
// Test the HMAC implementation
void setup() {
Serial.begin(9600);
// Example key and message
uint8_t key[] = "secret_key";
uint8_t message[] = "Hello, HMAC!";
uint8_t hmac[OUTPUT_SIZE];
// Compute HMAC
HMAC(key, sizeof(key) - 1, message, sizeof(message) - 1, hmac);
// Print the resulting HMAC
Serial.print("HMAC: ");
for (size_t i = 0; i < OUTPUT_SIZE; i++) {
if (hmac[i] < 16) Serial.print("0"); // Pad single hex digits
Serial.print(hmac[i], HEX);
Serial.print(" ");
}
Serial.println();
}
void loop() {
// Nothing to do here
}