diff options
author | John-Mark Bell <jmb@netsurf-browser.org> | 2022-11-02 22:12:58 +0000 |
---|---|---|
committer | John-Mark Bell <jmb@netsurf-browser.org> | 2022-11-02 23:39:31 +0000 |
commit | 7ff2458c536cad82bd0b589abbef1ec3770778ee (patch) | |
tree | ae2fe33d1957b99d4ca48e44ec0ffc3b7cf36882 | |
parent | c6bed28c3416c86995ec584f33f01d9e32008c5a (diff) | |
download | toolchains-7ff2458c536cad82bd0b589abbef1ec3770778ee.tar.gz toolchains-7ff2458c536cad82bd0b589abbef1ec3770778ee.tar.bz2 |
OpenSSL/ppc-amigaos: rework entropy gathering for OpenSSL 3
4 files changed, 287 insertions, 191 deletions
diff --git a/sdk/recipes/files/openssl/ppc-amigaos/crypto/rand/rand_amiga.c b/sdk/recipes/files/openssl/ppc-amigaos/crypto/rand/rand_amiga.c deleted file mode 100644 index cd3f236..0000000 --- a/sdk/recipes/files/openssl/ppc-amigaos/crypto/rand/rand_amiga.c +++ /dev/null @@ -1,182 +0,0 @@ -#include <openssl/rand.h> -#include <openssl/sha.h> -#include "rand_lcl.h" - -#if defined(OPENSSL_SYS_AMIGAOS3) || defined(OPENSSL_SYS_AMIGAOS4) -#define __USE_INLINE__ 1 - -#include <proto/exec.h> -#include <proto/timer.h> -#include <devices/timer.h> - -/* Maximum number of attempts to get a delay of 1 microsecond that is not equal to 0 */ -#define MAX_ATTEMPTS 1000 - -#ifdef __amigaos4__ - -#ifdef CreateMsgPort -#undef CreateMsgPort -#endif -#define CreateMsgPort() AllocSysObject(ASOT_PORT,NULL) -#ifdef DeleteMsgPort -#undef DeleteMsgPort -#endif -#define DeleteMsgPort(msgPort) FreeSysObject(ASOT_PORT,msgPort) -#ifdef CreateIORequest -#undef CreateIORequest -#endif -#define CreateIORequest(ioReplyPort,size) AllocSysObjectTags(ASOT_IOREQUEST,ASOIOR_ReplyPort,ioReplyPort,ASOIOR_Size,size,TAG_DONE) -#ifdef DeleteIORequest -#undef DeleteIORequest -#endif -#define DeleteIORequest(ioReq) FreeSysObject(ASOT_IOREQUEST,ioReq) - -#else - -#define GetInterface(a, b, c, d) 1 -#define DropInterface(x) - -/* OS3 has a different but compatible TimeVal definition */ -struct TimeVal -{ - uint32 Seconds; - uint32 Microseconds; -}; - -#endif /* !__amigaos4__ */ - -int RAND_poll(void) -{ - unsigned char temp_buffer[SHA_DIGEST_LENGTH], data_buffer[SHA_DIGEST_LENGTH]; - struct MsgPort *port = NULL; - double entropy_added = 0; - struct TimeRequest *time_request = NULL; -#ifdef __amigaos4__ - struct IOStdReq *entropy_request = NULL; - - if ((port = CreateMsgPort()) - && (entropy_request = (struct IOStdReq *)CreateIORequest(port, sizeof(*entropy_request)))) - { - if (OpenDevice(TIMERNAME, UNIT_ENTROPY, (struct IORequest *)entropy_request, 0) == 0) - { - while(entropy_added < ENTROPY_NEEDED) - { - entropy_request->io_Command = TR_READENTROPY; - entropy_request->io_Data = &temp_buffer[0]; - entropy_request->io_Length = sizeof(temp_buffer); - - if (DoIO((struct IORequest *)entropy_request) == 0) - { - SHA1(&temp_buffer[0], sizeof(temp_buffer), &data_buffer[0]); - RAND_add(&data_buffer[0], sizeof(data_buffer), sizeof(data_buffer)); - entropy_added += sizeof(data_buffer); - } - else - break; - } - - CloseDevice((struct IORequest *)entropy_request); - } - } - - DeleteIORequest((struct IORequest *)entropy_request); -#endif /* __amigaos4__ */ - - /* The following block will be used on "classic" machines. It does not generate - * a high degree of randomness, but it does the job since RAND_poll is - * called only once by OpenSSL to generate a 32 byte seed. - */ - if (entropy_added < ENTROPY_NEEDED - && (port || (port = CreateMsgPort())) - && (time_request = (struct TimeRequest *)CreateIORequest(port, sizeof(*time_request)))) - { - if (OpenDevice(TIMERNAME, UNIT_VBLANK, (struct IORequest *)time_request, 0) == 0) - { - #if defined(__amigaos4__) - struct TimerIFace *ITimer = NULL; - #endif - struct Device *TimerBase; - - if ((TimerBase = time_request->Request.io_Device) - #if defined(__amigaos4__) - && (ITimer = (struct TimerIFace *)GetInterface((struct Library *)TimerBase, "main", 1, NULL)) - #endif - ) - { - struct EClockVal curr_eclock; - ULONG prev_ev_lo = 0; - struct TimeVal tv; - int i, attempt; - BOOL aborted; - - ReadEClock(&curr_eclock); - aborted = FALSE; - - while(!aborted && entropy_added < ENTROPY_NEEDED) - { - for(i = 0; - !aborted && i < (int)sizeof(temp_buffer) - (int)sizeof(ULONG); - i++) - { - attempt = 0; - - /* Ask for a one microsecond delay and measure the time - * the delay actually took. - */ - do - { - time_request->Request.io_Command = TR_ADDREQUEST; - time_request->Time.Seconds = 0; - time_request->Time.Microseconds = 1; - - if (DoIO((struct IORequest *)time_request) == 0) - { - prev_ev_lo = curr_eclock.ev_lo; - ReadEClock(&curr_eclock); - - attempt++; - } - else - aborted = TRUE; - } while(!aborted && prev_ev_lo == 0 && attempt < MAX_ATTEMPTS); - - if (attempt >= MAX_ATTEMPTS) - aborted = TRUE; - - /* Since we are going for randomness, ev_hi is irrelevant */ - temp_buffer[i] = (unsigned char)(curr_eclock.ev_lo - prev_ev_lo); - } - - GetSysTime(&tv); - - if (sizeof(temp_buffer) > sizeof(ULONG)) - *(ULONG *)&temp_buffer[sizeof(temp_buffer) - sizeof(ULONG)] - = tv.Microseconds; - - /* Shuffle the bits around and specify that about - * one fourth of it adds to the entropy. - */ - if (!aborted) - { - SHA1(&temp_buffer[0], sizeof(temp_buffer), &data_buffer[0]); - RAND_add(&data_buffer[0], sizeof(data_buffer), (double)sizeof(data_buffer) / 4); - entropy_added += sizeof(data_buffer) / 4; - } - } - } - - #if defined(__amigaos4__) - DropInterface((struct Interface *)ITimer); - #endif - CloseDevice((struct IORequest *)time_request); - } - } - - DeleteIORequest((struct IORequest *)time_request); - - DeleteMsgPort(port); - - return(entropy_added >= ENTROPY_NEEDED); -} - -#endif /* OPENSSL_SYS_AMIGA */ diff --git a/sdk/recipes/files/openssl/ppc-amigaos/providers/implementations/rands/seeding/rand_amiga.c b/sdk/recipes/files/openssl/ppc-amigaos/providers/implementations/rands/seeding/rand_amiga.c new file mode 100644 index 0000000..ed315ed --- /dev/null +++ b/sdk/recipes/files/openssl/ppc-amigaos/providers/implementations/rands/seeding/rand_amiga.c @@ -0,0 +1,275 @@ +#include "internal/cryptlib.h" +#include <openssl/rand.h> +#include <openssl/sha.h> +#include "crypto/rand_pool.h" +#include "crypto/rand.h" +#include "prov/seeding.h" + +#if defined(OPENSSL_SYS_AMIGAOS3) || defined(OPENSSL_SYS_AMIGAOS4) + +# ifndef OPENSSL_RAND_SEED_OS +# error "Unsupported seeding method configured; must be os" +# endif + +#define __USE_INLINE__ 1 + +#include <sys/types.h> +#include <time.h> +#include <unistd.h> + +#include <proto/exec.h> +#include <proto/timer.h> +#include <devices/timer.h> + +/* Maximum number of attempts to get a delay of 1 microsecond that is not equal to 0 */ +#define MAX_ATTEMPTS 1000 + +#ifdef __amigaos4__ + +#ifdef CreateMsgPort +#undef CreateMsgPort +#endif +#define CreateMsgPort() AllocSysObject(ASOT_PORT,NULL) +#ifdef DeleteMsgPort +#undef DeleteMsgPort +#endif +#define DeleteMsgPort(msgPort) FreeSysObject(ASOT_PORT,msgPort) +#ifdef CreateIORequest +#undef CreateIORequest +#endif +#define CreateIORequest(ioReplyPort,size) AllocSysObjectTags(ASOT_IOREQUEST,ASOIOR_ReplyPort,ioReplyPort,ASOIOR_Size,size,TAG_DONE) +#ifdef DeleteIORequest +#undef DeleteIORequest +#endif +#define DeleteIORequest(ioReq) FreeSysObject(ASOT_IOREQUEST,ioReq) + +#else + +#define GetInterface(a, b, c, d) 1 +#define DropInterface(x) + +/* OS3 has a different but compatible TimeVal definition */ +struct TimeVal +{ + uint32 Seconds; + uint32 Microseconds; +}; + +#endif /* !__amigaos4__ */ + +size_t ossl_pool_acquire_entropy(RAND_POOL *pool) +{ + unsigned char temp_buffer[SHA_DIGEST_LENGTH], data_buffer[SHA_DIGEST_LENGTH]; + struct MsgPort *port = NULL; + size_t bytes_needed; + size_t entropy_available = 0; + struct TimeRequest *time_request = NULL; +#ifdef __amigaos4__ + struct IOStdReq *entropy_request = NULL; + + bytes_needed = ossl_rand_pool_bytes_needed(pool, 1); + + if ((port = CreateMsgPort()) + && (entropy_request = (struct IOStdReq *)CreateIORequest(port, sizeof(*entropy_request)))) + { + if (OpenDevice(TIMERNAME, UNIT_ENTROPY, (struct IORequest *)entropy_request, 0) == 0) + { + while(bytes_needed > 0) + { + entropy_request->io_Command = TR_READENTROPY; + entropy_request->io_Data = &temp_buffer[0]; + entropy_request->io_Length = sizeof(temp_buffer); + + if (DoIO((struct IORequest *)entropy_request) == 0) + { + unsigned char *buffer; + size_t bytes = (bytes_needed < sizeof(data_buffer) ? bytes_needed : sizeof(data_buffer)); + + buffer = ossl_rand_pool_add_begin(pool, bytes_needed); + SHA1(&temp_buffer[0], sizeof(temp_buffer), &data_buffer[0]); + memcpy(buffer, data_buffer, bytes); + ossl_rand_pool_add_end(pool, bytes, 8 * bytes); + bytes_needed -= bytes; + } + else + break; + } + + CloseDevice((struct IORequest *)entropy_request); + } + } + + DeleteIORequest((struct IORequest *)entropy_request); + + entropy_available = ossl_rand_pool_entropy_available(pool); + if (entropy_available > 0) + return entropy_available; +#endif /* __amigaos4__ */ + + /* The following block will be used on "classic" machines. It does not generate + * a high degree of randomness, but it does the job since RAND_poll is + * called only once by OpenSSL to generate a 32 byte seed. + */ + + bytes_needed = ossl_rand_pool_bytes_needed(pool, 1); + + if (bytes_needed > 0 + && (port || (port = CreateMsgPort())) + && (time_request = (struct TimeRequest *)CreateIORequest(port, sizeof(*time_request)))) + { + if (OpenDevice(TIMERNAME, UNIT_VBLANK, (struct IORequest *)time_request, 0) == 0) + { + #if defined(__amigaos4__) + struct TimerIFace *ITimer = NULL; + #endif + struct Device *TimerBase; + + if ((TimerBase = time_request->Request.io_Device) + #if defined(__amigaos4__) + && (ITimer = (struct TimerIFace *)GetInterface((struct Library *)TimerBase, "main", 1, NULL)) + #endif + ) + { + struct EClockVal curr_eclock; + ULONG prev_ev_lo = 0; + struct TimeVal tv; + int i, attempt; + BOOL aborted; + + ReadEClock(&curr_eclock); + aborted = FALSE; + + while(!aborted && bytes_needed > 0) + { + for(i = 0; + !aborted && i < (int)sizeof(temp_buffer) - (int)sizeof(ULONG); + i++) + { + attempt = 0; + + /* Ask for a one microsecond delay and measure the time + * the delay actually took. + */ + do + { + time_request->Request.io_Command = TR_ADDREQUEST; + time_request->Time.Seconds = 0; + time_request->Time.Microseconds = 1; + + if (DoIO((struct IORequest *)time_request) == 0) + { + prev_ev_lo = curr_eclock.ev_lo; + ReadEClock(&curr_eclock); + + attempt++; + } + else + aborted = TRUE; + } while(!aborted && prev_ev_lo == 0 && attempt < MAX_ATTEMPTS); + + if (attempt >= MAX_ATTEMPTS) + aborted = TRUE; + + /* Since we are going for randomness, ev_hi is irrelevant */ + temp_buffer[i] = (unsigned char)(curr_eclock.ev_lo - prev_ev_lo); + } + + GetSysTime(&tv); + + if (sizeof(temp_buffer) > sizeof(ULONG)) + *(ULONG *)&temp_buffer[sizeof(temp_buffer) - sizeof(ULONG)] + = tv.Microseconds; + + /* Shuffle the bits around and specify that about + * one fourth of it adds to the entropy. + */ + if (!aborted) + { + unsigned char *buffer; + size_t bytes = (bytes_needed < sizeof(data_buffer) ? bytes_needed : sizeof(data_buffer)); + + SHA1(&temp_buffer[0], sizeof(temp_buffer), &data_buffer[0]); + + ossl_rand_pool_add_end(pool, bytes, (sizeof(data_buffer) / 4) * 8); + bytes_needed -= bytes; + } + } + } + + #if defined(__amigaos4__) + DropInterface((struct Interface *)ITimer); + #endif + CloseDevice((struct IORequest *)time_request); + } + } + + DeleteIORequest((struct IORequest *)time_request); + + DeleteMsgPort(port); + + return ossl_rand_pool_entropy_available(pool); +} + +int ossl_pool_add_nonce_data(RAND_POOL *pool) +{ + struct { + pid_t pid; + CRYPTO_THREAD_ID tid; + uint64_t time; + } data; + + /* Erase the entire structure including any padding */ + memset(&data, 0, sizeof(data)); + + /* + * Add process id, thread id, and a high resolution timestamp to + * ensure that the nonce is unique with high probability for + * different process instances. + */ + data.pid = getpid(); + data.tid = CRYPTO_THREAD_get_current_id(); + /*XXX: can this be improved? */ + data.time = time(NULL); + + return ossl_rand_pool_add(pool, (unsigned char *)&data, sizeof(data), 0); +} + +int ossl_rand_pool_add_additional_data(RAND_POOL *pool) +{ + struct { + int fork_id; + CRYPTO_THREAD_ID tid; + uint64_t time; + } data; + + /* Erase the entire structure including any padding */ + memset(&data, 0, sizeof(data)); + + /* + * Add some noise from the thread id and a high resolution timer. + * The fork_id adds some extra fork-safety. + * The thread id adds a little randomness if the drbg is accessed + * concurrently (which is the case for the <master> drbg). + */ + data.fork_id = openssl_get_fork_id(); + data.tid = CRYPTO_THREAD_get_current_id(); + /*XXX: can this be improved? */ + data.time = (uint64_t) time(NULL); + + return ossl_rand_pool_add(pool, (unsigned char *)&data, sizeof(data), 0); +} + +int ossl_rand_pool_init(void) +{ + return 1; +} + +void ossl_rand_pool_cleanup(void) +{ +} + +void ossl_rand_pool_keep_random_devices_open(int keep) +{ +} + +#endif /* OPENSSL_SYS_AMIGA */ diff --git a/sdk/recipes/patches/openssl/ppc-amigaos/crypto.rand.build.info.p b/sdk/recipes/patches/openssl/ppc-amigaos/crypto.rand.build.info.p deleted file mode 100644 index 58b672f..0000000 --- a/sdk/recipes/patches/openssl/ppc-amigaos/crypto.rand.build.info.p +++ /dev/null @@ -1,9 +0,0 @@ ---- crypto/rand/build.info.orig 2017-11-22 11:36:06.585363219 +0000 -+++ crypto/rand/build.info 2017-11-22 11:36:39.267232034 +0000 -@@ -1,4 +1,4 @@ - LIBS=../../libcrypto - SOURCE[../../libcrypto]=\ -- md_rand.c randfile.c rand_lib.c rand_err.c rand_egd.c \ -- rand_win.c rand_unix.c rand_vms.c -+ md_rand.c randfile.c rand_lib.c rand_err.c rand_amiga.c \ -+ rand_egd.c rand_win.c rand_unix.c rand_vms.c diff --git a/sdk/recipes/patches/openssl/ppc-amigaos/providers.implementations.rands.seeding.build.info.p b/sdk/recipes/patches/openssl/ppc-amigaos/providers.implementations.rands.seeding.build.info.p new file mode 100644 index 0000000..c887eff --- /dev/null +++ b/sdk/recipes/patches/openssl/ppc-amigaos/providers.implementations.rands.seeding.build.info.p @@ -0,0 +1,12 @@ +--- providers/implementations/rands/seeding/build.info.orig 2017-11-21 22:49:00.185608040 +0000 ++++ providers/implementations/rands/seeding/build.info 2017-11-21 22:49:21.488219518 +0000 +@@ -5,6 +5,9 @@ + IF[{- $config{target} =~ /vms/i -}] + $COMMON=$COMMON rand_vms.c + ENDIF ++IF[{- $config{target} =~ /amiga/i -}] ++ $COMMON=$COMMON rand_amiga.c ++ENDIF + + SOURCE[../../../libdefault.a]=$COMMON + |