/src/gnutls/lib/nettle/rnd-fuzzer.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * Copyright (C) 2017 Red Hat |
3 | | * Copyright (C) 1995-2017 Free Software Foundation, Inc. |
4 | | * This file is part of the GNU C Library. |
5 | | * Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu>, August 1995. |
6 | | * |
7 | | * This file is part of GnuTLS. |
8 | | * |
9 | | * Libgcrypt is free software; you can redistribute it and/or modify |
10 | | * it under the terms of the GNU Lesser General Public License as |
11 | | * published by the Free Software Foundation; either version 2.1 of |
12 | | * the License, or (at your option) any later version. |
13 | | * |
14 | | * Libgcrypt is distributed in the hope that it will be useful, |
15 | | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
16 | | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
17 | | * GNU Lesser General Public License for more details. |
18 | | * |
19 | | * You should have received a copy of the GNU Lesser General Public |
20 | | * License along with this program. If not, see <https://www.gnu.org/licenses/>. |
21 | | */ |
22 | | |
23 | | #include "config.h" |
24 | | #include <stdio.h> |
25 | | #include <stdlib.h> |
26 | | #include <errno.h> |
27 | | #include <sys/types.h> |
28 | | #include "drbg-aes.h" |
29 | | #include "fips.h" |
30 | | |
31 | | #include "gnutls_int.h" |
32 | | #include "errors.h" |
33 | | #include <stdlib.h> |
34 | | #include "rnd-common.h" |
35 | | |
36 | | #ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION |
37 | | |
38 | | struct r48_rand_data { |
39 | | unsigned short int __x[3]; /* Current state. */ |
40 | | unsigned short int __old_x[3]; /* Old state. */ |
41 | | unsigned short int __c; /* Additive const. in congruential formula. */ |
42 | | unsigned short int __init; /* Flag for initializing. */ |
43 | | __extension__ unsigned long long int __a; /* Factor in congruential |
44 | | formula. */ |
45 | | }; |
46 | | |
47 | | #ifdef __clang__ |
48 | | __attribute__((no_sanitize("integer"))) |
49 | | #endif |
50 | | static int |
51 | | __r48_rand_iterate(unsigned short int xsubi[3], struct r48_rand_data *buffer) |
52 | 0 | { |
53 | 0 | uint64_t X; |
54 | 0 | uint64_t result; |
55 | | |
56 | | /* Initialize buffer, if not yet done. */ |
57 | 0 | if (unlikely(!buffer->__init)) { |
58 | 0 | buffer->__a = 0x5deece66dull; |
59 | 0 | buffer->__c = 0xb; |
60 | 0 | buffer->__init = 1; |
61 | 0 | } |
62 | | |
63 | | /* Do the real work. We choose a data type which contains at least |
64 | | 48 bits. Because we compute the modulus it does not care how |
65 | | many bits really are computed. */ |
66 | |
|
67 | 0 | X = (uint64_t)xsubi[2] << 32 | (uint32_t)xsubi[1] << 16 | xsubi[0]; |
68 | |
|
69 | 0 | result = X * buffer->__a + buffer->__c; |
70 | |
|
71 | 0 | xsubi[0] = result & 0xffff; |
72 | 0 | xsubi[1] = (result >> 16) & 0xffff; |
73 | 0 | xsubi[2] = (result >> 32) & 0xffff; |
74 | |
|
75 | 0 | return 0; |
76 | 0 | } |
77 | | |
78 | | #ifdef __clang__ |
79 | | __attribute__((no_sanitize("integer"))) |
80 | | #elif defined __GNUC__ |
81 | | __attribute__((no_sanitize("shift-base"))) |
82 | | #endif |
83 | | static int |
84 | | r48_r(unsigned short int xsubi[3], struct r48_rand_data *buffer, |
85 | | long int *result) |
86 | 0 | { |
87 | | /* Compute next state. */ |
88 | 0 | if (__r48_rand_iterate(xsubi, buffer) < 0) |
89 | 0 | return -1; |
90 | | |
91 | | /* Store the result. */ |
92 | 0 | *result = (int32_t)((xsubi[2] << 16) | xsubi[1]); |
93 | |
|
94 | 0 | return 0; |
95 | 0 | } |
96 | | |
97 | | static int r48(struct r48_rand_data *buffer, long int *result) |
98 | 0 | { |
99 | 0 | return r48_r(buffer->__x, buffer, result); |
100 | 0 | } |
101 | | |
102 | | /* This is a dummy random generator intended to be reproducible |
103 | | * for use in fuzzying targets. |
104 | | */ |
105 | | |
106 | | static int _rngfuzz_init(void **_ctx) |
107 | 0 | { |
108 | 0 | *_ctx = calloc(1, sizeof(struct r48_rand_data)); |
109 | |
|
110 | 0 | return 0; |
111 | 0 | } |
112 | | |
113 | | static int _rngfuzz_rnd(void *_ctx, int level, void *buffer, size_t length) |
114 | 0 | { |
115 | 0 | struct r48_rand_data *ctx = _ctx; |
116 | 0 | uint8_t *p = buffer; |
117 | 0 | long r; |
118 | 0 | unsigned i; |
119 | |
|
120 | 0 | memset(ctx, 0, sizeof(*ctx)); |
121 | |
|
122 | 0 | for (i = 0; i < length; i++) { |
123 | 0 | r48(ctx, &r); |
124 | 0 | p[i] = r; |
125 | 0 | } |
126 | 0 | return 0; |
127 | 0 | } |
128 | | |
129 | | static void _rngfuzz_deinit(void *_ctx) |
130 | 0 | { |
131 | 0 | struct r48_rand_data *ctx = _ctx; |
132 | |
|
133 | 0 | free(ctx); |
134 | 0 | } |
135 | | |
136 | | static void _rngfuzz_refresh(void *_ctx) |
137 | 0 | { |
138 | | /* this is predictable RNG. Don't refresh */ |
139 | 0 | return; |
140 | 0 | } |
141 | | |
142 | | gnutls_crypto_rnd_st _gnutls_fuzz_rnd_ops = { |
143 | | .init = _rngfuzz_init, |
144 | | .deinit = _rngfuzz_deinit, |
145 | | .rnd = _rngfuzz_rnd, |
146 | | .rnd_refresh = _rngfuzz_refresh, |
147 | | .self_test = NULL, |
148 | | }; |
149 | | |
150 | | #endif /* FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION */ |