root/drivers/md/dm-verity-verify-sig.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. verity_verify_is_sig_opt_arg
  2. verity_verify_get_sig_from_key
  3. verity_verify_sig_parse_opt_args
  4. verity_verify_root_hash
  5. verity_verify_sig_opts_cleanup

   1 // SPDX-License-Identifier: GPL-2.0
   2 /*
   3  * Copyright (C) 2019 Microsoft Corporation.
   4  *
   5  * Author:  Jaskaran Singh Khurana <jaskarankhurana@linux.microsoft.com>
   6  *
   7  */
   8 #include <linux/device-mapper.h>
   9 #include <linux/verification.h>
  10 #include <keys/user-type.h>
  11 #include <linux/module.h>
  12 #include "dm-verity.h"
  13 #include "dm-verity-verify-sig.h"
  14 
  15 #define DM_VERITY_VERIFY_ERR(s) DM_VERITY_ROOT_HASH_VERIFICATION " " s
  16 
  17 static bool require_signatures;
  18 module_param(require_signatures, bool, false);
  19 MODULE_PARM_DESC(require_signatures,
  20                 "Verify the roothash of dm-verity hash tree");
  21 
  22 #define DM_VERITY_IS_SIG_FORCE_ENABLED() \
  23         (require_signatures != false)
  24 
  25 bool verity_verify_is_sig_opt_arg(const char *arg_name)
  26 {
  27         return (!strcasecmp(arg_name,
  28                             DM_VERITY_ROOT_HASH_VERIFICATION_OPT_SIG_KEY));
  29 }
  30 
  31 static int verity_verify_get_sig_from_key(const char *key_desc,
  32                                         struct dm_verity_sig_opts *sig_opts)
  33 {
  34         struct key *key;
  35         const struct user_key_payload *ukp;
  36         int ret = 0;
  37 
  38         key = request_key(&key_type_user,
  39                         key_desc, NULL);
  40         if (IS_ERR(key))
  41                 return PTR_ERR(key);
  42 
  43         down_read(&key->sem);
  44 
  45         ukp = user_key_payload_locked(key);
  46         if (!ukp) {
  47                 ret = -EKEYREVOKED;
  48                 goto end;
  49         }
  50 
  51         sig_opts->sig = kmalloc(ukp->datalen, GFP_KERNEL);
  52         if (!sig_opts->sig) {
  53                 ret = -ENOMEM;
  54                 goto end;
  55         }
  56         sig_opts->sig_size = ukp->datalen;
  57 
  58         memcpy(sig_opts->sig, ukp->data, sig_opts->sig_size);
  59 
  60 end:
  61         up_read(&key->sem);
  62         key_put(key);
  63 
  64         return ret;
  65 }
  66 
  67 int verity_verify_sig_parse_opt_args(struct dm_arg_set *as,
  68                                      struct dm_verity *v,
  69                                      struct dm_verity_sig_opts *sig_opts,
  70                                      unsigned int *argc,
  71                                      const char *arg_name)
  72 {
  73         struct dm_target *ti = v->ti;
  74         int ret = 0;
  75         const char *sig_key = NULL;
  76 
  77         if (!*argc) {
  78                 ti->error = DM_VERITY_VERIFY_ERR("Signature key not specified");
  79                 return -EINVAL;
  80         }
  81 
  82         sig_key = dm_shift_arg(as);
  83         (*argc)--;
  84 
  85         ret = verity_verify_get_sig_from_key(sig_key, sig_opts);
  86         if (ret < 0)
  87                 ti->error = DM_VERITY_VERIFY_ERR("Invalid key specified");
  88 
  89         v->signature_key_desc = kstrdup(sig_key, GFP_KERNEL);
  90         if (!v->signature_key_desc)
  91                 return -ENOMEM;
  92 
  93         return ret;
  94 }
  95 
  96 /*
  97  * verify_verify_roothash - Verify the root hash of the verity hash device
  98  *                           using builtin trusted keys.
  99  *
 100  * @root_hash: For verity, the roothash/data to be verified.
 101  * @root_hash_len: Size of the roothash/data to be verified.
 102  * @sig_data: The trusted signature that verifies the roothash/data.
 103  * @sig_len: Size of the signature.
 104  *
 105  */
 106 int verity_verify_root_hash(const void *root_hash, size_t root_hash_len,
 107                             const void *sig_data, size_t sig_len)
 108 {
 109         int ret;
 110 
 111         if (!root_hash || root_hash_len == 0)
 112                 return -EINVAL;
 113 
 114         if (!sig_data  || sig_len == 0) {
 115                 if (DM_VERITY_IS_SIG_FORCE_ENABLED())
 116                         return -ENOKEY;
 117                 else
 118                         return 0;
 119         }
 120 
 121         ret = verify_pkcs7_signature(root_hash, root_hash_len, sig_data,
 122                                 sig_len, NULL, VERIFYING_UNSPECIFIED_SIGNATURE,
 123                                 NULL, NULL);
 124 
 125         return ret;
 126 }
 127 
 128 void verity_verify_sig_opts_cleanup(struct dm_verity_sig_opts *sig_opts)
 129 {
 130         kfree(sig_opts->sig);
 131         sig_opts->sig = NULL;
 132         sig_opts->sig_size = 0;
 133 }

/* [<][>][^][v][top][bottom][index][help] */