From 3b27b283d9f4dd4fcdf0c5c0da40322d9d5e7582 Mon Sep 17 00:00:00 2001 From: Chris Young Date: Wed, 29 Mar 2017 19:23:41 +0100 Subject: Fix OpenSSL random number generator on AmigaOS This fixes an issue with libcurl 7.53.1 which refuses to connect due to weak random seed (previous versions would connect regardless) This patch is derived from the one used by AmiSSL --- .../m68k-unknown-amigaos/crypto/rand/rand_amiga.c | 182 +++++++++++++++++++++ .../openssl/ppc-amigaos/crypto/rand/rand_amiga.c | 182 +++++++++++++++++++++ .../m68k-unknown-amigaos/crypto.rand.Makefile.p | 14 ++ .../m68k-unknown-amigaos/crypto.rand.rand_unix.c.p | 11 ++ .../openssl/ppc-amigaos/crypto.rand.Makefile.p | 14 ++ .../openssl/ppc-amigaos/crypto.rand.rand_unix.c.p | 11 ++ 6 files changed, 414 insertions(+) create mode 100644 sdk/recipes/files/openssl/m68k-unknown-amigaos/crypto/rand/rand_amiga.c create mode 100644 sdk/recipes/files/openssl/ppc-amigaos/crypto/rand/rand_amiga.c create mode 100644 sdk/recipes/patches/openssl/m68k-unknown-amigaos/crypto.rand.Makefile.p create mode 100644 sdk/recipes/patches/openssl/m68k-unknown-amigaos/crypto.rand.rand_unix.c.p create mode 100644 sdk/recipes/patches/openssl/ppc-amigaos/crypto.rand.Makefile.p create mode 100644 sdk/recipes/patches/openssl/ppc-amigaos/crypto.rand.rand_unix.c.p diff --git a/sdk/recipes/files/openssl/m68k-unknown-amigaos/crypto/rand/rand_amiga.c b/sdk/recipes/files/openssl/m68k-unknown-amigaos/crypto/rand/rand_amiga.c new file mode 100644 index 0000000..cd3f236 --- /dev/null +++ b/sdk/recipes/files/openssl/m68k-unknown-amigaos/crypto/rand/rand_amiga.c @@ -0,0 +1,182 @@ +#include +#include +#include "rand_lcl.h" + +#if defined(OPENSSL_SYS_AMIGAOS3) || defined(OPENSSL_SYS_AMIGAOS4) +#define __USE_INLINE__ 1 + +#include +#include +#include + +/* 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/crypto/rand/rand_amiga.c b/sdk/recipes/files/openssl/ppc-amigaos/crypto/rand/rand_amiga.c new file mode 100644 index 0000000..cd3f236 --- /dev/null +++ b/sdk/recipes/files/openssl/ppc-amigaos/crypto/rand/rand_amiga.c @@ -0,0 +1,182 @@ +#include +#include +#include "rand_lcl.h" + +#if defined(OPENSSL_SYS_AMIGAOS3) || defined(OPENSSL_SYS_AMIGAOS4) +#define __USE_INLINE__ 1 + +#include +#include +#include + +/* 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/patches/openssl/m68k-unknown-amigaos/crypto.rand.Makefile.p b/sdk/recipes/patches/openssl/m68k-unknown-amigaos/crypto.rand.Makefile.p new file mode 100644 index 0000000..623f599 --- /dev/null +++ b/sdk/recipes/patches/openssl/m68k-unknown-amigaos/crypto.rand.Makefile.p @@ -0,0 +1,14 @@ +--- crypto/rand/Makefile 2017-03-29 18:44:57.752006689 +0100 ++++ crypto/rand/Makefile 2017-03-29 18:45:23.976006610 +0100 +@@ -18,9 +18,9 @@ APPS= + + LIB=$(TOP)/libcrypto.a + LIBSRC=md_rand.c randfile.c rand_lib.c rand_err.c rand_egd.c \ +- rand_win.c rand_unix.c rand_os2.c rand_nw.c ++ rand_win.c rand_unix.c rand_os2.c rand_nw.c rand_amiga.c + LIBOBJ=md_rand.o randfile.o rand_lib.o rand_err.o rand_egd.o \ +- rand_win.o rand_unix.o rand_os2.o rand_nw.o ++ rand_win.o rand_unix.o rand_os2.o rand_nw.o rand_amiga.o + + SRC= $(LIBSRC) + diff --git a/sdk/recipes/patches/openssl/m68k-unknown-amigaos/crypto.rand.rand_unix.c.p b/sdk/recipes/patches/openssl/m68k-unknown-amigaos/crypto.rand.rand_unix.c.p new file mode 100644 index 0000000..2caae57 --- /dev/null +++ b/sdk/recipes/patches/openssl/m68k-unknown-amigaos/crypto.rand.rand_unix.c.p @@ -0,0 +1,11 @@ +--- crypto/rand/rand_unix.c 2017-01-26 13:22:03.000000000 +0000 ++++ crypto/rand/rand_unix.c 2017-03-29 17:42:59.932017575 +0100 +@@ -116,7 +116,7 @@ + #include + #include "rand_lcl.h" + +-#if !(defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_VMS) || defined(OPENSSL_SYS_OS2) || defined(OPENSSL_SYS_VXWORKS) || defined(OPENSSL_SYS_NETWARE)) ++#if !(defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_VMS) || defined(OPENSSL_SYS_OS2) || defined(OPENSSL_SYS_VXWORKS) || defined(OPENSSL_SYS_NETWARE) || defined(OPENSSL_SYS_AMIGAOS4) || defined(OPENSSL_SYS_AMIGAOS3)) + + # include + # include diff --git a/sdk/recipes/patches/openssl/ppc-amigaos/crypto.rand.Makefile.p b/sdk/recipes/patches/openssl/ppc-amigaos/crypto.rand.Makefile.p new file mode 100644 index 0000000..623f599 --- /dev/null +++ b/sdk/recipes/patches/openssl/ppc-amigaos/crypto.rand.Makefile.p @@ -0,0 +1,14 @@ +--- crypto/rand/Makefile 2017-03-29 18:44:57.752006689 +0100 ++++ crypto/rand/Makefile 2017-03-29 18:45:23.976006610 +0100 +@@ -18,9 +18,9 @@ APPS= + + LIB=$(TOP)/libcrypto.a + LIBSRC=md_rand.c randfile.c rand_lib.c rand_err.c rand_egd.c \ +- rand_win.c rand_unix.c rand_os2.c rand_nw.c ++ rand_win.c rand_unix.c rand_os2.c rand_nw.c rand_amiga.c + LIBOBJ=md_rand.o randfile.o rand_lib.o rand_err.o rand_egd.o \ +- rand_win.o rand_unix.o rand_os2.o rand_nw.o ++ rand_win.o rand_unix.o rand_os2.o rand_nw.o rand_amiga.o + + SRC= $(LIBSRC) + diff --git a/sdk/recipes/patches/openssl/ppc-amigaos/crypto.rand.rand_unix.c.p b/sdk/recipes/patches/openssl/ppc-amigaos/crypto.rand.rand_unix.c.p new file mode 100644 index 0000000..2caae57 --- /dev/null +++ b/sdk/recipes/patches/openssl/ppc-amigaos/crypto.rand.rand_unix.c.p @@ -0,0 +1,11 @@ +--- crypto/rand/rand_unix.c 2017-01-26 13:22:03.000000000 +0000 ++++ crypto/rand/rand_unix.c 2017-03-29 17:42:59.932017575 +0100 +@@ -116,7 +116,7 @@ + #include + #include "rand_lcl.h" + +-#if !(defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_VMS) || defined(OPENSSL_SYS_OS2) || defined(OPENSSL_SYS_VXWORKS) || defined(OPENSSL_SYS_NETWARE)) ++#if !(defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_VMS) || defined(OPENSSL_SYS_OS2) || defined(OPENSSL_SYS_VXWORKS) || defined(OPENSSL_SYS_NETWARE) || defined(OPENSSL_SYS_AMIGAOS4) || defined(OPENSSL_SYS_AMIGAOS3)) + + # include + # include -- cgit v1.2.3