Line data Source code
1 : /**
2 : * The MIT License (MIT)
3 : *
4 : * Copyright (c) 2021 RSK Labs Ltd
5 : *
6 : * Permission is hereby granted, free of charge, to any person obtaining a copy
7 : * of this software and associated documentation files (the "Software"), to
8 : * deal in the Software without restriction, including without limitation the
9 : * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10 : * sell copies of the Software, and to permit persons to whom the Software is
11 : * furnished to do so, subject to the following conditions:
12 : *
13 : * The above copyright notice and this permission notice shall be included in
14 : * all copies or substantial portions of the Software.
15 : *
16 : * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 : * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 : * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 : * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 : * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 : * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
22 : * IN THE SOFTWARE.
23 : */
24 :
25 : #include "hal/hash.h"
26 : #include "hal/platform.h"
27 : #include "hal/exceptions.h"
28 :
29 : #include "auth.h"
30 : #include "svarint.h"
31 : #include "mem.h"
32 : #include "memutil.h"
33 :
34 : #include "hal/log.h"
35 :
36 : // IMPORTANT: This callback only executes for the scriptSig at the desired input
37 : // (the one that is requested to sign)
38 : // In all the other cases the parser is not even initialized or called,
39 : // so it is not possible for this callback to execute.
40 8804 : static void btcscript_cb(const btcscript_cb_event_t event) {
41 : uint8_t redeemscript_length_size;
42 : uint8_t redeemscript_length[MAX_SVARINT_ENCODING_SIZE];
43 :
44 8804 : if (event == BTCSCRIPT_EV_OPCODE && auth.tx.script_ctx.operand_size > 0 &&
45 58 : auth.tx.script_ctx.operand_size == auth.tx.script_ctx.bytes_remaining) {
46 : // This is a push of exactly the remaining script bytes => this is the
47 : // last push of the script => this is the redeemScript
48 40 : auth.tx.redeemscript_found = 1;
49 : // Hash the script size using the size of the operand (redeemScript)
50 : redeemscript_length_size =
51 40 : svarint_encode(auth.tx.script_ctx.operand_size,
52 : redeemscript_length,
53 : sizeof(redeemscript_length));
54 40 : hash_sha256_update(&auth.tx.sig_hash_ctx,
55 : redeemscript_length,
56 : redeemscript_length_size);
57 8764 : } else if (event == BTCSCRIPT_EV_OPERAND && auth.tx.redeemscript_found) {
58 6862 : hash_sha256_update(&auth.tx.sig_hash_ctx,
59 : &auth.tx.script_ctx.operand_byte,
60 : sizeof(auth.tx.script_ctx.operand_byte));
61 : }
62 8804 : }
63 :
64 88518 : static void btctx_cb(const btctx_cb_event_t event) {
65 : // Update txhash
66 88518 : hash_sha256_update(
67 88518 : &auth.tx.tx_hash_ctx, auth.tx.ctx.raw, auth.tx.ctx.raw_size);
68 :
69 : // The bridge currently only generates pegout transactions with
70 : // versions 1 or 2. Validate that.
71 88518 : if (event == BTCTX_EV_VERSION && auth.tx.ctx.parsed.version != 1 &&
72 16 : auth.tx.ctx.parsed.version != 2) {
73 2 : LOG("[E] Unsupported TX Version: %u\n", auth.tx.ctx.parsed.version);
74 2 : THROW(ERR_AUTH_INVALID_TX_VERSION);
75 : }
76 :
77 : // Validate that the input index to sign is valid
78 88516 : if (event == BTCTX_EV_VIN_COUNT &&
79 44 : auth.input_index_to_sign >= auth.tx.ctx.parsed.varint.value) {
80 0 : LOG("[E] Input index to sign > number of inputs.\n");
81 0 : THROW(ERR_AUTH_INVALID_TX_INPUT_INDEX);
82 : }
83 :
84 : // Update sighash
85 88516 : if (event == BTCTX_EV_VIN_SLENGTH) {
86 554 : if (auth.tx.ctx.inout_current == auth.input_index_to_sign) {
87 : // Parse this scriptSig
88 44 : auth.tx.redeemscript_found = 0;
89 44 : btcscript_init(&auth.tx.script_ctx,
90 : &btcscript_cb,
91 : auth.tx.ctx.parsed.varint.value);
92 : } else {
93 : // All other scriptSigs get replaced by an empty scriptSig
94 : // when calculating the sigHash
95 510 : hash_sha256_update(&auth.tx.sig_hash_ctx, (uint8_t[]){0x00}, 1);
96 : }
97 87962 : } else if (event == BTCTX_EV_VIN_SCRIPT_DATA &&
98 65716 : auth.tx.ctx.inout_current == auth.input_index_to_sign) {
99 8804 : if (btcscript_consume(auth.tx.ctx.raw, auth.tx.ctx.raw_size) !=
100 8804 : auth.tx.ctx.raw_size) {
101 0 : LOG("[E] Expected to consume %u bytes from the script but didn't",
102 0 : auth.tx.ctx.raw_size);
103 0 : THROW(ERR_AUTH_TX_HASH_MISMATCH);
104 : }
105 :
106 8804 : if (btcscript_result() < 0) {
107 2 : LOG("[E] Error %u parsing the scriptSig", btcscript_result());
108 2 : THROW(ERR_AUTH_TX_HASH_MISMATCH);
109 : }
110 :
111 8802 : if (auth.tx.ctx.script_remaining == 0) {
112 40 : if (btcscript_result() != BTCSCRIPT_ST_DONE) {
113 0 : LOG("[E] No more scriptSig bytes to parse but "
114 : "the script parser isn't finished");
115 0 : THROW(ERR_AUTH_TX_HASH_MISMATCH);
116 : }
117 40 : if (!auth.tx.redeemscript_found) {
118 0 : LOG("[E] Finished parsing the scriptSig "
119 : "but the redeemScript was not found");
120 0 : THROW(ERR_AUTH_TX_HASH_MISMATCH);
121 : }
122 : }
123 79158 : } else if (event != BTCTX_EV_VIN_SCRIPT_DATA) {
124 22246 : hash_sha256_update(
125 22246 : &auth.tx.sig_hash_ctx, auth.tx.ctx.raw, auth.tx.ctx.raw_size);
126 : }
127 88514 : }
128 :
129 76204 : static void btctx_cb_segwit(const btctx_cb_event_t event) {
130 : // Update txhash
131 76204 : hash_sha256_update(
132 76204 : &auth.tx.tx_hash_ctx, auth.tx.ctx.raw, auth.tx.ctx.raw_size);
133 :
134 76204 : if (event == BTCTX_EV_VERSION) {
135 12 : hash_sha256_update(
136 12 : &auth.tx.sig_hash_ctx, auth.tx.ctx.raw, auth.tx.ctx.raw_size);
137 : }
138 :
139 76204 : if (event == BTCTX_EV_VIN_COUNT) {
140 12 : hash_sha256_init(&auth.tx.prevouts_hash_ctx);
141 12 : hash_sha256_init(&auth.tx.sequence_hash_ctx);
142 12 : auth.tx.aux_offset = 0;
143 : }
144 :
145 76204 : if (event == BTCTX_EV_VIN_TXH_DATA || event == BTCTX_EV_VIN_TXIX) {
146 17160 : hash_sha256_update(
147 17160 : &auth.tx.prevouts_hash_ctx, auth.tx.ctx.raw, auth.tx.ctx.raw_size);
148 :
149 17160 : if (auth.tx.ctx.inout_current == auth.input_index_to_sign) {
150 792 : SAFE_MEMMOVE(auth.tx.ip_prevout,
151 : sizeof(auth.tx.ip_prevout),
152 : auth.tx.aux_offset,
153 : auth.tx.ctx.raw,
154 : sizeof(auth.tx.ctx.raw),
155 : MEMMOVE_ZERO_OFFSET,
156 : auth.tx.ctx.raw_size,
157 : THROW(ERR_AUTH_INVALID_DATA_SIZE));
158 396 : auth.tx.aux_offset += auth.tx.ctx.raw_size;
159 : }
160 : }
161 :
162 76204 : if (event == BTCTX_EV_VIN_SEQNO) {
163 520 : hash_sha256_update(
164 520 : &auth.tx.sequence_hash_ctx, auth.tx.ctx.raw, auth.tx.ctx.raw_size);
165 :
166 520 : if (auth.tx.ctx.inout_current == auth.input_index_to_sign) {
167 24 : SAFE_MEMMOVE(auth.tx.ip_seqno,
168 : sizeof(auth.tx.ip_seqno),
169 : MEMMOVE_ZERO_OFFSET,
170 : auth.tx.ctx.raw,
171 : sizeof(auth.tx.ctx.raw),
172 : MEMMOVE_ZERO_OFFSET,
173 : auth.tx.ctx.raw_size,
174 : THROW(ERR_AUTH_INVALID_DATA_SIZE));
175 : }
176 : }
177 :
178 76204 : if (event == BTCTX_EV_VOUT_COUNT) {
179 12 : hash_sha256_final(&auth.tx.prevouts_hash_ctx, auth.tx.aux_hash);
180 12 : hash_sha256_init(&auth.tx.prevouts_hash_ctx);
181 12 : hash_sha256_update(&auth.tx.prevouts_hash_ctx,
182 : auth.tx.aux_hash,
183 : sizeof(auth.tx.aux_hash));
184 12 : hash_sha256_final(&auth.tx.prevouts_hash_ctx, auth.tx.aux_hash);
185 12 : hash_sha256_update(
186 : &auth.tx.sig_hash_ctx, auth.tx.aux_hash, sizeof(auth.tx.aux_hash));
187 :
188 12 : hash_sha256_final(&auth.tx.sequence_hash_ctx, auth.tx.aux_hash);
189 12 : hash_sha256_init(&auth.tx.sequence_hash_ctx);
190 12 : hash_sha256_update(&auth.tx.sequence_hash_ctx,
191 : auth.tx.aux_hash,
192 : sizeof(auth.tx.aux_hash));
193 12 : hash_sha256_final(&auth.tx.sequence_hash_ctx, auth.tx.aux_hash);
194 12 : hash_sha256_update(
195 : &auth.tx.sig_hash_ctx, auth.tx.aux_hash, sizeof(auth.tx.aux_hash));
196 :
197 : // Previously saved outpoint of input to sign
198 12 : hash_sha256_update(&auth.tx.sig_hash_ctx,
199 : auth.tx.ip_prevout,
200 : sizeof(auth.tx.ip_prevout));
201 :
202 12 : hash_sha256_init(&auth.tx.outputs_hash_ctx);
203 : }
204 :
205 76204 : if (event == BTCTX_EV_VOUT_VALUE || event == BTCTX_EV_VOUT_SLENGTH ||
206 : event == BTCTX_EV_VOUT_SCRIPT_DATA) {
207 640 : hash_sha256_update(
208 640 : &auth.tx.outputs_hash_ctx, auth.tx.ctx.raw, auth.tx.ctx.raw_size);
209 : }
210 :
211 76204 : if (event == BTCTX_EV_LOCKTIME) {
212 12 : hash_sha256_final(&auth.tx.outputs_hash_ctx, auth.tx.outputs_hash);
213 12 : hash_sha256_init(&auth.tx.outputs_hash_ctx);
214 12 : hash_sha256_update(&auth.tx.outputs_hash_ctx,
215 : auth.tx.outputs_hash,
216 : sizeof(auth.tx.outputs_hash));
217 12 : hash_sha256_final(&auth.tx.outputs_hash_ctx, auth.tx.outputs_hash);
218 :
219 24 : SAFE_MEMMOVE(auth.tx.lock_time,
220 : sizeof(auth.tx.lock_time),
221 : MEMMOVE_ZERO_OFFSET,
222 : auth.tx.ctx.raw,
223 : sizeof(auth.tx.ctx.raw),
224 : MEMMOVE_ZERO_OFFSET,
225 : auth.tx.ctx.raw_size,
226 : THROW(ERR_AUTH_INVALID_DATA_SIZE));
227 : }
228 76204 : }
229 :
230 : /*
231 : * Implement the BTC tx parsing and calculations portion
232 : * of the signing authorization protocol.
233 : *
234 : * @arg[in] rx number of received bytes from the host
235 : * @ret number of transmited bytes to the host
236 : */
237 2184 : unsigned int auth_sign_handle_btctx(volatile unsigned int rx) {
238 2184 : uint8_t apdu_offset = 0;
239 :
240 2184 : if (auth.state != STATE_AUTH_BTCTX) {
241 0 : LOG("[E] Expected to be in the BTC tx state\n");
242 0 : THROW(ERR_AUTH_INVALID_STATE);
243 : }
244 :
245 2184 : if (!auth.tx.segwit_processing_extradata) {
246 : // Read little endian TX length
247 : // (part of the legacy protocol, includes this length)
248 2146 : if (auth.tx.remaining_bytes == 0) {
249 290 : for (uint8_t i = 0; i < BTCTX_LENGTH_SIZE; i++) {
250 232 : auth.tx.remaining_bytes += APDU_DATA_PTR[i] << (8 * i);
251 : }
252 : // BTC tx length includes the length of the length
253 : // and the length of the sighash computation mode and
254 : // extradata length
255 58 : auth.tx.remaining_bytes -=
256 : BTCTX_LENGTH_SIZE + SIGHASH_COMP_MODE_SIZE + EXTRADATA_SIZE;
257 : // Init both hash operations
258 58 : hash_sha256_init(&auth.tx.tx_hash_ctx);
259 58 : hash_sha256_init(&auth.tx.sig_hash_ctx);
260 58 : apdu_offset = BTCTX_LENGTH_SIZE;
261 : // Following three bytes indicate the sighash computation
262 : // mode (1 byte) and extradata size (2 bytes LE, for segwit)
263 58 : auth.tx.sighash_computation_mode = APDU_DATA_PTR[apdu_offset++];
264 58 : auth.tx.segwit_processing_extradata = false;
265 58 : auth.tx.segwit_extradata_size = 0;
266 58 : auth.tx.segwit_extradata_size += APDU_DATA_PTR[apdu_offset++];
267 58 : auth.tx.segwit_extradata_size += APDU_DATA_PTR[apdu_offset++] << 8;
268 : // Validate computation mode and init tx parsing context
269 58 : switch (auth.tx.sighash_computation_mode) {
270 46 : case SIGHASH_COMPUTE_MODE_LEGACY:
271 46 : btctx_init(&auth.tx.ctx, &btctx_cb);
272 46 : break;
273 12 : case SIGHASH_COMPUTE_MODE_SEGWIT:
274 12 : btctx_init(&auth.tx.ctx, &btctx_cb_segwit);
275 12 : if (!auth.tx.segwit_extradata_size) {
276 0 : LOG("[E] Invalid extradata size for segwit");
277 0 : THROW(ERR_AUTH_INVALID_EXTRADATA_SIZE);
278 : }
279 12 : break;
280 0 : default:
281 0 : LOG("[E] Invalid sighash computation mode\n");
282 0 : THROW(ERR_AUTH_INVALID_SIGHASH_COMPUTATION_MODE);
283 : }
284 : }
285 :
286 6434 : auth.tx.remaining_bytes -= btctx_consume(
287 2146 : APDU_DATA_PTR + apdu_offset, APDU_DATA_SIZE(rx) - apdu_offset);
288 :
289 2142 : if (btctx_result() < 0) {
290 0 : LOG("[E] Error parsing BTC tx: %d\n", btctx_result());
291 : // To comply with the legacy implementation
292 0 : THROW(ERR_AUTH_TX_HASH_MISMATCH);
293 : }
294 :
295 2142 : if (btctx_result() == BTCTX_ST_DONE) {
296 52 : if (auth.tx.remaining_bytes > 0) {
297 2 : LOG("[E] Error parsing BTC tx: more bytes reported "
298 : "than actual tx bytes\n");
299 : // To comply with the legacy implementation
300 2 : THROW(ERR_AUTH_INVALID_DATA_SIZE);
301 : }
302 :
303 : // Finalize TX hash computation
304 50 : hash_sha256_final(&auth.tx.tx_hash_ctx, auth.tx_hash);
305 50 : hash_sha256_init(&auth.tx.tx_hash_ctx);
306 50 : hash_sha256_update(&auth.tx.tx_hash_ctx, auth.tx_hash, 32);
307 50 : hash_sha256_final(&auth.tx.tx_hash_ctx, auth.tx_hash);
308 850 : for (int j = 0; j < 16; j++) {
309 800 : uint8_t aux = auth.tx_hash[j];
310 800 : auth.tx_hash[j] = auth.tx_hash[31 - j];
311 800 : auth.tx_hash[31 - j] = aux;
312 : }
313 :
314 : // Segwit?
315 50 : if (auth.tx.sighash_computation_mode ==
316 : SIGHASH_COMPUTE_MODE_SEGWIT) {
317 12 : auth.tx.segwit_processing_extradata = true;
318 12 : auth.tx.remaining_bytes =
319 12 : (uint32_t)auth.tx.segwit_extradata_size;
320 : } else {
321 38 : auth.tx.finalise = true;
322 : }
323 : }
324 : } else {
325 : // Hash extradata
326 0 : hash_sha256_update(
327 38 : &auth.tx.sig_hash_ctx, APDU_DATA_PTR, APDU_DATA_SIZE(rx));
328 38 : auth.tx.remaining_bytes -= APDU_DATA_SIZE(rx);
329 38 : if (auth.tx.remaining_bytes == 0) {
330 12 : auth.tx.finalise = true;
331 : }
332 : }
333 :
334 2178 : if (auth.tx.finalise) {
335 50 : if (auth.tx.sighash_computation_mode == SIGHASH_COMPUTE_MODE_SEGWIT) {
336 : // Remaining tx items to hash for segwit
337 12 : hash_sha256_update(&auth.tx.sig_hash_ctx,
338 : auth.tx.ip_seqno,
339 : sizeof(auth.tx.ip_seqno));
340 12 : hash_sha256_update(&auth.tx.sig_hash_ctx,
341 : auth.tx.outputs_hash,
342 : sizeof(auth.tx.outputs_hash));
343 12 : hash_sha256_update(&auth.tx.sig_hash_ctx,
344 : auth.tx.lock_time,
345 : sizeof(auth.tx.lock_time));
346 : }
347 :
348 : // Add SIGHASH_ALL hash type at the end
349 50 : hash_sha256_update(&auth.tx.sig_hash_ctx,
350 50 : (uint8_t[])SIGHASH_ALL_BYTES,
351 : sizeof(SIGHASH_ALL_SIZE));
352 50 : hash_sha256_final(&auth.tx.sig_hash_ctx, auth.sig_hash);
353 :
354 50 : hash_sha256_init(&auth.tx.sig_hash_ctx);
355 50 : hash_sha256_update(&auth.tx.sig_hash_ctx, auth.sig_hash, 32);
356 50 : hash_sha256_final(&auth.tx.sig_hash_ctx, auth.sig_hash);
357 :
358 : // Log hashes for debugging purposes
359 50 : LOG_HEX("TX hash: ", auth.tx_hash, sizeof(auth.tx_hash));
360 50 : LOG_HEX("TX sig hash: ", auth.sig_hash, sizeof(auth.sig_hash));
361 :
362 : // Request RSK transaction receipt
363 50 : SET_APDU_OP(P1_RECEIPT);
364 50 : SET_APDU_TXLEN(AUTH_MAX_EXCHANGE_SIZE);
365 50 : auth.expected_bytes = APDU_TXLEN();
366 50 : auth_transition_to(STATE_AUTH_RECEIPT);
367 50 : return TX_FOR_TXLEN();
368 : }
369 :
370 2128 : if (auth.tx.remaining_bytes == 0) {
371 2 : LOG("[E] Error parsing BTC tx: no more bytes should "
372 : "remain but haven't finished parsing\n");
373 : // To comply with the legacy implementation
374 2 : THROW(ERR_AUTH_TX_HASH_MISMATCH);
375 : }
376 :
377 2126 : SET_APDU_TXLEN(MIN(auth.tx.remaining_bytes, AUTH_MAX_EXCHANGE_SIZE));
378 2126 : auth.expected_bytes = APDU_TXLEN();
379 2126 : return TX_FOR_TXLEN();
380 : }
|