spiped 0.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/ext/spiped/extconf.rb +3 -0
- data/ext/spiped/spiped-source/BUILDING +46 -0
- data/ext/spiped/spiped-source/CHANGELOG +44 -0
- data/ext/spiped/spiped-source/COPYRIGHT +33 -0
- data/ext/spiped/spiped-source/Makefile +47 -0
- data/ext/spiped/spiped-source/Makefile.POSIX +27 -0
- data/ext/spiped/spiped-source/Makefile.inc +20 -0
- data/ext/spiped/spiped-source/Makefile.prog +23 -0
- data/ext/spiped/spiped-source/POSIX/README +10 -0
- data/ext/spiped/spiped-source/POSIX/posix-cflags.sh +10 -0
- data/ext/spiped/spiped-source/POSIX/posix-clock_realtime.c +3 -0
- data/ext/spiped/spiped-source/POSIX/posix-l.c +1 -0
- data/ext/spiped/spiped-source/POSIX/posix-l.sh +14 -0
- data/ext/spiped/spiped-source/POSIX/posix-msg_nosignal.c +3 -0
- data/ext/spiped/spiped-source/README +198 -0
- data/ext/spiped/spiped-source/STYLE +151 -0
- data/ext/spiped/spiped-source/lib/dnsthread/dnsthread.c +464 -0
- data/ext/spiped/spiped-source/lib/dnsthread/dnsthread.h +45 -0
- data/ext/spiped/spiped-source/libcperciva/alg/sha256.c +442 -0
- data/ext/spiped/spiped-source/libcperciva/alg/sha256.h +95 -0
- data/ext/spiped/spiped-source/libcperciva/cpusupport/Build/cpusupport-X86-AESNI.c +13 -0
- data/ext/spiped/spiped-source/libcperciva/cpusupport/Build/cpusupport-X86-CPUID.c +8 -0
- data/ext/spiped/spiped-source/libcperciva/cpusupport/Build/cpusupport.sh +37 -0
- data/ext/spiped/spiped-source/libcperciva/cpusupport/cpusupport.h +63 -0
- data/ext/spiped/spiped-source/libcperciva/cpusupport/cpusupport_x86_aesni.c +30 -0
- data/ext/spiped/spiped-source/libcperciva/crypto/crypto_aes.c +166 -0
- data/ext/spiped/spiped-source/libcperciva/crypto/crypto_aes.h +31 -0
- data/ext/spiped/spiped-source/libcperciva/crypto/crypto_aes_aesni.c +229 -0
- data/ext/spiped/spiped-source/libcperciva/crypto/crypto_aes_aesni.h +31 -0
- data/ext/spiped/spiped-source/libcperciva/crypto/crypto_aesctr.c +124 -0
- data/ext/spiped/spiped-source/libcperciva/crypto/crypto_aesctr.h +41 -0
- data/ext/spiped/spiped-source/libcperciva/crypto/crypto_dh.c +293 -0
- data/ext/spiped/spiped-source/libcperciva/crypto/crypto_dh.h +43 -0
- data/ext/spiped/spiped-source/libcperciva/crypto/crypto_dh_group14.c +46 -0
- data/ext/spiped/spiped-source/libcperciva/crypto/crypto_dh_group14.h +9 -0
- data/ext/spiped/spiped-source/libcperciva/crypto/crypto_entropy.c +215 -0
- data/ext/spiped/spiped-source/libcperciva/crypto/crypto_entropy.h +14 -0
- data/ext/spiped/spiped-source/libcperciva/crypto/crypto_verify_bytes.c +21 -0
- data/ext/spiped/spiped-source/libcperciva/crypto/crypto_verify_bytes.h +14 -0
- data/ext/spiped/spiped-source/libcperciva/datastruct/elasticarray.c +276 -0
- data/ext/spiped/spiped-source/libcperciva/datastruct/elasticarray.h +167 -0
- data/ext/spiped/spiped-source/libcperciva/datastruct/mpool.h +85 -0
- data/ext/spiped/spiped-source/libcperciva/datastruct/ptrheap.c +334 -0
- data/ext/spiped/spiped-source/libcperciva/datastruct/ptrheap.h +89 -0
- data/ext/spiped/spiped-source/libcperciva/datastruct/timerqueue.c +241 -0
- data/ext/spiped/spiped-source/libcperciva/datastruct/timerqueue.h +60 -0
- data/ext/spiped/spiped-source/libcperciva/events/events.c +203 -0
- data/ext/spiped/spiped-source/libcperciva/events/events.h +106 -0
- data/ext/spiped/spiped-source/libcperciva/events/events_immediate.c +149 -0
- data/ext/spiped/spiped-source/libcperciva/events/events_internal.h +95 -0
- data/ext/spiped/spiped-source/libcperciva/events/events_network.c +347 -0
- data/ext/spiped/spiped-source/libcperciva/events/events_network_selectstats.c +106 -0
- data/ext/spiped/spiped-source/libcperciva/events/events_timer.c +273 -0
- data/ext/spiped/spiped-source/libcperciva/network/network.h +95 -0
- data/ext/spiped/spiped-source/libcperciva/network/network_accept.c +103 -0
- data/ext/spiped/spiped-source/libcperciva/network/network_connect.c +258 -0
- data/ext/spiped/spiped-source/libcperciva/network/network_read.c +155 -0
- data/ext/spiped/spiped-source/libcperciva/network/network_write.c +188 -0
- data/ext/spiped/spiped-source/libcperciva/util/asprintf.c +49 -0
- data/ext/spiped/spiped-source/libcperciva/util/asprintf.h +16 -0
- data/ext/spiped/spiped-source/libcperciva/util/daemonize.c +134 -0
- data/ext/spiped/spiped-source/libcperciva/util/daemonize.h +10 -0
- data/ext/spiped/spiped-source/libcperciva/util/entropy.c +76 -0
- data/ext/spiped/spiped-source/libcperciva/util/entropy.h +13 -0
- data/ext/spiped/spiped-source/libcperciva/util/imalloc.h +33 -0
- data/ext/spiped/spiped-source/libcperciva/util/insecure_memzero.c +19 -0
- data/ext/spiped/spiped-source/libcperciva/util/insecure_memzero.h +33 -0
- data/ext/spiped/spiped-source/libcperciva/util/monoclock.c +52 -0
- data/ext/spiped/spiped-source/libcperciva/util/monoclock.h +14 -0
- data/ext/spiped/spiped-source/libcperciva/util/noeintr.c +54 -0
- data/ext/spiped/spiped-source/libcperciva/util/noeintr.h +14 -0
- data/ext/spiped/spiped-source/libcperciva/util/sock.c +472 -0
- data/ext/spiped/spiped-source/libcperciva/util/sock.h +56 -0
- data/ext/spiped/spiped-source/libcperciva/util/sock_internal.h +14 -0
- data/ext/spiped/spiped-source/libcperciva/util/sock_util.c +271 -0
- data/ext/spiped/spiped-source/libcperciva/util/sock_util.h +51 -0
- data/ext/spiped/spiped-source/libcperciva/util/sysendian.h +146 -0
- data/ext/spiped/spiped-source/libcperciva/util/warnp.c +76 -0
- data/ext/spiped/spiped-source/libcperciva/util/warnp.h +59 -0
- data/ext/spiped/spiped-source/proto/proto_conn.c +362 -0
- data/ext/spiped/spiped-source/proto/proto_conn.h +25 -0
- data/ext/spiped/spiped-source/proto/proto_crypt.c +396 -0
- data/ext/spiped/spiped-source/proto/proto_crypt.h +102 -0
- data/ext/spiped/spiped-source/proto/proto_handshake.c +330 -0
- data/ext/spiped/spiped-source/proto/proto_handshake.h +30 -0
- data/ext/spiped/spiped-source/proto/proto_pipe.c +202 -0
- data/ext/spiped/spiped-source/proto/proto_pipe.h +23 -0
- data/ext/spiped/spiped-source/spipe/Makefile +90 -0
- data/ext/spiped/spiped-source/spipe/README +24 -0
- data/ext/spiped/spiped-source/spipe/main.c +178 -0
- data/ext/spiped/spiped-source/spipe/pushbits.c +101 -0
- data/ext/spiped/spiped-source/spipe/pushbits.h +10 -0
- data/ext/spiped/spiped-source/spipe/spipe.1 +60 -0
- data/ext/spiped/spiped-source/spiped/Makefile +98 -0
- data/ext/spiped/spiped-source/spiped/README +62 -0
- data/ext/spiped/spiped-source/spiped/dispatch.c +214 -0
- data/ext/spiped/spiped-source/spiped/dispatch.h +27 -0
- data/ext/spiped/spiped-source/spiped/main.c +267 -0
- data/ext/spiped/spiped-source/spiped/spiped.1 +112 -0
- data/lib/spiped.rb +3 -0
- metadata +143 -0
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
#ifndef _CRYPTO_DH_H_
|
|
2
|
+
#define _CRYPTO_DH_H_
|
|
3
|
+
|
|
4
|
+
#include <stdint.h>
|
|
5
|
+
|
|
6
|
+
/* Sizes of Diffie-Hellman private, public, and exchanged keys. */
|
|
7
|
+
#define CRYPTO_DH_PRIVLEN 32
|
|
8
|
+
#define CRYPTO_DH_PUBLEN 256
|
|
9
|
+
#define CRYPTO_DH_KEYLEN 256
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* crypto_dh_generate_pub(pub, priv):
|
|
13
|
+
* Compute ${pub} equal to 2^(2^258 + ${priv}) in Diffie-Hellman group #14.
|
|
14
|
+
*/
|
|
15
|
+
int crypto_dh_generate_pub(uint8_t[CRYPTO_DH_PUBLEN],
|
|
16
|
+
const uint8_t[CRYPTO_DH_PRIVLEN]);
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* crypto_dh_generate(pub, priv):
|
|
20
|
+
* Generate a 256-bit private key ${priv}, and compute ${pub} equal to
|
|
21
|
+
* 2^(2^258 + ${priv}) mod p where p is the Diffie-Hellman group #14 modulus.
|
|
22
|
+
* Both values are stored as big-endian integers.
|
|
23
|
+
*/
|
|
24
|
+
int crypto_dh_generate(uint8_t[CRYPTO_DH_PUBLEN], uint8_t[CRYPTO_DH_PRIVLEN]);
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* crypto_dh_compute(pub, priv, key):
|
|
28
|
+
* In the Diffie-Hellman group #14, compute ${pub}^(2^258 + ${priv}) and
|
|
29
|
+
* write the result into ${key}. All values are big-endian. Note that the
|
|
30
|
+
* value ${pub} is the public key produced by the call to crypto_dh_generate
|
|
31
|
+
* made by the *other* participant in the key exchange.
|
|
32
|
+
*/
|
|
33
|
+
int crypto_dh_compute(const uint8_t[CRYPTO_DH_PUBLEN],
|
|
34
|
+
const uint8_t[CRYPTO_DH_PRIVLEN], uint8_t[CRYPTO_DH_KEYLEN]);
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* crypto_dh_sanitycheck(pub):
|
|
38
|
+
* Sanity-check the Diffie-Hellman public value ${pub} by checking that it
|
|
39
|
+
* is less than the group #14 modulus. Return 0 if sane, -1 if insane.
|
|
40
|
+
*/
|
|
41
|
+
int crypto_dh_sanitycheck(const uint8_t[CRYPTO_DH_PUBLEN]);
|
|
42
|
+
|
|
43
|
+
#endif /* !_CRYPTO_DH_H_ */
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
#include <stdint.h>
|
|
2
|
+
|
|
3
|
+
#include "crypto_dh_group14.h"
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* This is the big-endian representation of
|
|
7
|
+
* p = 2^2048 - 2^1984 + 2^64 * floor(2^1918 pi + 124476) - 1
|
|
8
|
+
* where the value 124476 is chosen to be the least positive integer such
|
|
9
|
+
* that both p and (p - 1)/2 are prime. Diffie-Hellman operations are done
|
|
10
|
+
* in the group of quadratic residues modulo p, and the integer 2 is a
|
|
11
|
+
* generator of this group.
|
|
12
|
+
*/
|
|
13
|
+
uint8_t crypto_dh_group14[256] = {
|
|
14
|
+
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
|
15
|
+
0xc9, 0x0f, 0xda, 0xa2, 0x21, 0x68, 0xc2, 0x34,
|
|
16
|
+
0xc4, 0xc6, 0x62, 0x8b, 0x80, 0xdc, 0x1c, 0xd1,
|
|
17
|
+
0x29, 0x02, 0x4e, 0x08, 0x8a, 0x67, 0xcc, 0x74,
|
|
18
|
+
0x02, 0x0b, 0xbe, 0xa6, 0x3b, 0x13, 0x9b, 0x22,
|
|
19
|
+
0x51, 0x4a, 0x08, 0x79, 0x8e, 0x34, 0x04, 0xdd,
|
|
20
|
+
0xef, 0x95, 0x19, 0xb3, 0xcd, 0x3a, 0x43, 0x1b,
|
|
21
|
+
0x30, 0x2b, 0x0a, 0x6d, 0xf2, 0x5f, 0x14, 0x37,
|
|
22
|
+
0x4f, 0xe1, 0x35, 0x6d, 0x6d, 0x51, 0xc2, 0x45,
|
|
23
|
+
0xe4, 0x85, 0xb5, 0x76, 0x62, 0x5e, 0x7e, 0xc6,
|
|
24
|
+
0xf4, 0x4c, 0x42, 0xe9, 0xa6, 0x37, 0xed, 0x6b,
|
|
25
|
+
0x0b, 0xff, 0x5c, 0xb6, 0xf4, 0x06, 0xb7, 0xed,
|
|
26
|
+
0xee, 0x38, 0x6b, 0xfb, 0x5a, 0x89, 0x9f, 0xa5,
|
|
27
|
+
0xae, 0x9f, 0x24, 0x11, 0x7c, 0x4b, 0x1f, 0xe6,
|
|
28
|
+
0x49, 0x28, 0x66, 0x51, 0xec, 0xe4, 0x5b, 0x3d,
|
|
29
|
+
0xc2, 0x00, 0x7c, 0xb8, 0xa1, 0x63, 0xbf, 0x05,
|
|
30
|
+
0x98, 0xda, 0x48, 0x36, 0x1c, 0x55, 0xd3, 0x9a,
|
|
31
|
+
0x69, 0x16, 0x3f, 0xa8, 0xfd, 0x24, 0xcf, 0x5f,
|
|
32
|
+
0x83, 0x65, 0x5d, 0x23, 0xdc, 0xa3, 0xad, 0x96,
|
|
33
|
+
0x1c, 0x62, 0xf3, 0x56, 0x20, 0x85, 0x52, 0xbb,
|
|
34
|
+
0x9e, 0xd5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6d,
|
|
35
|
+
0x67, 0x0c, 0x35, 0x4e, 0x4a, 0xbc, 0x98, 0x04,
|
|
36
|
+
0xf1, 0x74, 0x6c, 0x08, 0xca, 0x18, 0x21, 0x7c,
|
|
37
|
+
0x32, 0x90, 0x5e, 0x46, 0x2e, 0x36, 0xce, 0x3b,
|
|
38
|
+
0xe3, 0x9e, 0x77, 0x2c, 0x18, 0x0e, 0x86, 0x03,
|
|
39
|
+
0x9b, 0x27, 0x83, 0xa2, 0xec, 0x07, 0xa2, 0x8f,
|
|
40
|
+
0xb5, 0xc5, 0x5d, 0xf0, 0x6f, 0x4c, 0x52, 0xc9,
|
|
41
|
+
0xde, 0x2b, 0xcb, 0xf6, 0x95, 0x58, 0x17, 0x18,
|
|
42
|
+
0x39, 0x95, 0x49, 0x7c, 0xea, 0x95, 0x6a, 0xe5,
|
|
43
|
+
0x15, 0xd2, 0x26, 0x18, 0x98, 0xfa, 0x05, 0x10,
|
|
44
|
+
0x15, 0x72, 0x8e, 0x5a, 0x8a, 0xac, 0xaa, 0x68,
|
|
45
|
+
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
|
|
46
|
+
};
|
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
#include <assert.h>
|
|
2
|
+
#include <stdint.h>
|
|
3
|
+
#include <string.h>
|
|
4
|
+
|
|
5
|
+
#include "entropy.h"
|
|
6
|
+
#include "insecure_memzero.h"
|
|
7
|
+
|
|
8
|
+
#include "sha256.h"
|
|
9
|
+
|
|
10
|
+
#include "crypto_entropy.h"
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* This system implements the HMAC_DRBG pseudo-random number generator as
|
|
14
|
+
* specified in section 10.1.2 of the NIST SP 800-90 standard. In this
|
|
15
|
+
* implementation, the optional personalization_string and additional_input
|
|
16
|
+
* specified in the standard are not implemented.
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
/* Internal HMAC_DRBG state. */
|
|
20
|
+
static struct {
|
|
21
|
+
uint8_t Key[32];
|
|
22
|
+
uint8_t V[32];
|
|
23
|
+
uint32_t reseed_counter;
|
|
24
|
+
} drbg;
|
|
25
|
+
|
|
26
|
+
/* Set to non-zero once the PRNG has been instantiated. */
|
|
27
|
+
static int instantiated = 0;
|
|
28
|
+
|
|
29
|
+
/* Could be as high as 2^48 if we wanted... */
|
|
30
|
+
#define RESEED_INTERVAL 256
|
|
31
|
+
|
|
32
|
+
/* Limited to 2^16 by specification. */
|
|
33
|
+
#define GENERATE_MAXLEN 65536
|
|
34
|
+
|
|
35
|
+
static int instantiate(void);
|
|
36
|
+
static void update(uint8_t *, size_t);
|
|
37
|
+
static int reseed(void);
|
|
38
|
+
static void generate(uint8_t *, size_t);
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* instantiate(void):
|
|
42
|
+
* Initialize the DRBG state. (Section 10.1.2.3)
|
|
43
|
+
*/
|
|
44
|
+
static int
|
|
45
|
+
instantiate(void)
|
|
46
|
+
{
|
|
47
|
+
uint8_t seed_material[48];
|
|
48
|
+
|
|
49
|
+
/* Obtain random seed_material = (entropy_input || nonce). */
|
|
50
|
+
if (entropy_read(seed_material, 48))
|
|
51
|
+
return (-1);
|
|
52
|
+
|
|
53
|
+
/* Initialize Key, V, and reseed_counter. */
|
|
54
|
+
memset(drbg.Key, 0x00, 32);
|
|
55
|
+
memset(drbg.V, 0x01, 32);
|
|
56
|
+
drbg.reseed_counter = 1;
|
|
57
|
+
|
|
58
|
+
/* Mix the random seed into the state. */
|
|
59
|
+
update(seed_material, 48);
|
|
60
|
+
|
|
61
|
+
/* Clean the stack. */
|
|
62
|
+
insecure_memzero(seed_material, 48);
|
|
63
|
+
|
|
64
|
+
/* Success! */
|
|
65
|
+
return (0);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* update(data, datalen):
|
|
70
|
+
* Update the DRBG state using the provided data. (Section 10.1.2.2)
|
|
71
|
+
*/
|
|
72
|
+
static void
|
|
73
|
+
update(uint8_t * data, size_t datalen)
|
|
74
|
+
{
|
|
75
|
+
HMAC_SHA256_CTX ctx;
|
|
76
|
+
uint8_t K[32];
|
|
77
|
+
uint8_t Vx[33];
|
|
78
|
+
|
|
79
|
+
/* Load (Key, V) into (K, Vx). */
|
|
80
|
+
memcpy(K, drbg.Key, 32);
|
|
81
|
+
memcpy(Vx, drbg.V, 32);
|
|
82
|
+
|
|
83
|
+
/* K <- HMAC(K, V || 0x00 || data). */
|
|
84
|
+
Vx[32] = 0x00;
|
|
85
|
+
HMAC_SHA256_Init(&ctx, K, 32);
|
|
86
|
+
HMAC_SHA256_Update(&ctx, Vx, 33);
|
|
87
|
+
HMAC_SHA256_Update(&ctx, data, datalen);
|
|
88
|
+
HMAC_SHA256_Final(K, &ctx);
|
|
89
|
+
|
|
90
|
+
/* V <- HMAC(K, V). */
|
|
91
|
+
HMAC_SHA256_Buf(K, 32, Vx, 32, Vx);
|
|
92
|
+
|
|
93
|
+
/* If the provided data is non-Null, perform another mixing stage. */
|
|
94
|
+
if (datalen != 0) {
|
|
95
|
+
/* K <- HMAC(K, V || 0x01 || data). */
|
|
96
|
+
Vx[32] = 0x01;
|
|
97
|
+
HMAC_SHA256_Init(&ctx, K, 32);
|
|
98
|
+
HMAC_SHA256_Update(&ctx, Vx, 33);
|
|
99
|
+
HMAC_SHA256_Update(&ctx, data, datalen);
|
|
100
|
+
HMAC_SHA256_Final(K, &ctx);
|
|
101
|
+
|
|
102
|
+
/* V <- HMAC(K, V). */
|
|
103
|
+
HMAC_SHA256_Buf(K, 32, Vx, 32, Vx);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/* Copy (K, Vx) back to (Key, V). */
|
|
107
|
+
memcpy(drbg.Key, K, 32);
|
|
108
|
+
memcpy(drbg.V, Vx, 32);
|
|
109
|
+
|
|
110
|
+
/* Clean the stack. */
|
|
111
|
+
insecure_memzero(K, 32);
|
|
112
|
+
insecure_memzero(Vx, 33);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* reseed(void):
|
|
117
|
+
* Reseed the DRBG state (mix in new entropy). (Section 10.1.2.4)
|
|
118
|
+
*/
|
|
119
|
+
static int
|
|
120
|
+
reseed(void)
|
|
121
|
+
{
|
|
122
|
+
uint8_t seed_material[32];
|
|
123
|
+
|
|
124
|
+
/* Obtain random seed_material = entropy_input. */
|
|
125
|
+
if (entropy_read(seed_material, 32))
|
|
126
|
+
return (-1);
|
|
127
|
+
|
|
128
|
+
/* Mix the random seed into the state. */
|
|
129
|
+
update(seed_material, 32);
|
|
130
|
+
|
|
131
|
+
/* Reset the reseed_counter. */
|
|
132
|
+
drbg.reseed_counter = 1;
|
|
133
|
+
|
|
134
|
+
/* Clean the stack. */
|
|
135
|
+
insecure_memzero(seed_material, 32);
|
|
136
|
+
|
|
137
|
+
/* Success! */
|
|
138
|
+
return (0);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* generate(buf, buflen):
|
|
143
|
+
* Fill the provided buffer with random bits, assuming that reseed_counter
|
|
144
|
+
* is less than RESEED_INTERVAL (the caller is responsible for calling
|
|
145
|
+
* reseed() as needed) and ${buflen} is less than 2^16 (the caller is
|
|
146
|
+
* responsible for splitting up larger requests). (Section 10.1.2.5)
|
|
147
|
+
*/
|
|
148
|
+
static void
|
|
149
|
+
generate(uint8_t * buf, size_t buflen)
|
|
150
|
+
{
|
|
151
|
+
size_t bufpos;
|
|
152
|
+
|
|
153
|
+
assert(buflen <= GENERATE_MAXLEN);
|
|
154
|
+
assert(drbg.reseed_counter <= RESEED_INTERVAL);
|
|
155
|
+
|
|
156
|
+
/* Iterate until we've filled the buffer. */
|
|
157
|
+
for (bufpos = 0; bufpos < buflen; bufpos += 32) {
|
|
158
|
+
HMAC_SHA256_Buf(drbg.Key, 32, drbg.V, 32, drbg.V);
|
|
159
|
+
if (buflen - bufpos >= 32)
|
|
160
|
+
memcpy(&buf[bufpos], drbg.V, 32);
|
|
161
|
+
else
|
|
162
|
+
memcpy(&buf[bufpos], drbg.V, buflen - bufpos);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
/* Mix up state. */
|
|
166
|
+
update(NULL, 0);
|
|
167
|
+
|
|
168
|
+
/* We're one data-generation step closer to needing a reseed. */
|
|
169
|
+
drbg.reseed_counter += 1;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
/**
|
|
173
|
+
* crypto_entropy_read(buf, buflen):
|
|
174
|
+
* Fill the buffer with unpredictable bits.
|
|
175
|
+
*/
|
|
176
|
+
int
|
|
177
|
+
crypto_entropy_read(uint8_t * buf, size_t buflen)
|
|
178
|
+
{
|
|
179
|
+
size_t bytes_to_provide;
|
|
180
|
+
|
|
181
|
+
/* Instantiate if needed. */
|
|
182
|
+
if (instantiated == 0) {
|
|
183
|
+
/* Try to instantiate the PRNG. */
|
|
184
|
+
if (instantiate())
|
|
185
|
+
return (-1);
|
|
186
|
+
|
|
187
|
+
/* We have instantiated the PRNG. */
|
|
188
|
+
instantiated = 1;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
/* Loop until we've filled the buffer. */
|
|
192
|
+
while (buflen > 0) {
|
|
193
|
+
/* Do we need to reseed? */
|
|
194
|
+
if (drbg.reseed_counter > RESEED_INTERVAL) {
|
|
195
|
+
if (reseed())
|
|
196
|
+
return (-1);
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
/* How much data are we generating in this step? */
|
|
200
|
+
if (buflen > GENERATE_MAXLEN)
|
|
201
|
+
bytes_to_provide = GENERATE_MAXLEN;
|
|
202
|
+
else
|
|
203
|
+
bytes_to_provide = buflen;
|
|
204
|
+
|
|
205
|
+
/* Generate bytes. */
|
|
206
|
+
generate(buf, bytes_to_provide);
|
|
207
|
+
|
|
208
|
+
/* We've done part of the buffer. */
|
|
209
|
+
buf += bytes_to_provide;
|
|
210
|
+
buflen -= bytes_to_provide;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
/* Success! */
|
|
214
|
+
return (0);
|
|
215
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
#ifndef _CRYPTO_ENTROPY_H_
|
|
2
|
+
#define _CRYPTO_ENTROPY_H_
|
|
3
|
+
|
|
4
|
+
#include <stddef.h>
|
|
5
|
+
#include <stdint.h>
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* crypto_entropy_read(buf, buflen):
|
|
9
|
+
* Fill the buffer with unpredictable bits. The value ${buflen} must be
|
|
10
|
+
* less than 2^16.
|
|
11
|
+
*/
|
|
12
|
+
int crypto_entropy_read(uint8_t *, size_t);
|
|
13
|
+
|
|
14
|
+
#endif /* !_CRYPTO_ENTROPY_H_ */
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
#include <stddef.h>
|
|
2
|
+
#include <stdint.h>
|
|
3
|
+
|
|
4
|
+
#include "crypto_verify_bytes.h"
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* crypto_verify_bytes(buf0, buf1, len):
|
|
8
|
+
* Return zero if and only if buf0[0 .. len - 1] and buf1[0 .. len - 1] are
|
|
9
|
+
* identical. Do not leak any information via timing side channels.
|
|
10
|
+
*/
|
|
11
|
+
uint8_t
|
|
12
|
+
crypto_verify_bytes(const uint8_t * buf0, const uint8_t * buf1, size_t len)
|
|
13
|
+
{
|
|
14
|
+
uint8_t rc = 0;
|
|
15
|
+
size_t i;
|
|
16
|
+
|
|
17
|
+
for (i = 0; i < len; i++)
|
|
18
|
+
rc = rc | (buf0[i] ^ buf1[i]);
|
|
19
|
+
|
|
20
|
+
return (rc);
|
|
21
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
#ifndef _CRYPTO_VERIFY_BYTES_H_
|
|
2
|
+
#define _CRYPTO_VERIFY_BYTES_H_
|
|
3
|
+
|
|
4
|
+
#include <stddef.h>
|
|
5
|
+
#include <stdint.h>
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* crypto_verify_bytes(buf0, buf1, len):
|
|
9
|
+
* Return zero if and only if buf0[0 .. len - 1] and buf1[0 .. len - 1] are
|
|
10
|
+
* identical. Do not leak any information via timing side channels.
|
|
11
|
+
*/
|
|
12
|
+
uint8_t crypto_verify_bytes(const uint8_t *, const uint8_t *, size_t);
|
|
13
|
+
|
|
14
|
+
#endif /* !_CRYPTO_VERIFY_BYTES_H_ */
|
|
@@ -0,0 +1,276 @@
|
|
|
1
|
+
#include <errno.h>
|
|
2
|
+
#include <stdint.h>
|
|
3
|
+
#include <stdlib.h>
|
|
4
|
+
#include <string.h>
|
|
5
|
+
|
|
6
|
+
#include "elasticarray.h"
|
|
7
|
+
|
|
8
|
+
struct elasticarray {
|
|
9
|
+
size_t size;
|
|
10
|
+
size_t alloc;
|
|
11
|
+
void * buf;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* resize(EA, nsize):
|
|
16
|
+
* Resize the virtual buffer for ${EA} to length ${nsize} bytes. The actual
|
|
17
|
+
* buffer may or may not need to be resized. On failure, the buffer will be
|
|
18
|
+
* unmodified.
|
|
19
|
+
*/
|
|
20
|
+
static int
|
|
21
|
+
resize(struct elasticarray * EA, size_t nsize)
|
|
22
|
+
{
|
|
23
|
+
size_t nalloc;
|
|
24
|
+
void * nbuf;
|
|
25
|
+
|
|
26
|
+
/* Figure out how large an allocation we want. */
|
|
27
|
+
if (EA->alloc < nsize) {
|
|
28
|
+
/* We need to enlarge the buffer. */
|
|
29
|
+
nalloc = EA->alloc * 2;
|
|
30
|
+
if (nalloc < nsize)
|
|
31
|
+
nalloc = nsize;
|
|
32
|
+
} else if (EA->alloc > nsize * 4) {
|
|
33
|
+
/* We need to shrink the buffer. */
|
|
34
|
+
nalloc = nsize * 2;
|
|
35
|
+
} else {
|
|
36
|
+
nalloc = EA->alloc;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/* Reallocate if necessary. */
|
|
40
|
+
if (nalloc != EA->alloc) {
|
|
41
|
+
nbuf = realloc(EA->buf, nalloc);
|
|
42
|
+
if ((nbuf == NULL) && (nalloc > 0))
|
|
43
|
+
goto err0;
|
|
44
|
+
EA->buf = nbuf;
|
|
45
|
+
EA->alloc = nalloc;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/* Record the new array size. */
|
|
49
|
+
EA->size = nsize;
|
|
50
|
+
|
|
51
|
+
/* Success! */
|
|
52
|
+
return (0);
|
|
53
|
+
|
|
54
|
+
err0:
|
|
55
|
+
/* Failure! */
|
|
56
|
+
return (-1);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* elasticarray_init(nrec, reclen):
|
|
61
|
+
* Create and return an elastic array holding ${nrec} (uninitialized) records
|
|
62
|
+
* of length ${reclen}. Takes O(nrec * reclen) time.
|
|
63
|
+
*/
|
|
64
|
+
struct elasticarray *
|
|
65
|
+
elasticarray_init(size_t nrec, size_t reclen)
|
|
66
|
+
{
|
|
67
|
+
struct elasticarray * EA;
|
|
68
|
+
|
|
69
|
+
/* Allocate structure. */
|
|
70
|
+
if ((EA = malloc(sizeof(struct elasticarray))) == NULL)
|
|
71
|
+
goto err0;
|
|
72
|
+
|
|
73
|
+
/* The array is empty for now. */
|
|
74
|
+
EA->size = EA->alloc = 0;
|
|
75
|
+
EA->buf = NULL;
|
|
76
|
+
|
|
77
|
+
/* Reallocate to the requested length. */
|
|
78
|
+
if (elasticarray_resize(EA, nrec, reclen))
|
|
79
|
+
goto err1;
|
|
80
|
+
|
|
81
|
+
/* Success! */
|
|
82
|
+
return (EA);
|
|
83
|
+
|
|
84
|
+
err1:
|
|
85
|
+
elasticarray_free(EA);
|
|
86
|
+
err0:
|
|
87
|
+
/* Failure! */
|
|
88
|
+
return (NULL);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* elasticarray_resize(EA, nrec, reclen):
|
|
93
|
+
* Resize the elastic array pointed to by ${EA} to hold ${nrec} records of
|
|
94
|
+
* length ${reclen}. If ${nrec} exceeds the number of records previously
|
|
95
|
+
* held by the array, the additional records will be uninitialized. Takes
|
|
96
|
+
* O(nrec * reclen) time.
|
|
97
|
+
*/
|
|
98
|
+
int
|
|
99
|
+
elasticarray_resize(struct elasticarray * EA, size_t nrec, size_t reclen)
|
|
100
|
+
{
|
|
101
|
+
|
|
102
|
+
/* Check for overflow. */
|
|
103
|
+
if (nrec > SIZE_MAX / reclen) {
|
|
104
|
+
errno = ENOMEM;
|
|
105
|
+
goto err0;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/* Resize the buffer. */
|
|
109
|
+
if (resize(EA, nrec * reclen))
|
|
110
|
+
goto err0;
|
|
111
|
+
|
|
112
|
+
/* Success! */
|
|
113
|
+
return (0);
|
|
114
|
+
|
|
115
|
+
err0:
|
|
116
|
+
/* Failure! */
|
|
117
|
+
return (-1);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* elasticarray_getsize(EA, reclen):
|
|
122
|
+
* Return the number of length-${reclen} records in the array, rounding down
|
|
123
|
+
* if there is a partial record (which can only occur if elasticarray_*
|
|
124
|
+
* functions have been called with different values of reclen).
|
|
125
|
+
*/
|
|
126
|
+
size_t
|
|
127
|
+
elasticarray_getsize(struct elasticarray * EA, size_t reclen)
|
|
128
|
+
{
|
|
129
|
+
|
|
130
|
+
return (EA->size / reclen);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* elasticarray_append(EA, buf, nrec, reclen):
|
|
135
|
+
* Append to the elastic array ${EA} the ${nrec} records of length ${reclen}
|
|
136
|
+
* stored in ${buf}. Takes O(nrec * reclen) amortized time.
|
|
137
|
+
*/
|
|
138
|
+
int
|
|
139
|
+
elasticarray_append(struct elasticarray * EA,
|
|
140
|
+
const void * buf, size_t nrec, size_t reclen)
|
|
141
|
+
{
|
|
142
|
+
size_t bufpos = EA->size;
|
|
143
|
+
|
|
144
|
+
/* Check for overflow. */
|
|
145
|
+
if ((nrec > SIZE_MAX / reclen) ||
|
|
146
|
+
(nrec * reclen > SIZE_MAX - EA->size)) {
|
|
147
|
+
errno = ENOMEM;
|
|
148
|
+
goto err0;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/* Resize the buffer. */
|
|
152
|
+
if (resize(EA, EA->size + nrec * reclen))
|
|
153
|
+
goto err0;
|
|
154
|
+
|
|
155
|
+
/* Copy bytes in. */
|
|
156
|
+
memcpy((uint8_t *)(EA->buf) + bufpos, buf, nrec * reclen);
|
|
157
|
+
|
|
158
|
+
/* Success! */
|
|
159
|
+
return (0);
|
|
160
|
+
|
|
161
|
+
err0:
|
|
162
|
+
/* Failure! */
|
|
163
|
+
return (-1);
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* elasticarray_shrink(EA, nrec, reclen):
|
|
168
|
+
* Delete the final ${nrec} records of length ${reclen} from the elastic
|
|
169
|
+
* array ${EA}. If there are fewer than ${nrec} records, all records
|
|
170
|
+
* present will be deleted.
|
|
171
|
+
*
|
|
172
|
+
* As an exception to the normal rule, an elastic array may occupy more than
|
|
173
|
+
* 4 times the optimal storage immediately following an elasticarray_shrink
|
|
174
|
+
* call; but only if realloc(3) failed to shrink a memory allocation.
|
|
175
|
+
*/
|
|
176
|
+
void
|
|
177
|
+
elasticarray_shrink(struct elasticarray * EA, size_t nrec, size_t reclen)
|
|
178
|
+
{
|
|
179
|
+
size_t nsize;
|
|
180
|
+
|
|
181
|
+
/* Figure out how much to keep. */
|
|
182
|
+
if ((nrec > SIZE_MAX / reclen) ||
|
|
183
|
+
(nrec * reclen > EA->size))
|
|
184
|
+
nsize = 0;
|
|
185
|
+
else
|
|
186
|
+
nsize = EA->size - nrec * reclen;
|
|
187
|
+
|
|
188
|
+
/* Resize the buffer... */
|
|
189
|
+
if (resize(EA, nsize)) {
|
|
190
|
+
/*
|
|
191
|
+
* ... and if we fail to reallocate, just record the new
|
|
192
|
+
* length and continue using the old buffer.
|
|
193
|
+
*/
|
|
194
|
+
EA->size = nsize;
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
/**
|
|
199
|
+
* elasticarray_truncate(EA):
|
|
200
|
+
* Release any spare space in the elastic array ${EA}.
|
|
201
|
+
*/
|
|
202
|
+
int
|
|
203
|
+
elasticarray_truncate(struct elasticarray * EA)
|
|
204
|
+
{
|
|
205
|
+
void * nbuf;
|
|
206
|
+
|
|
207
|
+
/* If there is spare space, reallocate. */
|
|
208
|
+
if (EA->alloc > EA->size) {
|
|
209
|
+
nbuf = realloc(EA->buf, EA->size);
|
|
210
|
+
if ((nbuf == NULL) && (EA->size > 0))
|
|
211
|
+
goto err0;
|
|
212
|
+
EA->buf = nbuf;
|
|
213
|
+
EA->alloc = EA->size;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
/* Success! */
|
|
217
|
+
return (0);
|
|
218
|
+
|
|
219
|
+
err0:
|
|
220
|
+
/* Failure! */
|
|
221
|
+
return (-1);
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
/**
|
|
225
|
+
* elasticarray_get(EA, pos, reclen):
|
|
226
|
+
* Return a pointer to record number ${pos} of length ${reclen} in the
|
|
227
|
+
* elastic array ${EA}. Takes O(1) time.
|
|
228
|
+
*/
|
|
229
|
+
void *
|
|
230
|
+
elasticarray_get(struct elasticarray * EA, size_t pos, size_t reclen)
|
|
231
|
+
{
|
|
232
|
+
|
|
233
|
+
return ((uint8_t *)(EA->buf) + pos * reclen);
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
/**
|
|
237
|
+
* elasticarray_free(EA):
|
|
238
|
+
* Free the elastic array ${EA}. Takes O(1) time.
|
|
239
|
+
*/
|
|
240
|
+
void
|
|
241
|
+
elasticarray_free(struct elasticarray * EA)
|
|
242
|
+
{
|
|
243
|
+
|
|
244
|
+
/* Be compatible with free(NULL). */
|
|
245
|
+
if (EA == NULL)
|
|
246
|
+
return;
|
|
247
|
+
|
|
248
|
+
free(EA->buf);
|
|
249
|
+
free(EA);
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
/**
|
|
253
|
+
* elasticarray_export(EA, buf, nrec, reclen):
|
|
254
|
+
* Return the data in the elastic array ${EA} as a buffer ${buf} containing
|
|
255
|
+
* ${nrec} records of length ${reclen}. Free the elastic array ${EA}.
|
|
256
|
+
*/
|
|
257
|
+
int
|
|
258
|
+
elasticarray_export(struct elasticarray * EA, void ** buf, size_t * nrec,
|
|
259
|
+
size_t reclen)
|
|
260
|
+
{
|
|
261
|
+
|
|
262
|
+
/* Remove any spare space. */
|
|
263
|
+
if (elasticarray_truncate(EA))
|
|
264
|
+
goto err0;
|
|
265
|
+
|
|
266
|
+
/* Return the buffer and number of records. */
|
|
267
|
+
*buf = EA->buf;
|
|
268
|
+
*nrec = elasticarray_getsize(EA, reclen);
|
|
269
|
+
|
|
270
|
+
/* Success! */
|
|
271
|
+
return (0);
|
|
272
|
+
|
|
273
|
+
err0:
|
|
274
|
+
/* Failure! */
|
|
275
|
+
return (-1);
|
|
276
|
+
}
|