LCOV - code coverage report
Current view: top level - src/edhoc - signature_or_mac_msg.c (source / functions) Hit Total Coverage
Test: lcov.info Lines: 61 69 88.4 %
Date: 2024-09-16 20:15:30 Functions: 3 3 100.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 87 222 39.2 %

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :    Copyright (c) 2021 Fraunhofer AISEC. See the COPYRIGHT
       3                 :            :    file at the top-level directory of this distribution.
       4                 :            : 
       5                 :            :    Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
       6                 :            :    http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
       7                 :            :    <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
       8                 :            :    option. This file may not be copied, modified, or distributed
       9                 :            :    except according to those terms.
      10                 :            : */
      11                 :            : 
      12                 :            : #include <stdint.h>
      13                 :            : 
      14                 :            : #include "edhoc/buffer_sizes.h"
      15                 :            : #include "edhoc/edhoc_cose.h"
      16                 :            : #include "edhoc/hkdf_info.h"
      17                 :            : #include "edhoc/okm.h"
      18                 :            : #include "edhoc/suites.h"
      19                 :            : #include "edhoc/signature_or_mac_msg.h"
      20                 :            : #include "edhoc/bstr_encode_decode.h"
      21                 :            : #include "edhoc/int_encode_decode.h"
      22                 :            : 
      23                 :            : #include "common/print_util.h"
      24                 :            : #include "common/crypto_wrapper.h"
      25                 :            : #include "common/oscore_edhoc_error.h"
      26                 :            : #include "common/memcpy_s.h"
      27                 :            : 
      28                 :            : #include "cbor/edhoc_encode_enc_structure.h"
      29                 :            : #include "cbor/edhoc_encode_sig_structure.h"
      30                 :            : 
      31                 :            : /**
      32                 :            :  * @brief                       Forms a serialized data structure from a set of 
      33                 :            :  *                              data items and computes a MAC over it.
      34                 :            :  * 
      35                 :            :  * @param[in] prk               The key to be used for the mac.
      36                 :            :  * @param[in] c_r               Connection identifier of the requester
      37                 :            :  * @param[in] th                Transcript hash.
      38                 :            :  * @param[in] id_cred           ID of the credential.
      39                 :            :  * @param[in] cred              The credential.
      40                 :            :  * @param[in] ead               External authorization data.
      41                 :            :  * @param mac_label             An info label.
      42                 :            :  * @param static_dh             True if static DH is used for authentication.
      43                 :            :  * @param suite                 The used crypto suite.
      44                 :            :  * @param[out] mac              The computed mac.
      45                 :            :  * @return                      Ok or error code.
      46                 :            :  */
      47                 :         12 : static enum err mac(const struct byte_array *prk, const struct byte_array *c_r,
      48                 :            :                     const struct byte_array *th,
      49                 :            :                     const struct byte_array *id_cred,
      50                 :            :                     const struct byte_array *cred, const struct byte_array *ead,
      51                 :            :                     enum info_label mac_label, bool static_dh,
      52                 :            :                     struct suite *suite, struct byte_array *mac)
      53                 :            : {
      54                 :            :         /*encode th as bstr*/
      55   [ +  -  -  +  :         12 :         BYTE_ARRAY_NEW(th_enc, AS_BSTR_SIZE(HASH_SIZE), AS_BSTR_SIZE(th->len));
          -  -  -  +  +  
          -  -  +  -  -  
          -  +  +  -  -  
                +  -  - ]
      56         [ -  + ]:         12 :         TRY(encode_bstr(th, &th_enc));
      57                 :            : 
      58                 :            :         /**/
      59   [ -  +  -  -  :         12 :         BYTE_ARRAY_NEW(context_mac, CONTEXT_MAC_SIZE,
          -  -  -  +  -  
          +  -  -  -  -  
          -  +  -  +  -  
                -  -  - ]
      60                 :            :                        AS_BSTR_SIZE(c_r->len) + id_cred->len + cred->len +
      61                 :            :                                ead->len + th_enc.len);
      62                 :         12 :         uint32_t capacity = context_mac.len;
      63                 :         12 :         context_mac.len = 0;
      64         [ +  + ]:         12 :         if (c_r->len != 0) {
      65   [ -  +  -  -  :          6 :                 BYTE_ARRAY_NEW(c_r_enc, AS_BSTR_SIZE(C_R_SIZE),
          -  -  -  +  -  
          +  -  -  -  -  
          -  +  -  +  -  
                -  -  - ]
      66                 :            :                                AS_BSTR_SIZE(c_r->len));
      67         [ -  + ]:          6 :                 if (c_r_is_raw_int(c_r)) {
      68         [ #  # ]:          0 :                         TRY(encode_int((const int32_t *)c_r->ptr, c_r->len,
      69                 :            :                                        &c_r_enc));
      70                 :            :                 } else {
      71         [ -  + ]:          6 :                         TRY(encode_bstr(c_r, &c_r_enc));
      72                 :            :                 }
      73         [ -  + ]:          6 :                 TRY(byte_array_append(&context_mac, &c_r_enc, capacity));
      74                 :            :         }
      75         [ -  + ]:         12 :         TRY(byte_array_append(&context_mac, id_cred, capacity));
      76         [ -  + ]:         12 :         TRY(byte_array_append(&context_mac, &th_enc, capacity));
      77         [ -  + ]:         12 :         TRY(byte_array_append(&context_mac, cred, capacity));
      78                 :            : 
      79         [ -  + ]:         12 :         if (0 < ead->len) {
      80         [ #  # ]:          0 :                 TRY(byte_array_append(&context_mac, ead, capacity));
      81                 :            :         }
      82                 :            : 
      83                 :         12 :         PRINT_ARRAY("MAC context", context_mac.ptr, context_mac.len);
      84                 :            : 
      85         [ -  + ]:         12 :         if (static_dh) {
      86                 :          0 :                 mac->len = suite->edhoc_mac_len_static_dh;
      87                 :            : 
      88                 :            :         } else {
      89                 :         12 :                 mac->len = get_hash_len(suite->edhoc_hash);
      90                 :            :         }
      91                 :            : 
      92         [ -  + ]:         12 :         TRY(edhoc_kdf(suite->edhoc_hash, prk, mac_label, &context_mac, mac));
      93                 :            : 
      94                 :         12 :         PRINT_ARRAY("MAC 2/3", mac->ptr, mac->len);
      95                 :         12 :         return ok;
      96                 :            : }
      97                 :            : 
      98                 :            : /**
      99                 :            :  * @brief                       Creates a byte array to be ready for signing. 
     100                 :            :  * 
     101                 :            :  * @param[in] th                Transcript hash.
     102                 :            :  * @param[in] id_cred           Id of the credential.
     103                 :            :  * @param[in] cred              The credential.
     104                 :            :  * @param[in] ead               External Authorization Data. 
     105                 :            :  * @param[in] mac               Message Authentication Code. 
     106                 :            :  * @param[out] out              The result.
     107                 :            :  * @return                      Ok or error code.
     108                 :            :  */
     109                 :         12 : static enum err signature_struct_gen(const struct byte_array *th,
     110                 :            :                                      const struct byte_array *id_cred,
     111                 :            :                                      const struct byte_array *cred,
     112                 :            :                                      const struct byte_array *ead,
     113                 :            :                                      const struct byte_array *mac,
     114                 :            :                                      struct byte_array *out)
     115                 :            : {
     116         [ -  + ]:         12 :         BYTE_ARRAY_NEW(th_enc, AS_BSTR_SIZE(HASH_SIZE),
     117                 :            :                        AS_BSTR_SIZE(HASH_SIZE));
     118                 :            : 
     119         [ -  + ]:         12 :         TRY(encode_bstr(th, &th_enc));
     120                 :            : 
     121   [ -  +  -  + ]:         12 :         BYTE_ARRAY_NEW(tmp,
     122                 :            :                        (CRED_MAX_SIZE + AS_BSTR_SIZE(HASH_SIZE) + EAD_SIZE),
     123                 :            :                        (th_enc.len + cred->len + ead->len));
     124                 :            : 
     125                 :         12 :         memcpy(tmp.ptr, th_enc.ptr, th_enc.len);
     126                 :         12 :         memcpy(tmp.ptr + th_enc.len, cred->ptr, cred->len);
     127         [ -  + ]:         12 :         if (ead->len != 0) {
     128                 :          0 :                 memcpy(tmp.ptr + th_enc.len + cred->len, ead->ptr, ead->len);
     129                 :            :         }
     130                 :            : 
     131                 :         12 :         uint8_t context_str[] = { "Signature1" };
     132                 :         12 :         struct byte_array str = BYTE_ARRAY_INIT(
     133                 :            :                 context_str, (uint32_t)strlen((char *)context_str));
     134                 :            : 
     135         [ -  + ]:         12 :         TRY(cose_sig_structure_encode(&str, id_cred, &tmp, mac, out));
     136                 :         12 :         PRINT_ARRAY("COSE_Sign1 object to be signed", out->ptr, out->len);
     137                 :         12 :         return ok;
     138                 :            : }
     139                 :            : 
     140                 :            : enum err
     141                 :         12 : signature_or_mac(enum sgn_or_mac_op op, bool static_dh, struct suite *suite,
     142                 :            :                  const struct byte_array *sk, const struct byte_array *pk,
     143                 :            :                  const struct byte_array *prk, const struct byte_array *c_r,
     144                 :            :                  const struct byte_array *th, const struct byte_array *id_cred,
     145                 :            :                  const struct byte_array *cred, const struct byte_array *ead,
     146                 :            :                  enum info_label mac_label, struct byte_array *signature_or_mac)
     147                 :            : {
     148         [ +  + ]:         12 :         if (op == GENERATE) {
     149                 :            :                 /*we always calculate the mac*/
     150         [ -  + ]:          6 :                 TRY(mac(prk, c_r, th, id_cred, cred, ead, mac_label, static_dh,
     151                 :            :                         suite, signature_or_mac));
     152                 :            : 
     153         [ -  + ]:          6 :                 if (static_dh) {
     154                 :            :                         /*signature_or_mac is mac when the caller of this function authenticates with static DH keys*/
     155                 :          0 :                         return ok;
     156                 :            :                 } else {
     157                 :          6 :                         PRINTF("SIG_STRUCT_SIZE: %d\n", SIG_STRUCT_SIZE);
     158   [ +  -  +  +  :          6 :                         uint32_t sig_struct_size = SIG_STRUCT_SIZE_CALC(
          +  -  +  -  -  
          +  -  -  +  -  
          +  -  -  +  -  
          -  +  -  +  -  
          -  +  -  -  +  
          -  +  -  -  +  
          -  -  +  -  -  
                +  -  - ]
     159                 :            :                                 COSE_SIGN1_STR_LEN, id_cred->len,
     160                 :            :                                 (AS_BSTR_SIZE(th->len) + cred->len + ead->len),
     161                 :            :                                 signature_or_mac->len);
     162                 :            : 
     163                 :          6 :                         PRINTF("sig_struct_size: %d\n", sig_struct_size);
     164   [ -  +  -  + ]:          6 :                         BYTE_ARRAY_NEW(sign_struct, SIG_STRUCT_SIZE,
     165                 :            :                                        sig_struct_size);
     166         [ -  + ]:          6 :                         TRY(signature_struct_gen(th, id_cred, cred, ead,
     167                 :            :                                                  signature_or_mac,
     168                 :            :                                                  &sign_struct));
     169                 :            : 
     170                 :          6 :                         signature_or_mac->len =
     171                 :          6 :                                 get_signature_len(suite->edhoc_sign);
     172                 :            : 
     173         [ -  + ]:          6 :                         TRY(sign(suite->edhoc_sign, sk, pk, &sign_struct,
     174                 :            :                                  signature_or_mac->ptr));
     175                 :          6 :                         PRINT_ARRAY("signature_or_mac (is signature)",
     176                 :            :                                     signature_or_mac->ptr,
     177                 :            :                                     signature_or_mac->len);
     178                 :            :                 }
     179                 :            :         } else { /*we verify here*/
     180   [ -  +  -  + ]:          6 :                 BYTE_ARRAY_NEW(_mac, HASH_SIZE,
     181                 :            :                                get_hash_len(suite->edhoc_hash));
     182                 :            : 
     183         [ -  + ]:          6 :                 TRY(mac(prk, c_r, th, id_cred, cred, ead, mac_label, static_dh,
     184                 :            :                         suite, &_mac));
     185                 :            : 
     186         [ -  + ]:          6 :                 if (static_dh) {
     187                 :            :                         /*signature_or_mac is mac when the caller of this function authenticates with static DH keys*/
     188                 :            : 
     189         [ #  # ]:          0 :                         if (0 != memcmp(_mac.ptr, signature_or_mac->ptr,
     190                 :            :                                         signature_or_mac->len)) {
     191                 :          0 :                                 return mac_authentication_failed;
     192                 :            :                         }
     193                 :            : 
     194                 :            :                 } else {
     195                 :          6 :                         PRINTF("SIG_STRUCT_SIZE: %d\n", SIG_STRUCT_SIZE);
     196   [ +  -  +  +  :          6 :                         uint32_t sig_struct_size = SIG_STRUCT_SIZE_CALC(
          +  -  +  -  -  
          +  -  -  +  -  
          +  -  -  +  -  
          -  +  -  +  -  
          -  +  -  -  +  
          -  +  -  -  +  
          -  -  +  -  -  
                +  -  - ]
     197                 :            :                                 COSE_SIGN1_STR_LEN, id_cred->len,
     198                 :            :                                 (AS_BSTR_SIZE(th->len) + cred->len + ead->len),
     199                 :            :                                 _mac.len);
     200                 :            : 
     201                 :          6 :                         PRINTF("sig_struct_size: %d\n", sig_struct_size);
     202   [ -  +  -  + ]:          6 :                         BYTE_ARRAY_NEW(sign_struct, SIG_STRUCT_SIZE,
     203                 :            :                                        sig_struct_size);
     204         [ -  + ]:          6 :                         TRY(signature_struct_gen(th, id_cred, cred, ead, &_mac,
     205                 :            :                                                  &sign_struct));
     206                 :            : 
     207                 :            :                         bool result;
     208                 :          6 :                         PRINT_ARRAY("pk", pk->ptr, pk->len);
     209                 :          6 :                         PRINT_ARRAY("signature_struct", sign_struct.ptr,
     210                 :            :                                     sign_struct.len);
     211                 :          6 :                         PRINT_ARRAY("signature_or_mac", signature_or_mac->ptr,
     212                 :            :                                     signature_or_mac->len);
     213                 :            : 
     214         [ -  + ]:          6 :                         TRY(verify(suite->edhoc_sign, pk,
     215                 :            :                                    (struct const_byte_array *)&sign_struct,
     216                 :            :                                    (struct const_byte_array *)signature_or_mac,
     217                 :            :                                    &result));
     218         [ -  + ]:          6 :                         if (!result) {
     219                 :          0 :                                 return signature_authentication_failed;
     220                 :            :                         }
     221                 :          6 :                         PRINT_MSG(
     222                 :            :                                 "Signature or MAC verification successful!\n");
     223                 :            :                 }
     224                 :            :         }
     225                 :         12 :         return ok;
     226                 :            : }

Generated by: LCOV version 1.14