diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-28 07:33:12 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-28 07:33:12 +0000 |
commit | 36082a2fe36ecd800d784ae44c14f1f18c66a7e9 (patch) | |
tree | 6c68e0c0097987aff85a01dabddd34b862309a7c /lib/nettle/rnd-fuzzer.c | |
parent | Initial commit. (diff) | |
download | gnutls28-upstream.tar.xz gnutls28-upstream.zip |
Adding upstream version 3.7.9.upstream/3.7.9upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'lib/nettle/rnd-fuzzer.c')
-rw-r--r-- | lib/nettle/rnd-fuzzer.c | 150 |
1 files changed, 150 insertions, 0 deletions
diff --git a/lib/nettle/rnd-fuzzer.c b/lib/nettle/rnd-fuzzer.c new file mode 100644 index 0000000..821eebc --- /dev/null +++ b/lib/nettle/rnd-fuzzer.c @@ -0,0 +1,150 @@ +/* + * Copyright (C) 2017 Red Hat + * Copyright (C) 1995-2017 Free Software Foundation, Inc. + * This file is part of the GNU C Library. + * Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu>, August 1995. + * + * This file is part of GnuTLS. + * + * Libgcrypt is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * Libgcrypt is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, see <https://www.gnu.org/licenses/>. + */ + +#include <config.h> +#include <stdio.h> +#include <stdlib.h> +#include <errno.h> +#include <sys/types.h> +#include <drbg-aes.h> +#include <fips.h> + +#include "gnutls_int.h" +#include "errors.h" +#include <stdlib.h> +#include <rnd-common.h> + +#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION + +struct r48_rand_data { + unsigned short int __x[3]; /* Current state. */ + unsigned short int __old_x[3]; /* Old state. */ + unsigned short int __c; /* Additive const. in congruential formula. */ + unsigned short int __init; /* Flag for initializing. */ + __extension__ unsigned long long int __a; /* Factor in congruential + formula. */ +}; + +#ifdef __clang__ +__attribute__((no_sanitize("integer"))) +#endif +static int +__r48_rand_iterate(unsigned short int xsubi[3], struct r48_rand_data *buffer) +{ + uint64_t X; + uint64_t result; + + /* Initialize buffer, if not yet done. */ + if (unlikely(!buffer->__init)) { + buffer->__a = 0x5deece66dull; + buffer->__c = 0xb; + buffer->__init = 1; + } + + /* Do the real work. We choose a data type which contains at least + 48 bits. Because we compute the modulus it does not care how + many bits really are computed. */ + + X = (uint64_t) xsubi[2] << 32 | (uint32_t) xsubi[1] << 16 | xsubi[0]; + + result = X * buffer->__a + buffer->__c; + + xsubi[0] = result & 0xffff; + xsubi[1] = (result >> 16) & 0xffff; + xsubi[2] = (result >> 32) & 0xffff; + + return 0; +} + +#ifdef __clang__ +__attribute__((no_sanitize("integer"))) +#elif defined __GNUC__ +__attribute__((no_sanitize("shift-base"))) +#endif +static int +r48_r(unsigned short int xsubi[3], struct r48_rand_data *buffer, + long int *result) +{ + /* Compute next state. */ + if (__r48_rand_iterate(xsubi, buffer) < 0) + return -1; + + /* Store the result. */ + *result = (int32_t) ((xsubi[2] << 16) | xsubi[1]); + + return 0; +} + +static int r48(struct r48_rand_data *buffer, long int *result) +{ + return r48_r(buffer->__x, buffer, result); +} + +/* This is a dummy random generator intended to be reproducible + * for use in fuzzying targets. + */ + +static int _rngfuzz_init(void **_ctx) +{ + *_ctx = calloc(1, sizeof(struct r48_rand_data)); + + return 0; +} + +static int _rngfuzz_rnd(void *_ctx, int level, void *buffer, size_t length) +{ + struct r48_rand_data *ctx = _ctx; + uint8_t *p = buffer; + long r; + unsigned i; + + memset(ctx, 0, sizeof(*ctx)); + + for (i = 0; i < length; i++) { + r48(ctx, &r); + p[i] = r; + } + return 0; +} + +static void _rngfuzz_deinit(void *_ctx) +{ + struct r48_rand_data *ctx = _ctx; + + free(ctx); +} + +static void _rngfuzz_refresh(void *_ctx) +{ + /* this is predictable RNG. Don't refresh */ + return; +} + +gnutls_crypto_rnd_st _gnutls_fuzz_rnd_ops = { + .init = _rngfuzz_init, + .deinit = _rngfuzz_deinit, + .rnd = _rngfuzz_rnd, + .rnd_refresh = _rngfuzz_refresh, + .self_test = NULL, +}; + +#endif /* FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION */ |