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))
|
if (!CRYPTO_atomic_or(&optsdone, opts, &tmp, optsdone_lock))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
RAND_set_rand_method(RAND_OpenSSL());
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -820,9 +822,7 @@ int ipcrypto_init_internal(SEM_ID semId)
|
|||||||
{
|
{
|
||||||
init = 1;
|
init = 1;
|
||||||
|
|
||||||
#ifndef _WRS_CONFIG_OPENSSL_FIPSMODULE
|
|
||||||
RAND_set_rand_method(vxRandLibMeth());
|
|
||||||
#endif
|
|
||||||
|
|
||||||
OpenSSL_add_all_algorithms();
|
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 "prov/seeding.h"
|
||||||
#include <version.h>
|
#include <version.h>
|
||||||
#include <taskLib.h>
|
#include <taskLib.h>
|
||||||
|
#include "sysLib.h"
|
||||||
|
|
||||||
|
extern unsigned char *collectEntropyFromInterruptJitter(void);
|
||||||
|
|
||||||
#if defined(OPENSSL_RAND_SEED_NONE)
|
#if defined(OPENSSL_RAND_SEED_NONE)
|
||||||
/* none means none */
|
/* none means none */
|
||||||
@@ -36,7 +39,7 @@
|
|||||||
|
|
||||||
int randSecure (void)
|
int randSecure (void)
|
||||||
{
|
{
|
||||||
return OK;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
STATUS randUBytes (unsigned char * randBuf, int numOfBytes)
|
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)
|
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)
|
#if defined(OPENSSL_SYS_VXWORKS)
|
||||||
/* vxRandLib based entropy method */
|
/* vxRandLib based entropy method */
|
||||||
size_t bytes_needed;
|
size_t bytes_needed;
|
||||||
@@ -165,4 +212,6 @@ size_t ossl_pool_acquire_entropy(RAND_POOL *pool)
|
|||||||
*/
|
*/
|
||||||
return ossl_rand_pool_entropy_available(pool);
|
return ossl_rand_pool_entropy_available(pool);
|
||||||
#endif /* defined(RAND_SEED_VXRANDLIB) */
|
#endif /* defined(RAND_SEED_VXRANDLIB) */
|
||||||
|
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user