| line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
|
1
|
|
|
|
|
|
|
/* |
|
2
|
|
|
|
|
|
|
* Copyright (c) 2016 Thomas Pornin |
|
3
|
|
|
|
|
|
|
* |
|
4
|
|
|
|
|
|
|
* Permission is hereby granted, free of charge, to any person obtaining |
|
5
|
|
|
|
|
|
|
* a copy of this software and associated documentation files (the |
|
6
|
|
|
|
|
|
|
* "Software"), to deal in the Software without restriction, including |
|
7
|
|
|
|
|
|
|
* without limitation the rights to use, copy, modify, merge, publish, |
|
8
|
|
|
|
|
|
|
* distribute, sublicense, and/or sell copies of the Software, and to |
|
9
|
|
|
|
|
|
|
* permit persons to whom the Software is furnished to do so, subject to |
|
10
|
|
|
|
|
|
|
* the following conditions: |
|
11
|
|
|
|
|
|
|
* |
|
12
|
|
|
|
|
|
|
* The above copyright notice and this permission notice shall be |
|
13
|
|
|
|
|
|
|
* included in all copies or substantial portions of the Software. |
|
14
|
|
|
|
|
|
|
* |
|
15
|
|
|
|
|
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
|
16
|
|
|
|
|
|
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
|
17
|
|
|
|
|
|
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
|
18
|
|
|
|
|
|
|
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS |
|
19
|
|
|
|
|
|
|
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN |
|
20
|
|
|
|
|
|
|
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN |
|
21
|
|
|
|
|
|
|
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
|
22
|
|
|
|
|
|
|
* SOFTWARE. |
|
23
|
|
|
|
|
|
|
*/ |
|
24
|
|
|
|
|
|
|
|
|
25
|
|
|
|
|
|
|
#include "inner.h" |
|
26
|
|
|
|
|
|
|
|
|
27
|
|
|
|
|
|
|
static inline size_t |
|
28
|
0
|
|
|
|
|
|
hash_size(const br_hash_class *dig) |
|
29
|
|
|
|
|
|
|
{ |
|
30
|
0
|
|
|
|
|
|
return (unsigned)(dig->desc >> BR_HASHDESC_OUT_OFF) |
|
31
|
0
|
|
|
|
|
|
& BR_HASHDESC_OUT_MASK; |
|
32
|
|
|
|
|
|
|
} |
|
33
|
|
|
|
|
|
|
|
|
34
|
|
|
|
|
|
|
static inline size_t |
|
35
|
0
|
|
|
|
|
|
block_size(const br_hash_class *dig) |
|
36
|
|
|
|
|
|
|
{ |
|
37
|
|
|
|
|
|
|
unsigned ls; |
|
38
|
|
|
|
|
|
|
|
|
39
|
0
|
|
|
|
|
|
ls = (unsigned)(dig->desc >> BR_HASHDESC_LBLEN_OFF) |
|
40
|
|
|
|
|
|
|
& BR_HASHDESC_LBLEN_MASK; |
|
41
|
0
|
|
|
|
|
|
return (size_t)1 << ls; |
|
42
|
|
|
|
|
|
|
} |
|
43
|
|
|
|
|
|
|
|
|
44
|
|
|
|
|
|
|
/* see bearssl.h */ |
|
45
|
|
|
|
|
|
|
size_t |
|
46
|
0
|
|
|
|
|
|
br_hmac_outCT(const br_hmac_context *ctx, |
|
47
|
|
|
|
|
|
|
const void *data, size_t len, size_t min_len, size_t max_len, |
|
48
|
|
|
|
|
|
|
void *out) |
|
49
|
|
|
|
|
|
|
{ |
|
50
|
|
|
|
|
|
|
/* |
|
51
|
|
|
|
|
|
|
* Method implemented here is inspired from the descriptions on: |
|
52
|
|
|
|
|
|
|
* https://www.imperialviolet.org/2013/02/04/luckythirteen.html |
|
53
|
|
|
|
|
|
|
* |
|
54
|
|
|
|
|
|
|
* Principle: we input bytes one by one. We use a MUX to push |
|
55
|
|
|
|
|
|
|
* padding bytes instead of data bytes when appropriate. At each |
|
56
|
|
|
|
|
|
|
* block limit, we get the current hash function state: this is |
|
57
|
|
|
|
|
|
|
* a potential output, since we handle MD padding ourselves. |
|
58
|
|
|
|
|
|
|
* |
|
59
|
|
|
|
|
|
|
* be 1 for big-endian, 0 for little-endian |
|
60
|
|
|
|
|
|
|
* po minimal MD padding length |
|
61
|
|
|
|
|
|
|
* bs block size (always a power of 2) |
|
62
|
|
|
|
|
|
|
* hlen hash output size |
|
63
|
|
|
|
|
|
|
*/ |
|
64
|
|
|
|
|
|
|
|
|
65
|
|
|
|
|
|
|
const br_hash_class *dig; |
|
66
|
|
|
|
|
|
|
br_hash_compat_context hc; |
|
67
|
|
|
|
|
|
|
int be; |
|
68
|
|
|
|
|
|
|
uint32_t po, bs; |
|
69
|
|
|
|
|
|
|
uint32_t kr, km, kl, kz, u; |
|
70
|
|
|
|
|
|
|
uint64_t count, ncount, bit_len; |
|
71
|
|
|
|
|
|
|
unsigned char tmp1[64], tmp2[64]; |
|
72
|
|
|
|
|
|
|
size_t hlen; |
|
73
|
|
|
|
|
|
|
|
|
74
|
|
|
|
|
|
|
/* |
|
75
|
|
|
|
|
|
|
* Copy the current hash context. |
|
76
|
|
|
|
|
|
|
*/ |
|
77
|
0
|
|
|
|
|
|
hc = ctx->dig; |
|
78
|
|
|
|
|
|
|
|
|
79
|
|
|
|
|
|
|
/* |
|
80
|
|
|
|
|
|
|
* Get function-specific information. |
|
81
|
|
|
|
|
|
|
*/ |
|
82
|
0
|
|
|
|
|
|
dig = hc.vtable; |
|
83
|
0
|
|
|
|
|
|
be = (dig->desc & BR_HASHDESC_MD_PADDING_BE) != 0; |
|
84
|
0
|
|
|
|
|
|
po = 9; |
|
85
|
0
|
0
|
|
|
|
|
if (dig->desc & BR_HASHDESC_MD_PADDING_128) { |
|
86
|
0
|
|
|
|
|
|
po += 8; |
|
87
|
|
|
|
|
|
|
} |
|
88
|
0
|
|
|
|
|
|
bs = block_size(dig); |
|
89
|
0
|
|
|
|
|
|
hlen = hash_size(dig); |
|
90
|
|
|
|
|
|
|
|
|
91
|
|
|
|
|
|
|
/* |
|
92
|
|
|
|
|
|
|
* Get current input length and compute total bit length. |
|
93
|
|
|
|
|
|
|
*/ |
|
94
|
0
|
|
|
|
|
|
count = dig->state(&hc.vtable, tmp1); |
|
95
|
0
|
|
|
|
|
|
bit_len = (count + (uint64_t)len) << 3; |
|
96
|
|
|
|
|
|
|
|
|
97
|
|
|
|
|
|
|
/* |
|
98
|
|
|
|
|
|
|
* We can input the blocks that we are sure we will use. |
|
99
|
|
|
|
|
|
|
* This offers better performance (no MUX for these blocks) |
|
100
|
|
|
|
|
|
|
* and also ensures that the remaining lengths fit on 32 bits. |
|
101
|
|
|
|
|
|
|
*/ |
|
102
|
0
|
|
|
|
|
|
ncount = (count + (uint64_t)min_len) & ~(uint64_t)(bs - 1); |
|
103
|
0
|
0
|
|
|
|
|
if (ncount > count) { |
|
104
|
|
|
|
|
|
|
size_t zlen; |
|
105
|
|
|
|
|
|
|
|
|
106
|
0
|
|
|
|
|
|
zlen = (size_t)(ncount - count); |
|
107
|
0
|
|
|
|
|
|
dig->update(&hc.vtable, data, zlen); |
|
108
|
0
|
|
|
|
|
|
data = (const unsigned char *)data + zlen; |
|
109
|
0
|
|
|
|
|
|
len -= zlen; |
|
110
|
0
|
|
|
|
|
|
max_len -= zlen; |
|
111
|
0
|
|
|
|
|
|
count = ncount; |
|
112
|
|
|
|
|
|
|
} |
|
113
|
|
|
|
|
|
|
|
|
114
|
|
|
|
|
|
|
/* |
|
115
|
|
|
|
|
|
|
* At that point: |
|
116
|
|
|
|
|
|
|
* -- 'count' contains the number of bytes already processed |
|
117
|
|
|
|
|
|
|
* (in total). |
|
118
|
|
|
|
|
|
|
* -- We must input 'len' bytes. 'min_len' is unimportant: we |
|
119
|
|
|
|
|
|
|
* used it to know how many full blocks we could process |
|
120
|
|
|
|
|
|
|
* directly. Now only len and max_len matter. |
|
121
|
|
|
|
|
|
|
* |
|
122
|
|
|
|
|
|
|
* We compute kr, kl, kz and km. |
|
123
|
|
|
|
|
|
|
* kr number of input bytes already in the current block |
|
124
|
|
|
|
|
|
|
* km index of the first byte after the end of the last padding |
|
125
|
|
|
|
|
|
|
* block, if length is max_len |
|
126
|
|
|
|
|
|
|
* kz index of the last byte of the actual last padding block |
|
127
|
|
|
|
|
|
|
* kl index of the start of the encoded length |
|
128
|
|
|
|
|
|
|
* |
|
129
|
|
|
|
|
|
|
* km, kz and kl are counted from the current offset in the |
|
130
|
|
|
|
|
|
|
* input data. |
|
131
|
|
|
|
|
|
|
*/ |
|
132
|
0
|
|
|
|
|
|
kr = (uint32_t)count & (bs - 1); |
|
133
|
0
|
|
|
|
|
|
kz = ((kr + (uint32_t)len + po + bs - 1) & ~(bs - 1)) - 1 - kr; |
|
134
|
0
|
|
|
|
|
|
kl = kz - 7; |
|
135
|
0
|
|
|
|
|
|
km = ((kr + (uint32_t)max_len + po + bs - 1) & ~(bs - 1)) - kr; |
|
136
|
|
|
|
|
|
|
|
|
137
|
|
|
|
|
|
|
/* |
|
138
|
|
|
|
|
|
|
* We must now process km bytes. For index u from 0 to km-1: |
|
139
|
|
|
|
|
|
|
* d is from data[] if u < max_len, 0x00 otherwise |
|
140
|
|
|
|
|
|
|
* e is an encoded length byte or 0x00, depending on u |
|
141
|
|
|
|
|
|
|
* The tests for d and e need not be constant-time, since |
|
142
|
|
|
|
|
|
|
* they relate only to u and max_len, not to the actual length. |
|
143
|
|
|
|
|
|
|
* |
|
144
|
|
|
|
|
|
|
* Actual input length is then: |
|
145
|
|
|
|
|
|
|
* d if u < len |
|
146
|
|
|
|
|
|
|
* 0x80 if u == len |
|
147
|
|
|
|
|
|
|
* 0x00 if u > len and u < kl |
|
148
|
|
|
|
|
|
|
* e if u >= kl |
|
149
|
|
|
|
|
|
|
* |
|
150
|
|
|
|
|
|
|
* Hash state is obtained whenever we reach a full block. This |
|
151
|
|
|
|
|
|
|
* is the result we want if and only if u == kz. |
|
152
|
|
|
|
|
|
|
*/ |
|
153
|
0
|
|
|
|
|
|
memset(tmp2, 0, sizeof tmp2); |
|
154
|
0
|
0
|
|
|
|
|
for (u = 0; u < km; u ++) { |
|
155
|
|
|
|
|
|
|
uint32_t v; |
|
156
|
|
|
|
|
|
|
uint32_t d, e, x0, x1; |
|
157
|
|
|
|
|
|
|
unsigned char x[1]; |
|
158
|
|
|
|
|
|
|
|
|
159
|
0
|
0
|
|
|
|
|
d = (u < max_len) ? ((const unsigned char *)data)[u] : 0x00; |
|
160
|
0
|
|
|
|
|
|
v = (kr + u) & (bs - 1); |
|
161
|
0
|
0
|
|
|
|
|
if (v >= (bs - 8)) { |
|
162
|
|
|
|
|
|
|
unsigned j; |
|
163
|
|
|
|
|
|
|
|
|
164
|
0
|
|
|
|
|
|
j = (v - (bs - 8)) << 3; |
|
165
|
0
|
0
|
|
|
|
|
if (be) { |
|
166
|
0
|
|
|
|
|
|
e = (uint32_t)(bit_len >> (56 - j)); |
|
167
|
|
|
|
|
|
|
} else { |
|
168
|
0
|
|
|
|
|
|
e = (uint32_t)(bit_len >> j); |
|
169
|
|
|
|
|
|
|
} |
|
170
|
0
|
|
|
|
|
|
e &= 0xFF; |
|
171
|
|
|
|
|
|
|
} else { |
|
172
|
0
|
|
|
|
|
|
e = 0x00; |
|
173
|
|
|
|
|
|
|
} |
|
174
|
0
|
|
|
|
|
|
x0 = MUX(EQ(u, (uint32_t)len), 0x80, d); |
|
175
|
0
|
|
|
|
|
|
x1 = MUX(LT(u, kl), 0x00, e); |
|
176
|
0
|
|
|
|
|
|
x[0] = MUX(LE(u, (uint32_t)len), x0, x1); |
|
177
|
0
|
|
|
|
|
|
dig->update(&hc.vtable, x, 1); |
|
178
|
0
|
0
|
|
|
|
|
if (v == (bs - 1)) { |
|
179
|
0
|
|
|
|
|
|
dig->state(&hc.vtable, tmp1); |
|
180
|
0
|
|
|
|
|
|
CCOPY(EQ(u, kz), tmp2, tmp1, hlen); |
|
181
|
|
|
|
|
|
|
} |
|
182
|
|
|
|
|
|
|
} |
|
183
|
|
|
|
|
|
|
|
|
184
|
|
|
|
|
|
|
/* |
|
185
|
|
|
|
|
|
|
* Inner hash output is in tmp2[]; we finish processing. |
|
186
|
|
|
|
|
|
|
*/ |
|
187
|
0
|
|
|
|
|
|
dig->init(&hc.vtable); |
|
188
|
0
|
|
|
|
|
|
dig->set_state(&hc.vtable, ctx->kso, (uint64_t)bs); |
|
189
|
0
|
|
|
|
|
|
dig->update(&hc.vtable, tmp2, hlen); |
|
190
|
0
|
|
|
|
|
|
dig->out(&hc.vtable, tmp2); |
|
191
|
0
|
|
|
|
|
|
memcpy(out, tmp2, ctx->out_len); |
|
192
|
0
|
|
|
|
|
|
return ctx->out_len; |
|
193
|
|
|
|
|
|
|
} |