Changes needed for RSA key generation (#30)
Co-authored-by: neelimap <neelimaps@neominds.in> Reviewed-on: http://13.234.246.121:3000/Neominds/ossl35vx69/pulls/30 Co-authored-by: Neelima P S <neelima.ps@neominds.in> Co-committed-by: Neelima P S <neelima.ps@neominds.in>
This commit is contained in:
committed by
neelimap
co-authored by
neelimap
parent
0d0e6f73c4
commit
67cbb5af87
@@ -708,6 +708,8 @@ int OPENSSL_init_crypto(uint64_t opts, const OPENSSL_INIT_SETTINGS *settings)
|
||||
if (!CRYPTO_atomic_or(&optsdone, opts, &tmp, optsdone_lock))
|
||||
return 0;
|
||||
|
||||
RAND_set_rand_method(RAND_OpenSSL());
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -820,9 +822,7 @@ int ipcrypto_init_internal(SEM_ID semId)
|
||||
{
|
||||
init = 1;
|
||||
|
||||
#ifndef _WRS_CONFIG_OPENSSL_FIPSMODULE
|
||||
RAND_set_rand_method(vxRandLibMeth());
|
||||
#endif
|
||||
|
||||
|
||||
OpenSSL_add_all_algorithms();
|
||||
|
||||
|
||||
+228
@@ -0,0 +1,228 @@
|
||||
#include <vxWorks.h>
|
||||
#include <sysLib.h>
|
||||
#include <wdLib.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <openssl/rand.h>
|
||||
#include "sysLib.h"
|
||||
|
||||
#define ENTROPY_SAMPLE_COUNT 64 /* Number of interrupt samples to collect */
|
||||
#define ENTROPY_BUFFER_SIZE 32 /* Output entropy buffer size in bytes */
|
||||
|
||||
/* Structure to hold entropy collection state */
|
||||
typedef struct {
|
||||
UINT32 samples[ENTROPY_SAMPLE_COUNT];
|
||||
int sample_index;
|
||||
UINT32 last_tick;
|
||||
WDOG_ID watchdog;
|
||||
UINT8 entropy_pool[ENTROPY_BUFFER_SIZE];
|
||||
int pool_filled;
|
||||
} EntropyCollector;
|
||||
|
||||
/* Forward declarations */
|
||||
static void entropyWatchdogCallback(void *arg);
|
||||
|
||||
/*******************************************************************************
|
||||
* entropyWatchdogCallback - Callback function invoked at interrupt context
|
||||
*
|
||||
* This function runs in interrupt context (system tick interrupt). It samples
|
||||
* the current system tick count and computes jitter as the delta between
|
||||
* consecutive interrupts. VxWorks watchdogs execute in interrupt context,
|
||||
* so this function must NOT:
|
||||
* - Call any blocking functions
|
||||
* - Use printf()
|
||||
* - Use C++ objects with constructors/destructors
|
||||
* - Use memory allocation (malloc/new)
|
||||
*
|
||||
* See: VxWorks Programmer's Guide - C++ limitations in interrupt context [citation:1][citation:2]
|
||||
*******************************************************************************/
|
||||
static void entropyWatchdogCallback(void *arg) {
|
||||
EntropyCollector *collector = (EntropyCollector*)arg;
|
||||
UINT32 current_tick;
|
||||
UINT32 jitter;
|
||||
|
||||
if (collector == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Get current system tick count - high resolution timing source */
|
||||
current_tick = sysTimestamp();
|
||||
|
||||
/* Calculate jitter as timing delta between successive interrupts */
|
||||
if (collector->last_tick != 0) {
|
||||
jitter = current_tick - collector->last_tick;
|
||||
|
||||
/* Store jitter sample if we haven't collected enough */
|
||||
if (collector->sample_index < ENTROPY_SAMPLE_COUNT) {
|
||||
collector->samples[collector->sample_index++] = jitter;
|
||||
}
|
||||
}
|
||||
|
||||
/* Update last tick for next measurement */
|
||||
collector->last_tick = current_tick;
|
||||
|
||||
/*
|
||||
* Reschedule watchdog for next interrupt (non-periodic to avoid
|
||||
* predictable patterns - this actually increases entropy)
|
||||
*/
|
||||
if (collector->sample_index < ENTROPY_SAMPLE_COUNT) {
|
||||
/* Randomize next delay using existing entropy for better jitter */
|
||||
int next_delay = 1 + (collector->samples[collector->sample_index - 1] % 10);
|
||||
wdStart(collector->watchdog, next_delay,
|
||||
(FUNCPTR)entropyWatchdogCallback, (_Vx_usr_arg_t)collector);
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* mixEntropyIntoPool - Mix collected jitter samples into entropy pool using
|
||||
* a simple hash function (Jenkins one-at-a-time)
|
||||
*
|
||||
* This function runs in task context, NOT interrupt context.
|
||||
*******************************************************************************/
|
||||
static void mixEntropyIntoPool(EntropyCollector *collector) {
|
||||
UINT32 hash = 0;
|
||||
int i, j;
|
||||
UINT8 *pool = collector->entropy_pool;
|
||||
|
||||
/* Mix all jitter samples into the entropy pool */
|
||||
for (i = 0; i < ENTROPY_SAMPLE_COUNT && i < collector->sample_index; i++) {
|
||||
UINT32 sample = collector->samples[i];
|
||||
|
||||
/* Jenkins one-at-a-time hash mixing */
|
||||
for (j = 0; j < sizeof(UINT32); j++) {
|
||||
hash += (sample >> (j * 8)) & 0xFF;
|
||||
hash += (hash << 10);
|
||||
hash ^= (hash >> 6);
|
||||
}
|
||||
|
||||
/* XOR sample into pool at rotating position */
|
||||
pool[i % ENTROPY_BUFFER_SIZE] ^= (sample & 0xFF);
|
||||
pool[(i + 1) % ENTROPY_BUFFER_SIZE] ^= ((sample >> 8) & 0xFF);
|
||||
pool[(i + 2) % ENTROPY_BUFFER_SIZE] ^= ((sample >> 16) & 0xFF);
|
||||
pool[(i + 3) % ENTROPY_BUFFER_SIZE] ^= ((sample >> 24) & 0xFF);
|
||||
}
|
||||
|
||||
/* Final mixing pass */
|
||||
for (i = 0; i < ENTROPY_BUFFER_SIZE; i++) {
|
||||
hash += pool[i];
|
||||
hash += (hash << 10);
|
||||
hash ^= (hash >> 6);
|
||||
pool[i] ^= (hash & 0xFF);
|
||||
}
|
||||
|
||||
/* Second mixing pass for avalanche effect */
|
||||
for (i = ENTROPY_BUFFER_SIZE - 1; i >= 0; i--) {
|
||||
hash += pool[i];
|
||||
hash += (hash << 10);
|
||||
hash ^= (hash >> 6);
|
||||
pool[i] ^= (hash & 0xFF);
|
||||
}
|
||||
|
||||
collector->pool_filled = 1;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* collectEntropyFromInterruptJitter - Main function to collect entropy
|
||||
*
|
||||
* This function creates a watchdog timer that samples interrupt jitter
|
||||
* by exploiting timing variations in the system tick interrupt handler.
|
||||
*
|
||||
* Returns: Pointer to entropy buffer (32 bytes) on success, NULL on failure
|
||||
*
|
||||
* Usage example:
|
||||
* UINT8 *entropy = collectEntropyFromInterruptJitter();
|
||||
* if (entropy) {
|
||||
* RAND_add(entropy, 32, 32.0); // Seed OpenSSL with 32 bytes of entropy
|
||||
* free(entropy);
|
||||
* }
|
||||
*
|
||||
* IMPORTANT: This function MUST be called from task context, NOT interrupt context.
|
||||
* The watchdog callback runs in interrupt context, but the collection and mixing
|
||||
* happen in the calling task's context.
|
||||
*******************************************************************************/
|
||||
UINT8* collectEntropyFromInterruptJitter(void) {
|
||||
EntropyCollector *collector;
|
||||
UINT8 *result = NULL;
|
||||
|
||||
|
||||
/*neelimaps*/
|
||||
sysTimestampEnable();
|
||||
UINT32 tick;
|
||||
unsigned long freq;
|
||||
|
||||
/* 2. Get the timestamp value */
|
||||
tick = sysTimestamp();
|
||||
|
||||
/* 3. Print it - Note: %u for unsigned int */
|
||||
printf("sysTimestamp = %u ticks in %s\n", tick, __func__);
|
||||
/*neelimaps*/
|
||||
|
||||
/* Allocate collector structure (in task context - OK to use malloc) */
|
||||
collector = (EntropyCollector*)malloc(sizeof(EntropyCollector));
|
||||
if (collector == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Initialize collector */
|
||||
memset(collector, 0, sizeof(EntropyCollector));
|
||||
collector->last_tick = 0;
|
||||
collector->sample_index = 0;
|
||||
collector->pool_filled = 0;
|
||||
|
||||
/* Create watchdog timer */
|
||||
collector->watchdog = wdCreate();
|
||||
if (collector->watchdog == NULL) {
|
||||
free(collector);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Start the first watchdog - initial delay of 1 tick */
|
||||
if (wdStart(collector->watchdog, 1,
|
||||
(FUNCPTR)entropyWatchdogCallback,
|
||||
(_Vx_usr_arg_t)collector) != OK) {
|
||||
wdDelete(collector->watchdog);
|
||||
free(collector);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Wait for entropy collection to complete.
|
||||
* In a real implementation, you'd want to add a timeout.
|
||||
*/
|
||||
while (collector->sample_index < ENTROPY_SAMPLE_COUNT) {
|
||||
taskDelay(1); /* Yield to let watchdog callbacks run */
|
||||
}
|
||||
|
||||
/* Stop and delete watchdog */
|
||||
wdCancel(collector->watchdog);
|
||||
wdDelete(collector->watchdog);
|
||||
|
||||
/* Mix collected samples into entropy pool */
|
||||
mixEntropyIntoPool(collector);
|
||||
|
||||
/* Allocate and copy result */
|
||||
result = (UINT8*)malloc(ENTROPY_BUFFER_SIZE);
|
||||
if (result) {
|
||||
memcpy(result, collector->entropy_pool, ENTROPY_BUFFER_SIZE);
|
||||
}
|
||||
|
||||
/* Cleanup */
|
||||
free(collector);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void seedOpenSSLWithJitterEntropy(void) {
|
||||
sysTimestampEnable();
|
||||
UINT8 *entropy = collectEntropyFromInterruptJitter();
|
||||
|
||||
if (entropy) {
|
||||
/* Add 32 bytes of entropy with estimated 256 bits of randomness */
|
||||
RAND_add(entropy, ENTROPY_BUFFER_SIZE, ENTROPY_BUFFER_SIZE * 8.0);
|
||||
free(entropy);
|
||||
|
||||
printf("OpenSSL RNG seeded with interrupt jitter entropy\n");
|
||||
} else {
|
||||
printf("Failed to collect entropy from interrupt jitter\n");
|
||||
}
|
||||
}
|
||||
+50
-1
@@ -16,6 +16,9 @@
|
||||
#include "prov/seeding.h"
|
||||
#include <version.h>
|
||||
#include <taskLib.h>
|
||||
#include "sysLib.h"
|
||||
|
||||
extern unsigned char *collectEntropyFromInterruptJitter(void);
|
||||
|
||||
#if defined(OPENSSL_RAND_SEED_NONE)
|
||||
/* none means none */
|
||||
@@ -36,7 +39,7 @@
|
||||
|
||||
int randSecure (void)
|
||||
{
|
||||
return OK;
|
||||
return 1;
|
||||
}
|
||||
|
||||
STATUS randUBytes (unsigned char * randBuf, int numOfBytes)
|
||||
@@ -121,6 +124,50 @@ int ossl_pool_add_nonce_data(RAND_POOL *pool)
|
||||
|
||||
size_t ossl_pool_acquire_entropy(RAND_POOL *pool)
|
||||
{
|
||||
#ifdef VX69_TIMESTAMP_ENTROPY_SUPPORT
|
||||
|
||||
#if defined(OPENSSL_SYS_VXWORKS)
|
||||
/* vxRandLib based entropy method */
|
||||
size_t bytes_needed;
|
||||
unsigned char *original_buffer;
|
||||
|
||||
bytes_needed = ossl_rand_pool_bytes_needed(pool, 1 /*entropy_factor*/);
|
||||
|
||||
if (bytes_needed > 0) {
|
||||
int retryCount = 0;
|
||||
STATUS result = ERROR;
|
||||
unsigned char *buffer;
|
||||
|
||||
buffer = ossl_rand_pool_add_begin(pool, bytes_needed);
|
||||
original_buffer = buffer;
|
||||
size_t needed;
|
||||
needed = bytes_needed;
|
||||
while (needed) {
|
||||
if (needed < 32) {
|
||||
memcpy(buffer,collectEntropyFromInterruptJitter(),needed);
|
||||
needed = 0;
|
||||
}
|
||||
else {
|
||||
memcpy(buffer, collectEntropyFromInterruptJitter(),32);
|
||||
needed -= 32;
|
||||
buffer += 32;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ossl_rand_pool_add_end(pool, bytes_needed, 8 * bytes_needed);
|
||||
return ossl_rand_pool_entropy_available(pool);
|
||||
#else
|
||||
/*
|
||||
* SEED_NONE means none, without randlib we dont have entropy and
|
||||
* rely on it being added externally
|
||||
*/
|
||||
return ossl_rand_pool_entropy_available(pool);
|
||||
#endif /* defined(RAND_SEED_VXRANDLIB) */
|
||||
|
||||
|
||||
#else
|
||||
|
||||
#if defined(OPENSSL_SYS_VXWORKS)
|
||||
/* vxRandLib based entropy method */
|
||||
size_t bytes_needed;
|
||||
@@ -165,4 +212,6 @@ size_t ossl_pool_acquire_entropy(RAND_POOL *pool)
|
||||
*/
|
||||
return ossl_rand_pool_entropy_available(pool);
|
||||
#endif /* defined(RAND_SEED_VXRANDLIB) */
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user