diff options
author | jsing <> | 2023-04-15 17:56:35 +0000 |
---|---|---|
committer | jsing <> | 2023-04-15 17:56:35 +0000 |
commit | 544e86ca593b5cf7552875599cd3e1d2581eeab0 (patch) | |
tree | da1c7b16380eb3bb690343f812a5da0b42bc18d4 /src | |
parent | 3e1ff76458200d603d89c1acf7741c1c31497902 (diff) | |
download | openbsd-544e86ca593b5cf7552875599cd3e1d2581eeab0.tar.gz openbsd-544e86ca593b5cf7552875599cd3e1d2581eeab0.tar.bz2 openbsd-544e86ca593b5cf7552875599cd3e1d2581eeab0.zip |
Import tiny_sha3
This is a minimal and readable SHA3 implementation.
ok tb@
Diffstat (limited to 'src')
-rw-r--r-- | src/lib/libcrypto/sha/sha3.c | 191 | ||||
-rw-r--r-- | src/lib/libcrypto/sha/sha3_internal.h | 47 |
2 files changed, 238 insertions, 0 deletions
diff --git a/src/lib/libcrypto/sha/sha3.c b/src/lib/libcrypto/sha/sha3.c new file mode 100644 index 0000000000..931ae02084 --- /dev/null +++ b/src/lib/libcrypto/sha/sha3.c | |||
@@ -0,0 +1,191 @@ | |||
1 | // sha3.c | ||
2 | // 19-Nov-11 Markku-Juhani O. Saarinen <mjos@iki.fi> | ||
3 | |||
4 | // Revised 07-Aug-15 to match with official release of FIPS PUB 202 "SHA3" | ||
5 | // Revised 03-Sep-15 for portability + OpenSSL - style API | ||
6 | |||
7 | #include "sha3.h" | ||
8 | |||
9 | // update the state with given number of rounds | ||
10 | |||
11 | void sha3_keccakf(uint64_t st[25]) | ||
12 | { | ||
13 | // constants | ||
14 | const uint64_t keccakf_rndc[24] = { | ||
15 | 0x0000000000000001, 0x0000000000008082, 0x800000000000808a, | ||
16 | 0x8000000080008000, 0x000000000000808b, 0x0000000080000001, | ||
17 | 0x8000000080008081, 0x8000000000008009, 0x000000000000008a, | ||
18 | 0x0000000000000088, 0x0000000080008009, 0x000000008000000a, | ||
19 | 0x000000008000808b, 0x800000000000008b, 0x8000000000008089, | ||
20 | 0x8000000000008003, 0x8000000000008002, 0x8000000000000080, | ||
21 | 0x000000000000800a, 0x800000008000000a, 0x8000000080008081, | ||
22 | 0x8000000000008080, 0x0000000080000001, 0x8000000080008008 | ||
23 | }; | ||
24 | const int keccakf_rotc[24] = { | ||
25 | 1, 3, 6, 10, 15, 21, 28, 36, 45, 55, 2, 14, | ||
26 | 27, 41, 56, 8, 25, 43, 62, 18, 39, 61, 20, 44 | ||
27 | }; | ||
28 | const int keccakf_piln[24] = { | ||
29 | 10, 7, 11, 17, 18, 3, 5, 16, 8, 21, 24, 4, | ||
30 | 15, 23, 19, 13, 12, 2, 20, 14, 22, 9, 6, 1 | ||
31 | }; | ||
32 | |||
33 | // variables | ||
34 | int i, j, r; | ||
35 | uint64_t t, bc[5]; | ||
36 | |||
37 | #if __BYTE_ORDER__ != __ORDER_LITTLE_ENDIAN__ | ||
38 | uint8_t *v; | ||
39 | |||
40 | // endianess conversion. this is redundant on little-endian targets | ||
41 | for (i = 0; i < 25; i++) { | ||
42 | v = (uint8_t *) &st[i]; | ||
43 | st[i] = ((uint64_t) v[0]) | (((uint64_t) v[1]) << 8) | | ||
44 | (((uint64_t) v[2]) << 16) | (((uint64_t) v[3]) << 24) | | ||
45 | (((uint64_t) v[4]) << 32) | (((uint64_t) v[5]) << 40) | | ||
46 | (((uint64_t) v[6]) << 48) | (((uint64_t) v[7]) << 56); | ||
47 | } | ||
48 | #endif | ||
49 | |||
50 | // actual iteration | ||
51 | for (r = 0; r < KECCAKF_ROUNDS; r++) { | ||
52 | |||
53 | // Theta | ||
54 | for (i = 0; i < 5; i++) | ||
55 | bc[i] = st[i] ^ st[i + 5] ^ st[i + 10] ^ st[i + 15] ^ st[i + 20]; | ||
56 | |||
57 | for (i = 0; i < 5; i++) { | ||
58 | t = bc[(i + 4) % 5] ^ ROTL64(bc[(i + 1) % 5], 1); | ||
59 | for (j = 0; j < 25; j += 5) | ||
60 | st[j + i] ^= t; | ||
61 | } | ||
62 | |||
63 | // Rho Pi | ||
64 | t = st[1]; | ||
65 | for (i = 0; i < 24; i++) { | ||
66 | j = keccakf_piln[i]; | ||
67 | bc[0] = st[j]; | ||
68 | st[j] = ROTL64(t, keccakf_rotc[i]); | ||
69 | t = bc[0]; | ||
70 | } | ||
71 | |||
72 | // Chi | ||
73 | for (j = 0; j < 25; j += 5) { | ||
74 | for (i = 0; i < 5; i++) | ||
75 | bc[i] = st[j + i]; | ||
76 | for (i = 0; i < 5; i++) | ||
77 | st[j + i] ^= (~bc[(i + 1) % 5]) & bc[(i + 2) % 5]; | ||
78 | } | ||
79 | |||
80 | // Iota | ||
81 | st[0] ^= keccakf_rndc[r]; | ||
82 | } | ||
83 | |||
84 | #if __BYTE_ORDER__ != __ORDER_LITTLE_ENDIAN__ | ||
85 | // endianess conversion. this is redundant on little-endian targets | ||
86 | for (i = 0; i < 25; i++) { | ||
87 | v = (uint8_t *) &st[i]; | ||
88 | t = st[i]; | ||
89 | v[0] = t & 0xFF; | ||
90 | v[1] = (t >> 8) & 0xFF; | ||
91 | v[2] = (t >> 16) & 0xFF; | ||
92 | v[3] = (t >> 24) & 0xFF; | ||
93 | v[4] = (t >> 32) & 0xFF; | ||
94 | v[5] = (t >> 40) & 0xFF; | ||
95 | v[6] = (t >> 48) & 0xFF; | ||
96 | v[7] = (t >> 56) & 0xFF; | ||
97 | } | ||
98 | #endif | ||
99 | } | ||
100 | |||
101 | // Initialize the context for SHA3 | ||
102 | |||
103 | int sha3_init(sha3_ctx_t *c, int mdlen) | ||
104 | { | ||
105 | int i; | ||
106 | |||
107 | for (i = 0; i < 25; i++) | ||
108 | c->st.q[i] = 0; | ||
109 | c->mdlen = mdlen; | ||
110 | c->rsiz = 200 - 2 * mdlen; | ||
111 | c->pt = 0; | ||
112 | |||
113 | return 1; | ||
114 | } | ||
115 | |||
116 | // update state with more data | ||
117 | |||
118 | int sha3_update(sha3_ctx_t *c, const void *data, size_t len) | ||
119 | { | ||
120 | size_t i; | ||
121 | int j; | ||
122 | |||
123 | j = c->pt; | ||
124 | for (i = 0; i < len; i++) { | ||
125 | c->st.b[j++] ^= ((const uint8_t *) data)[i]; | ||
126 | if (j >= c->rsiz) { | ||
127 | sha3_keccakf(c->st.q); | ||
128 | j = 0; | ||
129 | } | ||
130 | } | ||
131 | c->pt = j; | ||
132 | |||
133 | return 1; | ||
134 | } | ||
135 | |||
136 | // finalize and output a hash | ||
137 | |||
138 | int sha3_final(void *md, sha3_ctx_t *c) | ||
139 | { | ||
140 | int i; | ||
141 | |||
142 | c->st.b[c->pt] ^= 0x06; | ||
143 | c->st.b[c->rsiz - 1] ^= 0x80; | ||
144 | sha3_keccakf(c->st.q); | ||
145 | |||
146 | for (i = 0; i < c->mdlen; i++) { | ||
147 | ((uint8_t *) md)[i] = c->st.b[i]; | ||
148 | } | ||
149 | |||
150 | return 1; | ||
151 | } | ||
152 | |||
153 | // compute a SHA-3 hash (md) of given byte length from "in" | ||
154 | |||
155 | void *sha3(const void *in, size_t inlen, void *md, int mdlen) | ||
156 | { | ||
157 | sha3_ctx_t sha3; | ||
158 | |||
159 | sha3_init(&sha3, mdlen); | ||
160 | sha3_update(&sha3, in, inlen); | ||
161 | sha3_final(md, &sha3); | ||
162 | |||
163 | return md; | ||
164 | } | ||
165 | |||
166 | // SHAKE128 and SHAKE256 extensible-output functionality | ||
167 | |||
168 | void shake_xof(sha3_ctx_t *c) | ||
169 | { | ||
170 | c->st.b[c->pt] ^= 0x1F; | ||
171 | c->st.b[c->rsiz - 1] ^= 0x80; | ||
172 | sha3_keccakf(c->st.q); | ||
173 | c->pt = 0; | ||
174 | } | ||
175 | |||
176 | void shake_out(sha3_ctx_t *c, void *out, size_t len) | ||
177 | { | ||
178 | size_t i; | ||
179 | int j; | ||
180 | |||
181 | j = c->pt; | ||
182 | for (i = 0; i < len; i++) { | ||
183 | if (j >= c->rsiz) { | ||
184 | sha3_keccakf(c->st.q); | ||
185 | j = 0; | ||
186 | } | ||
187 | ((uint8_t *) out)[i] = c->st.b[j++]; | ||
188 | } | ||
189 | c->pt = j; | ||
190 | } | ||
191 | |||
diff --git a/src/lib/libcrypto/sha/sha3_internal.h b/src/lib/libcrypto/sha/sha3_internal.h new file mode 100644 index 0000000000..ba24f43478 --- /dev/null +++ b/src/lib/libcrypto/sha/sha3_internal.h | |||
@@ -0,0 +1,47 @@ | |||
1 | // sha3.h | ||
2 | // 19-Nov-11 Markku-Juhani O. Saarinen <mjos@iki.fi> | ||
3 | |||
4 | #ifndef SHA3_H | ||
5 | #define SHA3_H | ||
6 | |||
7 | #include <stddef.h> | ||
8 | #include <stdint.h> | ||
9 | |||
10 | #ifndef KECCAKF_ROUNDS | ||
11 | #define KECCAKF_ROUNDS 24 | ||
12 | #endif | ||
13 | |||
14 | #ifndef ROTL64 | ||
15 | #define ROTL64(x, y) (((x) << (y)) | ((x) >> (64 - (y)))) | ||
16 | #endif | ||
17 | |||
18 | // state context | ||
19 | typedef struct { | ||
20 | union { // state: | ||
21 | uint8_t b[200]; // 8-bit bytes | ||
22 | uint64_t q[25]; // 64-bit words | ||
23 | } st; | ||
24 | int pt, rsiz, mdlen; // these don't overflow | ||
25 | } sha3_ctx_t; | ||
26 | |||
27 | // Compression function. | ||
28 | void sha3_keccakf(uint64_t st[25]); | ||
29 | |||
30 | // OpenSSL - like interfece | ||
31 | int sha3_init(sha3_ctx_t *c, int mdlen); // mdlen = hash output in bytes | ||
32 | int sha3_update(sha3_ctx_t *c, const void *data, size_t len); | ||
33 | int sha3_final(void *md, sha3_ctx_t *c); // digest goes to md | ||
34 | |||
35 | // compute a sha3 hash (md) of given byte length from "in" | ||
36 | void *sha3(const void *in, size_t inlen, void *md, int mdlen); | ||
37 | |||
38 | // SHAKE128 and SHAKE256 extensible-output functions | ||
39 | #define shake128_init(c) sha3_init(c, 16) | ||
40 | #define shake256_init(c) sha3_init(c, 32) | ||
41 | #define shake_update sha3_update | ||
42 | |||
43 | void shake_xof(sha3_ctx_t *c); | ||
44 | void shake_out(sha3_ctx_t *c, void *out, size_t len); | ||
45 | |||
46 | #endif | ||
47 | |||