LCOV - code coverage report
Current view: top level - egg - egg-keyring1-libgcrypt.c (source / functions) Hit Total Coverage
Test: Code coverage Lines: 64 79 81.0 %
Date: 2024-02-08 14:44:34 Functions: 7 7 100.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 18 34 52.9 %

           Branch data     Line data    Source code
       1                 :            : /* libsecret - GLib wrapper for Secret Service
       2                 :            :  *
       3                 :            :  * Copyright 2019 Red Hat, Inc.
       4                 :            :  *
       5                 :            :  * This program is free software: you can redistribute it and/or modify
       6                 :            :  * it under the terms of the GNU Lesser General Public License as published
       7                 :            :  * by the Free Software Foundation; either version 2.1 of the licence or (at
       8                 :            :  * your option) any later version.
       9                 :            :  *
      10                 :            :  * See the included COPYING file for more information.
      11                 :            :  *
      12                 :            :  * Author: Daiki Ueno
      13                 :            :  */
      14                 :            : 
      15                 :            : #include "config.h"
      16                 :            : 
      17                 :            : #include "egg-keyring1.h"
      18                 :            : 
      19                 :            : #include "egg/egg-secure-memory.h"
      20                 :            : 
      21                 :         19 : EGG_SECURE_DECLARE (egg_keyring1);
      22                 :            : 
      23                 :            : #include <gcrypt.h>
      24                 :            : 
      25                 :            : #define PBKDF2_HASH_ALGO GCRY_MD_SHA256
      26                 :            : #define MAC_ALGO GCRY_MAC_HMAC_SHA256
      27                 :            : #define CIPHER_ALGO GCRY_CIPHER_AES128
      28                 :            : 
      29                 :            : void
      30                 :         20 : egg_keyring1_create_nonce (guint8 *nonce,
      31                 :            :                            gsize nonce_size)
      32                 :            : {
      33                 :         20 :         gcry_create_nonce (nonce, nonce_size);
      34                 :         20 : }
      35                 :            : 
      36                 :            : GBytes *
      37                 :         19 : egg_keyring1_derive_key (const gchar *password,
      38                 :            :                          gsize n_password,
      39                 :            :                          GBytes *salt,
      40                 :            :                          guint32 iteration_count)
      41                 :            : {
      42                 :            :         guint8 *buffer;
      43                 :            :         gcry_error_t gcry;
      44                 :            : 
      45                 :         19 :         buffer = egg_secure_alloc (KEY_SIZE);
      46         [ -  + ]:         19 :         g_return_val_if_fail (buffer, NULL);
      47                 :            : 
      48                 :         19 :         gcry = gcry_kdf_derive (password,
      49                 :            :                                 n_password,
      50                 :            :                                 GCRY_KDF_PBKDF2, PBKDF2_HASH_ALGO,
      51                 :            :                                 g_bytes_get_data (salt, NULL),
      52                 :            :                                 g_bytes_get_size (salt),
      53                 :            :                                 iteration_count,
      54                 :            :                                 KEY_SIZE, buffer);
      55         [ -  + ]:         19 :         if (gcry != 0) {
      56                 :          0 :                 egg_secure_free (buffer);
      57                 :          0 :                 return NULL;
      58                 :            :         }
      59                 :            : 
      60                 :         19 :         return g_bytes_new_with_free_func (buffer,
      61                 :            :                                            KEY_SIZE,
      62                 :            :                                            egg_secure_free,
      63                 :            :                                            buffer);
      64                 :            : }
      65                 :            : 
      66                 :            : gboolean
      67                 :         75 : egg_keyring1_calculate_mac (GBytes *key,
      68                 :            :                             const guint8 *value,
      69                 :            :                             gsize n_value,
      70                 :            :                             guint8 *buffer)
      71                 :            : {
      72                 :            :         gcry_mac_hd_t hd;
      73                 :            :         gcry_error_t gcry;
      74                 :            :         gconstpointer secret;
      75                 :            :         gsize n_secret;
      76                 :         75 :         gboolean ret = FALSE;
      77                 :            : 
      78                 :         75 :         gcry = gcry_mac_open (&hd, MAC_ALGO, 0, NULL);
      79         [ -  + ]:         75 :         g_return_val_if_fail (gcry == 0, FALSE);
      80                 :            : 
      81                 :         75 :         secret = g_bytes_get_data (key, &n_secret);
      82                 :         75 :         gcry = gcry_mac_setkey (hd, secret, n_secret);
      83         [ -  + ]:         75 :         if (gcry != 0)
      84                 :          0 :                 goto out;
      85                 :            : 
      86                 :         75 :         gcry = gcry_mac_write (hd, value, n_value);
      87         [ -  + ]:         75 :         if (gcry != 0)
      88                 :          0 :                 goto out;
      89                 :            : 
      90                 :         75 :         n_value = MAC_SIZE;
      91                 :         75 :         gcry = gcry_mac_read (hd, buffer, &n_value);
      92         [ -  + ]:         75 :         if (gcry != 0)
      93                 :          0 :                 goto out;
      94                 :            : 
      95         [ -  + ]:         75 :         if (n_value != MAC_SIZE)
      96                 :          0 :                 goto out;
      97                 :            : 
      98                 :         75 :         ret = TRUE;
      99                 :         75 :  out:
     100                 :         75 :         gcry_mac_close (hd);
     101                 :         75 :         return ret;
     102                 :            : }
     103                 :            : 
     104                 :            : gboolean
     105                 :         34 : egg_keyring1_verify_mac (GBytes *key,
     106                 :            :                          const guint8 *value,
     107                 :            :                          gsize n_value,
     108                 :            :                          const guint8 *data)
     109                 :            : {
     110                 :            :         guint8 buffer[MAC_SIZE];
     111                 :         34 :         guint8 status = 0;
     112                 :            :         gsize i;
     113                 :            : 
     114         [ -  + ]:         34 :         if (!egg_keyring1_calculate_mac (key, value, n_value, buffer)) {
     115                 :          0 :                 return FALSE;
     116                 :            :         }
     117                 :            : 
     118         [ +  + ]:       1122 :         for (i = 0; i < MAC_SIZE; i++) {
     119                 :       1088 :                 status |= data[i] ^ buffer[i];
     120                 :            :         }
     121                 :            : 
     122                 :         34 :         return status == 0;
     123                 :            : }
     124                 :            : 
     125                 :            : gboolean
     126                 :         11 : egg_keyring1_decrypt (GBytes *key,
     127                 :            :                       guint8 *data,
     128                 :            :                       gsize n_data)
     129                 :            : {
     130                 :            :         gcry_cipher_hd_t hd;
     131                 :            :         gcry_error_t gcry;
     132                 :            :         gconstpointer secret;
     133                 :            :         gsize n_secret;
     134                 :         11 :         gboolean ret = FALSE;
     135                 :            : 
     136                 :         11 :         gcry = gcry_cipher_open (&hd, CIPHER_ALGO, GCRY_CIPHER_MODE_CBC, 0);
     137         [ -  + ]:         11 :         if (gcry != 0)
     138                 :          0 :                 goto out;
     139                 :            : 
     140                 :         11 :         secret = g_bytes_get_data (key, &n_secret);
     141                 :         11 :         gcry = gcry_cipher_setkey (hd, secret, n_secret);
     142         [ -  + ]:         11 :         if (gcry != 0)
     143                 :          0 :                 goto out;
     144                 :            : 
     145                 :         11 :         gcry = gcry_cipher_setiv (hd, data + n_data, IV_SIZE);
     146         [ -  + ]:         11 :         if (gcry != 0)
     147                 :          0 :                 goto out;
     148                 :            : 
     149                 :         11 :         gcry = gcry_cipher_decrypt (hd, data, n_data, NULL, 0);
     150         [ -  + ]:         11 :         if (gcry != 0)
     151                 :          0 :                 goto out;
     152                 :            : 
     153                 :         11 :         ret = TRUE;
     154                 :         11 :  out:
     155                 :         11 :         gcry_cipher_close (hd);
     156                 :         11 :         return ret;
     157                 :            : }
     158                 :            : 
     159                 :            : gboolean
     160                 :         12 : egg_keyring1_encrypt (GBytes *key,
     161                 :            :                       guint8 *data,
     162                 :            :                       gsize n_data)
     163                 :            : {
     164                 :            :         gcry_cipher_hd_t hd;
     165                 :            :         gcry_error_t gcry;
     166                 :            :         gconstpointer secret;
     167                 :            :         gsize n_secret;
     168                 :         12 :         gboolean ret = FALSE;
     169                 :            : 
     170                 :         12 :         gcry = gcry_cipher_open (&hd, CIPHER_ALGO, GCRY_CIPHER_MODE_CBC, 0);
     171         [ -  + ]:         12 :         if (gcry != 0)
     172                 :          0 :                 goto out;
     173                 :            : 
     174                 :         12 :         secret = g_bytes_get_data (key, &n_secret);
     175                 :         12 :         gcry = gcry_cipher_setkey (hd, secret, n_secret);
     176         [ -  + ]:         12 :         if (gcry != 0)
     177                 :          0 :                 goto out;
     178                 :            : 
     179                 :         12 :         egg_keyring1_create_nonce (data + n_data, IV_SIZE);
     180                 :            : 
     181                 :         12 :         gcry = gcry_cipher_setiv (hd, data + n_data, IV_SIZE);
     182         [ -  + ]:         12 :         if (gcry != 0)
     183                 :          0 :                 goto out;
     184                 :            : 
     185                 :         12 :         gcry = gcry_cipher_encrypt (hd, data, n_data, NULL, 0);
     186         [ -  + ]:         12 :         if (gcry != 0)
     187                 :          0 :                 goto out;
     188                 :            : 
     189                 :         12 :         ret = TRUE;
     190                 :         12 :  out:
     191                 :         12 :         gcry_cipher_close (hd);
     192                 :         12 :         return ret;
     193                 :            : }

Generated by: LCOV version 1.14