details: https://hg.nginx.org/njs/rev/0479e5821ab2 branches: changeset: 2288:0479e5821ab2 user: Dmitry Volyntsev <xei...@nginx.com> date: Wed Feb 14 21:34:02 2024 -0800 description: Moving hash code out of the njs core.
diffstat: auto/modules | 5 +- auto/sources | 3 - external/njs_crypto_module.c | 2 +- external/njs_hash.h | 32 ++++ external/njs_md5.c | 270 ++++++++++++++++++++++++++++++++++++ external/njs_sha1.c | 298 ++++++++++++++++++++++++++++++++++++++++ external/njs_sha2.c | 320 +++++++++++++++++++++++++++++++++++++++++++ src/njs_hash.h | 32 ---- src/njs_main.h | 2 - src/njs_md5.c | 266 ----------------------------------- src/njs_sha1.c | 294 --------------------------------------- src/njs_sha2.c | 316 ------------------------------------------ 12 files changed, 925 insertions(+), 915 deletions(-) diffs (truncated from 1914 to 1000 lines): diff -r 6fa96ea99037 -r 0479e5821ab2 auto/modules --- a/auto/modules Wed Feb 14 21:33:56 2024 -0800 +++ b/auto/modules Wed Feb 14 21:34:02 2024 -0800 @@ -9,7 +9,10 @@ njs_module_srcs=src/njs_buffer.c njs_module_name=njs_crypto_module njs_module_incs= -njs_module_srcs=external/njs_crypto_module.c +njs_module_srcs="external/njs_crypto_module.c \ + external/njs_md5.c \ + external/njs_sha1.c \ + external/njs_sha2.c" . auto/module diff -r 6fa96ea99037 -r 0479e5821ab2 auto/sources --- a/auto/sources Wed Feb 14 21:33:56 2024 -0800 +++ b/auto/sources Wed Feb 14 21:34:02 2024 -0800 @@ -13,9 +13,6 @@ NJS_LIB_SRCS=" \ src/njs_flathsh.c \ src/njs_trace.c \ src/njs_random.c \ - src/njs_md5.c \ - src/njs_sha1.c \ - src/njs_sha2.c \ src/njs_malloc.c \ src/njs_mp.c \ src/njs_sprintf.c \ diff -r 6fa96ea99037 -r 0479e5821ab2 external/njs_crypto_module.c --- a/external/njs_crypto_module.c Wed Feb 14 21:33:56 2024 -0800 +++ b/external/njs_crypto_module.c Wed Feb 14 21:34:02 2024 -0800 @@ -6,9 +6,9 @@ #include <njs.h> -#include <njs_hash.h> #include <njs_string.h> #include <njs_buffer.h> +#include "njs_hash.h" typedef void (*njs_hash_init)(njs_hash_t *ctx); diff -r 6fa96ea99037 -r 0479e5821ab2 external/njs_hash.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/external/njs_hash.h Wed Feb 14 21:34:02 2024 -0800 @@ -0,0 +1,32 @@ + +/* + * Copyright (C) Dmitry Volyntsev + * Copyright (C) NGINX, Inc. + */ + + +#ifndef _NJS_HASH_H_INCLUDED_ +#define _NJS_HASH_H_INCLUDED_ + + +typedef struct { + uint64_t bytes; + uint32_t a, b, c, d, e, f, g, h; + u_char buffer[64]; +} njs_hash_t; + + +NJS_EXPORT void njs_md5_init(njs_hash_t *ctx); +NJS_EXPORT void njs_md5_update(njs_hash_t *ctx, const void *data, size_t size); +NJS_EXPORT void njs_md5_final(u_char result[32], njs_hash_t *ctx); + +NJS_EXPORT void njs_sha1_init(njs_hash_t *ctx); +NJS_EXPORT void njs_sha1_update(njs_hash_t *ctx, const void *data, size_t size); +NJS_EXPORT void njs_sha1_final(u_char result[32], njs_hash_t *ctx); + +NJS_EXPORT void njs_sha2_init(njs_hash_t *ctx); +NJS_EXPORT void njs_sha2_update(njs_hash_t *ctx, const void *data, size_t size); +NJS_EXPORT void njs_sha2_final(u_char result[32], njs_hash_t *ctx); + + +#endif /* _NJS_HASH_H_INCLUDED_ */ diff -r 6fa96ea99037 -r 0479e5821ab2 external/njs_md5.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/external/njs_md5.c Wed Feb 14 21:34:02 2024 -0800 @@ -0,0 +1,270 @@ + +/* + * An internal implementation, based on Alexander Peslyak's + * public domain implementation: + * http://openwall.info/wiki/people/solar/software/public-domain-source-code/md5 + */ + + +#include <njs_unix.h> +#include <njs_types.h> +#include <njs_clang.h> +#include <njs_str.h> +#include "njs_hash.h" + + +static const u_char *njs_md5_body(njs_hash_t *ctx, const u_char *data, + size_t size); + + +void +njs_md5_init(njs_hash_t *ctx) +{ + ctx->a = 0x67452301; + ctx->b = 0xefcdab89; + ctx->c = 0x98badcfe; + ctx->d = 0x10325476; + + ctx->bytes = 0; +} + + +void +njs_md5_update(njs_hash_t *ctx, const void *data, size_t size) +{ + size_t used, free; + + used = (size_t) (ctx->bytes & 0x3f); + ctx->bytes += size; + + if (used) { + free = 64 - used; + + if (size < free) { + memcpy(&ctx->buffer[used], data, size); + return; + } + + memcpy(&ctx->buffer[used], data, free); + data = (u_char *) data + free; + size -= free; + (void) njs_md5_body(ctx, ctx->buffer, 64); + } + + if (size >= 64) { + data = njs_md5_body(ctx, data, size & ~(size_t) 0x3f); + size &= 0x3f; + } + + memcpy(ctx->buffer, data, size); +} + + +void +njs_md5_final(u_char result[32], njs_hash_t *ctx) +{ + size_t used, free; + + used = (size_t) (ctx->bytes & 0x3f); + + ctx->buffer[used++] = 0x80; + + free = 64 - used; + + if (free < 8) { + njs_memzero(&ctx->buffer[used], free); + (void) njs_md5_body(ctx, ctx->buffer, 64); + used = 0; + free = 64; + } + + njs_memzero(&ctx->buffer[used], free - 8); + + ctx->bytes <<= 3; + ctx->buffer[56] = (u_char) ctx->bytes; + ctx->buffer[57] = (u_char) (ctx->bytes >> 8); + ctx->buffer[58] = (u_char) (ctx->bytes >> 16); + ctx->buffer[59] = (u_char) (ctx->bytes >> 24); + ctx->buffer[60] = (u_char) (ctx->bytes >> 32); + ctx->buffer[61] = (u_char) (ctx->bytes >> 40); + ctx->buffer[62] = (u_char) (ctx->bytes >> 48); + ctx->buffer[63] = (u_char) (ctx->bytes >> 56); + + (void) njs_md5_body(ctx, ctx->buffer, 64); + + result[0] = (u_char) ctx->a; + result[1] = (u_char) (ctx->a >> 8); + result[2] = (u_char) (ctx->a >> 16); + result[3] = (u_char) (ctx->a >> 24); + result[4] = (u_char) ctx->b; + result[5] = (u_char) (ctx->b >> 8); + result[6] = (u_char) (ctx->b >> 16); + result[7] = (u_char) (ctx->b >> 24); + result[8] = (u_char) ctx->c; + result[9] = (u_char) (ctx->c >> 8); + result[10] = (u_char) (ctx->c >> 16); + result[11] = (u_char) (ctx->c >> 24); + result[12] = (u_char) ctx->d; + result[13] = (u_char) (ctx->d >> 8); + result[14] = (u_char) (ctx->d >> 16); + result[15] = (u_char) (ctx->d >> 24); + + njs_explicit_memzero(ctx, sizeof(*ctx)); +} + + +/* + * The basic MD5 functions. + * + * F and G are optimized compared to their RFC 1321 definitions for + * architectures that lack an AND-NOT instruction, just like in + * Colin Plumb's implementation. + */ + +#define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z)))) +#define G(x, y, z) ((y) ^ ((z) & ((x) ^ (y)))) +#define H(x, y, z) ((x) ^ (y) ^ (z)) +#define I(x, y, z) ((y) ^ ((x) | ~(z))) + +/* + * The MD5 transformation for all four rounds. + */ + +#define STEP(f, a, b, c, d, x, t, s) \ + (a) += f((b), (c), (d)) + (x) + (t); \ + (a) = (((a) << (s)) | (((a) & 0xffffffff) >> (32 - (s)))); \ + (a) += (b) + +/* + * SET() reads 4 input bytes in little-endian byte order and stores them + * in a properly aligned word in host byte order. + */ + +#define SET(n) \ + (block[n] = \ + ( (uint32_t) p[n * 4] \ + | ((uint32_t) p[n * 4 + 1] << 8) \ + | ((uint32_t) p[n * 4 + 2] << 16) \ + | ((uint32_t) p[n * 4 + 3] << 24))) \ + +#define GET(n) block[n] + + +/* + * This processes one or more 64-byte data blocks, but does not update + * the bit counters. There are no alignment requirements. + */ + +static const u_char * +njs_md5_body(njs_hash_t *ctx, const u_char *data, size_t size) +{ + uint32_t a, b, c, d; + uint32_t saved_a, saved_b, saved_c, saved_d; + const u_char *p; + uint32_t block[16]; + + p = data; + + a = ctx->a; + b = ctx->b; + c = ctx->c; + d = ctx->d; + + do { + saved_a = a; + saved_b = b; + saved_c = c; + saved_d = d; + + /* Round 1 */ + + STEP(F, a, b, c, d, SET(0), 0xd76aa478, 7); + STEP(F, d, a, b, c, SET(1), 0xe8c7b756, 12); + STEP(F, c, d, a, b, SET(2), 0x242070db, 17); + STEP(F, b, c, d, a, SET(3), 0xc1bdceee, 22); + STEP(F, a, b, c, d, SET(4), 0xf57c0faf, 7); + STEP(F, d, a, b, c, SET(5), 0x4787c62a, 12); + STEP(F, c, d, a, b, SET(6), 0xa8304613, 17); + STEP(F, b, c, d, a, SET(7), 0xfd469501, 22); + STEP(F, a, b, c, d, SET(8), 0x698098d8, 7); + STEP(F, d, a, b, c, SET(9), 0x8b44f7af, 12); + STEP(F, c, d, a, b, SET(10), 0xffff5bb1, 17); + STEP(F, b, c, d, a, SET(11), 0x895cd7be, 22); + STEP(F, a, b, c, d, SET(12), 0x6b901122, 7); + STEP(F, d, a, b, c, SET(13), 0xfd987193, 12); + STEP(F, c, d, a, b, SET(14), 0xa679438e, 17); + STEP(F, b, c, d, a, SET(15), 0x49b40821, 22); + + /* Round 2 */ + + STEP(G, a, b, c, d, GET(1), 0xf61e2562, 5); + STEP(G, d, a, b, c, GET(6), 0xc040b340, 9); + STEP(G, c, d, a, b, GET(11), 0x265e5a51, 14); + STEP(G, b, c, d, a, GET(0), 0xe9b6c7aa, 20); + STEP(G, a, b, c, d, GET(5), 0xd62f105d, 5); + STEP(G, d, a, b, c, GET(10), 0x02441453, 9); + STEP(G, c, d, a, b, GET(15), 0xd8a1e681, 14); + STEP(G, b, c, d, a, GET(4), 0xe7d3fbc8, 20); + STEP(G, a, b, c, d, GET(9), 0x21e1cde6, 5); + STEP(G, d, a, b, c, GET(14), 0xc33707d6, 9); + STEP(G, c, d, a, b, GET(3), 0xf4d50d87, 14); + STEP(G, b, c, d, a, GET(8), 0x455a14ed, 20); + STEP(G, a, b, c, d, GET(13), 0xa9e3e905, 5); + STEP(G, d, a, b, c, GET(2), 0xfcefa3f8, 9); + STEP(G, c, d, a, b, GET(7), 0x676f02d9, 14); + STEP(G, b, c, d, a, GET(12), 0x8d2a4c8a, 20); + + /* Round 3 */ + + STEP(H, a, b, c, d, GET(5), 0xfffa3942, 4); + STEP(H, d, a, b, c, GET(8), 0x8771f681, 11); + STEP(H, c, d, a, b, GET(11), 0x6d9d6122, 16); + STEP(H, b, c, d, a, GET(14), 0xfde5380c, 23); + STEP(H, a, b, c, d, GET(1), 0xa4beea44, 4); + STEP(H, d, a, b, c, GET(4), 0x4bdecfa9, 11); + STEP(H, c, d, a, b, GET(7), 0xf6bb4b60, 16); + STEP(H, b, c, d, a, GET(10), 0xbebfbc70, 23); + STEP(H, a, b, c, d, GET(13), 0x289b7ec6, 4); + STEP(H, d, a, b, c, GET(0), 0xeaa127fa, 11); + STEP(H, c, d, a, b, GET(3), 0xd4ef3085, 16); + STEP(H, b, c, d, a, GET(6), 0x04881d05, 23); + STEP(H, a, b, c, d, GET(9), 0xd9d4d039, 4); + STEP(H, d, a, b, c, GET(12), 0xe6db99e5, 11); + STEP(H, c, d, a, b, GET(15), 0x1fa27cf8, 16); + STEP(H, b, c, d, a, GET(2), 0xc4ac5665, 23); + + /* Round 4 */ + + STEP(I, a, b, c, d, GET(0), 0xf4292244, 6); + STEP(I, d, a, b, c, GET(7), 0x432aff97, 10); + STEP(I, c, d, a, b, GET(14), 0xab9423a7, 15); + STEP(I, b, c, d, a, GET(5), 0xfc93a039, 21); + STEP(I, a, b, c, d, GET(12), 0x655b59c3, 6); + STEP(I, d, a, b, c, GET(3), 0x8f0ccc92, 10); + STEP(I, c, d, a, b, GET(10), 0xffeff47d, 15); + STEP(I, b, c, d, a, GET(1), 0x85845dd1, 21); + STEP(I, a, b, c, d, GET(8), 0x6fa87e4f, 6); + STEP(I, d, a, b, c, GET(15), 0xfe2ce6e0, 10); + STEP(I, c, d, a, b, GET(6), 0xa3014314, 15); + STEP(I, b, c, d, a, GET(13), 0x4e0811a1, 21); + STEP(I, a, b, c, d, GET(4), 0xf7537e82, 6); + STEP(I, d, a, b, c, GET(11), 0xbd3af235, 10); + STEP(I, c, d, a, b, GET(2), 0x2ad7d2bb, 15); + STEP(I, b, c, d, a, GET(9), 0xeb86d391, 21); + + a += saved_a; + b += saved_b; + c += saved_c; + d += saved_d; + + p += 64; + + } while (size -= 64); + + ctx->a = a; + ctx->b = b; + ctx->c = c; + ctx->d = d; + + return p; +} diff -r 6fa96ea99037 -r 0479e5821ab2 external/njs_sha1.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/external/njs_sha1.c Wed Feb 14 21:34:02 2024 -0800 @@ -0,0 +1,298 @@ + +/* + * Copyright (C) Maxim Dounin + * Copyright (C) NGINX, Inc. + * + * An internal SHA1 implementation. + */ + + +#include <njs_unix.h> +#include <njs_types.h> +#include <njs_clang.h> +#include <njs_str.h> +#include "njs_hash.h" + + +static const u_char *njs_sha1_body(njs_hash_t *ctx, const u_char *data, + size_t size); + + +void +njs_sha1_init(njs_hash_t *ctx) +{ + ctx->a = 0x67452301; + ctx->b = 0xefcdab89; + ctx->c = 0x98badcfe; + ctx->d = 0x10325476; + ctx->e = 0xc3d2e1f0; + + ctx->bytes = 0; +} + + +void +njs_sha1_update(njs_hash_t *ctx, const void *data, size_t size) +{ + size_t used, free; + + used = (size_t) (ctx->bytes & 0x3f); + ctx->bytes += size; + + if (used) { + free = 64 - used; + + if (size < free) { + memcpy(&ctx->buffer[used], data, size); + return; + } + + memcpy(&ctx->buffer[used], data, free); + data = (u_char *) data + free; + size -= free; + (void) njs_sha1_body(ctx, ctx->buffer, 64); + } + + if (size >= 64) { + data = njs_sha1_body(ctx, data, size & ~(size_t) 0x3f); + size &= 0x3f; + } + + memcpy(ctx->buffer, data, size); +} + + +void +njs_sha1_final(u_char result[32], njs_hash_t *ctx) +{ + size_t used, free; + + used = (size_t) (ctx->bytes & 0x3f); + + ctx->buffer[used++] = 0x80; + + free = 64 - used; + + if (free < 8) { + njs_memzero(&ctx->buffer[used], free); + (void) njs_sha1_body(ctx, ctx->buffer, 64); + used = 0; + free = 64; + } + + njs_memzero(&ctx->buffer[used], free - 8); + + ctx->bytes <<= 3; + ctx->buffer[56] = (u_char) (ctx->bytes >> 56); + ctx->buffer[57] = (u_char) (ctx->bytes >> 48); + ctx->buffer[58] = (u_char) (ctx->bytes >> 40); + ctx->buffer[59] = (u_char) (ctx->bytes >> 32); + ctx->buffer[60] = (u_char) (ctx->bytes >> 24); + ctx->buffer[61] = (u_char) (ctx->bytes >> 16); + ctx->buffer[62] = (u_char) (ctx->bytes >> 8); + ctx->buffer[63] = (u_char) ctx->bytes; + + (void) njs_sha1_body(ctx, ctx->buffer, 64); + + result[0] = (u_char) (ctx->a >> 24); + result[1] = (u_char) (ctx->a >> 16); + result[2] = (u_char) (ctx->a >> 8); + result[3] = (u_char) ctx->a; + result[4] = (u_char) (ctx->b >> 24); + result[5] = (u_char) (ctx->b >> 16); + result[6] = (u_char) (ctx->b >> 8); + result[7] = (u_char) ctx->b; + result[8] = (u_char) (ctx->c >> 24); + result[9] = (u_char) (ctx->c >> 16); + result[10] = (u_char) (ctx->c >> 8); + result[11] = (u_char) ctx->c; + result[12] = (u_char) (ctx->d >> 24); + result[13] = (u_char) (ctx->d >> 16); + result[14] = (u_char) (ctx->d >> 8); + result[15] = (u_char) ctx->d; + result[16] = (u_char) (ctx->e >> 24); + result[17] = (u_char) (ctx->e >> 16); + result[18] = (u_char) (ctx->e >> 8); + result[19] = (u_char) ctx->e; + + njs_explicit_memzero(ctx, sizeof(*ctx)); +} + + +/* + * Helper functions. + */ + +#define ROTATE(bits, word) (((word) << (bits)) | ((word) >> (32 - (bits)))) + +#define F1(b, c, d) (((b) & (c)) | ((~(b)) & (d))) +#define F2(b, c, d) ((b) ^ (c) ^ (d)) +#define F3(b, c, d) (((b) & (c)) | ((b) & (d)) | ((c) & (d))) + +#define STEP(f, a, b, c, d, e, w, t) \ + temp = ROTATE(5, (a)) + f((b), (c), (d)) + (e) + (w) + (t); \ + (e) = (d); \ + (d) = (c); \ + (c) = ROTATE(30, (b)); \ + (b) = (a); \ + (a) = temp; + + +/* + * GET() reads 4 input bytes in big-endian byte order and returns + * them as uint32_t. + */ + +#define GET(n) \ + ( ((uint32_t) p[n * 4 + 3]) \ + | ((uint32_t) p[n * 4 + 2] << 8) \ + | ((uint32_t) p[n * 4 + 1] << 16) \ + | ((uint32_t) p[n * 4] << 24)) + + +/* + * This processes one or more 64-byte data blocks, but does not update + * the bit counters. There are no alignment requirements. + */ + +static const u_char * +njs_sha1_body(njs_hash_t *ctx, const u_char *data, size_t size) +{ + uint32_t a, b, c, d, e, temp; + uint32_t saved_a, saved_b, saved_c, saved_d, saved_e; + uint32_t words[80]; + njs_uint_t i; + const u_char *p; + + p = data; + + a = ctx->a; + b = ctx->b; + c = ctx->c; + d = ctx->d; + e = ctx->e; + + do { + saved_a = a; + saved_b = b; + saved_c = c; + saved_d = d; + saved_e = e; + + /* Load data block into the words array */ + + for (i = 0; i < 16; i++) { + words[i] = GET(i); + } + + for (i = 16; i < 80; i++) { + words[i] = ROTATE(1, words[i - 3] + ^ words[i - 8] + ^ words[i - 14] + ^ words[i - 16]); + } + + /* Transformations */ + + STEP(F1, a, b, c, d, e, words[0], 0x5a827999); + STEP(F1, a, b, c, d, e, words[1], 0x5a827999); + STEP(F1, a, b, c, d, e, words[2], 0x5a827999); + STEP(F1, a, b, c, d, e, words[3], 0x5a827999); + STEP(F1, a, b, c, d, e, words[4], 0x5a827999); + STEP(F1, a, b, c, d, e, words[5], 0x5a827999); + STEP(F1, a, b, c, d, e, words[6], 0x5a827999); + STEP(F1, a, b, c, d, e, words[7], 0x5a827999); + STEP(F1, a, b, c, d, e, words[8], 0x5a827999); + STEP(F1, a, b, c, d, e, words[9], 0x5a827999); + STEP(F1, a, b, c, d, e, words[10], 0x5a827999); + STEP(F1, a, b, c, d, e, words[11], 0x5a827999); + STEP(F1, a, b, c, d, e, words[12], 0x5a827999); + STEP(F1, a, b, c, d, e, words[13], 0x5a827999); + STEP(F1, a, b, c, d, e, words[14], 0x5a827999); + STEP(F1, a, b, c, d, e, words[15], 0x5a827999); + STEP(F1, a, b, c, d, e, words[16], 0x5a827999); + STEP(F1, a, b, c, d, e, words[17], 0x5a827999); + STEP(F1, a, b, c, d, e, words[18], 0x5a827999); + STEP(F1, a, b, c, d, e, words[19], 0x5a827999); + + STEP(F2, a, b, c, d, e, words[20], 0x6ed9eba1); + STEP(F2, a, b, c, d, e, words[21], 0x6ed9eba1); + STEP(F2, a, b, c, d, e, words[22], 0x6ed9eba1); + STEP(F2, a, b, c, d, e, words[23], 0x6ed9eba1); + STEP(F2, a, b, c, d, e, words[24], 0x6ed9eba1); + STEP(F2, a, b, c, d, e, words[25], 0x6ed9eba1); + STEP(F2, a, b, c, d, e, words[26], 0x6ed9eba1); + STEP(F2, a, b, c, d, e, words[27], 0x6ed9eba1); + STEP(F2, a, b, c, d, e, words[28], 0x6ed9eba1); + STEP(F2, a, b, c, d, e, words[29], 0x6ed9eba1); + STEP(F2, a, b, c, d, e, words[30], 0x6ed9eba1); + STEP(F2, a, b, c, d, e, words[31], 0x6ed9eba1); + STEP(F2, a, b, c, d, e, words[32], 0x6ed9eba1); + STEP(F2, a, b, c, d, e, words[33], 0x6ed9eba1); + STEP(F2, a, b, c, d, e, words[34], 0x6ed9eba1); + STEP(F2, a, b, c, d, e, words[35], 0x6ed9eba1); + STEP(F2, a, b, c, d, e, words[36], 0x6ed9eba1); + STEP(F2, a, b, c, d, e, words[37], 0x6ed9eba1); + STEP(F2, a, b, c, d, e, words[38], 0x6ed9eba1); + STEP(F2, a, b, c, d, e, words[39], 0x6ed9eba1); + + STEP(F3, a, b, c, d, e, words[40], 0x8f1bbcdc); + STEP(F3, a, b, c, d, e, words[41], 0x8f1bbcdc); + STEP(F3, a, b, c, d, e, words[42], 0x8f1bbcdc); + STEP(F3, a, b, c, d, e, words[43], 0x8f1bbcdc); + STEP(F3, a, b, c, d, e, words[44], 0x8f1bbcdc); + STEP(F3, a, b, c, d, e, words[45], 0x8f1bbcdc); + STEP(F3, a, b, c, d, e, words[46], 0x8f1bbcdc); + STEP(F3, a, b, c, d, e, words[47], 0x8f1bbcdc); + STEP(F3, a, b, c, d, e, words[48], 0x8f1bbcdc); + STEP(F3, a, b, c, d, e, words[49], 0x8f1bbcdc); + STEP(F3, a, b, c, d, e, words[50], 0x8f1bbcdc); + STEP(F3, a, b, c, d, e, words[51], 0x8f1bbcdc); + STEP(F3, a, b, c, d, e, words[52], 0x8f1bbcdc); + STEP(F3, a, b, c, d, e, words[53], 0x8f1bbcdc); + STEP(F3, a, b, c, d, e, words[54], 0x8f1bbcdc); + STEP(F3, a, b, c, d, e, words[55], 0x8f1bbcdc); + STEP(F3, a, b, c, d, e, words[56], 0x8f1bbcdc); + STEP(F3, a, b, c, d, e, words[57], 0x8f1bbcdc); + STEP(F3, a, b, c, d, e, words[58], 0x8f1bbcdc); + STEP(F3, a, b, c, d, e, words[59], 0x8f1bbcdc); + + STEP(F2, a, b, c, d, e, words[60], 0xca62c1d6); + STEP(F2, a, b, c, d, e, words[61], 0xca62c1d6); + STEP(F2, a, b, c, d, e, words[62], 0xca62c1d6); + STEP(F2, a, b, c, d, e, words[63], 0xca62c1d6); + STEP(F2, a, b, c, d, e, words[64], 0xca62c1d6); + STEP(F2, a, b, c, d, e, words[65], 0xca62c1d6); + STEP(F2, a, b, c, d, e, words[66], 0xca62c1d6); + STEP(F2, a, b, c, d, e, words[67], 0xca62c1d6); + STEP(F2, a, b, c, d, e, words[68], 0xca62c1d6); + STEP(F2, a, b, c, d, e, words[69], 0xca62c1d6); + STEP(F2, a, b, c, d, e, words[70], 0xca62c1d6); + STEP(F2, a, b, c, d, e, words[71], 0xca62c1d6); + STEP(F2, a, b, c, d, e, words[72], 0xca62c1d6); + STEP(F2, a, b, c, d, e, words[73], 0xca62c1d6); + STEP(F2, a, b, c, d, e, words[74], 0xca62c1d6); + STEP(F2, a, b, c, d, e, words[75], 0xca62c1d6); + STEP(F2, a, b, c, d, e, words[76], 0xca62c1d6); + STEP(F2, a, b, c, d, e, words[77], 0xca62c1d6); + STEP(F2, a, b, c, d, e, words[78], 0xca62c1d6); + STEP(F2, a, b, c, d, e, words[79], 0xca62c1d6); + + a += saved_a; + b += saved_b; + c += saved_c; + d += saved_d; + e += saved_e; + + p += 64; + + } while (size -= 64); + + ctx->a = a; + ctx->b = b; + ctx->c = c; + ctx->d = d; + ctx->e = e; + + return p; +} diff -r 6fa96ea99037 -r 0479e5821ab2 external/njs_sha2.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/external/njs_sha2.c Wed Feb 14 21:34:02 2024 -0800 @@ -0,0 +1,320 @@ + +/* + * Copyright (C) Dmitry Volyntsev + * Copyright (C) NGINX, Inc. + * + * An internal SHA2 implementation. + */ + + +#include <njs_unix.h> +#include <njs_types.h> +#include <njs_clang.h> +#include <njs_str.h> +#include "njs_hash.h" + + +static const u_char *njs_sha2_body(njs_hash_t *ctx, const u_char *data, + size_t size); + + +void +njs_sha2_init(njs_hash_t *ctx) +{ + ctx->a = 0x6a09e667; + ctx->b = 0xbb67ae85; + ctx->c = 0x3c6ef372; + ctx->d = 0xa54ff53a; + ctx->e = 0x510e527f; + ctx->f = 0x9b05688c; + ctx->g = 0x1f83d9ab; + ctx->h = 0x5be0cd19; + + ctx->bytes = 0; +} + + +void +njs_sha2_update(njs_hash_t *ctx, const void *data, size_t size) +{ + size_t used, free; + + used = (size_t) (ctx->bytes & 0x3f); + ctx->bytes += size; + + if (used) { + free = 64 - used; + + if (size < free) { + memcpy(&ctx->buffer[used], data, size); + return; + } + + memcpy(&ctx->buffer[used], data, free); + data = (u_char *) data + free; + size -= free; + (void) njs_sha2_body(ctx, ctx->buffer, 64); + } + + if (size >= 64) { + data = njs_sha2_body(ctx, data, size & ~(size_t) 0x3f); + size &= 0x3f; + } + + memcpy(ctx->buffer, data, size); +} + + +void +njs_sha2_final(u_char result[32], njs_hash_t *ctx) +{ + size_t used, free; + + used = (size_t) (ctx->bytes & 0x3f); + + ctx->buffer[used++] = 0x80; + + free = 64 - used; + + if (free < 8) { + njs_memzero(&ctx->buffer[used], free); + (void) njs_sha2_body(ctx, ctx->buffer, 64); + used = 0; + free = 64; + } + + njs_memzero(&ctx->buffer[used], free - 8); + + ctx->bytes <<= 3; + ctx->buffer[56] = (u_char) (ctx->bytes >> 56); + ctx->buffer[57] = (u_char) (ctx->bytes >> 48); + ctx->buffer[58] = (u_char) (ctx->bytes >> 40); + ctx->buffer[59] = (u_char) (ctx->bytes >> 32); + ctx->buffer[60] = (u_char) (ctx->bytes >> 24); + ctx->buffer[61] = (u_char) (ctx->bytes >> 16); + ctx->buffer[62] = (u_char) (ctx->bytes >> 8); + ctx->buffer[63] = (u_char) ctx->bytes; + + (void) njs_sha2_body(ctx, ctx->buffer, 64); + + result[0] = (u_char) (ctx->a >> 24); + result[1] = (u_char) (ctx->a >> 16); + result[2] = (u_char) (ctx->a >> 8); + result[3] = (u_char) ctx->a; + result[4] = (u_char) (ctx->b >> 24); + result[5] = (u_char) (ctx->b >> 16); + result[6] = (u_char) (ctx->b >> 8); + result[7] = (u_char) ctx->b; + result[8] = (u_char) (ctx->c >> 24); + result[9] = (u_char) (ctx->c >> 16); + result[10] = (u_char) (ctx->c >> 8); + result[11] = (u_char) ctx->c; + result[12] = (u_char) (ctx->d >> 24); + result[13] = (u_char) (ctx->d >> 16); + result[14] = (u_char) (ctx->d >> 8); + result[15] = (u_char) ctx->d; + result[16] = (u_char) (ctx->e >> 24); + result[17] = (u_char) (ctx->e >> 16); + result[18] = (u_char) (ctx->e >> 8); + result[19] = (u_char) ctx->e; + result[20] = (u_char) (ctx->f >> 24); + result[21] = (u_char) (ctx->f >> 16); + result[22] = (u_char) (ctx->f >> 8); + result[23] = (u_char) ctx->f; + result[24] = (u_char) (ctx->g >> 24); + result[25] = (u_char) (ctx->g >> 16); + result[26] = (u_char) (ctx->g >> 8); + result[27] = (u_char) ctx->g; + result[28] = (u_char) (ctx->h >> 24); + result[29] = (u_char) (ctx->h >> 16); + result[30] = (u_char) (ctx->h >> 8); + result[31] = (u_char) ctx->h; + + njs_explicit_memzero(ctx, sizeof(*ctx)); +} + + +/* + * Helper functions. + */ + +#define ROTATE(bits, word) (((word) >> (bits)) | ((word) << (32 - (bits)))) + +#define S0(a) (ROTATE(2, a) ^ ROTATE(13, a) ^ ROTATE(22, a)) +#define S1(e) (ROTATE(6, e) ^ ROTATE(11, e) ^ ROTATE(25, e)) +#define CH(e, f, g) (((e) & (f)) ^ ((~(e)) & (g))) +#define MAJ(a, b, c) (((a) & (b)) ^ ((a) & (c)) ^ ((b) & (c))) + +#define STEP(a, b, c, d, e, f, g, h, w, k) \ + temp1 = (h) + S1(e) + CH(e, f, g) + (k) + (w); \ + temp2 = S0(a) + MAJ(a, b, c); \ + (h) = (g); \ + (g) = (f); \ + (f) = (e); \ + (e) = (d) + temp1; \ + (d) = (c); \ + (c) = (b); \ + (b) = (a); \ + (a) = temp1 + temp2; + + +/* + * GET() reads 4 input bytes in big-endian byte order and returns + * them as uint32_t. + */ + +#define GET(n) \ + ( ((uint32_t) p[n * 4 + 3]) \ + | ((uint32_t) p[n * 4 + 2] << 8) \ + | ((uint32_t) p[n * 4 + 1] << 16) \ + | ((uint32_t) p[n * 4] << 24)) + + +/* + * This processes one or more 64-byte data blocks, but does not update + * the bit counters. There are no alignment requirements. + */ + +static const u_char * +njs_sha2_body(njs_hash_t *ctx, const u_char *data, size_t size) +{ + uint32_t a, b, c, d, e, f, g, h, s0, s1, temp1, temp2; + uint32_t saved_a, saved_b, saved_c, saved_d, saved_e, saved_f, + saved_g, saved_h; + uint32_t words[64]; + njs_uint_t i; + const u_char *p; + + p = data; + + a = ctx->a; + b = ctx->b; + c = ctx->c; + d = ctx->d; + e = ctx->e; + f = ctx->f; + g = ctx->g; + h = ctx->h; + + do { + saved_a = a; + saved_b = b; + saved_c = c; + saved_d = d; + saved_e = e; + saved_f = f; + saved_g = g; + saved_h = h; + + /* Load data block into the words array */ + + for (i = 0; i < 16; i++) { + words[i] = GET(i); + } + + for (i = 16; i < 64; i++) { + s0 = ROTATE(7, words[i - 15]) + ^ ROTATE(18, words[i - 15]) + ^ (words[i - 15] >> 3); + + s1 = ROTATE(17, words[i - 2]) + ^ ROTATE(19, words[i - 2]) + ^ (words[i - 2] >> 10); + + words[i] = words[i - 16] + s0 + words[i - 7] + s1; + } + + /* Transformations */ + + STEP(a, b, c, d, e, f, g, h, words[0], 0x428a2f98); + STEP(a, b, c, d, e, f, g, h, words[1], 0x71374491); + STEP(a, b, c, d, e, f, g, h, words[2], 0xb5c0fbcf); + STEP(a, b, c, d, e, f, g, h, words[3], 0xe9b5dba5); + STEP(a, b, c, d, e, f, g, h, words[4], 0x3956c25b); + STEP(a, b, c, d, e, f, g, h, words[5], 0x59f111f1); + STEP(a, b, c, d, e, f, g, h, words[6], 0x923f82a4); + STEP(a, b, c, d, e, f, g, h, words[7], 0xab1c5ed5); + STEP(a, b, c, d, e, f, g, h, words[8], 0xd807aa98); + STEP(a, b, c, d, e, f, g, h, words[9], 0x12835b01); + STEP(a, b, c, d, e, f, g, h, words[10], 0x243185be); + STEP(a, b, c, d, e, f, g, h, words[11], 0x550c7dc3); + STEP(a, b, c, d, e, f, g, h, words[12], 0x72be5d74); + STEP(a, b, c, d, e, f, g, h, words[13], 0x80deb1fe); + STEP(a, b, c, d, e, f, g, h, words[14], 0x9bdc06a7); + STEP(a, b, c, d, e, f, g, h, words[15], 0xc19bf174); + + STEP(a, b, c, d, e, f, g, h, words[16], 0xe49b69c1); + STEP(a, b, c, d, e, f, g, h, words[17], 0xefbe4786); + STEP(a, b, c, d, e, f, g, h, words[18], 0x0fc19dc6); + STEP(a, b, c, d, e, f, g, h, words[19], 0x240ca1cc); + STEP(a, b, c, d, e, f, g, h, words[20], 0x2de92c6f); + STEP(a, b, c, d, e, f, g, h, words[21], 0x4a7484aa); + STEP(a, b, c, d, e, f, g, h, words[22], 0x5cb0a9dc); + STEP(a, b, c, d, e, f, g, h, words[23], 0x76f988da); + STEP(a, b, c, d, e, f, g, h, words[24], 0x983e5152); + STEP(a, b, c, d, e, f, g, h, words[25], 0xa831c66d); + STEP(a, b, c, d, e, f, g, h, words[26], 0xb00327c8); + STEP(a, b, c, d, e, f, g, h, words[27], 0xbf597fc7); + STEP(a, b, c, d, e, f, g, h, words[28], 0xc6e00bf3); + STEP(a, b, c, d, e, f, g, h, words[29], 0xd5a79147); + STEP(a, b, c, d, e, f, g, h, words[30], 0x06ca6351); + STEP(a, b, c, d, e, f, g, h, words[31], 0x14292967); + + STEP(a, b, c, d, e, f, g, h, words[32], 0x27b70a85); + STEP(a, b, c, d, e, f, g, h, words[33], 0x2e1b2138); + STEP(a, b, c, d, e, f, g, h, words[34], 0x4d2c6dfc); + STEP(a, b, c, d, e, f, g, h, words[35], 0x53380d13); + STEP(a, b, c, d, e, f, g, h, words[36], 0x650a7354); + STEP(a, b, c, d, e, f, g, h, words[37], 0x766a0abb); + STEP(a, b, c, d, e, f, g, h, words[38], 0x81c2c92e); + STEP(a, b, c, d, e, f, g, h, words[39], 0x92722c85); + STEP(a, b, c, d, e, f, g, h, words[40], 0xa2bfe8a1); + STEP(a, b, c, d, e, f, g, h, words[41], 0xa81a664b); + STEP(a, b, c, d, e, f, g, h, words[42], 0xc24b8b70); + STEP(a, b, c, d, e, f, g, h, words[43], 0xc76c51a3); + STEP(a, b, c, d, e, f, g, h, words[44], 0xd192e819); + STEP(a, b, c, d, e, f, g, h, words[45], 0xd6990624); + STEP(a, b, c, d, e, f, g, h, words[46], 0xf40e3585); + STEP(a, b, c, d, e, f, g, h, words[47], 0x106aa070); + + STEP(a, b, c, d, e, f, g, h, words[48], 0x19a4c116); + STEP(a, b, c, d, e, f, g, h, words[49], 0x1e376c08); + STEP(a, b, c, d, e, f, g, h, words[50], 0x2748774c); + STEP(a, b, c, d, e, f, g, h, words[51], 0x34b0bcb5); + STEP(a, b, c, d, e, f, g, h, words[52], 0x391c0cb3); + STEP(a, b, c, d, e, f, g, h, words[53], 0x4ed8aa4a); + STEP(a, b, c, d, e, f, g, h, words[54], 0x5b9cca4f); + STEP(a, b, c, d, e, f, g, h, words[55], 0x682e6ff3); + STEP(a, b, c, d, e, f, g, h, words[56], 0x748f82ee); + STEP(a, b, c, d, e, f, g, h, words[57], 0x78a5636f); + STEP(a, b, c, d, e, f, g, h, words[58], 0x84c87814); + STEP(a, b, c, d, e, f, g, h, words[59], 0x8cc70208); + STEP(a, b, c, d, e, f, g, h, words[60], 0x90befffa); + STEP(a, b, c, d, e, f, g, h, words[61], 0xa4506ceb); + STEP(a, b, c, d, e, f, g, h, words[62], 0xbef9a3f7); + STEP(a, b, c, d, e, f, g, h, words[63], 0xc67178f2); + + a += saved_a; + b += saved_b; + c += saved_c; + d += saved_d; + e += saved_e; + f += saved_f; + g += saved_g; + h += saved_h; + + p += 64; + + } while (size -= 64); + + ctx->a = a; + ctx->b = b; + ctx->c = c; + ctx->d = d; + ctx->e = e; + ctx->f = f; + ctx->g = g; + ctx->h = h; + + return p; +} diff -r 6fa96ea99037 -r 0479e5821ab2 src/njs_hash.h --- a/src/njs_hash.h Wed Feb 14 21:33:56 2024 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,32 +0,0 @@ - -/* - * Copyright (C) Dmitry Volyntsev - * Copyright (C) NGINX, Inc. - */ - - -#ifndef _NJS_HASH_H_INCLUDED_ -#define _NJS_HASH_H_INCLUDED_ - - -typedef struct { - uint64_t bytes; - uint32_t a, b, c, d, e, f, g, h; - u_char buffer[64]; -} njs_hash_t; - - _______________________________________________ nginx-devel mailing list nginx-devel@nginx.org https://mailman.nginx.org/mailman/listinfo/nginx-devel