LCOV - code coverage report
Current view: top level - sgx/src/trusted - meta_bc.c (source / functions) Hit Total Coverage
Test: powHSM firmware Lines: 50 50 100.0 %
Date: 2025-11-18 03:05:18 Functions: 1 1 100.0 %

          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             : #ifndef __TRUSTED_META_BC_H
      26             : #define __TRUSTED_META_BC_H
      27             : 
      28             : #include <stdlib.h>
      29             : #include <stdint.h>
      30             : #include <string.h>
      31             : 
      32             : #include "meta_bc.h"
      33             : 
      34             : #include "hal/exceptions.h"
      35             : #include "hal/log.h"
      36             : 
      37             : #include "apdu.h"
      38             : #include "instructions.h"
      39             : #include "err.h"
      40             : 
      41             : #include "bc_advance.h"
      42             : #include "bc_ancestor.h"
      43             : #include "bc_err.h"
      44             : 
      45             : #define MAX_CHUNK_SIZE 80
      46             : #define CHUNK_OVERHEAD 5
      47             : 
      48          26 : unsigned int do_meta_advupd(unsigned int rx) {
      49             :     uint8_t cmd;
      50             :     uint8_t internal_buffer[MAX_CHUNK_SIZE + CHUNK_OVERHEAD];
      51             :     uint8_t* old_buffer;
      52             :     size_t old_buffer_size;
      53             : 
      54          26 :     cmd = APDU_CMD();
      55             : 
      56             :     // Backup message buffer spec
      57          26 :     old_buffer = communication_get_msg_buffer();
      58          26 :     old_buffer_size = communication_get_msg_buffer_size();
      59             : 
      60             :     // Set new buffer
      61          26 :     communication_set_msg_buffer(internal_buffer, sizeof(internal_buffer));
      62             : 
      63             :     // Send data in chunks
      64          26 :     unsigned int total_data = APDU_DATA_SIZE(rx);
      65          26 :     unsigned int data_offset = 0;
      66          26 :     unsigned int chunk_size =
      67             :         total_data < MAX_CHUNK_SIZE ? total_data : MAX_CHUNK_SIZE;
      68          26 :     unsigned int irx = 0;
      69             : 
      70             :     BEGIN_TRY {
      71          26 :         TRY {
      72             :             // Initialize internal buffer for soundness
      73          26 :             memcpy(internal_buffer, old_buffer, rx < DATA ? rx : DATA);
      74          26 :             if (rx < DATA)
      75           1 :                 SET_APDU_OP(0);
      76             : 
      77          59 :             while (data_offset < total_data) {
      78          50 :                 SET_APDU_CLA();
      79          50 :                 SET_APDU_CMD(cmd);
      80          50 :                 SET_APDU_OP(old_buffer[OP]);
      81          50 :                 if (chunk_size == 0 || chunk_size > APDU_TOTAL_DATA_SIZE) {
      82             :                     // This shouldn't happen
      83           2 :                     THROW(ERR_INTERNAL);
      84             :                 }
      85          48 :                 if (chunk_size > total_data - data_offset) {
      86             :                     // Not enough data
      87           1 :                     THROW(PROT_INVALID);
      88             :                 }
      89          94 :                 memcpy(
      90          47 :                     APDU_DATA_PTR, &old_buffer[DATA + data_offset], chunk_size);
      91          47 :                 irx = TX_FOR_DATA_SIZE(chunk_size);
      92             :                 LOG_HEX("ITX >", internal_buffer, irx);
      93          47 :                 switch (cmd) {
      94          23 :                 case INS_ADVANCE:
      95          23 :                     irx = bc_advance(irx);
      96          22 :                     break;
      97          23 :                 case INS_UPD_ANCESTOR:
      98          23 :                     irx = bc_upd_ancestor(irx);
      99          22 :                     break;
     100           1 :                 default:
     101             :                     // We should never reach this point
     102           1 :                     THROW(ERR_INTERNAL);
     103             :                 }
     104             :                 LOG_HEX("ITX <", internal_buffer, irx);
     105             :                 // Validate response
     106          44 :                 if (irx != TX_FOR_TXLEN() && irx != TX_NO_DATA()) {
     107             :                     LOG("Unexpected response size\n");
     108           1 :                     THROW(ERR_INTERNAL);
     109             :                 }
     110          43 :                 if (APDU_CLA() != CLA || APDU_CMD() != cmd) {
     111             :                     LOG("Unexpected response command\n");
     112           2 :                     THROW(ERR_INTERNAL);
     113             :                 }
     114             :                 // Done?
     115          41 :                 if (APDU_OP() != old_buffer[OP]) {
     116           8 :                     break;
     117             :                 }
     118          33 :                 data_offset += chunk_size;
     119          33 :                 chunk_size = APDU_TXLEN();
     120             :             }
     121             : 
     122             :             // Restore message buffer
     123          17 :             communication_set_msg_buffer(old_buffer, old_buffer_size);
     124             : 
     125             :             // Response
     126          17 :             SET_APDU_OP(internal_buffer[OP]);
     127          17 :             if (irx == TX_FOR_DATA_SIZE(1)) {
     128           8 :                 SET_APDU_TXLEN(internal_buffer[DATA]);
     129          17 :                 return TX_FOR_TXLEN();
     130             :             } else {
     131           9 :                 return TX_NO_DATA();
     132             :             }
     133             :         }
     134           9 :         CATCH_OTHER(e) {
     135             :             // Restore message buffer
     136           9 :             communication_set_msg_buffer(old_buffer, old_buffer_size);
     137             :             // Forward
     138           9 :             THROW(e);
     139             :         }
     140             :         FINALLY {
     141             :         }
     142             :     }
     143             :     END_TRY;
     144             : }
     145             : 
     146             : #endif // __TRUSTED_META_BC_H

Generated by: LCOV version 1.16