Skip to content

Commit b54af04

Browse files
committed
SHA512 HMAC + fix fio_http_is_clean
1 parent 5030cda commit b54af04

File tree

5 files changed

+418
-6
lines changed

5 files changed

+418
-6
lines changed

fio-stl.h

Lines changed: 208 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24034,7 +24034,7 @@ SFUNC void fio_sha512_consume(fio_sha512_s *restrict h,
2403424034
const size_t byte2copy = 128UL - offset;
2403524035
fio_memcpy127x(h->cache.u8 + offset, r, byte2copy);
2403624036
fio___sha512_round(&h->hash, h->cache.u8);
24037-
FIO_MEMSET(h->cache.u8, 0, 128);
24037+
h->cache = (fio_u1024){0};
2403824038
r += byte2copy;
2403924039
len -= byte2copy;
2404024040
}
@@ -24055,7 +24055,7 @@ SFUNC fio_u512 fio_sha512_finalize(fio_sha512_s *h) {
2405524055
h->cache.u8[remainder] = 0x80U; /* set the 1 bit at the left most position */
2405624056
if ((remainder) > 112) { /* make sure there's room to attach `total_len` */
2405724057
fio___sha512_round(&h->hash, h->cache.u8);
24058-
FIO_MEMSET(h->cache.u8, 0, 128);
24058+
h->cache = (fio_u1024){0};
2405924059
}
2406024060
h->cache.u64[15] = fio_lton64((total << 3));
2406124061
fio___sha512_round(&h->hash, h->cache.u8);
@@ -24065,6 +24065,66 @@ SFUNC fio_u512 fio_sha512_finalize(fio_sha512_s *h) {
2406524065
return h->hash;
2406624066
}
2406724067

24068+
/* *****************************************************************************
24069+
HMAC
24070+
***************************************************************************** */
24071+
24072+
/**
24073+
* HMAC-SHA512, resulting in a 64 byte authentication code.
24074+
*
24075+
* Keys are limited to 128 bytes.
24076+
*
24077+
* TODO: FIXME!
24078+
*/
24079+
SFUNC fio_u512 fio_sha512_hmac(const void *key,
24080+
uint64_t key_len,
24081+
const void *msg,
24082+
uint64_t msg_len) {
24083+
fio_sha512_s inner = fio_sha512_init();
24084+
fio_u2048 k;
24085+
/* copy key */
24086+
if (key_len > 128)
24087+
goto key_too_long;
24088+
if (key_len == 128)
24089+
fio_memcpy128(k.u8, key);
24090+
else {
24091+
k.u1024[0] = (fio_u1024){0};
24092+
fio_memcpy127x(k.u8, key, key_len);
24093+
}
24094+
/* prepare inner key */
24095+
for (size_t i = 0; i < 16; ++i)
24096+
k.u64[i] ^= (uint64_t)0x3636363636363636ULL;
24097+
/* hash of inner key + msg */
24098+
if (1) {
24099+
/* consume key block */
24100+
fio___sha512_round(&inner.hash, k.u8);
24101+
/* consume data */
24102+
uint8_t *buf = (uint8_t *)msg;
24103+
for (size_t i = 127; i < msg_len; (i += 128), (buf += 128))
24104+
fio___sha512_round(&inner.hash, buf);
24105+
if ((msg_len & 127)) {
24106+
inner.cache = (fio_u1024){0};
24107+
fio_memcpy127x(inner.cache.u8, buf, msg_len);
24108+
}
24109+
inner.total_len = 128 + msg_len;
24110+
} else { /* ... same as ... */
24111+
fio_sha512_consume(&inner, k.u8, 128);
24112+
fio_sha512_consume(&inner, msg, msg_len);
24113+
}
24114+
/* finalize SHA512 and append to end of key */
24115+
k.u512[2] = fio_sha512_finalize(&inner);
24116+
/* switch key to outer key */
24117+
for (size_t i = 0; i < 16; ++i)
24118+
k.u64[i] ^=
24119+
((uint64_t)0x3636363636363636ULL ^ (uint64_t)0x5C5C5C5C5C5C5C5CULL);
24120+
/* hash outer key with inner hash appended and return */
24121+
return fio_sha512(k.u8, 192);
24122+
24123+
key_too_long:
24124+
k.u512[3] = fio_sha512(key, key_len);
24125+
return fio_sha512_hmac(k.u512[3].u8, sizeof(k.u512[3]), msg, msg_len);
24126+
}
24127+
2406824128
/* *****************************************************************************
2406924129
Cleanup
2407024130
***************************************************************************** */
@@ -43230,7 +43290,7 @@ Handler State
4323043290

4323143291
SFUNC int fio_http_is_clean(fio_http_s *h) {
4323243292
FIO_ASSERT_DEBUG(h, "NULL HTTP handler!");
43233-
return !h->state;
43293+
return !(h->state & (~FIO_HTTP_STATE_COOKIES_PARSED));
4323443294
}
4323543295

4323643296
/** Returns true if the HTTP handle's response was sent. */
@@ -56757,10 +56817,105 @@ FIO_SFUNC void FIO_NAME_TEST(stl, sha2)(void) {
5675756817
"\x18\xD2\x87\x7E\xEC\x2F\x63\xB9\x31\xBD\x47\x41\x7A\x81"
5675856818
"\xA5\x38\x32\x7A\xF9\x27\xDA\x3E",
5675956819
},
56820+
{
56821+
.str = (char *)"There was an Old Man on some rocks, Who shut his "
56822+
"wife up in a box; When she said, \"Let me out,\" He "
56823+
"exclaimed, \"Without doubt, You will pass all your "
56824+
"life in that box.\"",
56825+
},
56826+
{
56827+
.str = (char *)"Once upon a time, there was a little secret garden "
56828+
"locked away behind a little mouse hole in Agatha's "
56829+
"kitchen. The mouse hole was tucked away behind the "
56830+
"fridge.",
56831+
},
56832+
{
56833+
.str = (char *)"It was a loud fridge, that would klunk happily "
56834+
"through the night, humming softly to mask the sound "
56835+
"of chippering birds from t...",
56836+
},
5676056837
};
56838+
#if HAVE_OPENSSL
56839+
FIO_LOG_DEBUG2("Testing against OpenSSL SHA512 and SHA256");
56840+
#endif
5676156841
for (size_t i = 0; i < sizeof(data) / sizeof(data[0]); ++i) {
5676256842
if (!data[i].str)
5676356843
continue;
56844+
#if HAVE_OPENSSL
56845+
{
56846+
fio_u512 openssl_result;
56847+
fio_u512 sha512 = fio_sha512(data[i].str, FIO_STRLEN(data[i].str));
56848+
fio_u256 sha256 = fio_sha256(data[i].str, FIO_STRLEN(data[i].str));
56849+
SHA256((const unsigned char *)data[i].str,
56850+
FIO_STRLEN(data[i].str),
56851+
openssl_result.u8);
56852+
FIO_ASSERT(fio_u256_is_eq(openssl_result.u256, &sha256),
56853+
"SHA256 OpenSSL mismatch for \"%s\":\n\t %X%X%X%X...%X%X%X%X",
56854+
data[i].str,
56855+
sha256.u8[0],
56856+
sha256.u8[1],
56857+
sha256.u8[2],
56858+
sha256.u8[3],
56859+
sha256.u8[28],
56860+
sha256.u8[29],
56861+
sha256.u8[30],
56862+
sha256.u8[31]);
56863+
56864+
SHA512((const unsigned char *)data[i].str,
56865+
FIO_STRLEN(data[i].str),
56866+
openssl_result.u8);
56867+
FIO_ASSERT(fio_u512_is_eq(&openssl_result, &sha512),
56868+
"SHA512 OpenSSL mismatch for \"%s\":\n\t "
56869+
"%X%X%X%X%X%X%X%X...%X%X%X%X%X%X%X%X",
56870+
data[i].str,
56871+
sha512.u8[0],
56872+
sha512.u8[1],
56873+
sha512.u8[2],
56874+
sha512.u8[3],
56875+
sha512.u8[4],
56876+
sha512.u8[5],
56877+
sha512.u8[6],
56878+
sha512.u8[7],
56879+
sha512.u8[24],
56880+
sha512.u8[25],
56881+
sha512.u8[26],
56882+
sha512.u8[27],
56883+
sha512.u8[28],
56884+
sha512.u8[29],
56885+
sha512.u8[30],
56886+
sha512.u8[31]);
56887+
56888+
if (FIO_STRLEN(data[i].str) > 128) {
56889+
fio_sha512_s tmp = fio_sha512_init();
56890+
fio_sha512_consume(&tmp, data[i].str, 128);
56891+
fio_sha512_consume(&tmp,
56892+
data[i].str + 128,
56893+
FIO_STRLEN(data[i].str) - 128);
56894+
sha512 = fio_sha512_finalize(&tmp);
56895+
FIO_ASSERT(fio_u512_is_eq(&openssl_result, &sha512),
56896+
"SHA512 OpenSSL mismatch for streamed \"%s\":\n\t "
56897+
"%X%X%X%X%X%X%X%X...%X%X%X%X%X%X%X%X",
56898+
data[i].str,
56899+
sha512.u8[0],
56900+
sha512.u8[1],
56901+
sha512.u8[2],
56902+
sha512.u8[3],
56903+
sha512.u8[4],
56904+
sha512.u8[5],
56905+
sha512.u8[6],
56906+
sha512.u8[7],
56907+
sha512.u8[24],
56908+
sha512.u8[25],
56909+
sha512.u8[26],
56910+
sha512.u8[27],
56911+
sha512.u8[28],
56912+
sha512.u8[29],
56913+
sha512.u8[30],
56914+
sha512.u8[31]);
56915+
}
56916+
}
56917+
#endif
56918+
5676456919
if (data[i].sha256) {
5676556920
fio_u256 sha256 = fio_sha256(data[i].str, FIO_STRLEN(data[i].str));
5676656921
FIO_ASSERT(!memcmp(sha256.u8, data[i].sha256, 32),
@@ -56774,6 +56929,27 @@ FIO_SFUNC void FIO_NAME_TEST(stl, sha2)(void) {
5677456929
sha256.u8[29],
5677556930
sha256.u8[30],
5677656931
sha256.u8[31]);
56932+
if (FIO_STRLEN(data[i].str) > 8) {
56933+
fio_sha256_s sha = fio_sha256_init();
56934+
fio_sha256_consume(&sha, data[i].str, 4);
56935+
FIO_COMPILER_GUARD;
56936+
fio_sha256_consume(&sha, data[i].str + 4, 4);
56937+
FIO_COMPILER_GUARD;
56938+
fio_sha256_consume(&sha, data[i].str + 8, FIO_STRLEN(data[i].str) - 8);
56939+
sha256 = fio_sha256_finalize(&sha);
56940+
FIO_ASSERT(
56941+
!memcmp(sha256.u8, data[i].sha256, 32),
56942+
"SHA256 mismatch for \"%s\" (in parts):\n\t %X%X%X%X...%X%X%X%X",
56943+
data[i].str,
56944+
sha256.u8[0],
56945+
sha256.u8[1],
56946+
sha256.u8[2],
56947+
sha256.u8[3],
56948+
sha256.u8[28],
56949+
sha256.u8[29],
56950+
sha256.u8[30],
56951+
sha256.u8[31]);
56952+
}
5677756953
}
5677856954
if (data[i].sha512) {
5677956955
fio_u512 sha512 = fio_sha512(data[i].str, FIO_STRLEN(data[i].str));
@@ -56797,6 +56973,35 @@ FIO_SFUNC void FIO_NAME_TEST(stl, sha2)(void) {
5679756973
sha512.u8[29],
5679856974
sha512.u8[30],
5679956975
sha512.u8[31]);
56976+
if (FIO_STRLEN(data[i].str) > 8) {
56977+
fio_sha512_s sha = fio_sha512_init();
56978+
fio_sha512_consume(&sha, data[i].str, 4);
56979+
FIO_COMPILER_GUARD;
56980+
fio_sha512_consume(&sha, data[i].str + 4, 4);
56981+
FIO_COMPILER_GUARD;
56982+
fio_sha512_consume(&sha, data[i].str + 8, FIO_STRLEN(data[i].str) - 8);
56983+
sha512 = fio_sha512_finalize(&sha);
56984+
FIO_ASSERT(!memcmp(sha512.u8, data[i].sha512, 64),
56985+
"SHA512 mismatch for \"%s\" (in parts):\n\t "
56986+
"%X%X%X%X%X%X%X%X...%X%X%X%X%X%X%X%X",
56987+
data[i].str,
56988+
sha512.u8[0],
56989+
sha512.u8[1],
56990+
sha512.u8[2],
56991+
sha512.u8[3],
56992+
sha512.u8[4],
56993+
sha512.u8[5],
56994+
sha512.u8[6],
56995+
sha512.u8[7],
56996+
sha512.u8[24],
56997+
sha512.u8[25],
56998+
sha512.u8[26],
56999+
sha512.u8[27],
57000+
sha512.u8[28],
57001+
sha512.u8[29],
57002+
sha512.u8[30],
57003+
sha512.u8[31]);
57004+
}
5680057005
}
5680157006
}
5680257007

fio-stl/152 sha2.h

Lines changed: 62 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -341,7 +341,7 @@ SFUNC void fio_sha512_consume(fio_sha512_s *restrict h,
341341
const size_t byte2copy = 128UL - offset;
342342
fio_memcpy127x(h->cache.u8 + offset, r, byte2copy);
343343
fio___sha512_round(&h->hash, h->cache.u8);
344-
FIO_MEMSET(h->cache.u8, 0, 128);
344+
h->cache = (fio_u1024){0};
345345
r += byte2copy;
346346
len -= byte2copy;
347347
}
@@ -362,7 +362,7 @@ SFUNC fio_u512 fio_sha512_finalize(fio_sha512_s *h) {
362362
h->cache.u8[remainder] = 0x80U; /* set the 1 bit at the left most position */
363363
if ((remainder) > 112) { /* make sure there's room to attach `total_len` */
364364
fio___sha512_round(&h->hash, h->cache.u8);
365-
FIO_MEMSET(h->cache.u8, 0, 128);
365+
h->cache = (fio_u1024){0};
366366
}
367367
h->cache.u64[15] = fio_lton64((total << 3));
368368
fio___sha512_round(&h->hash, h->cache.u8);
@@ -372,6 +372,66 @@ SFUNC fio_u512 fio_sha512_finalize(fio_sha512_s *h) {
372372
return h->hash;
373373
}
374374

375+
/* *****************************************************************************
376+
HMAC
377+
***************************************************************************** */
378+
379+
/**
380+
* HMAC-SHA512, resulting in a 64 byte authentication code.
381+
*
382+
* Keys are limited to 128 bytes.
383+
*
384+
* TODO: FIXME!
385+
*/
386+
SFUNC fio_u512 fio_sha512_hmac(const void *key,
387+
uint64_t key_len,
388+
const void *msg,
389+
uint64_t msg_len) {
390+
fio_sha512_s inner = fio_sha512_init();
391+
fio_u2048 k;
392+
/* copy key */
393+
if (key_len > 128)
394+
goto key_too_long;
395+
if (key_len == 128)
396+
fio_memcpy128(k.u8, key);
397+
else {
398+
k.u1024[0] = (fio_u1024){0};
399+
fio_memcpy127x(k.u8, key, key_len);
400+
}
401+
/* prepare inner key */
402+
for (size_t i = 0; i < 16; ++i)
403+
k.u64[i] ^= (uint64_t)0x3636363636363636ULL;
404+
/* hash of inner key + msg */
405+
if (1) {
406+
/* consume key block */
407+
fio___sha512_round(&inner.hash, k.u8);
408+
/* consume data */
409+
uint8_t *buf = (uint8_t *)msg;
410+
for (size_t i = 127; i < msg_len; (i += 128), (buf += 128))
411+
fio___sha512_round(&inner.hash, buf);
412+
if ((msg_len & 127)) {
413+
inner.cache = (fio_u1024){0};
414+
fio_memcpy127x(inner.cache.u8, buf, msg_len);
415+
}
416+
inner.total_len = 128 + msg_len;
417+
} else { /* ... same as ... */
418+
fio_sha512_consume(&inner, k.u8, 128);
419+
fio_sha512_consume(&inner, msg, msg_len);
420+
}
421+
/* finalize SHA512 and append to end of key */
422+
k.u512[2] = fio_sha512_finalize(&inner);
423+
/* switch key to outer key */
424+
for (size_t i = 0; i < 16; ++i)
425+
k.u64[i] ^=
426+
((uint64_t)0x3636363636363636ULL ^ (uint64_t)0x5C5C5C5C5C5C5C5CULL);
427+
/* hash outer key with inner hash appended and return */
428+
return fio_sha512(k.u8, 192);
429+
430+
key_too_long:
431+
k.u512[3] = fio_sha512(key, key_len);
432+
return fio_sha512_hmac(k.u512[3].u8, sizeof(k.u512[3]), msg, msg_len);
433+
}
434+
375435
/* *****************************************************************************
376436
Cleanup
377437
***************************************************************************** */

fio-stl/431 http handle.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1604,7 +1604,7 @@ Handler State
16041604

16051605
SFUNC int fio_http_is_clean(fio_http_s *h) {
16061606
FIO_ASSERT_DEBUG(h, "NULL HTTP handler!");
1607-
return !h->state;
1607+
return !(h->state & (~FIO_HTTP_STATE_COOKIES_PARSED));
16081608
}
16091609

16101610
/** Returns true if the HTTP handle's response was sent. */

0 commit comments

Comments
 (0)