LCOV - code coverage report
Current view: top level - sgx/src/trusted - meta_bc.c (source / functions) Hit Total Coverage
Test: powHSM firmware Lines: 46 46 100.0 %
Date: 2025-07-10 13:49:13 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          24 : 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          24 :     cmd = APDU_CMD();
      55             : 
      56             :     // Backup message buffer spec
      57          24 :     old_buffer = communication_get_msg_buffer();
      58          24 :     old_buffer_size = communication_get_msg_buffer_size();
      59             : 
      60             :     // Set new buffer
      61          24 :     communication_set_msg_buffer(internal_buffer, sizeof(internal_buffer));
      62             : 
      63             :     // Send data in chunks
      64          24 :     unsigned int total_data = rx - DATA;
      65          24 :     unsigned int data_offset = 0;
      66          24 :     unsigned int chunk_size =
      67             :         total_data < MAX_CHUNK_SIZE ? total_data : MAX_CHUNK_SIZE;
      68             :     unsigned int irx;
      69             : 
      70             :     BEGIN_TRY {
      71          24 :         TRY {
      72          56 :             while (data_offset < total_data) {
      73          48 :                 SET_APDU_CLA();
      74          48 :                 SET_APDU_CMD(cmd);
      75          48 :                 SET_APDU_OP(old_buffer[OP]);
      76          48 :                 if (chunk_size > APDU_TOTAL_DATA_SIZE) {
      77             :                     // This shouldn't happen
      78           1 :                     THROW(ERR_INTERNAL);
      79             :                 }
      80          47 :                 if (chunk_size > total_data - data_offset) {
      81             :                     // Not enough data
      82           1 :                     THROW(PROT_INVALID);
      83             :                 }
      84          92 :                 memcpy(
      85          46 :                     APDU_DATA_PTR, &old_buffer[DATA + data_offset], chunk_size);
      86          46 :                 irx = TX_FOR_DATA_SIZE(chunk_size);
      87             :                 LOG_HEX("ITX >", internal_buffer, irx);
      88          46 :                 switch (cmd) {
      89          22 :                 case INS_ADVANCE:
      90          22 :                     irx = bc_advance(irx);
      91          21 :                     break;
      92          23 :                 case INS_UPD_ANCESTOR:
      93          23 :                     irx = bc_upd_ancestor(irx);
      94          22 :                     break;
      95           1 :                 default:
      96             :                     // We should never reach this point
      97           1 :                     THROW(ERR_INTERNAL);
      98             :                 }
      99             :                 LOG_HEX("ITX <", internal_buffer, irx);
     100             :                 // Validate response
     101          43 :                 if (irx != TX_FOR_TXLEN() && irx != TX_NO_DATA()) {
     102             :                     LOG("Unexpected response size\n");
     103           1 :                     THROW(ERR_INTERNAL);
     104             :                 }
     105          42 :                 if (APDU_CLA() != CLA || APDU_CMD() != cmd) {
     106             :                     LOG("Unexpected response command\n");
     107           2 :                     THROW(ERR_INTERNAL);
     108             :                 }
     109             :                 // Done?
     110          40 :                 if (APDU_OP() != old_buffer[OP]) {
     111           8 :                     break;
     112             :                 }
     113          32 :                 data_offset += chunk_size;
     114          32 :                 chunk_size = APDU_TXLEN();
     115             :             }
     116             : 
     117             :             // Restore message buffer
     118          16 :             communication_set_msg_buffer(old_buffer, old_buffer_size);
     119             : 
     120             :             // Response
     121          16 :             SET_APDU_OP(internal_buffer[OP]);
     122          16 :             if (irx == TX_FOR_DATA_SIZE(1)) {
     123           8 :                 SET_APDU_TXLEN(internal_buffer[DATA]);
     124          16 :                 return TX_FOR_TXLEN();
     125             :             } else {
     126           8 :                 return TX_NO_DATA();
     127             :             }
     128             :         }
     129           8 :         CATCH_OTHER(e) {
     130             :             // Restore message buffer
     131           8 :             communication_set_msg_buffer(old_buffer, old_buffer_size);
     132             :             // Forward
     133           8 :             THROW(e);
     134             :         }
     135             :         FINALLY {
     136             :         }
     137             :     }
     138             :     END_TRY;
     139             : }
     140             : 
     141             : #endif // __TRUSTED_META_BC_H

Generated by: LCOV version 1.16