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.
Files changed (102) hide show
  1. checksums.yaml +7 -0
  2. data/ext/spiped/extconf.rb +3 -0
  3. data/ext/spiped/spiped-source/BUILDING +46 -0
  4. data/ext/spiped/spiped-source/CHANGELOG +44 -0
  5. data/ext/spiped/spiped-source/COPYRIGHT +33 -0
  6. data/ext/spiped/spiped-source/Makefile +47 -0
  7. data/ext/spiped/spiped-source/Makefile.POSIX +27 -0
  8. data/ext/spiped/spiped-source/Makefile.inc +20 -0
  9. data/ext/spiped/spiped-source/Makefile.prog +23 -0
  10. data/ext/spiped/spiped-source/POSIX/README +10 -0
  11. data/ext/spiped/spiped-source/POSIX/posix-cflags.sh +10 -0
  12. data/ext/spiped/spiped-source/POSIX/posix-clock_realtime.c +3 -0
  13. data/ext/spiped/spiped-source/POSIX/posix-l.c +1 -0
  14. data/ext/spiped/spiped-source/POSIX/posix-l.sh +14 -0
  15. data/ext/spiped/spiped-source/POSIX/posix-msg_nosignal.c +3 -0
  16. data/ext/spiped/spiped-source/README +198 -0
  17. data/ext/spiped/spiped-source/STYLE +151 -0
  18. data/ext/spiped/spiped-source/lib/dnsthread/dnsthread.c +464 -0
  19. data/ext/spiped/spiped-source/lib/dnsthread/dnsthread.h +45 -0
  20. data/ext/spiped/spiped-source/libcperciva/alg/sha256.c +442 -0
  21. data/ext/spiped/spiped-source/libcperciva/alg/sha256.h +95 -0
  22. data/ext/spiped/spiped-source/libcperciva/cpusupport/Build/cpusupport-X86-AESNI.c +13 -0
  23. data/ext/spiped/spiped-source/libcperciva/cpusupport/Build/cpusupport-X86-CPUID.c +8 -0
  24. data/ext/spiped/spiped-source/libcperciva/cpusupport/Build/cpusupport.sh +37 -0
  25. data/ext/spiped/spiped-source/libcperciva/cpusupport/cpusupport.h +63 -0
  26. data/ext/spiped/spiped-source/libcperciva/cpusupport/cpusupport_x86_aesni.c +30 -0
  27. data/ext/spiped/spiped-source/libcperciva/crypto/crypto_aes.c +166 -0
  28. data/ext/spiped/spiped-source/libcperciva/crypto/crypto_aes.h +31 -0
  29. data/ext/spiped/spiped-source/libcperciva/crypto/crypto_aes_aesni.c +229 -0
  30. data/ext/spiped/spiped-source/libcperciva/crypto/crypto_aes_aesni.h +31 -0
  31. data/ext/spiped/spiped-source/libcperciva/crypto/crypto_aesctr.c +124 -0
  32. data/ext/spiped/spiped-source/libcperciva/crypto/crypto_aesctr.h +41 -0
  33. data/ext/spiped/spiped-source/libcperciva/crypto/crypto_dh.c +293 -0
  34. data/ext/spiped/spiped-source/libcperciva/crypto/crypto_dh.h +43 -0
  35. data/ext/spiped/spiped-source/libcperciva/crypto/crypto_dh_group14.c +46 -0
  36. data/ext/spiped/spiped-source/libcperciva/crypto/crypto_dh_group14.h +9 -0
  37. data/ext/spiped/spiped-source/libcperciva/crypto/crypto_entropy.c +215 -0
  38. data/ext/spiped/spiped-source/libcperciva/crypto/crypto_entropy.h +14 -0
  39. data/ext/spiped/spiped-source/libcperciva/crypto/crypto_verify_bytes.c +21 -0
  40. data/ext/spiped/spiped-source/libcperciva/crypto/crypto_verify_bytes.h +14 -0
  41. data/ext/spiped/spiped-source/libcperciva/datastruct/elasticarray.c +276 -0
  42. data/ext/spiped/spiped-source/libcperciva/datastruct/elasticarray.h +167 -0
  43. data/ext/spiped/spiped-source/libcperciva/datastruct/mpool.h +85 -0
  44. data/ext/spiped/spiped-source/libcperciva/datastruct/ptrheap.c +334 -0
  45. data/ext/spiped/spiped-source/libcperciva/datastruct/ptrheap.h +89 -0
  46. data/ext/spiped/spiped-source/libcperciva/datastruct/timerqueue.c +241 -0
  47. data/ext/spiped/spiped-source/libcperciva/datastruct/timerqueue.h +60 -0
  48. data/ext/spiped/spiped-source/libcperciva/events/events.c +203 -0
  49. data/ext/spiped/spiped-source/libcperciva/events/events.h +106 -0
  50. data/ext/spiped/spiped-source/libcperciva/events/events_immediate.c +149 -0
  51. data/ext/spiped/spiped-source/libcperciva/events/events_internal.h +95 -0
  52. data/ext/spiped/spiped-source/libcperciva/events/events_network.c +347 -0
  53. data/ext/spiped/spiped-source/libcperciva/events/events_network_selectstats.c +106 -0
  54. data/ext/spiped/spiped-source/libcperciva/events/events_timer.c +273 -0
  55. data/ext/spiped/spiped-source/libcperciva/network/network.h +95 -0
  56. data/ext/spiped/spiped-source/libcperciva/network/network_accept.c +103 -0
  57. data/ext/spiped/spiped-source/libcperciva/network/network_connect.c +258 -0
  58. data/ext/spiped/spiped-source/libcperciva/network/network_read.c +155 -0
  59. data/ext/spiped/spiped-source/libcperciva/network/network_write.c +188 -0
  60. data/ext/spiped/spiped-source/libcperciva/util/asprintf.c +49 -0
  61. data/ext/spiped/spiped-source/libcperciva/util/asprintf.h +16 -0
  62. data/ext/spiped/spiped-source/libcperciva/util/daemonize.c +134 -0
  63. data/ext/spiped/spiped-source/libcperciva/util/daemonize.h +10 -0
  64. data/ext/spiped/spiped-source/libcperciva/util/entropy.c +76 -0
  65. data/ext/spiped/spiped-source/libcperciva/util/entropy.h +13 -0
  66. data/ext/spiped/spiped-source/libcperciva/util/imalloc.h +33 -0
  67. data/ext/spiped/spiped-source/libcperciva/util/insecure_memzero.c +19 -0
  68. data/ext/spiped/spiped-source/libcperciva/util/insecure_memzero.h +33 -0
  69. data/ext/spiped/spiped-source/libcperciva/util/monoclock.c +52 -0
  70. data/ext/spiped/spiped-source/libcperciva/util/monoclock.h +14 -0
  71. data/ext/spiped/spiped-source/libcperciva/util/noeintr.c +54 -0
  72. data/ext/spiped/spiped-source/libcperciva/util/noeintr.h +14 -0
  73. data/ext/spiped/spiped-source/libcperciva/util/sock.c +472 -0
  74. data/ext/spiped/spiped-source/libcperciva/util/sock.h +56 -0
  75. data/ext/spiped/spiped-source/libcperciva/util/sock_internal.h +14 -0
  76. data/ext/spiped/spiped-source/libcperciva/util/sock_util.c +271 -0
  77. data/ext/spiped/spiped-source/libcperciva/util/sock_util.h +51 -0
  78. data/ext/spiped/spiped-source/libcperciva/util/sysendian.h +146 -0
  79. data/ext/spiped/spiped-source/libcperciva/util/warnp.c +76 -0
  80. data/ext/spiped/spiped-source/libcperciva/util/warnp.h +59 -0
  81. data/ext/spiped/spiped-source/proto/proto_conn.c +362 -0
  82. data/ext/spiped/spiped-source/proto/proto_conn.h +25 -0
  83. data/ext/spiped/spiped-source/proto/proto_crypt.c +396 -0
  84. data/ext/spiped/spiped-source/proto/proto_crypt.h +102 -0
  85. data/ext/spiped/spiped-source/proto/proto_handshake.c +330 -0
  86. data/ext/spiped/spiped-source/proto/proto_handshake.h +30 -0
  87. data/ext/spiped/spiped-source/proto/proto_pipe.c +202 -0
  88. data/ext/spiped/spiped-source/proto/proto_pipe.h +23 -0
  89. data/ext/spiped/spiped-source/spipe/Makefile +90 -0
  90. data/ext/spiped/spiped-source/spipe/README +24 -0
  91. data/ext/spiped/spiped-source/spipe/main.c +178 -0
  92. data/ext/spiped/spiped-source/spipe/pushbits.c +101 -0
  93. data/ext/spiped/spiped-source/spipe/pushbits.h +10 -0
  94. data/ext/spiped/spiped-source/spipe/spipe.1 +60 -0
  95. data/ext/spiped/spiped-source/spiped/Makefile +98 -0
  96. data/ext/spiped/spiped-source/spiped/README +62 -0
  97. data/ext/spiped/spiped-source/spiped/dispatch.c +214 -0
  98. data/ext/spiped/spiped-source/spiped/dispatch.h +27 -0
  99. data/ext/spiped/spiped-source/spiped/main.c +267 -0
  100. data/ext/spiped/spiped-source/spiped/spiped.1 +112 -0
  101. data/lib/spiped.rb +3 -0
  102. 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,9 @@
1
+ #ifndef _CRYPTO_DH_GROUP14_H_
2
+ #define _CRYPTO_DH_GROUP14_H_
3
+
4
+ #include <stdint.h>
5
+
6
+ /* Diffie-Hellman group #14, from RFC 3526. */
7
+ extern uint8_t crypto_dh_group14[];
8
+
9
+ #endif /* !_CRYPTO_DH_GROUP14_H_ */
@@ -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
+ }