LCOV - code coverage report
Current view: top level - powhsm/src - bc_mm.c (source / functions) Hit Total Coverage
Test: powHSM firmware Lines: 44 46 95.7 %
Date: 2025-07-10 13:49:13 Functions: 5 5 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             : #include "bc_mm.h"
      26             : 
      27             : /*
      28             :  * Helper function: encode a RLP list prefix to the given buffer.
      29             :  *
      30             :  * @arg[in] list_size list size in bytes
      31             :  * @arg[out] buf      pointer to destination buffer
      32             :  */
      33         691 : static uint8_t rlp_encode_list_prefix(uint16_t list_size, uint8_t* buf) {
      34             :     uint8_t prefix_size;
      35         691 :     if (list_size <= 55) {
      36           0 :         prefix_size = 1;
      37           0 :         buf[0] = (RLP_SHORT_LIST_BASE + list_size) & 0xFF;
      38             :     } else {
      39         691 :         prefix_size = 0;
      40         691 :         uint16_t remaining = list_size;
      41        2073 :         while (remaining > 0) {
      42        1382 :             prefix_size++;
      43        1382 :             remaining >>= 8;
      44             :         }
      45         691 :         buf[0] = RLP_LONG_LIST_BASE + prefix_size;
      46         691 :         remaining = list_size;
      47        2073 :         for (uint8_t i = 0; i < prefix_size; i++) {
      48        1382 :             buf[prefix_size - i] = remaining & 0xff;
      49        1382 :             remaining >>= 8;
      50             :         }
      51         691 :         prefix_size++;
      52             :     }
      53             : 
      54         691 :     return prefix_size;
      55             : }
      56             : 
      57             : /*
      58             :  * Helper function: encode a RLP str prefix to the given buffer.
      59             :  *
      60             :  * The first_str_byte para is ignored for "good" strings. Those
      61             :  * are strings whose length is greater than one. It is safe to
      62             :  * just pass a zero. If you have a "bad" single byte string,
      63             :  * pass 1 for str_size and the unique string byte in the
      64             :  * first_str_byte parameter.
      65             :  *
      66             :  * @arg[in] str_size       string size in bytes
      67             :  * @arb[in] first_str_byte first byte of the string.
      68             :  * @arg[out] buf           pointer to destination buffer
      69             :  */
      70       12106 : static uint8_t rlp_encode_str_prefix(uint16_t str_size,
      71             :                                      uint8_t first_str_byte,
      72             :                                      uint8_t* buf) {
      73             :     uint8_t prefix_size;
      74       12106 :     if (str_size == 1 && first_str_byte <= RLP_MAX_SINGLE_BYTE) {
      75        1444 :         prefix_size = 0;
      76       10662 :     } else if (str_size <= 55) {
      77        9582 :         prefix_size = 1;
      78        9582 :         buf[0] = (RLP_SHORT_STRING_BASE + str_size) & 0xff;
      79             :     } else {
      80        1080 :         prefix_size = 0;
      81        1080 :         uint16_t remaining = str_size;
      82        2849 :         while (remaining > 0) {
      83        1769 :             prefix_size++;
      84        1769 :             remaining >>= 8;
      85             :         }
      86        1080 :         buf[0] = RLP_LONG_STRING_BASE + prefix_size;
      87        1080 :         remaining = str_size;
      88        2849 :         for (uint8_t i = 0; i < prefix_size; i++) {
      89        1769 :             buf[prefix_size - i] = remaining & 0xff;
      90        1769 :             remaining >>= 8;
      91             :         }
      92        1080 :         prefix_size++;
      93             :     }
      94             : 
      95       12106 :     return prefix_size;
      96             : }
      97             : 
      98             : static uint8_t prefix_buf[MAX_RLP_PREFIX_SIZE];
      99             : 
     100             : /*
     101             :  * Hash a RLP prefix for a list of the given size.
     102             :  *
     103             :  * @arg[out] kctx     Keccak context for hashing
     104             :  * @arg[in] list_size list size in bytes
     105             :  */
     106         691 : void mm_hash_rlp_list_prefix(keccak_ctx_t* kctx, uint16_t list_size) {
     107         691 :     uint8_t prefix_size = rlp_encode_list_prefix(list_size, prefix_buf);
     108         691 :     KECCAK_UPDATE(kctx, prefix_buf, prefix_size);
     109         691 : }
     110             : 
     111             : /*
     112             :  * Hash a RLP prefix for a "good" string of the given size.
     113             :  * A string is "good" if the RLP prefix can be determined
     114             :  * from the string length alone. This will be the case
     115             :  * any string with lenght greater than one.
     116             :  *
     117             :  * @arg[out] kctx     Keccak context for hashing
     118             :  * @arg[in] str_size  string size in bytes, must be greater than one
     119             :  */
     120       10662 : void mm_hash_good_rlp_str_prefix(keccak_ctx_t* kctx, uint16_t str_size) {
     121       10662 :     uint8_t prefix_size = rlp_encode_str_prefix(str_size, 0, prefix_buf);
     122       10662 :     KECCAK_UPDATE(kctx, prefix_buf, prefix_size);
     123       10662 : }
     124             : 
     125             : /*
     126             :  * Hash a RLP prefix for a "bad" string. Bad strings are one byte
     127             :  * long, and the prefix length is determined by the contexts of
     128             :  * the string's single byte.
     129             :  *
     130             :  * @arg[out] kctx Keccak context for hashing
     131             :  * @arg[in]  str  pointer to the bad string's single byte
     132             :  */
     133        1444 : void mm_hash_bad_rlp_str_prefix(keccak_ctx_t* kctx, const uint8_t* str) {
     134        1444 :     uint8_t prefix_size = rlp_encode_str_prefix(1, *str, prefix_buf);
     135        1444 :     KECCAK_UPDATE(kctx, prefix_buf, prefix_size);
     136        1444 : }

Generated by: LCOV version 1.16