VeraCrypt
aboutsummaryrefslogtreecommitdiff
path: root/src/Crypto/jitterentropy.h
blob: 3dd6901751f7320e2a74eca1da61fd07ea563807 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
/*
 * Non-physical true random number generator based on timing jitter.
 *
 * Copyright Stephan Mueller <smueller@chronox.de>, 2014 - 2019
 *
 * License
 * =======
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, and the entire permission notice in its entirety,
 *    including the disclaimer of warranties.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. The name of the author may not be used to endorse or promote
 *    products derived from this software without specific prior
 *    written permission.
 *
 * ALTERNATIVELY, this product may be distributed under the terms of
 * the GNU General Public License, in which case the provisions of the GPL are
 * required INSTEAD OF the above restrictions.  (This clause is
 * necessary due to a potential bad interaction between the GPL and
 * the restrictions contained in a BSD-style copyright.)
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF
 * WHICH ARE HEREBY DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
 * USE OF THIS SOFTWARE, EVEN IF NOT ADVISED OF THE POSSIBILITY OF SUCH
 * DAMAGE.
 */

/* Adapted for VeraCrypt */

#ifndef _JITTERENTROPY_H
#define _JITTERENTROPY_H

#include "jitterentropy-base-user.h"

/* The entropy pool */
struct rand_data
{
	/* all data values that are vital to maintain the security
	 * of the RNG are marked as SENSITIVE. A user must not
	 * access that information while the RNG executes its loops to
	 * calculate the next random value. */
	uint64_t data;			/* SENSITIVE Actual random number */
	uint64_t prev_time;		/* SENSITIVE Previous time stamp */
#define DATA_SIZE_BITS ((sizeof(uint64_t)) * 8)
	uint64_t last_delta;		/* SENSITIVE stuck test */
	uint64_t last_delta2;		/* SENSITIVE stuck test */
	unsigned int osr;		/* Oversampling rate */
#define JENT_MEMORY_BLOCKS 64
#define JENT_MEMORY_BLOCKSIZE 32
#define JENT_MEMORY_ACCESSLOOPS 128
#define JENT_MEMORY_SIZE (JENT_MEMORY_BLOCKS*JENT_MEMORY_BLOCKSIZE)
	unsigned char *mem;		/* Memory access location with size of
					 * memblocks * memblocksize */
	unsigned int memlocation; 	/* Pointer to byte in *mem */
	unsigned int memblocks;		/* Number of memory blocks in *mem */
	unsigned int memblocksize; 	/* Size of one memory block in bytes */
	unsigned int memaccessloops;	/* Number of memory accesses per random
					 * bit generation */

	/* Repetition Count Test */
	int rct_count;			/* Number of stuck values */

	/* Adaptive Proportion Test for a significance level of 2^-30 */
#define JENT_APT_CUTOFF		325	/* Taken from SP800-90B sec 4.4.2 */
#define JENT_APT_WINDOW_SIZE	512	/* Data window size */
	/* LSB of time stamp to process */
#define JENT_APT_LSB		16
#define JENT_APT_WORD_MASK	(JENT_APT_LSB - 1)
	unsigned int apt_observations;	/* Number of collected observations */
	unsigned int apt_count;		/* APT counter */
	unsigned int apt_base;		/* APT base reference */
	unsigned int apt_base_set:1;	/* APT base reference set? */

	unsigned int fips_enabled:1;
	unsigned int health_failure:1;	/* Permanent health failure */
};

/* Flags that can be used to initialize the RNG */
#define JENT_DISABLE_STIR (1<<0) 	/* UNUSED */
#define JENT_DISABLE_UNBIAS (1<<1) 	/* UNUSED */
#define JENT_DISABLE_MEMORY_ACCESS (1<<2) /* Disable memory access for more
					     entropy, saves MEMORY_SIZE RAM for
					     entropy collector */

/* -- BEGIN Main interface functions -- */

#ifndef JENT_STUCK_INIT_THRES
/*
 * Per default, not more than 90% of all measurements during initialization
 * are allowed to be stuck.
 *
 * It is allowed to change this value as required for the intended environment.
 */
#define JENT_STUCK_INIT_THRES(x) (x/10 * 9)
#endif

#ifdef JENT_PRIVATE_COMPILE
# define JENT_PRIVATE_STATIC static
#else /* JENT_PRIVATE_COMPILE */
# define JENT_PRIVATE_STATIC
#endif

#ifdef __cplusplus
extern "C" {
#endif

/* Number of low bits of the time value that we want to consider */
/* get raw entropy */
JENT_PRIVATE_STATIC
ssize_t jent_read_entropy(struct rand_data *ec, char *data, size_t len);
/* initialize an instance of the entropy collector */
JENT_PRIVATE_STATIC
struct rand_data *jent_entropy_collector_alloc(unsigned int osr,
	       				       unsigned int flags);
/* clearing of entropy collector */
JENT_PRIVATE_STATIC
void jent_entropy_collector_free(struct rand_data *entropy_collector);

/* initialization of entropy collector */
JENT_PRIVATE_STATIC
int jent_entropy_init(void);

/* return version number of core library */
JENT_PRIVATE_STATIC
unsigned int jent_version(void);

/* -- END of Main interface functions -- */

/* -- BEGIN error codes for init function -- */
#define ENOTIME  	1 /* Timer service not available */
#define ECOARSETIME	2 /* Timer too coarse for RNG */
#define ENOMONOTONIC	3 /* Timer is not monotonic increasing */
#define EMINVARIATION	4 /* Timer variations too small for RNG */
#define EVARVAR		5 /* Timer does not produce variations of variations
			     (2nd derivation of time is zero) */
#define EMINVARVAR	6 /* Timer variations of variations is too small */
#define EPROGERR	7 /* Programming error */
#define ESTUCK		8 /* Too many stuck results during init. */
#define EHEALTH		9 /* Health test failed during initialization */
#define ERCT		10 /* RCT failed during initialization */

/* -- BEGIN statistical test functions only complied with CONFIG_CRYPTO_CPU_JITTERENTROPY_STAT -- */

#ifdef CONFIG_CRYPTO_CPU_JITTERENTROPY_STAT
JENT_PRIVATE_STATIC
uint64_t jent_lfsr_var_stat(struct rand_data *ec, unsigned int min);
#endif /* CONFIG_CRYPTO_CPU_JITTERENTROPY_STAT */

/* -- END of statistical test function -- */

#ifdef __cplusplus
}
#endif


#endif /* _JITTERENTROPY_H */
(shared_ptr <EncryptionAlgorithm> (new AESTwofish ())); l.push_back (shared_ptr <EncryptionAlgorithm> (new AESTwofishSerpent ())); l.push_back (shared_ptr <EncryptionAlgorithm> (new SerpentAES ())); l.push_back (shared_ptr <EncryptionAlgorithm> (new SerpentTwofishAES ())); l.push_back (shared_ptr <EncryptionAlgorithm> (new TwofishSerpent ())); return l; } size_t EncryptionAlgorithm::GetLargestKeySize (const EncryptionAlgorithmList &algorithms) { size_t largestKeySize = 0; foreach_ref (const EncryptionAlgorithm &ea, algorithms) { if (ea.GetKeySize() > largestKeySize) largestKeySize = ea.GetKeySize(); } return largestKeySize; } size_t EncryptionAlgorithm::GetKeySize () const { if (Ciphers.size() < 1) throw NotInitialized (SRC_POS); size_t keySize = 0; foreach_ref (const Cipher &c, Ciphers) keySize += c.GetKeySize(); return keySize; } size_t EncryptionAlgorithm::GetMaxBlockSize () const { size_t blockSize = 0; foreach_ref (const Cipher &c, Ciphers) if (c.GetBlockSize() > blockSize) blockSize = c.GetBlockSize(); return blockSize; } size_t EncryptionAlgorithm::GetMinBlockSize () const { size_t blockSize = 0; foreach_ref (const Cipher &c, Ciphers) if (blockSize == 0 || c.GetBlockSize() < blockSize) blockSize = c.GetBlockSize(); return blockSize; } shared_ptr <EncryptionMode> EncryptionAlgorithm::GetMode () const { if (Mode.get() == nullptr) throw NotInitialized (SRC_POS); return Mode; } wstring EncryptionAlgorithm::GetName (bool forGuiDisplay) const { if (Ciphers.size() < 1) throw NotInitialized (SRC_POS); wstring name; int depth = 0; foreach_reverse_ref (const Cipher &c, Ciphers) { if (name.empty()) name = c.GetName(); else { depth++; if (forGuiDisplay) name += wstring (L"("); else name += wstring (L"-"); name += c.GetName(); } } if (forGuiDisplay && depth) { for (int i = 0; i < depth; i++) name += wstring(L")"); } return name; } bool EncryptionAlgorithm::IsModeSupported (const EncryptionMode &mode) const { bool supported = false; foreach_ref (const EncryptionMode &em, SupportedModes) { if (typeid (mode) == typeid (em)) { supported = true; break; } } return supported; } bool EncryptionAlgorithm::IsModeSupported (const shared_ptr <EncryptionMode> mode) const { return IsModeSupported (*mode); } void EncryptionAlgorithm::SetMode (shared_ptr <EncryptionMode> mode) { if (!IsModeSupported (*mode)) throw ParameterIncorrect (SRC_POS); mode->SetCiphers (Ciphers); Mode = mode; } void EncryptionAlgorithm::SetKey (const ConstBufferPtr &key) { if (Ciphers.size() < 1) throw NotInitialized (SRC_POS); if (GetKeySize() != key.Size()) throw ParameterIncorrect (SRC_POS); size_t keyOffset = 0; foreach_ref (Cipher &c, Ciphers) { c.SetKey (key.GetRange (keyOffset, c.GetKeySize())); keyOffset += c.GetKeySize(); } } void EncryptionAlgorithm::ValidateState () const { if (Ciphers.size() < 1 || Mode.get() == nullptr) throw NotInitialized (SRC_POS); } // AES AES::AES () { Ciphers.push_back (shared_ptr <Cipher> (new CipherAES())); SupportedModes.push_back (shared_ptr <EncryptionMode> (new EncryptionModeXTS ())); } // AES-Twofish AESTwofish::AESTwofish () { Ciphers.push_back (shared_ptr <Cipher> (new CipherTwofish ())); Ciphers.push_back (shared_ptr <Cipher> (new CipherAES ())); SupportedModes.push_back (shared_ptr <EncryptionMode> (new EncryptionModeXTS ())); } // AES-Twofish-Serpent AESTwofishSerpent::AESTwofishSerpent () { Ciphers.push_back (shared_ptr <Cipher> (new CipherSerpent ())); Ciphers.push_back (shared_ptr <Cipher> (new CipherTwofish ())); Ciphers.push_back (shared_ptr <Cipher> (new CipherAES ())); SupportedModes.push_back (shared_ptr <EncryptionMode> (new EncryptionModeXTS ())); } // Serpent Serpent::Serpent () { Ciphers.push_back (shared_ptr <Cipher> (new CipherSerpent())); SupportedModes.push_back (shared_ptr <EncryptionMode> (new EncryptionModeXTS ())); } // Serpent-AES SerpentAES::SerpentAES () { Ciphers.push_back (shared_ptr <Cipher> (new CipherAES ())); Ciphers.push_back (shared_ptr <Cipher> (new CipherSerpent ())); SupportedModes.push_back (shared_ptr <EncryptionMode> (new EncryptionModeXTS ())); } // Twofish Twofish::Twofish () { Ciphers.push_back (shared_ptr <Cipher> (new CipherTwofish())); SupportedModes.push_back (shared_ptr <EncryptionMode> (new EncryptionModeXTS ())); } // Twofish-Serpent TwofishSerpent::TwofishSerpent () { Ciphers.push_back (shared_ptr <Cipher> (new CipherSerpent ())); Ciphers.push_back (shared_ptr <Cipher> (new CipherTwofish ())); SupportedModes.push_back (shared_ptr <EncryptionMode> (new EncryptionModeXTS ())); } // Serpent-Twofish-AES SerpentTwofishAES::SerpentTwofishAES () { Ciphers.push_back (shared_ptr <Cipher> (new CipherAES ())); Ciphers.push_back (shared_ptr <Cipher> (new CipherTwofish ())); Ciphers.push_back (shared_ptr <Cipher> (new CipherSerpent ())); SupportedModes.push_back (shared_ptr <EncryptionMode> (new EncryptionModeXTS ())); } // Camellia Camellia::Camellia () { Ciphers.push_back (shared_ptr <Cipher> (new CipherCamellia())); SupportedModes.push_back (shared_ptr <EncryptionMode> (new EncryptionModeXTS ())); } // GOST89 GOST89::GOST89 () { Deprecated = true; Ciphers.push_back (shared_ptr <Cipher> (new CipherGost89())); SupportedModes.push_back (shared_ptr <EncryptionMode> (new EncryptionModeXTS ())); } // Kuznyechik Kuznyechik::Kuznyechik () { Ciphers.push_back (shared_ptr <Cipher> (new CipherKuznyechik())); SupportedModes.push_back (shared_ptr <EncryptionMode> (new EncryptionModeXTS ())); } }