This commit is contained in:
Eugene 2026-05-24 05:40:58 +00:00 committed by GitHub
commit 318ed600da
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 133 additions and 13 deletions

View file

@ -25,6 +25,7 @@ CORE_DEPS="src/core/nginx.h \
src/core/ngx_crc.h \
src/core/ngx_crc32.h \
src/core/ngx_murmurhash.h \
src/core/ngx_siphash.h \
src/core/ngx_md5.h \
src/core/ngx_sha1.h \
src/core/ngx_rbtree.h \
@ -60,6 +61,7 @@ CORE_SRCS="src/core/nginx.c \
src/core/ngx_file.c \
src/core/ngx_crc32.c \
src/core/ngx_murmurhash.c \
src/core/ngx_siphash.c \
src/core/ngx_md5.c \
src/core/ngx_sha1.c \
src/core/ngx_rbtree.c \

View file

@ -71,6 +71,7 @@ typedef void (*ngx_connection_handler_pt)(ngx_connection_t *c);
#include <ngx_crc.h>
#include <ngx_crc32.h>
#include <ngx_murmurhash.h>
#include <ngx_siphash.h>
#if (NGX_PCRE)
#include <ngx_regex.h>
#endif

95
src/core/ngx_siphash.c Normal file
View file

@ -0,0 +1,95 @@
/*
* Copyright (C) Nginx, Inc.
*/
#include <ngx_config.h>
#include <ngx_core.h>
/*
* SipHash-2-4 implementation based on the SipHash specification by
* Jean-Philippe Aumasson and Daniel J. Bernstein.
* https://eprint.iacr.org/2012/351.pdf
*/
#define ngx_siphash_rotl(x, b) \
(uint64_t) (((x) << (b)) | ((x) >> (64 - (b))))
#define ngx_sipround \
do { \
v0 += v1; v1 = ngx_siphash_rotl(v1, 13); v1 ^= v0; \
v0 = ngx_siphash_rotl(v0, 32); \
v2 += v3; v3 = ngx_siphash_rotl(v3, 16); v3 ^= v2; \
v0 += v3; v3 = ngx_siphash_rotl(v3, 21); v3 ^= v0; \
v2 += v1; v1 = ngx_siphash_rotl(v1, 17); v1 ^= v2; \
v2 = ngx_siphash_rotl(v2, 32); \
} while (0)
uint64_t
ngx_siphash(uint64_t k0, uint64_t k1, u_char *data, size_t len)
{
u_char *end;
size_t remainder;
uint64_t v0, v1, v2, v3, m;
v0 = k0 ^ 0x736f6d6570736575ULL;
v1 = k1 ^ 0x646f72616e646f6dULL;
v2 = k0 ^ 0x6c7967656e657261ULL;
v3 = k1 ^ 0x7465646279746573ULL;
end = data + (len - (len % 8));
for ( ; data != end; data += 8) {
ngx_memcpy(&m, data, 8);
v3 ^= m;
ngx_sipround;
ngx_sipround;
v0 ^= m;
}
m = (uint64_t) len << 56;
remainder = len & 7;
switch (remainder) {
case 7:
m |= (uint64_t) data[6] << 48;
/* fall through */
case 6:
m |= (uint64_t) data[5] << 40;
/* fall through */
case 5:
m |= (uint64_t) data[4] << 32;
/* fall through */
case 4:
m |= (uint64_t) data[3] << 24;
/* fall through */
case 3:
m |= (uint64_t) data[2] << 16;
/* fall through */
case 2:
m |= (uint64_t) data[1] << 8;
/* fall through */
case 1:
m |= (uint64_t) data[0];
break;
case 0:
break;
}
v3 ^= m;
ngx_sipround;
ngx_sipround;
v0 ^= m;
v2 ^= 0xff;
ngx_sipround;
ngx_sipround;
ngx_sipround;
ngx_sipround;
return v0 ^ v1 ^ v2 ^ v3;
}

18
src/core/ngx_siphash.h Normal file
View file

@ -0,0 +1,18 @@
/*
* Copyright (C) Nginx, Inc.
*/
#ifndef _NGX_SIPHASH_H_INCLUDED_
#define _NGX_SIPHASH_H_INCLUDED_
#include <ngx_config.h>
#include <ngx_core.h>
uint64_t ngx_siphash(uint64_t k0, uint64_t k1, u_char *data, size_t len);
#endif /* _NGX_SIPHASH_H_INCLUDED_ */

View file

@ -2298,11 +2298,10 @@ static ngx_int_t
ngx_http_variable_request_id(ngx_http_request_t *r,
ngx_http_variable_value_t *v, uintptr_t data)
{
u_char *id;
u_char *id;
uint64_t random_bytes[2];
#if (NGX_OPENSSL)
u_char random_bytes[16];
#endif
static uint64_t counter, key[2];
id = ngx_pnalloc(r->pool, 32);
if (id == NULL) {
@ -2316,20 +2315,25 @@ ngx_http_variable_request_id(ngx_http_request_t *r,
v->len = 32;
v->data = id;
if (counter == 0) {
#if (NGX_OPENSSL)
if (RAND_bytes(random_bytes, 16) == 1) {
ngx_hex_dump(id, random_bytes, 16);
return NGX_OK;
if (RAND_bytes((u_char *) key, 16) != 1)
#endif
{
key[0] = ((uint64_t) ngx_random() << 32) | (uint32_t) ngx_random();
key[1] = ((uint64_t) ngx_random() << 32) | (uint32_t) ngx_random();
key[0] ^= (uint64_t) ngx_pid << 16;
key[1] ^= (uint64_t) ngx_time();
}
}
ngx_ssl_error(NGX_LOG_ERR, r->connection->log, 0, "RAND_bytes() failed");
counter++;
random_bytes[0] = ngx_siphash(key[0], key[1], (u_char *) &counter, 8);
#endif
counter++;
random_bytes[1] = ngx_siphash(key[0], key[1], (u_char *) &counter, 8);
ngx_sprintf(id, "%08xD%08xD%08xD%08xD",
(uint32_t) ngx_random(), (uint32_t) ngx_random(),
(uint32_t) ngx_random(), (uint32_t) ngx_random());
ngx_hex_dump(id, (u_char *) random_bytes, 16);
return NGX_OK;
}