Coverage Report

Created: 2024-11-21 07:03

/src/nss-nspr/nss/lib/freebl/det_rng.c
Line
Count
Source (jump to first uncovered line)
1
/* This Source Code Form is subject to the terms of the Mozilla Public
2
 * License, v. 2.0. If a copy of the MPL was not distributed with this
3
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4
5
#include "blapi.h"
6
#include "blapit.h"
7
#include "Hacl_Chacha20.h"
8
#include "nssilock.h"
9
#include "seccomon.h"
10
#include "secerr.h"
11
#include "prinit.h"
12
13
2
#define GLOBAL_BYTES_SIZE 100
14
static PRUint8 globalBytes[GLOBAL_BYTES_SIZE];
15
static unsigned long globalNumCalls = 0;
16
static PZLock *rng_lock = NULL;
17
static PRCallOnceType coRNGInit;
18
static const PRCallOnceType pristineCallOnce;
19
20
static PRStatus
21
rng_init(void)
22
2
{
23
2
    rng_lock = PZ_NewLock(nssILockOther);
24
2
    if (!rng_lock) {
25
0
        PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
26
0
        return PR_FAILURE;
27
0
    }
28
    /* --- LOCKED --- */
29
2
    PZ_Lock(rng_lock);
30
2
    memset(globalBytes, 0, GLOBAL_BYTES_SIZE);
31
2
    PZ_Unlock(rng_lock);
32
    /* --- UNLOCKED --- */
33
34
2
    return PR_SUCCESS;
35
2
}
36
37
SECStatus
38
RNG_RNGInit(void)
39
6
{
40
    /* Allow only one call to initialize the context */
41
6
    if (PR_CallOnce(&coRNGInit, rng_init) != PR_SUCCESS) {
42
0
        return SECFailure;
43
0
    }
44
45
6
    return SECSuccess;
46
6
}
47
48
/* Take min(size, GLOBAL_BYTES_SIZE) bytes from data and use as seed and reset
49
 * the rng state. */
50
SECStatus
51
RNG_RandomUpdate(const void *data, size_t bytes)
52
0
{
53
    /* Check for a valid RNG lock. */
54
0
    PORT_Assert(rng_lock != NULL);
55
0
    if (rng_lock == NULL) {
56
0
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
57
0
        return SECFailure;
58
0
    }
59
60
    /* --- LOCKED --- */
61
0
    PZ_Lock(rng_lock);
62
0
    memset(globalBytes, 0, GLOBAL_BYTES_SIZE);
63
0
    globalNumCalls = 0;
64
0
    if (data) {
65
0
        memcpy(globalBytes, (PRUint8 *)data, PR_MIN(bytes, GLOBAL_BYTES_SIZE));
66
0
    }
67
0
    PZ_Unlock(rng_lock);
68
    /* --- UNLOCKED --- */
69
70
0
    return SECSuccess;
71
0
}
72
73
SECStatus
74
RNG_GenerateGlobalRandomBytes(void *dest, size_t len)
75
156
{
76
156
    static const uint8_t key[32] = { 0 };
77
156
    uint8_t nonce[12] = { 0 };
78
79
    /* Check for a valid RNG lock. */
80
156
    PORT_Assert(rng_lock != NULL);
81
156
    if (rng_lock == NULL) {
82
0
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
83
0
        return SECFailure;
84
0
    }
85
86
    /* --- LOCKED --- */
87
156
    PZ_Lock(rng_lock);
88
89
156
    memcpy(nonce, &globalNumCalls, sizeof(globalNumCalls));
90
156
    globalNumCalls++;
91
92
156
    ChaCha20Poly1305Context *cx =
93
156
        ChaCha20Poly1305_CreateContext(key, sizeof(key), 16);
94
156
    if (!cx) {
95
0
        PORT_SetError(SEC_ERROR_NO_MEMORY);
96
0
        PZ_Unlock(rng_lock);
97
0
        return SECFailure;
98
0
    }
99
100
156
    memset(dest, 0, len);
101
156
    memcpy(dest, globalBytes, PR_MIN(len, GLOBAL_BYTES_SIZE));
102
156
    Hacl_Chacha20_chacha20_encrypt(len, (uint8_t *)dest, (uint8_t *)dest,
103
156
                                   (uint8_t *)key, nonce, 0);
104
156
    ChaCha20Poly1305_DestroyContext(cx, PR_TRUE);
105
106
156
    PZ_Unlock(rng_lock);
107
    /* --- UNLOCKED --- */
108
109
156
    return SECSuccess;
110
156
}
111
112
void
113
RNG_RNGShutdown(void)
114
0
{
115
0
    if (rng_lock) {
116
0
        PZ_DestroyLock(rng_lock);
117
0
        rng_lock = NULL;
118
0
    }
119
0
    coRNGInit = pristineCallOnce;
120
0
}
121
122
/* Test functions are not implemented! */
123
SECStatus
124
PRNGTEST_Instantiate(const PRUint8 *entropy, unsigned int entropy_len,
125
                     const PRUint8 *nonce, unsigned int nonce_len,
126
                     const PRUint8 *personal_string, unsigned int ps_len)
127
0
{
128
0
    return SECFailure;
129
0
}
130
131
SECStatus
132
PRNGTEST_Reseed(const PRUint8 *entropy, unsigned int entropy_len,
133
                const PRUint8 *additional, unsigned int additional_len)
134
0
{
135
0
    return SECFailure;
136
0
}
137
138
SECStatus
139
PRNGTEST_Generate(PRUint8 *bytes, unsigned int bytes_len,
140
                  const PRUint8 *additional, unsigned int additional_len)
141
0
{
142
0
    return SECFailure;
143
0
}
144
145
SECStatus
146
PRNGTEST_Uninstantiate()
147
0
{
148
0
    return SECFailure;
149
0
}
150
151
SECStatus
152
PRNGTEST_RunHealthTests()
153
2
{
154
2
    return SECFailure;
155
2
}
156
157
SECStatus
158
PRNGTEST_Instantiate_Kat(const PRUint8 *entropy, unsigned int entropy_len,
159
                         const PRUint8 *nonce, unsigned int nonce_len,
160
                         const PRUint8 *personal_string, unsigned int ps_len)
161
0
{
162
0
    return SECFailure;
163
0
}