Since a websocket handshake hashes only 16 bytes you don't need an
implementation that provides incremental updates. The attached SHA1
is slower than the openssl implementation, but quite short.
Just in case.


-------- Weitergeleitete Nachricht --------
Von: "Gausmann, David" <david.gausm...@measx.com>
Antwort an: libmicrohttpd development and user mailinglist <
libmicrohttpd@gnu.org>
An: libmicrohttpd@gnu.org <libmicrohttpd@gnu.org>
Betreff: [libmicrohttpd] Update for websocket library
Datum: Sun, 17 Oct 2021 18:20:17 +0000

Hi @all,
some months ago I wrote an additional library for libmicrohttpd to add
support for the websocket protocol.Christian and Evgeny added that
library with the configure flag “--with-experimental”.There were still
some tasks to do, but now I am finally done with them.
In the attachment you find the patch file, which must be applied to get
the final version of the API.
For short it contains the following changes:- added API documentation
to libmicrohttpd.texi- added websocket tutorial chapter to
libmicrohttpd-tutorial and an much easier example for the tutorial-
added additional helper functions to ease the HTTP websocket handshake-
the code can now be compiled on Linux without errors :-)- changed
sha1.c and sha1.h to the files provided by Evgeny (I replaced those
files in src/microhttpd_ws/ with the files from src/microhttpd/ - maybe
there is a smarter way...?)- removed dependency for "htons" and "htonl"
(these functions are now implemented in MHD_websocket.c; no need for
OS-dependent files anymore)- added an additional test script for
testing of the library with any webbrowser (for manual practice test)-
several bugfixes- parameters renamed- special things clarified
(fragmentation, RNG for client mode)
The new version of the API is at some points incompatible with the old
version, but since it was in an experimental phase and it didn't
compile on Linux, I guess this shouldn't bother anyone.From my point of
view, I am now finished with the library and it could go out of
experimental.Maybe it would be good if anyone could give it a review.

Kind RegardsDavid Gausmann

measX GmbH & Co. KG
David GausmannFachinformatiker Anwendungsentwicklung
|  Testdatenmanagement und AuswertesystemeBüro: Aachen (Pascalstraße
67, 52076 Aachen-Oberforstbach)Telefon: +49 (0) 2166 9520-170E-
Mail:  david.gausm...@measx.com | Web: https://www.measx.com


measX GmbH & Co. KG | Trompeterallee 110 | 41189 Mönchengladbach |
Germany | Telefon: +49 (0) 2166 9520-0 | Fax: +49 (0) 2166 9520-20Sitz
der Gesellschaft: Mönchengladbach | Registergericht: AG Mönchengladbach
(HRA 5623) |  USt-IdNr: DE 814281560Geschäftsführer: Dr. Joachim
Hilsmann | Stadtsparkasse Mönchengladbach IBAN: DE84310500000000276600
| BIC-Swift: MG LS DE 33Persönlich haftende Gesellschafterin: measX
Verwaltungsgesellschaft mbH | Registergericht: AG Mönchengladbach (HRB
10947)_________________________________________________________________
_________________________________________________

void sha1_encode( const uint8_t *data, size_t databytes, uint8_t digest[20] )
{
    uint64_t i, loopcount, databits, tailbytes;
    uint8_t datatail[128] = {0};
    uint32_t H[] = { 0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476, 0xC3D2E1F0 };
    uint32_t W[80];
    uint64_t idx, widx, didx = 0;

    /* Pre-processing of data tail (includes padding to fill out 512-bit chunk):
       Add bit '1' to end of message (big-endian)
       Add 64-bit message length in bits at very end (big-endian) */
    loopcount = (databytes + 8) / 64 + 1;
    databits = databytes * 8;
    tailbytes = 64 * loopcount - databytes;
    datatail[0] = 0x80;
    datatail[tailbytes - 8] = uint8_t((databits >> 56) & 0xFF);
    datatail[tailbytes - 7] = uint8_t((databits >> 48) & 0xFF);
    datatail[tailbytes - 6] = uint8_t((databits >> 40) & 0xFF);
    datatail[tailbytes - 5] = uint8_t((databits >> 32) & 0xFF);
    datatail[tailbytes - 4] = uint8_t((databits >> 24) & 0xFF);
    datatail[tailbytes - 3] = uint8_t((databits >> 16) & 0xFF);
    datatail[tailbytes - 2] = uint8_t((databits >>  8) & 0xFF);
    datatail[tailbytes - 1] = uint8_t((databits >>  0) & 0xFF);
    /* Process each 512-bit chunk */
    for( i=0; i < loopcount; ++i )
    {
        uint32_t a = H[0];
        uint32_t b = H[1];
        uint32_t c = H[2];
        uint32_t d = H[3];
        uint32_t e = H[4];
        uint32_t f=0, k=0, temp;

        /* Compute all elements in W */
        memset( W, 0, 80 * sizeof(uint32_t) );
        /* Break 512-bit chunk into sixteen 32-bit, big endian words */
        for( widx=0; widx <= 15; ++widx )
        {
            int wcount = 24;
            /* Copy byte-per byte from specified buffer */
            while( didx < databytes && wcount >= 0 )
            {
                W[widx] += (((uint32_t)data[didx]) << wcount);
                didx++;
                wcount -= 8;
            }
            /* Fill out W with padding as needed */
            while( wcount >= 0 )
            {
                W[widx] += (((uint32_t)datatail[didx - databytes]) << wcount);
                didx++;
                wcount -= 8;
            }
        }
        /* Extend the sixteen 32-bit words into eighty 32-bit words, with potential optimization from:
           "Improving the Performance of the Secure Hash Algorithm (SHA-1)" by Max Locktyukhin */
#define SHA1ROTATELEFT(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
        for( widx = 16; widx <= 31; ++widx )
        {
            W[widx] = SHA1ROTATELEFT( (W[widx - 3] ^ W[widx - 8] ^ W[widx - 14] ^ W[widx - 16]), 1 );
        }
        for( widx = 32; widx <= 79; ++widx )
        {
            W[widx] = SHA1ROTATELEFT( (W[widx - 6] ^ W[widx - 16] ^ W[widx - 28] ^ W[widx - 32]), 2 );
        }
        /* Main loop */
        for( idx=0; idx <= 79; ++idx )
        {
            if( idx <= 19 )
            {
                f = (b & c) | ((~b) & d);
                k = 0x5A827999;
            }
            else if( idx >= 20 && idx <= 39 )
            {
                f = b ^ c ^ d;
                k = 0x6ED9EBA1;
            }
            else if( idx >= 40 && idx <= 59 )
            {
                f = (b & c) | (b & d) | (c & d);
                k = 0x8F1BBCDC;
            }
            else if( idx >= 60 && idx <= 79 )
            {
                f = b ^ c ^ d;
                k = 0xCA62C1D6;
            }
            temp = SHA1ROTATELEFT(a, 5) + f + e + k + W[idx];
            e = d;
            d = c;
            c = SHA1ROTATELEFT(b, 30);
            b = a;
            a = temp;
        }
        H[0] += a;
        H[1] += b;
        H[2] += c;
        H[3] += d;
        H[4] += e;
    }
    /* Store binary digest in supplied buffer */
    for( i=0; i < 5; ++i )
    {
        digest[i * 4 + 0] = (uint8_t) (H[i] >> 24);
        digest[i * 4 + 1] = (uint8_t) (H[i] >> 16);
        digest[i * 4 + 2] = (uint8_t) (H[i] >> 8);
        digest[i * 4 + 3] = (uint8_t) (H[i]);
    }
}

Reply via email to